From 6e8f2c819cf12e371011eeeefe6f884ed3739549 Mon Sep 17 00:00:00 2001 From: Santiago Pericas-Geertsen Date: Wed, 29 May 2024 13:51:12 -0400 Subject: [PATCH] Ports helidon-microprofile-core module from 3.x and moves additional classes to helidon-grpc module. Signed-off-by: Santiago Pericas-Geertsen --- grpc/core/pom.xml | 4 + .../java/io/helidon/grpc/core/GrpcHelper.java | 157 ++++++ .../helidon/grpc/core/MarshallerSupplier.java | 10 + .../io/helidon/grpc/core/ResponseHelper.java | 455 ++++++++++++++++++ .../helidon/grpc/core/SafeStreamObserver.java | 169 +++++++ grpc/core/src/main/java/module-info.java | 4 + microprofile/grpc/client/pom.xml | 66 --- .../grpc/client/ChannelProducer.java | 115 ----- .../grpc/client/DelegatingBeanAttributes.java | 98 ---- .../microprofile/grpc/client/GrpcChannel.java | 92 ---- .../grpc/client/GrpcClientBuilder.java | 198 -------- .../grpc/client/GrpcClientCdiExtension.java | 115 ----- .../microprofile/grpc/client/GrpcProxy.java | 50 -- .../grpc/client/GrpcProxyBuilder.java | 124 ----- .../grpc/client/GrpcProxyProducer.java | 89 ---- .../grpc/client/package-info.java | 20 - .../client/src/main/java/module-info.java | 37 -- .../src/main/resources/META-INF/beans.xml | 25 - .../grpc/client/GrpcClientBuilderTest.java | 249 ---------- .../grpc/client/GrpcProxyBuilderTest.java | 43 -- .../grpc/client/StubMarshaller.java | 53 -- .../io.helidon.grpc.core.MarshallerSupplier | 17 - microprofile/grpc/core/pom.xml | 6 +- .../core/AbstractMethodHandlerSupplier.java | 2 +- .../grpc/core/AbstractServiceBuilder.java | 6 +- .../grpc/core/AnnotatedMethod.java | 2 +- .../grpc/core/AnnotatedMethodList.java | 2 +- .../microprofile/grpc/core/Bidirectional.java | 2 +- .../BidirectionalMethodHandlerSupplier.java | 2 +- .../grpc/core/ClientStreaming.java | 2 +- .../ClientStreamingMethodHandlerSupplier.java | 2 +- .../helidon/microprofile/grpc/core/Grpc.java | 2 +- .../grpc/core/GrpcCdiExtension.java | 2 +- .../grpc/core/GrpcInterceptor.java | 2 +- .../grpc/core/GrpcInterceptorBinding.java | 2 +- .../grpc/core/GrpcInterceptors.java | 2 +- .../grpc/core/GrpcMarshaller.java | 2 +- .../microprofile/grpc/core/GrpcMethod.java | 2 +- .../grpc/core/InProcessGrpcChannel.java | 2 +- .../microprofile/grpc/core/Instance.java | 2 +- .../grpc/core/MethodHandlerSupplier.java | 2 +- .../microprofile/grpc/core/ModelHelper.java | 2 +- .../microprofile/grpc/core/RequestType.java | 2 +- .../microprofile/grpc/core/ResponseType.java | 2 +- .../grpc/core/ServerStreaming.java | 2 +- .../ServerStreamingMethodHandlerSupplier.java | 2 +- .../helidon/microprofile/grpc/core/Unary.java | 2 +- .../grpc/core/UnaryMethodHandlerSupplier.java | 2 +- .../microprofile/grpc/core/package-info.java | 2 +- .../grpc/core/src/main/java/module-info.java | 6 +- .../AbstractMethodHandlerSupplierTest.java | 2 +- .../grpc/core/AnnotatedMethodListTest.java | 2 +- .../grpc/core/AnnotatedMethodTest.java | 2 +- ...idirectionalMethodHandlerSupplierTest.java | 2 +- ...entStreamingMethodHandlerSupplierTest.java | 2 +- .../microprofile/grpc/core/InstanceTest.java | 2 +- .../grpc/core/MethodHandlerTest.java | 2 +- .../grpc/core/ModelHelperTest.java | 2 +- ...verStreamingMethodHandlerSupplierTest.java | 2 +- .../core/UnaryMethodHandlerSupplierTest.java | 2 +- microprofile/grpc/metrics/README.md | 104 ---- microprofile/grpc/metrics/pom.xml | 108 ----- ...GrpcMetricAnnotationDiscoveryObserver.java | 99 ---- .../GrpcMetricRegistrationObserver.java | 57 --- .../grpc/metrics/GrpcMetricsCdiExtension.java | 39 -- .../grpc/metrics/MetricsConfigurer.java | 168 ------- .../grpc/metrics/package-info.java | 20 - .../metrics/src/main/java/module-info.java | 38 -- .../src/main/resources/META-INF/beans.xml | 25 - .../grpc/metrics/CoverageTestBeanBase.java | 22 - .../CoverageTestBeanConcurrentGauge.java | 28 -- .../grpc/metrics/CoverageTestBeanCounted.java | 28 -- .../grpc/metrics/CoverageTestBeanMetered.java | 28 -- .../metrics/CoverageTestBeanSimplyTimed.java | 28 -- .../grpc/metrics/CoverageTestBeanTimed.java | 28 -- .../GrpcMetricsCoverageTestCdiExtension.java | 137 ------ .../grpc/metrics/TestMetricsCoverage.java | 118 ----- ...s.TestMetricsCoverage$GeneratedBeanCatalog | 18 - microprofile/grpc/pom.xml | 3 - microprofile/grpc/server/pom.xml | 121 ----- .../server/AnnotatedServiceConfigurer.java | 40 -- .../grpc/server/GrpcServerCdiExtension.java | 329 ------------- .../grpc/server/GrpcServiceBuilder.java | 364 -------------- .../grpc/server/package-info.java | 20 - .../grpc/server/spi/GrpcMpContext.java | 76 --- .../grpc/server/spi/GrpcMpExtension.java | 29 -- .../grpc/server/spi/package-info.java | 20 - .../server/src/main/java/module-info.java | 44 -- .../src/main/resources/META-INF/beans.xml | 25 - .../grpc/server/GrpcServiceBuilderTest.java | 331 ------------- .../grpc/server/StubMarshaller.java | 53 -- .../grpc/server/src/test/proto/services.proto | 58 --- .../src/test/resources/META-INF/beans.xml | 25 - .../io.helidon.grpc.core.MarshallerSupplier | 17 - ...croprofile.grpc.server.spi.GrpcMpExtension | 17 - .../src/test/resources/logging.properties | 34 -- 96 files changed, 843 insertions(+), 4134 deletions(-) create mode 100644 grpc/core/src/main/java/io/helidon/grpc/core/GrpcHelper.java create mode 100644 grpc/core/src/main/java/io/helidon/grpc/core/ResponseHelper.java create mode 100644 grpc/core/src/main/java/io/helidon/grpc/core/SafeStreamObserver.java delete mode 100644 microprofile/grpc/client/pom.xml delete mode 100644 microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/ChannelProducer.java delete mode 100644 microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/DelegatingBeanAttributes.java delete mode 100644 microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcChannel.java delete mode 100644 microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcClientBuilder.java delete mode 100644 microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcClientCdiExtension.java delete mode 100644 microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcProxy.java delete mode 100644 microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcProxyBuilder.java delete mode 100644 microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcProxyProducer.java delete mode 100644 microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/package-info.java delete mode 100644 microprofile/grpc/client/src/main/java/module-info.java delete mode 100644 microprofile/grpc/client/src/main/resources/META-INF/beans.xml delete mode 100644 microprofile/grpc/client/src/test/java/io/helidon/microprofile/grpc/client/GrpcClientBuilderTest.java delete mode 100644 microprofile/grpc/client/src/test/java/io/helidon/microprofile/grpc/client/GrpcProxyBuilderTest.java delete mode 100644 microprofile/grpc/client/src/test/java/io/helidon/microprofile/grpc/client/StubMarshaller.java delete mode 100644 microprofile/grpc/client/src/test/resources/META-INF/services/io.helidon.grpc.core.MarshallerSupplier delete mode 100644 microprofile/grpc/metrics/README.md delete mode 100644 microprofile/grpc/metrics/pom.xml delete mode 100644 microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/GrpcMetricAnnotationDiscoveryObserver.java delete mode 100644 microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/GrpcMetricRegistrationObserver.java delete mode 100644 microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/GrpcMetricsCdiExtension.java delete mode 100644 microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/MetricsConfigurer.java delete mode 100644 microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/package-info.java delete mode 100644 microprofile/grpc/metrics/src/main/java/module-info.java delete mode 100644 microprofile/grpc/metrics/src/main/resources/META-INF/beans.xml delete mode 100644 microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanBase.java delete mode 100644 microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanConcurrentGauge.java delete mode 100644 microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanCounted.java delete mode 100644 microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanMetered.java delete mode 100644 microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanSimplyTimed.java delete mode 100644 microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanTimed.java delete mode 100644 microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/GrpcMetricsCoverageTestCdiExtension.java delete mode 100644 microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/TestMetricsCoverage.java delete mode 100644 microprofile/grpc/metrics/src/test/resources/META-INF/services/io.helidon.microprofile.grpc.metrics.TestMetricsCoverage$GeneratedBeanCatalog delete mode 100644 microprofile/grpc/server/pom.xml delete mode 100644 microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/AnnotatedServiceConfigurer.java delete mode 100644 microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/GrpcServerCdiExtension.java delete mode 100644 microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/GrpcServiceBuilder.java delete mode 100644 microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/package-info.java delete mode 100644 microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/spi/GrpcMpContext.java delete mode 100644 microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/spi/GrpcMpExtension.java delete mode 100644 microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/spi/package-info.java delete mode 100644 microprofile/grpc/server/src/main/java/module-info.java delete mode 100644 microprofile/grpc/server/src/main/resources/META-INF/beans.xml delete mode 100644 microprofile/grpc/server/src/test/java/io/helidon/microprofile/grpc/server/GrpcServiceBuilderTest.java delete mode 100644 microprofile/grpc/server/src/test/java/io/helidon/microprofile/grpc/server/StubMarshaller.java delete mode 100644 microprofile/grpc/server/src/test/proto/services.proto delete mode 100644 microprofile/grpc/server/src/test/resources/META-INF/beans.xml delete mode 100644 microprofile/grpc/server/src/test/resources/META-INF/services/io.helidon.grpc.core.MarshallerSupplier delete mode 100644 microprofile/grpc/server/src/test/resources/META-INF/services/io.helidon.microprofile.grpc.server.spi.GrpcMpExtension delete mode 100644 microprofile/grpc/server/src/test/resources/logging.properties diff --git a/grpc/core/pom.xml b/grpc/core/pom.xml index a1a059712c2..5dab7401202 100644 --- a/grpc/core/pom.xml +++ b/grpc/core/pom.xml @@ -33,6 +33,10 @@ io.helidon.common helidon-common + + io.helidon.http + helidon-http + io.grpc grpc-api diff --git a/grpc/core/src/main/java/io/helidon/grpc/core/GrpcHelper.java b/grpc/core/src/main/java/io/helidon/grpc/core/GrpcHelper.java new file mode 100644 index 00000000000..dbba7cc24cf --- /dev/null +++ b/grpc/core/src/main/java/io/helidon/grpc/core/GrpcHelper.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.helidon.grpc.core; + +import io.grpc.Status; +import io.grpc.StatusException; +import io.grpc.StatusRuntimeException; + +/** + * Helper methods for common gRPC tasks. + */ +public final class GrpcHelper { + + /** + * Private constructor for utility class. + */ + private GrpcHelper() { + } + + /** + * Extract the gRPC service name from a method full name. + * + * @param fullMethodName the gRPC method full name + * + * @return the service name extracted from the full name + */ + public static String extractServiceName(String fullMethodName) { + int index = fullMethodName.indexOf('/'); + return index == -1 ? fullMethodName : fullMethodName.substring(0, index); + } + + /** + * Extract the name prefix from a method full name. + *

+ * The prefix is everything upto the but not including the last + * '/' character in the full name. + * + * @param fullMethodName the gRPC method full name + * + * @return the name prefix extracted from the full name + */ + public static String extractNamePrefix(String fullMethodName) { + int index = fullMethodName.lastIndexOf('/'); + return index == -1 ? fullMethodName : fullMethodName.substring(0, index); + } + + /** + * Extract the gRPC method name from a method full name. + * + * @param fullMethodName the gRPC method full name + * + * @return the method name extracted from the full name + */ + public static String extractMethodName(String fullMethodName) { + int index = fullMethodName.lastIndexOf('/'); + return index == -1 ? fullMethodName : fullMethodName.substring(index + 1); + } + + /** + * Convert a gRPC {@link StatusException} to a {@link io.helidon.http.Status}. + * + * @param ex the gRPC {@link StatusException} to convert + * + * @return the gRPC {@link StatusException} converted to a {@link io.helidon.http.Status} + */ + public static io.helidon.http.Status toHttpResponseStatus(StatusException ex) { + return toHttpResponseStatus(ex.getStatus()); + } + + /** + * Convert a gRPC {@link StatusRuntimeException} to a {@link io.helidon.http.Status}. + * + * @param ex the gRPC {@link StatusRuntimeException} to convert + * + * @return the gRPC {@link StatusRuntimeException} converted to a {@link io.helidon.http.Status} + */ + public static io.helidon.http.Status toHttpResponseStatus(StatusRuntimeException ex) { + return toHttpResponseStatus(ex.getStatus()); + } + + /** + * Convert a gRPC {@link Status} to a {@link io.helidon.http.Status}. + * + * @param status the gRPC {@link Status} to convert + * + * @return the gRPC {@link Status} converted to a {@link io.helidon.http.Status} + */ + public static io.helidon.http.Status toHttpResponseStatus(Status status) { + io.helidon.http.Status httpStatus = switch (status.getCode()) { + case OK -> io.helidon.http.Status.create(200, status.getDescription()); + case INVALID_ARGUMENT -> io.helidon.http.Status.create(400, status.getDescription()); + case DEADLINE_EXCEEDED -> io.helidon.http.Status.create(408, status.getDescription()); + case NOT_FOUND -> io.helidon.http.Status.create(404, status.getDescription()); + case ALREADY_EXISTS -> io.helidon.http.Status.create(412, status.getDescription()); + case PERMISSION_DENIED -> io.helidon.http.Status.create(403, status.getDescription()); + case FAILED_PRECONDITION -> io.helidon.http.Status.create(412, status.getDescription()); + case OUT_OF_RANGE -> io.helidon.http.Status.create(400, status.getDescription()); + case UNIMPLEMENTED -> io.helidon.http.Status.create(501, status.getDescription()); + case UNAVAILABLE -> io.helidon.http.Status.create(503, status.getDescription()); + case UNAUTHENTICATED -> io.helidon.http.Status.create(401, status.getDescription()); + default -> io.helidon.http.Status.create(500, status.getDescription()); + }; + return httpStatus; + } + + /** + * Ensure that a {@link Throwable} is either a {@link StatusRuntimeException} or + * a {@link StatusException}. + * + * @param thrown the {@link Throwable} to test + * @param status the {@link Status} to use if the {@link Throwable} has to be converted + * @return the {@link Throwable} if it is a {@link StatusRuntimeException} or a + * {@link StatusException}, or a new {@link StatusException} created from the + * specified {@link Status} with the {@link Throwable} as the cause. + */ + public static Throwable ensureStatusException(Throwable thrown, Status status) { + if (thrown instanceof StatusRuntimeException || thrown instanceof StatusException) { + return thrown; + } else { + return status.withCause(thrown).asException(); + } + } + + /** + * Ensure that a {@link Throwable} is a {@link StatusRuntimeException}. + * + * @param thrown the {@link Throwable} to test + * @param status the {@link Status} to use if the {@link Throwable} has to be converted + * @return the {@link Throwable} if it is a {@link StatusRuntimeException} or a new + * {@link StatusRuntimeException} created from the specified {@link Status} + * with the {@link Throwable} as the cause. + */ + public static StatusRuntimeException ensureStatusRuntimeException(Throwable thrown, Status status) { + if (thrown instanceof StatusRuntimeException) { + return (StatusRuntimeException) thrown; + } else if (thrown instanceof StatusException) { + StatusException ex = (StatusException) thrown; + return new StatusRuntimeException(ex.getStatus(), ex.getTrailers()); + } else { + return status.withCause(thrown).asRuntimeException(); + } + } +} diff --git a/grpc/core/src/main/java/io/helidon/grpc/core/MarshallerSupplier.java b/grpc/core/src/main/java/io/helidon/grpc/core/MarshallerSupplier.java index 625d777f775..a4d7ed7298b 100644 --- a/grpc/core/src/main/java/io/helidon/grpc/core/MarshallerSupplier.java +++ b/grpc/core/src/main/java/io/helidon/grpc/core/MarshallerSupplier.java @@ -25,6 +25,16 @@ @FunctionalInterface public interface MarshallerSupplier { + /** + * The name of the Protocol Buffer marshaller supplier. + */ + String PROTO = "proto"; + + /** + * The name to use to specify the default marshaller supplier. + */ + String DEFAULT = "default"; + /** * Obtain a {@link MethodDescriptor.Marshaller} for a type. * diff --git a/grpc/core/src/main/java/io/helidon/grpc/core/ResponseHelper.java b/grpc/core/src/main/java/io/helidon/grpc/core/ResponseHelper.java new file mode 100644 index 00000000000..e95afb2a83a --- /dev/null +++ b/grpc/core/src/main/java/io/helidon/grpc/core/ResponseHelper.java @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.helidon.grpc.core; + +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import io.grpc.stub.StreamObserver; + +/** + * A number of helper methods to handle sending responses to a {@link StreamObserver}. + */ +public final class ResponseHelper { + private ResponseHelper() { + } + + /** + * Complete a gRPC request. + *

+ * The request will be completed by calling {@link StreamObserver#onNext(Object)} using the + * specified value then calling {@link StreamObserver#onCompleted()}. + * + * @param observer the {@link StreamObserver} to complete + * @param value the value to use when calling {@link StreamObserver#onNext(Object)} + * @param they type of the request result + */ + public static void complete(StreamObserver observer, T value) { + StreamObserver safe = SafeStreamObserver.ensureSafeObserver(observer); + safe.onNext(value); + safe.onCompleted(); + } + + /** + * Complete a gRPC request based on the result of a {@link CompletionStage}. + *

+ * The request will be completed by calling {@link StreamObserver#onNext(Object)} using the + * result obtained on completion of the specified {@link CompletionStage} and then calling + * {@link StreamObserver#onCompleted()}. + *

+ * If the {@link CompletionStage} completes with an error then {@link StreamObserver#onError(Throwable)} + * will be called. + * + * @param observer the {@link StreamObserver} to complete + * @param future the {@link CompletionStage} to use to obtain the value to use to call + * {@link StreamObserver#onNext(Object)} + * @param they type of the request result + */ + public static void complete(StreamObserver observer, CompletionStage future) { + future.whenComplete(completeWithResult(observer)); + } + + /** + * Asynchronously complete a gRPC request based on the result of a {@link CompletionStage}. + *

+ * The request will be completed by calling {@link StreamObserver#onNext(Object)} using the + * result obtained on completion of the specified {@link CompletionStage} and then calling + * {@link StreamObserver#onCompleted()}. + *

+ * If the {@link CompletionStage} completes with an error then {@link StreamObserver#onError(Throwable)} + * will be called. + *

+ * The execution will take place asynchronously on the fork-join thread pool. + * + * @param observer the {@link StreamObserver} to complete + * @param future the {@link CompletionStage} to use to obtain the value to use to call + * {@link StreamObserver#onNext(Object)} + * @param they type of the request result + */ + public static void completeAsync(StreamObserver observer, CompletionStage future) { + future.whenCompleteAsync(completeWithResult(observer)); + } + + /** + * Asynchronously complete a gRPC request based on the result of a {@link CompletionStage}. + *

+ * The request will be completed by calling {@link StreamObserver#onNext(Object)} using the + * result obtained on completion of the specified {@link CompletionStage} and then calling + * {@link StreamObserver#onCompleted()}. + *

+ * If the {@link CompletionStage} completes with an error then {@link StreamObserver#onError(Throwable)} + * will be called. + * + * @param observer the {@link StreamObserver} to complete + * @param future the {@link CompletionStage} to use to obtain the value to use to call + * {@link StreamObserver#onNext(Object)} + * @param executor the {@link Executor} on which to execute the asynchronous + * request completion + * @param they type of the request result + */ + public static void completeAsync(StreamObserver observer, CompletionStage future, Executor executor) { + future.whenCompleteAsync(completeWithResult(observer), executor); + } + + /** + * Complete a gRPC request based on the result of a {@link Callable}. + *

+ * The request will be completed by calling {@link StreamObserver#onNext(Object)} using the + * result obtained on completion of the specified {@link Callable} and then calling + * {@link StreamObserver#onCompleted()}. + *

+ * If the {@link Callable#call()} method throws an exception then {@link StreamObserver#onError(Throwable)} + * will be called. + * + * @param observer the {@link StreamObserver} to complete + * @param callable the {@link Callable} to use to obtain the value to use to call + * {@link StreamObserver#onNext(Object)} + * @param they type of the request result + */ + public static void complete(StreamObserver observer, Callable callable) { + try { + observer.onNext(callable.call()); + observer.onCompleted(); + } catch (Throwable t) { + observer.onError(t); + } + } + + /** + * Asynchronously complete a gRPC request based on the result of a {@link Callable}. + *

+ * The request will be completed by calling {@link StreamObserver#onNext(Object)} using the + * result obtained on completion of the specified {@link Callable} and then calling + * {@link StreamObserver#onCompleted()}. + *

+ * If the {@link Callable#call()} method throws an exception then {@link StreamObserver#onError(Throwable)} + * will be called. + *

+ * The execution will take place asynchronously on the fork-join thread pool. + * + * @param observer the {@link StreamObserver} to complete + * @param callable the {@link Callable} to use to obtain the value to use to call + * {@link StreamObserver#onNext(Object)} + * @param they type of the request result + */ + public static void completeAsync(StreamObserver observer, Callable callable) { + completeAsync(observer, CompletableFuture.supplyAsync(createSupplier(callable))); + } + + /** + * Asynchronously complete a gRPC request based on the result of a {@link Callable}. + *

+ * The request will be completed by calling {@link StreamObserver#onNext(Object)} using the + * result obtained on completion of the specified {@link Callable} and then calling + * {@link StreamObserver#onCompleted()}. + *

+ * If the {@link Callable#call()} method throws an exception then {@link StreamObserver#onError(Throwable)} + * will be called. + * + * @param observer the {@link StreamObserver} to complete + * @param callable the {@link Callable} to use to obtain the value to use to call + * {@link StreamObserver#onNext(Object)} + * @param executor the {@link Executor} on which to execute the asynchronous + * request completion + * @param they type of the request result + */ + public static void completeAsync(StreamObserver observer, Callable callable, Executor executor) { + completeAsync(observer, CompletableFuture.supplyAsync(createSupplier(callable), executor)); + } + + /** + * Execute a {@link Runnable} task and on completion of the task complete the gRPC request by + * calling {@link StreamObserver#onNext(Object)} using the specified result and then call + * {@link StreamObserver#onCompleted()}. + *

+ * If the {@link Runnable#run()} method throws an exception then {@link StreamObserver#onError(Throwable)} + * will be called. + * + * @param observer the {@link StreamObserver} to complete + * @param task the {@link Runnable} to execute + * @param result the result to pass to {@link StreamObserver#onNext(Object)} + * @param they type of the request result + */ + public static void complete(StreamObserver observer, Runnable task, T result) { + complete(observer, Executors.callable(task, result)); + } + + /** + * Asynchronously execute a {@link Runnable} task and on completion of the task complete the gRPC + * request by calling {@link StreamObserver#onNext(Object)} using the specified result and then + * call {@link StreamObserver#onCompleted()}. + *

+ * If the {@link Runnable#run()} method throws an exception then {@link StreamObserver#onError(Throwable)} + * will be called. + *

+ * The task and and request completion will be executed on the fork-join thread pool. + * + * @param observer the {@link StreamObserver} to complete + * @param task the {@link Runnable} to execute + * @param result the result to pass to {@link StreamObserver#onNext(Object)} + * @param they type of the request result + */ + public static void completeAsync(StreamObserver observer, Runnable task, T result) { + completeAsync(observer, Executors.callable(task, result)); + } + + /** + * Asynchronously execute a {@link Runnable} task and on completion of the task complete the gRPC + * request by calling {@link StreamObserver#onNext(Object)} using the specified result and then + * call {@link StreamObserver#onCompleted()}. + *

+ * If the {@link Runnable#run()} method throws an exception then {@link StreamObserver#onError(Throwable)} + * will be called. + * + * @param observer the {@link StreamObserver} to complete + * @param task the {@link Runnable} to execute + * @param result the result to pass to {@link StreamObserver#onNext(Object)} + * @param executor the {@link Executor} on which to execute the asynchronous + * request completion + * @param they type of the request result + */ + public static void completeAsync(StreamObserver observer, Runnable task, T result, Executor executor) { + completeAsync(observer, Executors.callable(task, result), executor); + } + + /** + * Send the values from a {@link Stream} to the {@link StreamObserver#onNext(Object)} method until the + * {@link Stream} is exhausted call {@link StreamObserver#onCompleted()}. + *

+ * If an error occurs whilst streaming results then {@link StreamObserver#onError(Throwable)} will be called. + * + * @param observer the {@link StreamObserver} to complete + * @param stream the {@link Stream} of results to send to {@link StreamObserver#onNext(Object)} + * @param they type of the request result + */ + public static void stream(StreamObserver observer, Stream stream) { + stream(observer, () -> stream); + } + + /** + * Asynchronously send the values from a {@link Stream} to the {@link StreamObserver#onNext(Object)} method until + * the {@link Stream} is exhausted call {@link StreamObserver#onCompleted()}. + *

+ * If an error occurs whilst streaming results then {@link StreamObserver#onError(Throwable)} will be called. + * + * @param observer the {@link StreamObserver} to complete + * @param stream the {@link Stream} of results to send to {@link StreamObserver#onNext(Object)} + * @param executor the {@link Executor} on which to execute the asynchronous + * request completion + * @param they type of the request result + */ + public static void streamAsync(StreamObserver observer, Stream stream, Executor executor) { + executor.execute(() -> stream(observer, () -> stream)); + } + + /** + * Send the values from a {@link Stream} to the {@link StreamObserver#onNext(Object)} method until the + * {@link Stream} is exhausted call {@link StreamObserver#onCompleted()}. + *

+ * If an error occurs whilst streaming results then {@link StreamObserver#onError(Throwable)} will be called. + * + * @param observer the {@link StreamObserver} to complete + * @param supplier the {@link Supplier} of the {@link Stream} of results to send to {@link StreamObserver#onNext(Object)} + * @param they type of the request result + */ + public static void stream(StreamObserver observer, Supplier> supplier) { + StreamObserver safe = SafeStreamObserver.ensureSafeObserver(observer); + Throwable thrown = null; + + try { + supplier.get().forEach(safe::onNext); + } catch (Throwable t) { + thrown = t; + } + + if (thrown == null) { + safe.onCompleted(); + } else { + safe.onError(thrown); + } + } + + /** + * Asynchronously send the values from a {@link Stream} to the {@link StreamObserver#onNext(Object)} method + * until the {@link Stream} is exhausted call {@link StreamObserver#onCompleted()}. + *

+ * If an error occurs whilst streaming results then {@link StreamObserver#onError(Throwable)} will be called. + * + * @param observer the {@link StreamObserver} to complete + * @param supplier the {@link Supplier} of the {@link Stream} of results to send to {@link StreamObserver#onNext(Object)} + * @param executor the {@link Executor} on which to execute the asynchronous + * request completion + * @param they type of the request result + */ + public static void streamAsync(StreamObserver observer, Supplier> supplier, Executor executor) { + executor.execute(() -> stream(observer, supplier)); + } + + + /** + * Obtain a {@link Consumer} that can be used to send values to the {@link StreamObserver#onNext(Object)} method until + * the {@link CompletionStage} completes then call {@link StreamObserver#onCompleted()}. + *

+ * If the {@link CompletionStage} completes with an error then {@link StreamObserver#onError(Throwable)} + * will be called instead of {@link StreamObserver#onCompleted()}. + * + * @param observer the {@link StreamObserver} to send values to and complete when the {@link CompletionStage} completes + * @param stage the {@link CompletionStage} to await completion of + * @param they type of the request result + * + * @return a {@link Consumer} that can be used to send values to the {@link StreamObserver#onNext(Object)} method + */ + // todo: a bit of a chicken or egg when used with Coherence streaming methods, isn't it? + public static Consumer stream(StreamObserver observer, CompletionStage stage) { + StreamObserver safe = SafeStreamObserver.ensureSafeObserver(observer); + stage.whenComplete(completeWithoutResult(safe)); + return safe::onNext; + } + + /** + * Obtain a {@link Consumer} that can be used to send values to the {@link StreamObserver#onNext(Object)} method until + * the {@link CompletionStage} completes then asynchronously call {@link StreamObserver#onCompleted()} using the + * fork-join thread pool. + *

+ * If the {@link CompletionStage} completes with an error then {@link StreamObserver#onError(Throwable)} + * will be called instead of {@link StreamObserver#onCompleted()}. + * + * @param observer the {@link StreamObserver} to send values to and complete when the {@link CompletionStage} completes + * @param stage the {@link CompletionStage} to await completion of + * @param they type of the request result + * + * @return a {@link Consumer} that can be used to send values to the {@link StreamObserver#onNext(Object)} method + */ + public static Consumer streamAsync(StreamObserver observer, CompletionStage stage) { + StreamObserver safe = SafeStreamObserver.ensureSafeObserver(observer); + stage.whenCompleteAsync(completeWithoutResult(safe)); + return value -> CompletableFuture.runAsync(() -> safe.onNext(value)); + } + + /** + * Obtain a {@link Consumer} that can be used to send values to the {@link StreamObserver#onNext(Object)} method until + * the {@link CompletionStage} completes then asynchronously call {@link StreamObserver#onCompleted()} using the executor + * thread. + *

+ * If the {@link CompletionStage} completes with an error then {@link StreamObserver#onError(Throwable)} + * will be called instead of {@link StreamObserver#onCompleted()}. + * + * @param observer the {@link StreamObserver} to send values to and complete when the {@link CompletionStage} completes + * @param stage the {@link CompletionStage} to await completion of + * @param executor the {@link Executor} on which to execute the asynchronous + * request completion + * @param they type of the request result + * + * @return a {@link Consumer} that can be used to send values to the {@link StreamObserver#onNext(Object)} method + */ + public static Consumer streamAsync(StreamObserver observer, CompletionStage stage, Executor executor) { + StreamObserver safe = SafeStreamObserver.ensureSafeObserver(observer); + stage.whenCompleteAsync(completeWithoutResult(safe), executor); + return value -> CompletableFuture.runAsync(() -> safe.onNext(value), executor); + } + + /** + * Obtain a {@link Consumer} that can be used to send values to the {@link StreamObserver#onNext(Object)} method. + * @param observer the {@link StreamObserver} to complete + * @param the type of the result + * @param the type of the response + * @return a {@link Consumer} that can be used to send values to the {@link StreamObserver#onNext(Object)} method + */ + public static BiConsumer completeWithResult(StreamObserver observer) { + return new CompletionAction<>(observer, true); + } + + /** + * Obtain a {@link Consumer} that can be used to complete a {@link StreamObserver}. + * @param observer the {@link StreamObserver} to complete + * @param the type of the response + * @return a {@link Consumer} that can be used to complete a {@link StreamObserver} + */ + public static BiConsumer completeWithoutResult(StreamObserver observer) { + return new CompletionAction<>(observer, false); + } + + /** + * Convert a {@link Callable} to a {@link Supplier}. + * @param callable the {@link Callable} to convert + * @param the result returned by the {@link Callable} + * @return a {@link Supplier} that wraps the {@link Callable} + */ + public static Supplier createSupplier(Callable callable) { + return new CallableSupplier<>(callable); + } + + /** + * A {@link BiConsumer} that is used to handle completion of a + * {@link CompletionStage} by forwarding + * the result to a {@link StreamObserver}. + * + * @param the type of the {@link CompletionStage}'s result + * @param the type of result expected by the {@link StreamObserver} + */ + private static class CompletionAction implements BiConsumer { + private StreamObserver observer; + private boolean sendResult; + + CompletionAction(StreamObserver observer, boolean sendResult) { + this.observer = observer; + this.sendResult = sendResult; + } + + @Override + @SuppressWarnings("unchecked") + public void accept(T result, Throwable error) { + if (error != null) { + observer.onError(error); + } else { + if (sendResult) { + observer.onNext((U) result); + } + observer.onCompleted(); + } + } + } + + /** + * A class that converts a {@link Callable} to a {@link Supplier}. + * @param the type of result returned from the callable + */ + private static class CallableSupplier implements Supplier { + private Callable callable; + + CallableSupplier(Callable callable) { + this.callable = callable; + } + + @Override + public T get() { + try { + return callable.call(); + } catch (Exception e) { + throw new CompletionException(e.getMessage(), e); + } + } + } +} diff --git a/grpc/core/src/main/java/io/helidon/grpc/core/SafeStreamObserver.java b/grpc/core/src/main/java/io/helidon/grpc/core/SafeStreamObserver.java new file mode 100644 index 00000000000..31cfb1db7ef --- /dev/null +++ b/grpc/core/src/main/java/io/helidon/grpc/core/SafeStreamObserver.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.helidon.grpc.core; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import io.grpc.Status; +import io.grpc.stub.StreamObserver; + +/** + * A {@link StreamObserver} that handles exceptions correctly. + * + * @param the type of response expected + */ +public class SafeStreamObserver + implements StreamObserver { + + /** + * Create a {@link SafeStreamObserver} that wraps + * another {@link StreamObserver}. + * + * @param streamObserver the {@link StreamObserver} to wrap + */ + private SafeStreamObserver(StreamObserver streamObserver) { + delegate = streamObserver; + } + + @Override + public void onNext(T t) { + if (done) { + return; + } + + if (t == null) { + onError(Status.INVALID_ARGUMENT + .withDescription("onNext called with null. Null values are generally not allowed.") + .asRuntimeException()); + } else { + try { + delegate.onNext(t); + } catch (Throwable thrown) { + throwIfFatal(thrown); + onError(thrown); + } + } + } + + @Override + public void onError(Throwable thrown) { + try { + if (done) { + LOGGER.log(Level.SEVERE, checkNotNull(thrown), () -> "OnError called after StreamObserver was closed"); + } else { + done = true; + delegate.onError(checkNotNull(thrown)); + } + } catch (Throwable t) { + throwIfFatal(t); + LOGGER.log(Level.SEVERE, t, () -> "Caught exception handling onError"); + } + } + + @Override + public void onCompleted() { + if (done) { + LOGGER.log(Level.WARNING, "onComplete called after StreamObserver was closed"); + } else { + try { + done = true; + delegate.onCompleted(); + } catch (Throwable thrown) { + throwIfFatal(thrown); + LOGGER.log(Level.SEVERE, thrown, () -> "Caught exception handling onComplete"); + } + } + } + + /** + * Obtain the wrapped {@link StreamObserver}. + * @return the wrapped {@link StreamObserver} + */ + public StreamObserver delegate() { + return delegate; + } + + private Throwable checkNotNull(Throwable thrown) { + if (thrown == null) { + thrown = Status.INVALID_ARGUMENT + .withDescription("onError called with null Throwable. Null exceptions are generally not allowed.") + .asRuntimeException(); + } + + return thrown; + } + + /** + * Throws a particular {@code Throwable} only if it belongs to a set of "fatal" error varieties. These varieties are + * as follows: + *

    + *
  • {@code VirtualMachineError}
  • + *
  • {@code ThreadDeath}
  • + *
  • {@code LinkageError}
  • + *
+ * + * @param thrown the {@code Throwable} to test and perhaps throw + */ + private static void throwIfFatal(Throwable thrown) { + if (thrown instanceof VirtualMachineError) { + throw (VirtualMachineError) thrown; + } else if (thrown instanceof ThreadDeath) { + throw (ThreadDeath) thrown; + } else if (thrown instanceof LinkageError) { + throw (LinkageError) thrown; + } + } + + /** + * Ensure that the specified {@link StreamObserver} is a safe observer. + *

+ * If the specified observer is not an instance of {@link SafeStreamObserver} then wrap + * it in a {@link SafeStreamObserver}. + * + * @param observer the {@link StreamObserver} to test + * @param the response type expected by the observer + * + * @return a safe {@link StreamObserver} + */ + public static StreamObserver ensureSafeObserver(StreamObserver observer) { + if (observer instanceof SafeStreamObserver) { + return observer; + } + + return new SafeStreamObserver<>(observer); + } + + // ----- constants ------------------------------------------------------ + + /** + * The {2link Logger} to use. + */ + private static final Logger LOGGER = Logger.getLogger(SafeStreamObserver.class.getName()); + + // ----- data members --------------------------------------------------- + + /** + * The actual StreamObserver. + */ + private StreamObserver delegate; + + /** + * Indicates a terminal state. + */ + private boolean done; +} diff --git a/grpc/core/src/main/java/module-info.java b/grpc/core/src/main/java/module-info.java index 695cf325613..2bb58f7a62e 100644 --- a/grpc/core/src/main/java/module-info.java +++ b/grpc/core/src/main/java/module-info.java @@ -19,7 +19,11 @@ */ module io.helidon.grpc.core { + requires java.logging; + requires io.helidon.common; + requires io.helidon.http; + requires transitive io.grpc; requires transitive io.grpc.stub; requires transitive com.google.protobuf; diff --git a/microprofile/grpc/client/pom.xml b/microprofile/grpc/client/pom.xml deleted file mode 100644 index 1ffc3779ea5..00000000000 --- a/microprofile/grpc/client/pom.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - 4.0.0 - - io.helidon.microprofile.grpc - helidon-microprofile-grpc - 3.2.9-SNAPSHOT - - - helidon-microprofile-grpc-client - Helidon Microprofile gRPC Client - Microprofile gRPC client implementation - - - - io.helidon.microprofile.grpc - helidon-microprofile-grpc-core - - - io.helidon.grpc - helidon-grpc-client - - - io.helidon.config - helidon-config - - - jakarta.enterprise - jakarta.enterprise.cdi-api - provided - - - io.helidon.microprofile.cdi - helidon-microprofile-cdi - test - - - org.junit.jupiter - junit-jupiter-api - test - - - org.hamcrest - hamcrest-all - test - - - diff --git a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/ChannelProducer.java b/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/ChannelProducer.java deleted file mode 100644 index e95b830c667..00000000000 --- a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/ChannelProducer.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.client; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import io.helidon.config.Config; -import io.helidon.grpc.client.GrpcChannelsProvider; -import io.helidon.microprofile.grpc.core.InProcessGrpcChannel; - -import io.grpc.Channel; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.enterprise.inject.Instance; -import jakarta.enterprise.inject.Produces; -import jakarta.enterprise.inject.spi.BeanManager; -import jakarta.enterprise.inject.spi.InjectionPoint; -import jakarta.inject.Inject; - -/** - * A producer of gRPC {@link io.grpc.Channel Channels}. - */ -@ApplicationScoped -public class ChannelProducer { - - private final GrpcChannelsProvider provider; - - private final Map channelMap = new ConcurrentHashMap<>(); - - /** - * Create a {@link ChannelProducer}. - * - * @param config the {@link io.helidon.config.Config} to use to configure - * the provided {@link io.grpc.Channel}s - */ - @Inject - ChannelProducer(Config config) { - provider = GrpcChannelsProvider.create(config.get("grpc")); - } - - /** - * Produces a gRPC {@link io.grpc.Channel}. - * - * @param injectionPoint the injection point - * @return a gRPC {@link io.grpc.Channel} - */ - @Produces - @GrpcChannel(name = GrpcChannelsProvider.DEFAULT_CHANNEL_NAME) - public Channel get(InjectionPoint injectionPoint) { - GrpcChannel qualifier = injectionPoint.getQualifiers() - .stream() - .filter(q -> q.annotationType().equals(GrpcChannel.class)) - .map(q -> (GrpcChannel) q) - .findFirst() - .orElse(null); - - String name = qualifier == null ? GrpcChannelsProvider.DEFAULT_CHANNEL_NAME : qualifier.name(); - - return findChannel(name); - } - - /** - * Produces the default gRPC {@link io.grpc.Channel}. - * - * @return the default gRPC {@link io.grpc.Channel} - */ - @Produces - public Channel getDefaultChannel() { - return findChannel(GrpcChannelsProvider.DEFAULT_CHANNEL_NAME); - } - - /** - * Obtain the named {@link io.grpc.Channel}. - * - * @param name the channel name - * @return the named {@link io.grpc.Channel} - */ - Channel findChannel(String name) { - return channelMap.computeIfAbsent(name, provider::channel); - } - - /** - * A utility method to obtain an in-process {@link io.grpc.Channel}. - * - * @param beanManager the CDI {@link BeanManager} to use to find the {@link io.grpc.Channel} - * @return an in-process {@link io.grpc.Channel} - */ - static Channel inProcessChannel(BeanManager beanManager) { - return inProcessChannel(beanManager.createInstance()); - } - - /** - * A utility method to obtain an in-process {@link io.grpc.Channel}. - * - * @param instance the CDI {@link Instance} to use to find the {@link io.grpc.Channel} - * @return an in-process {@link io.grpc.Channel} - */ - static Channel inProcessChannel(Instance instance) { - return instance.select(Channel.class, InProcessGrpcChannel.Literal.INSTANCE).get(); - } -} diff --git a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/DelegatingBeanAttributes.java b/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/DelegatingBeanAttributes.java deleted file mode 100644 index c37d3fd64c9..00000000000 --- a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/DelegatingBeanAttributes.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.client; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import java.util.Collections; -import java.util.Objects; -import java.util.Set; - -import jakarta.enterprise.inject.spi.BeanAttributes; - -/** - * A {@link BeanAttributes} implementation. - * - * @param the class of the bean instance - */ -class DelegatingBeanAttributes implements BeanAttributes { - - private final BeanAttributes delegate; - private final Set types; - - /** - * Create a {@link DelegatingBeanAttributes}. - * - * @param delegate the {@link BeanAttributes} to delegate to - * @param types the {@link Type}s for this bean - */ - private DelegatingBeanAttributes(BeanAttributes delegate, Set types) { - super(); - Objects.requireNonNull(delegate); - this.delegate = delegate; - this.types = Collections.unmodifiableSet(types); - } - - /** - * Create a {@link DelegatingBeanAttributes}. - * - * @param delegate the {@link BeanAttributes} to delegate to - * @param types the {@link Type}s for this bean - */ - static DelegatingBeanAttributes create(BeanAttributes delegate, Set types) { - return new DelegatingBeanAttributes<>(delegate, types); - } - - @Override - public String getName() { - return this.delegate.getName(); - } - - @Override - public Set getQualifiers() { - return this.delegate.getQualifiers(); - } - - @Override - public Class getScope() { - return this.delegate.getScope(); - } - - @Override - public Set> getStereotypes() { - return this.delegate.getStereotypes(); - } - - @Override - public Set getTypes() { - if (types == null || types.isEmpty()) { - return this.delegate.getTypes(); - } else { - return types; - } - } - - @Override - public boolean isAlternative() { - return this.delegate.isAlternative(); - } - - @Override - public String toString() { - return this.delegate.toString(); - } -} diff --git a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcChannel.java b/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcChannel.java deleted file mode 100644 index e5e31000711..00000000000 --- a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcChannel.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2019, 2023 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.client; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import jakarta.enterprise.util.AnnotationLiteral; -import jakarta.enterprise.util.Nonbinding; -import jakarta.inject.Qualifier; - -/** - * A qualifier annotation that can be used to specify the name of a configured gRPC - * channel to inject, or the name of the host to connect to, as described in - * {@link io.helidon.grpc.client.GrpcChannelsProvider#channel(String)} documentation. - *

- * For example: - * - *

- *     @Inject
- *     @GrpcChannel(name = "foo")
- *     private Channel channel;
- * 
- * - * This annotation can also be specified at the injection point for a client proxy, - * in combination with the {@link GrpcProxy @GrpcProxy} annotation: - * - *
- *     @Inject
- *     @GrpcChannel(name = "foo")
- *     @GrpcProxy
- *     private FooServiceClient client;
- * 
- * - * Alternatively, if the client proxy should always use the same channel, it can - * be specified on the client interface instead: - * - *
- *     @Grpc(name = "FooService")
- *     @GrpcChannel(name = "foo")
- *     public interface FooServiceClient {
- *         ...
- *     };
- * 
- * - */ -@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -@Qualifier -public @interface GrpcChannel { - /** - * The name of the configured channel or gRPC server host. - * - * @return name of the channel - */ - @Nonbinding String name(); - - /** - * An {@link jakarta.enterprise.util.AnnotationLiteral} for the - * {@link GrpcChannel} annotation. - */ - class Literal extends AnnotationLiteral implements GrpcChannel { - - @Override - public String name() { - return ""; - } - - /** - * The singleton instance of {@link GrpcChannel.Literal}. - */ - public static final Literal INSTANCE = new Literal(); - - private static final long serialVersionUID = 1L; - } -} diff --git a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcClientBuilder.java b/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcClientBuilder.java deleted file mode 100644 index 3a588c7f67a..00000000000 --- a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcClientBuilder.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.client; - -import java.util.Objects; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.logging.Level; -import java.util.logging.Logger; - -import io.helidon.common.Builder; -import io.helidon.grpc.client.ClientMethodDescriptor; -import io.helidon.grpc.client.ClientServiceDescriptor; -import io.helidon.grpc.core.MethodHandler; -import io.helidon.microprofile.grpc.core.AbstractServiceBuilder; -import io.helidon.microprofile.grpc.core.AnnotatedMethod; -import io.helidon.microprofile.grpc.core.AnnotatedMethodList; -import io.helidon.microprofile.grpc.core.GrpcMarshaller; -import io.helidon.microprofile.grpc.core.GrpcMethod; -import io.helidon.microprofile.grpc.core.Instance; -import io.helidon.microprofile.grpc.core.ModelHelper; - -/** - * A builder for constructing a {@link ClientServiceDescriptor.Builder} instances - * from an annotated POJO. - */ -class GrpcClientBuilder - extends AbstractServiceBuilder - implements Builder { - - private static final Logger LOGGER = Logger.getLogger(GrpcClientBuilder.class.getName()); - - /** - * Create a {@link GrpcClientBuilder} for a given gRPC service class. - * - * @param serviceClass gRPC service (handler) class. - * @param instance the target instance to call gRPC handler methods on - * @throws NullPointerException if the service or instance parameters are null - */ - private GrpcClientBuilder(Class serviceClass, Supplier instance) { - super(serviceClass, instance); - } - - /** - * Create a {@link GrpcClientBuilder} for a given gRPC service. - * - * @param service the service to call gRPC handler methods on - * @throws NullPointerException if the service is null - * @return a {@link GrpcClientBuilder} - */ - static GrpcClientBuilder create(Object service) { - return new GrpcClientBuilder(service.getClass(), Instance.singleton(service)); - } - - /** - * Create a {@link GrpcClientBuilder} for a given gRPC service class. - * - * @param serviceClass gRPC service (handler) class. - * @throws NullPointerException if the service class is null - * @return a {@link GrpcClientBuilder} - */ - static GrpcClientBuilder create(Class serviceClass) { - return new GrpcClientBuilder(Objects.requireNonNull(serviceClass), createInstanceSupplier(serviceClass)); - } - - /** - * Create a new resource model builder for the introspected class. - *

- * The model returned is filled with the introspected data. - *

- * - * @return new resource model builder for the introspected class. - */ - @Override - public ClientServiceDescriptor.Builder build() { - checkForNonPublicMethodIssues(); - - Class annotatedServiceClass = annotatedServiceClass(); - AnnotatedMethodList methodList = AnnotatedMethodList.create(annotatedServiceClass); - String name = determineServiceName(annotatedServiceClass); - - ClientServiceDescriptor.Builder builder = ClientServiceDescriptor.builder(serviceClass()) - .name(name) - .marshallerSupplier(getMarshallerSupplier()); - - addServiceMethods(builder, methodList); - - LOGGER.log(Level.FINEST, () -> String.format("A new gRPC service was created by ServiceModeller: %s", builder)); - - return builder; - } - - /** - * Add methods to the {@link ClientServiceDescriptor.Builder}. - * - * @param builder the {@link ClientServiceDescriptor.Builder} to add the method to - * @param methodList the list of methods to add - */ - private void addServiceMethods(ClientServiceDescriptor.Builder builder, AnnotatedMethodList methodList) { - for (AnnotatedMethod am : methodList.withAnnotation(GrpcMethod.class)) { - addServiceMethod(builder, am); - } - for (AnnotatedMethod am : methodList.withMetaAnnotation(GrpcMethod.class)) { - addServiceMethod(builder, am); - } - } - - /** - * Add a method to the {@link ClientServiceDescriptor.Builder}. - *

- * The method configuration will be determined by the annotations present on the - * method and the method signature. - * - * @param builder the {@link ClientServiceDescriptor.Builder} to add the method to - * @param method the {@link io.helidon.microprofile.grpc.core.AnnotatedMethod} representing the method to add - */ - private void addServiceMethod(ClientServiceDescriptor.Builder builder, AnnotatedMethod method) { - GrpcMethod annotation = method.firstAnnotationOrMetaAnnotation(GrpcMethod.class); - String name = determineMethodName(method, annotation); - - MethodHandler handler = handlerSuppliers().stream() - .filter(supplier -> supplier.supplies(method)) - .findFirst() - .map(supplier -> supplier.get(name, method, instanceSupplier())) - .orElseThrow(() -> new IllegalArgumentException("Cannot locate a method handler supplier for method " + method)); - - Class requestType = handler.getRequestType(); - Class responseType = handler.getResponseType(); - AnnotatedMethodConfigurer configurer = new AnnotatedMethodConfigurer(method, requestType, responseType, handler); - - switch (annotation.type()) { - case UNARY: - builder.unary(name, configurer); - break; - case CLIENT_STREAMING: - builder.clientStreaming(name, configurer); - break; - case SERVER_STREAMING: - builder.serverStreaming(name, configurer); - break; - case BIDI_STREAMING: - builder.bidirectional(name, configurer); - break; - case UNKNOWN: - default: - LOGGER.log(Level.SEVERE, () -> "Unrecognized method type " + annotation.type()); - } - } - - /** - * A {@link java.util.function.Consumer} of {@link ClientMethodDescriptor.Rules} - * that applies configuration changes based on annotations present on the gRPC - * method. - */ - private static class AnnotatedMethodConfigurer - implements Consumer { - - private final AnnotatedMethod method; - private final Class requestType; - private final Class responseType; - private final MethodHandler methodHandler; - - private AnnotatedMethodConfigurer(AnnotatedMethod method, - Class requestType, - Class responseType, - MethodHandler methodHandler) { - this.method = method; - this.requestType = requestType; - this.responseType = responseType; - this.methodHandler = methodHandler; - } - - @Override - public void accept(ClientMethodDescriptor.Rules config) { - config.requestType(requestType) - .responseType(responseType) - .methodHandler(methodHandler); - - if (method.isAnnotationPresent(GrpcMarshaller.class)) { - config.marshallerSupplier(ModelHelper.getMarshallerSupplier(method.getAnnotation(GrpcMarshaller.class))); - } - } - } -} diff --git a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcClientCdiExtension.java b/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcClientCdiExtension.java deleted file mode 100644 index 67ed77356c3..00000000000 --- a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcClientCdiExtension.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2019, 2023 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.client; - -import java.lang.reflect.Type; -import java.util.HashSet; -import java.util.Set; - -import io.helidon.microprofile.grpc.core.InProcessGrpcChannel; - -import jakarta.enterprise.event.Observes; -import jakarta.enterprise.inject.spi.AfterBeanDiscovery; -import jakarta.enterprise.inject.spi.Annotated; -import jakarta.enterprise.inject.spi.AnnotatedMethod; -import jakarta.enterprise.inject.spi.AnnotatedType; -import jakarta.enterprise.inject.spi.BeanAttributes; -import jakarta.enterprise.inject.spi.BeanManager; -import jakarta.enterprise.inject.spi.Extension; -import jakarta.enterprise.inject.spi.ProcessInjectionPoint; -import jakarta.enterprise.inject.spi.ProducerFactory; - -/** - * A CDI extension to add gRPC client functionality. - */ -public class GrpcClientCdiExtension implements Extension { - - private final Set proxyTypes = new HashSet<>(); - private final Set inProcessProxyTypes = new HashSet<>(); - - /** - * Process injection points. - *

- * In this method all of the injection points that have the {@link GrpcProxy} are processed - * and their types are stored so that in the {@link #afterBean(AfterBeanDiscovery, BeanManager)} - * we can manually create a producer for the correct service proxy type. - * - * @param pip the injection point - * @param the declared type of the injection point. - * @param the bean class of the bean that declares the injection point - */ - public void gatherApplications(@Observes ProcessInjectionPoint pip) { - Annotated annotated = pip.getInjectionPoint().getAnnotated(); - if (annotated.isAnnotationPresent(GrpcProxy.class)) { - Type type = pip.getInjectionPoint().getType(); - - // ToDo: verify that the type is an interface - how are we supposed to signal errors? - - if (annotated.isAnnotationPresent(InProcessGrpcChannel.class)) { - inProcessProxyTypes.add(type); - } else { - proxyTypes.add(type); - } - } - } - - /** - * Process the previously captured {@link GrpcProxy} injection points. - *

- * For each {@link GrpcProxy} injection point we create a producer bean - * for the required type. - * - * @param event the {@link AfterBeanDiscovery} event - * @param beanManager the CDI bean manager - */ - public void afterBean(@Observes AfterBeanDiscovery event, BeanManager beanManager) { - AnnotatedType producerType = beanManager.createAnnotatedType(GrpcProxyProducer.class); - AnnotatedMethod producerMethod = producerType.getMethods() - .stream() - .filter(m -> m.isAnnotationPresent(GrpcProxy.class)) - .filter(m -> m.isAnnotationPresent(GrpcChannel.class)) - .findFirst() - .get(); - - AnnotatedMethod inProcessMethod = producerType.getMethods() - .stream() - .filter(m -> m.isAnnotationPresent(GrpcProxy.class)) - .filter(m -> m.isAnnotationPresent(InProcessGrpcChannel.class)) - .findFirst() - .get(); - - for (Type type : proxyTypes) { - addProducerBean(event, beanManager, producerMethod, type); - } - - for (Type type : inProcessProxyTypes) { - addProducerBean(event, beanManager, inProcessMethod, type); - } - } - - private void addProducerBean(AfterBeanDiscovery event, - BeanManager beanManager, - AnnotatedMethod producerMethod, - Type type) { - - BeanAttributes producerAttributes = beanManager.createBeanAttributes(producerMethod); - ProducerFactory factory = beanManager.getProducerFactory(producerMethod, null); - Set types = Set.of(Object.class, type); - BeanAttributes beanAttributes = DelegatingBeanAttributes.create(producerAttributes, types); - event.addBean(beanManager.createBean(beanAttributes, GrpcProxyProducer.class, factory)); - } -} diff --git a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcProxy.java b/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcProxy.java deleted file mode 100644 index 494fcbfc8b6..00000000000 --- a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcProxy.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2019, 2023 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.client; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import jakarta.enterprise.util.AnnotationLiteral; -import jakarta.inject.Qualifier; - -/** - * A qualifier annotation used to mark an injection point for - * a gRPC service client proxy. - */ -@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -@Qualifier -public @interface GrpcProxy { - - /** - * An {@link jakarta.enterprise.util.AnnotationLiteral} for the - * {@link GrpcProxy} annotation. - */ - class Literal - extends AnnotationLiteral implements GrpcProxy { - - /** - * The singleton instance of {@link GrpcProxy.Literal}. - */ - public static final Literal INSTANCE = new Literal(); - - private static final long serialVersionUID = 1L; - } -} diff --git a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcProxyBuilder.java b/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcProxyBuilder.java deleted file mode 100644 index 991a4828816..00000000000 --- a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcProxyBuilder.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.client; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import io.helidon.common.Builder; -import io.helidon.grpc.client.ClientServiceDescriptor; -import io.helidon.grpc.client.GrpcServiceClient; - -import io.grpc.Channel; -import io.grpc.inprocess.InProcessChannelBuilder; - -/** - * A builder for gRPC clients dynamic proxies. - * - * @param the type of the interface to be proxied - */ -public class GrpcProxyBuilder - implements Builder, T> { - - private static final Map, ClientServiceDescriptor> DESCRIPTORS = new ConcurrentHashMap<>(); - - private final GrpcServiceClient client; - - private final Class type; - - private GrpcProxyBuilder(GrpcServiceClient client, Class type) { - this.client = client; - this.type = type; - } - - /** - * Create a {@code GrpcProxyBuilder} that can build gRPC dynamic proxies - * for a given gRPC service interface using in-process channel. - *

- * This method will attempt to create in-process channel for the default - * gRPC server. If you have changed the gRPC server name, use - * {@link #create(String, Class)} instead. - *

- * The class passed to this method should be properly annotated with - * {@link io.helidon.microprofile.grpc.core.Grpc} and - * {@link io.helidon.microprofile.grpc.core.GrpcMethod} annotations - * so that the proxy can properly route calls to the server. - * - * @param type the service type - * @param the service type - * @return a {@link GrpcProxyBuilder} that can build dynamic proxies - * for the gRPC service - */ - public static GrpcProxyBuilder create(Class type) { - return create("grpc.server", type); - } - - /** - * Create a {@code GrpcProxyBuilder} that can build gRPC dynamic proxies - * for a given gRPC service interface using in-process channel. - *

- * The class passed to this method should be properly annotated with - * {@link io.helidon.microprofile.grpc.core.Grpc} and - * {@link io.helidon.microprofile.grpc.core.GrpcMethod} annotations - * so that the proxy can properly route calls to the server. - * - * @param serverName the name of the gRPC server proxy should connect to - * @param type the service type - * @param the service type - * @return a {@link GrpcProxyBuilder} that can build dynamic proxies - * for the gRPC service - */ - public static GrpcProxyBuilder create(String serverName, Class type) { - return create(InProcessChannelBuilder.forName(serverName).usePlaintext().build(), type); - } - - /** - * Create a {@code GrpcProxyBuilder} that can build gRPC dynamic proxies - * for a given gRPC service interface. - *

- * The class passed to this method should be properly annotated with - * {@link io.helidon.microprofile.grpc.core.Grpc} and - * {@link io.helidon.microprofile.grpc.core.GrpcMethod} annotations - * so that the proxy can properly route calls to the server. - * - * @param channel the {@link Channel} to connect to the server - * @param type the service type - * @param the service type - * @return a {@link GrpcProxyBuilder} that can build dynamic proxies - * for the gRPC service - */ - public static GrpcProxyBuilder create(Channel channel, Class type) { - ClientServiceDescriptor descriptor = DESCRIPTORS.computeIfAbsent(type, GrpcProxyBuilder::createDescriptor); - return new GrpcProxyBuilder<>(GrpcServiceClient.builder(channel, descriptor).build(), type); - } - - /** - * Build a gRPC client dynamic proxy of the required type. - * - * @return a gRPC client dynamic proxy - */ - @Override - public T build() { - return client.proxy(type); - } - - private static ClientServiceDescriptor createDescriptor(Class type) { - GrpcClientBuilder builder = GrpcClientBuilder.create(type); - ClientServiceDescriptor.Builder descriptorBuilder = builder.build(); - return descriptorBuilder.build(); - } -} diff --git a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcProxyProducer.java b/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcProxyProducer.java deleted file mode 100644 index 9989b16b862..00000000000 --- a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/GrpcProxyProducer.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2019, 2023 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.client; - -import io.helidon.grpc.client.GrpcChannelsProvider; -import io.helidon.microprofile.grpc.core.InProcessGrpcChannel; -import io.helidon.microprofile.grpc.core.ModelHelper; - -import io.grpc.Channel; -import jakarta.enterprise.inject.spi.BeanManager; -import jakarta.enterprise.inject.spi.InjectionPoint; - -/** - * A utility class of gRPC CDI producer stubs. - *

- * The methods in this class are not real CDI producer methods, - * they act as templates that the {@link GrpcClientCdiExtension} - * will use to create producers on the fly as injection points - * are observed. - */ -class GrpcProxyProducer { - - private GrpcProxyProducer() { - } - - /** - * A CDI producer method that produces a client proxy for a gRPC service that - * will connect to the server using the channel specified via {@link GrpcChannel} - * annotation on the proxy interface or injection point, or the default {@link Channel}. - *

- * This is not a real producer method but is used as a stub by the gRPC client - * CDI extension to create real producers as injection points are discovered. - * - * @param injectionPoint the injection point where the client proxy is to be injected - * @return a gRPC client proxy - */ - @GrpcProxy - @GrpcChannel(name = GrpcChannelsProvider.DEFAULT_CHANNEL_NAME) - static Object proxyUsingNamedChannel(InjectionPoint injectionPoint, ChannelProducer producer) { - Class type = ModelHelper.getGenericType(injectionPoint.getType()); - - String channelName; - if (injectionPoint.getAnnotated().isAnnotationPresent(GrpcChannel.class)) { - channelName = injectionPoint.getAnnotated().getAnnotation(GrpcChannel.class).name(); - } else { - channelName = type.isAnnotationPresent(GrpcChannel.class) - ? type.getAnnotation(GrpcChannel.class).name() - : GrpcChannelsProvider.DEFAULT_CHANNEL_NAME; - } - - Channel channel = producer.findChannel(channelName); - GrpcProxyBuilder builder = GrpcProxyBuilder.create(channel, type); - - return builder.build(); - } - - /** - * A CDI producer method that produces a client proxy for a gRPC service that - * will connect to the server using an in-process {@link Channel}. - *

- * This is not a real producer method but is used as a stub by the gRPC client - * CDI extension to create real producers as injection points are discovered. - * - * @param injectionPoint the injection point where the client proxy is to be injected - * @return a gRPC client proxy - */ - @GrpcProxy - @InProcessGrpcChannel - static Object proxyUsingInProcessChannel(InjectionPoint injectionPoint, BeanManager beanManager) { - Class type = ModelHelper.getGenericType(injectionPoint.getType()); - Channel channel = ChannelProducer.inProcessChannel(beanManager); - GrpcProxyBuilder builder = GrpcProxyBuilder.create(channel, type); - return builder.build(); - } -} diff --git a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/package-info.java b/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/package-info.java deleted file mode 100644 index 62f61b835f0..00000000000 --- a/microprofile/grpc/client/src/main/java/io/helidon/microprofile/grpc/client/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * gRPC client microprofile classes. - */ -package io.helidon.microprofile.grpc.client; diff --git a/microprofile/grpc/client/src/main/java/module-info.java b/microprofile/grpc/client/src/main/java/module-info.java deleted file mode 100644 index b23225d51c9..00000000000 --- a/microprofile/grpc/client/src/main/java/module-info.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2019, 2023 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * gRPC client implementation for Helidon MP. - */ -module io.helidon.microprofile.grpc.client { - requires java.logging; - - requires jakarta.cdi; - requires jakarta.inject; - - requires transitive io.grpc.inprocess; - requires transitive io.grpc.internal; - requires transitive io.helidon.microprofile.grpc.core; - - exports io.helidon.microprofile.grpc.client; - - provides jakarta.enterprise.inject.spi.Extension - with io.helidon.microprofile.grpc.client.GrpcClientCdiExtension; - - // needed when running with modules - to make private methods accessible - opens io.helidon.microprofile.grpc.client to weld.core.impl, io.helidon.microprofile.cdi; -} diff --git a/microprofile/grpc/client/src/main/resources/META-INF/beans.xml b/microprofile/grpc/client/src/main/resources/META-INF/beans.xml deleted file mode 100644 index f2f827007a8..00000000000 --- a/microprofile/grpc/client/src/main/resources/META-INF/beans.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - diff --git a/microprofile/grpc/client/src/test/java/io/helidon/microprofile/grpc/client/GrpcClientBuilderTest.java b/microprofile/grpc/client/src/test/java/io/helidon/microprofile/grpc/client/GrpcClientBuilderTest.java deleted file mode 100644 index 0468243d52d..00000000000 --- a/microprofile/grpc/client/src/test/java/io/helidon/microprofile/grpc/client/GrpcClientBuilderTest.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (c) 2019, 2022 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.client; - -import io.helidon.grpc.client.ClientMethodDescriptor; -import io.helidon.grpc.client.ClientServiceDescriptor; -import io.helidon.microprofile.grpc.core.Grpc; -import io.helidon.microprofile.grpc.core.GrpcMarshaller; -import io.helidon.microprofile.grpc.core.GrpcMethod; - -import io.grpc.stub.StreamObserver; -import jakarta.inject.Singleton; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; - -public class GrpcClientBuilderTest { - @Test - public void shouldUseServiceNameFromAnnotation() { - ServiceOne service = new ServiceOne(); - GrpcClientBuilder builder = GrpcClientBuilder.create(service); - ClientServiceDescriptor.Builder descriptorBuilder = builder.build(); - - assertThat(descriptorBuilder.name(), is("ServiceOne/foo")); - } - - @Test - public void shouldUseDefaultServiceName() { - ServiceTwo service = new ServiceTwo(); - GrpcClientBuilder builder = GrpcClientBuilder.create(service); - ClientServiceDescriptor.Builder descriptorBuilder = builder.build(); - - assertThat(descriptorBuilder.name(), is("ServiceTwo")); - } - - @Test - public void shouldCreateServiceFromInstance() { - ServiceOne service = new ServiceOne(); - assertServiceOne(GrpcClientBuilder.create(service)); - } - - @Test - public void shouldCreateServiceFromClass() { - assertServiceOne(GrpcClientBuilder.create(ServiceOne.class)); - } - - public void assertServiceOne(GrpcClientBuilder builder) { - ClientServiceDescriptor.Builder descriptorBuilder = builder.build(); - - ClientServiceDescriptor descriptor = descriptorBuilder.build(); - assertThat(descriptor.name(), is("ServiceOne/foo")); - assertThat(descriptor.methods().size(), is(4)); - - ClientMethodDescriptor ClientMethodDescriptor; - io.grpc.MethodDescriptor grpcDescriptor; - - ClientMethodDescriptor = descriptor.method("unary"); - assertThat(ClientMethodDescriptor, is(notNullValue())); - assertThat(ClientMethodDescriptor.name(), is("unary")); - - grpcDescriptor = ClientMethodDescriptor.descriptor(); - assertThat(grpcDescriptor, is(notNullValue())); - assertThat(grpcDescriptor.getFullMethodName(), is("ServiceOne/foo/unary")); - assertThat(grpcDescriptor.getType(), is(io.grpc.MethodDescriptor.MethodType.UNARY)); - assertThat(grpcDescriptor.getRequestMarshaller(), is(instanceOf(StubMarshaller.class))); - assertThat(grpcDescriptor.getResponseMarshaller(), is(instanceOf(StubMarshaller.class))); - - ClientMethodDescriptor = descriptor.method("clientStreaming"); - assertThat(ClientMethodDescriptor, is(notNullValue())); - assertThat(ClientMethodDescriptor.name(), is("clientStreaming")); - - grpcDescriptor = ClientMethodDescriptor.descriptor(); - assertThat(grpcDescriptor, is(notNullValue())); - assertThat(grpcDescriptor.getFullMethodName(), is("ServiceOne/foo/clientStreaming")); - assertThat(grpcDescriptor.getType(), is(io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING)); - assertThat(grpcDescriptor.getRequestMarshaller(), is(instanceOf(StubMarshaller.class))); - assertThat(grpcDescriptor.getResponseMarshaller(), is(instanceOf(StubMarshaller.class))); - - ClientMethodDescriptor = descriptor.method("serverStreaming"); - assertThat(ClientMethodDescriptor, is(notNullValue())); - assertThat(ClientMethodDescriptor.name(), is("serverStreaming")); - - grpcDescriptor = ClientMethodDescriptor.descriptor(); - assertThat(grpcDescriptor, is(notNullValue())); - assertThat(grpcDescriptor.getFullMethodName(), is("ServiceOne/foo/serverStreaming")); - assertThat(grpcDescriptor.getType(), is(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)); - assertThat(grpcDescriptor.getRequestMarshaller(), is(instanceOf(StubMarshaller.class))); - assertThat(grpcDescriptor.getResponseMarshaller(), is(instanceOf(StubMarshaller.class))); - - ClientMethodDescriptor = descriptor.method("bidiStreaming"); - assertThat(ClientMethodDescriptor, is(notNullValue())); - assertThat(ClientMethodDescriptor.name(), is("bidiStreaming")); - - grpcDescriptor = ClientMethodDescriptor.descriptor(); - assertThat(grpcDescriptor, is(notNullValue())); - assertThat(grpcDescriptor.getFullMethodName(), is("ServiceOne/foo/bidiStreaming")); - assertThat(grpcDescriptor.getType(), is(io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING)); - assertThat(grpcDescriptor.getRequestMarshaller(), is(instanceOf(StubMarshaller.class))); - assertThat(grpcDescriptor.getResponseMarshaller(), is(instanceOf(StubMarshaller.class))); - } - - @Test - public void shouldCreateServiceWithMethodNamesFromAnnotation() { - ServiceTwo service = new ServiceTwo(); - GrpcClientBuilder builder = GrpcClientBuilder.create(service); - ClientServiceDescriptor.Builder descriptorBuilder = builder.build(); - - ClientServiceDescriptor descriptor = descriptorBuilder.build(); - assertThat(descriptor.name(), is("ServiceTwo")); - assertThat(descriptor.methods().size(), is(4)); - - ClientMethodDescriptor ClientMethodDescriptor; - io.grpc.MethodDescriptor grpcDescriptor; - - ClientMethodDescriptor = descriptor.method("One"); - assertThat(ClientMethodDescriptor, is(notNullValue())); - assertThat(ClientMethodDescriptor.name(), is("One")); - - grpcDescriptor = ClientMethodDescriptor.descriptor(); - assertThat(grpcDescriptor, is(notNullValue())); - assertThat(grpcDescriptor.getFullMethodName(), is("ServiceTwo/One")); - assertThat(grpcDescriptor.getType(), is(io.grpc.MethodDescriptor.MethodType.UNARY)); - assertThat(grpcDescriptor.getRequestMarshaller(), is(instanceOf(StubMarshaller.class))); - assertThat(grpcDescriptor.getResponseMarshaller(), is(instanceOf(StubMarshaller.class))); - - ClientMethodDescriptor = descriptor.method("Two"); - assertThat(ClientMethodDescriptor, is(notNullValue())); - assertThat(ClientMethodDescriptor.name(), is("Two")); - - grpcDescriptor = ClientMethodDescriptor.descriptor(); - assertThat(grpcDescriptor, is(notNullValue())); - assertThat(grpcDescriptor.getFullMethodName(), is("ServiceTwo/Two")); - assertThat(grpcDescriptor.getType(), is(io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING)); - assertThat(grpcDescriptor.getRequestMarshaller(), is(instanceOf(StubMarshaller.class))); - assertThat(grpcDescriptor.getResponseMarshaller(), is(instanceOf(StubMarshaller.class))); - - ClientMethodDescriptor = descriptor.method("Three"); - assertThat(ClientMethodDescriptor, is(notNullValue())); - assertThat(ClientMethodDescriptor.name(), is("Three")); - - grpcDescriptor = ClientMethodDescriptor.descriptor(); - assertThat(grpcDescriptor, is(notNullValue())); - assertThat(grpcDescriptor.getFullMethodName(), is("ServiceTwo/Three")); - assertThat(grpcDescriptor.getType(), is(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)); - assertThat(grpcDescriptor.getRequestMarshaller(), is(instanceOf(StubMarshaller.class))); - assertThat(grpcDescriptor.getResponseMarshaller(), is(instanceOf(StubMarshaller.class))); - - ClientMethodDescriptor = descriptor.method("Four"); - assertThat(ClientMethodDescriptor, is(notNullValue())); - assertThat(ClientMethodDescriptor.name(), is("Four")); - - grpcDescriptor = ClientMethodDescriptor.descriptor(); - assertThat(grpcDescriptor, is(notNullValue())); - assertThat(grpcDescriptor.getFullMethodName(), is("ServiceTwo/Four")); - assertThat(grpcDescriptor.getType(), is(io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING)); - assertThat(grpcDescriptor.getRequestMarshaller(), is(instanceOf(StubMarshaller.class))); - assertThat(grpcDescriptor.getResponseMarshaller(), is(instanceOf(StubMarshaller.class))); - } - - @Grpc(name = "ServiceOne/foo") - @GrpcMarshaller("stub") - public static class ServiceOne { - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.UNARY) - public void unary(String param, StreamObserver observer) { - } - - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING) - public StreamObserver clientStreaming(StreamObserver observer) { - return null; - } - - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) - public void serverStreaming(String param, StreamObserver observer) { - } - - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING) - public StreamObserver bidiStreaming(StreamObserver observer) { - return null; - } - } - - @Grpc - @GrpcMarshaller("stub") - public static class ServiceTwo { - @GrpcMethod(name = "One", type = io.grpc.MethodDescriptor.MethodType.UNARY) - public void unary(String param, StreamObserver observer) { - } - - @GrpcMethod(name = "Two", type = io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING) - public StreamObserver clientStreaming(StreamObserver observer) { - return null; - } - - @GrpcMethod(name = "Three", type = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) - public void serverStreaming(String param, StreamObserver observer) { - } - - @GrpcMethod(name = "Four", type = io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING) - public StreamObserver bidiStreaming(StreamObserver observer) { - return null; - } - } - - @Grpc - @GrpcMarshaller("stub") - public static class ServiceThree { - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.UNARY) - public void unary(String param, StreamObserver observer) { - } - } - - @Grpc - @GrpcMarshaller("stub") - public static class ServiceFour { - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.UNARY) - @GrpcMarshaller("stub") - public void unary(String param, StreamObserver observer) { - } - } - - @Grpc - @GrpcMarshaller("stub") - @Singleton - public static class ServiceFive { - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.UNARY) - @GrpcMarshaller("stub") - public void unary(String param, StreamObserver observer) { - observer.onNext(this); - observer.onCompleted(); - } - } -} diff --git a/microprofile/grpc/client/src/test/java/io/helidon/microprofile/grpc/client/GrpcProxyBuilderTest.java b/microprofile/grpc/client/src/test/java/io/helidon/microprofile/grpc/client/GrpcProxyBuilderTest.java deleted file mode 100644 index 604fe50367d..00000000000 --- a/microprofile/grpc/client/src/test/java/io/helidon/microprofile/grpc/client/GrpcProxyBuilderTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2022 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.client; - -import java.util.Collection; -import java.util.concurrent.CompletionStage; - -import io.helidon.microprofile.grpc.core.GrpcMarshaller; -import io.helidon.microprofile.grpc.core.Unary; - -import org.junit.jupiter.api.Test; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.MatcherAssert.assertThat; - -public class GrpcProxyBuilderTest { - @Test - public void shouldCreateProxyForMethodWithWithNestedGenerics() { - TestService service = GrpcProxyBuilder.create(TestService.class).build(); - assertThat(service, is(notNullValue())); - } - - @GrpcMarshaller("stub") - public interface TestService { - @Unary - CompletionStage> getBooks(); - } -} diff --git a/microprofile/grpc/client/src/test/java/io/helidon/microprofile/grpc/client/StubMarshaller.java b/microprofile/grpc/client/src/test/java/io/helidon/microprofile/grpc/client/StubMarshaller.java deleted file mode 100644 index 98999fc37ea..00000000000 --- a/microprofile/grpc/client/src/test/java/io/helidon/microprofile/grpc/client/StubMarshaller.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.client; - -import java.io.InputStream; - -import io.helidon.grpc.core.MarshallerSupplier; - -import io.grpc.MethodDescriptor; -import jakarta.inject.Named; - -/** - * A stub {@link io.grpc.MethodDescriptor.Marshaller}. - *

- * This marshaller will not actually work and should not - * be used as a real marshaller. - */ -public class StubMarshaller - implements MethodDescriptor.Marshaller { - - @Override - public InputStream stream(T value) { - return null; - } - - @Override - public T parse(InputStream stream) { - return null; - } - - @Named("stub") - public static class Supplier - implements MarshallerSupplier { - @Override - public MethodDescriptor.Marshaller get(Class clazz) { - return new StubMarshaller<>(); - } - } -} diff --git a/microprofile/grpc/client/src/test/resources/META-INF/services/io.helidon.grpc.core.MarshallerSupplier b/microprofile/grpc/client/src/test/resources/META-INF/services/io.helidon.grpc.core.MarshallerSupplier deleted file mode 100644 index 4fe53ec8b5d..00000000000 --- a/microprofile/grpc/client/src/test/resources/META-INF/services/io.helidon.grpc.core.MarshallerSupplier +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2019, 2022 Oracle and/or its affiliates. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -io.helidon.microprofile.grpc.client.StubMarshaller$Supplier diff --git a/microprofile/grpc/core/pom.xml b/microprofile/grpc/core/pom.xml index e68cafe1a90..d8ee2f6be43 100644 --- a/microprofile/grpc/core/pom.xml +++ b/microprofile/grpc/core/pom.xml @@ -35,8 +35,8 @@ helidon-grpc-core - io.helidon.grpc - helidon-grpc-client + io.helidon.webclient + helidon-webclient-grpc jakarta.enterprise @@ -45,7 +45,7 @@ io.helidon.common - helidon-common-service-loader + helidon-common io.helidon.microprofile.config diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/AbstractMethodHandlerSupplier.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/AbstractMethodHandlerSupplier.java index c8698a3102b..8d43437b9c0 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/AbstractMethodHandlerSupplier.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/AbstractMethodHandlerSupplier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/AbstractServiceBuilder.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/AbstractServiceBuilder.java index 2050834900a..a5bdab576d3 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/AbstractServiceBuilder.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/AbstractServiceBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ import java.util.logging.Level; import java.util.logging.Logger; -import io.helidon.common.serviceloader.HelidonServiceLoader; +import io.helidon.common.HelidonServiceLoader; import io.helidon.grpc.core.MarshallerSupplier; import jakarta.annotation.Priority; @@ -96,7 +96,7 @@ protected Class annotatedServiceClass() { */ protected MarshallerSupplier getMarshallerSupplier() { GrpcMarshaller annotation = annotatedServiceClass.getAnnotation(GrpcMarshaller.class); - return annotation == null ? MarshallerSupplier.defaultInstance() : ModelHelper.getMarshallerSupplier(annotation); + return annotation == null ? MarshallerSupplier.create() : ModelHelper.getMarshallerSupplier(annotation); } /** diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/AnnotatedMethod.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/AnnotatedMethod.java index 920c2ada1fb..53bc1f61375 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/AnnotatedMethod.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/AnnotatedMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/AnnotatedMethodList.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/AnnotatedMethodList.java index 7da2a5237a7..f6997f68df2 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/AnnotatedMethodList.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/AnnotatedMethodList.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/Bidirectional.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/Bidirectional.java index 6b285322153..6f5dc4df63a 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/Bidirectional.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/Bidirectional.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/BidirectionalMethodHandlerSupplier.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/BidirectionalMethodHandlerSupplier.java index 1928660d69a..3ba8f0339e2 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/BidirectionalMethodHandlerSupplier.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/BidirectionalMethodHandlerSupplier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ClientStreaming.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ClientStreaming.java index e3322755b35..45822c54560 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ClientStreaming.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ClientStreaming.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ClientStreamingMethodHandlerSupplier.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ClientStreamingMethodHandlerSupplier.java index 19be811adf0..e95350df1dc 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ClientStreamingMethodHandlerSupplier.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ClientStreamingMethodHandlerSupplier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/Grpc.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/Grpc.java index cc6c032dd37..ddd59270e07 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/Grpc.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/Grpc.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcCdiExtension.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcCdiExtension.java index 39da6669cf9..2cd38e4d2c1 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcCdiExtension.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcCdiExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcInterceptor.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcInterceptor.java index 6d9e3a913a2..0aa9efd805a 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcInterceptor.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcInterceptorBinding.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcInterceptorBinding.java index 148c7b15219..9d2e20556a7 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcInterceptorBinding.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcInterceptorBinding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcInterceptors.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcInterceptors.java index 94e75ecc516..9621c68a7f4 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcInterceptors.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcInterceptors.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcMarshaller.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcMarshaller.java index 426778889fe..a35d1a72e32 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcMarshaller.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcMarshaller.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcMethod.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcMethod.java index 5d4e114dcb8..44e6ddc544d 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcMethod.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/GrpcMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/InProcessGrpcChannel.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/InProcessGrpcChannel.java index e9f63afac07..299678351dd 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/InProcessGrpcChannel.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/InProcessGrpcChannel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/Instance.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/Instance.java index fdea246d603..a51e0d53808 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/Instance.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/Instance.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/MethodHandlerSupplier.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/MethodHandlerSupplier.java index e04196e7d4c..3c9a908326c 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/MethodHandlerSupplier.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/MethodHandlerSupplier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ModelHelper.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ModelHelper.java index 31a960bce84..1b585fe569b 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ModelHelper.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ModelHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/RequestType.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/RequestType.java index fcb3cb4a49c..2d615662228 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/RequestType.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/RequestType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ResponseType.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ResponseType.java index 82492878574..d59738c3dae 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ResponseType.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ResponseType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ServerStreaming.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ServerStreaming.java index 44004bce93a..6f4c9f85a9b 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ServerStreaming.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ServerStreaming.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ServerStreamingMethodHandlerSupplier.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ServerStreamingMethodHandlerSupplier.java index e0923ddadb8..f4703f88883 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ServerStreamingMethodHandlerSupplier.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/ServerStreamingMethodHandlerSupplier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/Unary.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/Unary.java index 300b3274160..eaba07e0543 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/Unary.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/Unary.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/UnaryMethodHandlerSupplier.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/UnaryMethodHandlerSupplier.java index b9df9ab1b5f..ea1a46536b5 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/UnaryMethodHandlerSupplier.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/UnaryMethodHandlerSupplier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/package-info.java b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/package-info.java index 17da46d7f4c..3687f1005fe 100644 --- a/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/package-info.java +++ b/microprofile/grpc/core/src/main/java/io/helidon/microprofile/grpc/core/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/main/java/module-info.java b/microprofile/grpc/core/src/main/java/module-info.java index bd347001df2..b6a32f9cc81 100644 --- a/microprofile/grpc/core/src/main/java/module-info.java +++ b/microprofile/grpc/core/src/main/java/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,10 +20,10 @@ module io.helidon.microprofile.grpc.core { exports io.helidon.microprofile.grpc.core; + requires io.helidon.common; requires transitive io.helidon.grpc.core; - requires transitive io.helidon.grpc.client; + requires transitive io.helidon.webclient.grpc; requires transitive io.helidon.microprofile.config; - requires io.helidon.common.serviceloader; requires transitive jakarta.cdi; diff --git a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/AbstractMethodHandlerSupplierTest.java b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/AbstractMethodHandlerSupplierTest.java index b53dd3e590a..e893e457330 100644 --- a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/AbstractMethodHandlerSupplierTest.java +++ b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/AbstractMethodHandlerSupplierTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/AnnotatedMethodListTest.java b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/AnnotatedMethodListTest.java index 62bba502b60..53a6b8c328a 100644 --- a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/AnnotatedMethodListTest.java +++ b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/AnnotatedMethodListTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/AnnotatedMethodTest.java b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/AnnotatedMethodTest.java index 7d2d3071f0d..15f7e336e91 100644 --- a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/AnnotatedMethodTest.java +++ b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/AnnotatedMethodTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/BidirectionalMethodHandlerSupplierTest.java b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/BidirectionalMethodHandlerSupplierTest.java index ef5a2a09225..ba6476e36d8 100644 --- a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/BidirectionalMethodHandlerSupplierTest.java +++ b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/BidirectionalMethodHandlerSupplierTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/ClientStreamingMethodHandlerSupplierTest.java b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/ClientStreamingMethodHandlerSupplierTest.java index 2206d0a3f46..318a2c13b91 100644 --- a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/ClientStreamingMethodHandlerSupplierTest.java +++ b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/ClientStreamingMethodHandlerSupplierTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/InstanceTest.java b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/InstanceTest.java index 7a16d4eebea..a449cec1e2d 100644 --- a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/InstanceTest.java +++ b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/InstanceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/MethodHandlerTest.java b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/MethodHandlerTest.java index ffd9bcfc8c4..530c245603b 100644 --- a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/MethodHandlerTest.java +++ b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/MethodHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/ModelHelperTest.java b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/ModelHelperTest.java index 6a1324d7dfa..2c342dc5268 100644 --- a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/ModelHelperTest.java +++ b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/ModelHelperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/ServerStreamingMethodHandlerSupplierTest.java b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/ServerStreamingMethodHandlerSupplierTest.java index 3cb2dc42d8e..375324dfc51 100644 --- a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/ServerStreamingMethodHandlerSupplierTest.java +++ b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/ServerStreamingMethodHandlerSupplierTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/UnaryMethodHandlerSupplierTest.java b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/UnaryMethodHandlerSupplierTest.java index a6c716f39f8..77486c703d7 100644 --- a/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/UnaryMethodHandlerSupplierTest.java +++ b/microprofile/grpc/core/src/test/java/io/helidon/microprofile/grpc/core/UnaryMethodHandlerSupplierTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/microprofile/grpc/metrics/README.md b/microprofile/grpc/metrics/README.md deleted file mode 100644 index 0c9fb16fd95..00000000000 --- a/microprofile/grpc/metrics/README.md +++ /dev/null @@ -1,104 +0,0 @@ -# gRPC Metrics - -## Adding support for a new metric type -From time to time, the metrics spec evolves and new metrics appear. -To add support for a new metric to gRPC, follow these steps. - -### Update `GrpcMetrics` -#### Add `xxx` metric factory method -The class contains a very simple method for each metric type like this: -```java -public static GrpcMetrics concurrentGauge() {...} -``` -Just add a new method following the same pattern for the new metric type. - -#### Add `xxxServerCall` method -The class also contains a method per metrics like this: -```java -private class ConcurrentGaugeServerCall - extends MetricServerCall {...} -``` -Add a new method following the same pattern for the new metric type. The new method will need to -update its metric in a way that varies among the different metrics types. - -#### Update the `interceptCall` method -Add a new `case` for the new metric to the `switch` statement. - -### Update `GrpcMetricsInterceptorIT` -Add a test for the new metric: -```java -public void shouldUseConcurrentGaugeMetric() throws Exception {...} -``` -Follow the pattern set by the methods for other metrics, changing the names and using a -metric-specific check to make sure the metric was correctly updated. -### Update `MetricsConfigurer` -Update the map near the top of the file to add the new metric annotation. -The rest of the logic uses the map rather than hard-coded methods. - -### Update `GrpcMetricsCdiExtension` - -Add the new metric and its corresponding annotation to the `METRICS_ANNOTATIONS` `EnumMap` -initialization. - -On the `registerMetrics` method, add the new metrics annotation(s) to the `@WithAnnotation` list of -metrics -annotations. - -### Update `MetricsConfigurerTest` -#### Update `ServiceOne` inner class -Add an empty method for the new metric type. -```java -@Unary -@ConcurrentGauge -public void concurrentGauge(String request, StreamObserver response) {} -``` - -#### Update `ServiceTwo` interface -Add a method for the new metric type: -```java -@Unary -@ConcurrentGauge -void concurrentGauge(String request, StreamObserver response); -``` - -#### Update `ServiceTwoImpl` class -Add a method for the new metric type: -```java -@Override -public void concurrentGauge(String request, StreamObserver response) { -} -``` - -Add an invocation of the new method to the `update` method: -```java - ... - .unary("concurrentGauge", this::concurrentGauge); -``` -#### Add tests -##### Add a test to make sure the metric is updated - -Follow the pattern: -```java -@Test -public void shouldAddConcurrentGaugeMetricFromClassAnnotation() {...} -``` -##### Add a test to make sure the new metric annotation on the interface is ignored - -Follow the pattern: -```java -@Test -public void shouldIgnoreConcurrentGaugeMetricFromInterfaceAnnotation {...} -``` -### Add `CoverageTestBeanXXX` test class -where `XXX` is the simple name of the new metrics annotation (e.g., `Counted`). -Use one of the existing classes as a pattern, removing the existing metrics annotation from the -method and adding the new metrics annotation in its place. - -## Testing -To help make sure all known metrics annotations (from the `microprofile/metrics` artifact) are -handled, a test-time CDI extension finds all the coverage test beans and adds them to CDI. -It also examines those classes during the normal CDI extension life cycle to make sure the -actual gRPC extension processes them as expected. - -Several tests make sure that all the metrics annotations are represented and processed, listing any annotations that were not processed as expected. - diff --git a/microprofile/grpc/metrics/pom.xml b/microprofile/grpc/metrics/pom.xml deleted file mode 100644 index f91c67c6b37..00000000000 --- a/microprofile/grpc/metrics/pom.xml +++ /dev/null @@ -1,108 +0,0 @@ - - - - - 4.0.0 - - io.helidon.microprofile.grpc - helidon-microprofile-grpc - 3.2.9-SNAPSHOT - - - helidon-microprofile-grpc-metrics - Helidon Microprofile gRPC Metrics - Core microprofile gRPC metrics - - - - io.helidon.microprofile.grpc - helidon-microprofile-grpc-core - - - io.helidon.grpc - helidon-grpc-metrics - - - io.helidon.microprofile.grpc - helidon-microprofile-grpc-server - - - io.helidon.common - helidon-common-service-loader - - - io.helidon.microprofile.metrics - helidon-microprofile-metrics - provided - - - jakarta.enterprise - jakarta.enterprise.cdi-api - provided - - - io.helidon.microprofile.cdi - helidon-microprofile-cdi - - - org.slf4j - slf4j-api - - - - org.slf4j - slf4j-jdk14 - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter-params - test - - - org.hamcrest - hamcrest-all - test - - - org.mockito - mockito-core - test - - - io.helidon.microprofile.tests - helidon-microprofile-tests-junit5 - test - - - - - - - kr.motd.maven - os-maven-plugin - ${version.plugin.os} - - - - diff --git a/microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/GrpcMetricAnnotationDiscoveryObserver.java b/microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/GrpcMetricAnnotationDiscoveryObserver.java deleted file mode 100644 index 10da1c76d57..00000000000 --- a/microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/GrpcMetricAnnotationDiscoveryObserver.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2022 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.helidon.microprofile.grpc.metrics; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; - -import io.helidon.common.LazyValue; -import io.helidon.microprofile.grpc.core.AnnotatedMethod; -import io.helidon.microprofile.grpc.core.GrpcMethod; -import io.helidon.microprofile.metrics.MetricAnnotationDiscovery; -import io.helidon.microprofile.metrics.spi.MetricAnnotationDiscoveryObserver; - -import jakarta.enterprise.inject.spi.configurator.AnnotatedMethodConfigurator; - -/** - * The gRPC implementation of {@link io.helidon.microprofile.metrics.spi.MetricAnnotationDiscoveryObserver}. - */ -class GrpcMetricAnnotationDiscoveryObserver implements MetricAnnotationDiscoveryObserver { - - private static final LazyValue INSTANCE = - LazyValue.create(GrpcMetricAnnotationDiscoveryObserver::new); - - private final Map, MetricAnnotationDiscovery.OfMethod>> discoveriesByMethod = - new HashMap<>(); - - - private GrpcMetricAnnotationDiscoveryObserver() { - } - - - static GrpcMetricAnnotationDiscoveryObserver instance() { - return INSTANCE.get(); - } - - @Override - public void onDiscovery(MetricAnnotationDiscovery discovery) { - if (discovery instanceof MetricAnnotationDiscovery.OfMethod methodDiscovery - && isRpcMethod(methodDiscovery.configurator(), discovery.annotation().annotationType())) { - - if (!MetricsConfigurer.isServiceAnnotated(methodDiscovery.annotatedTypeConfigurator().getAnnotated().getJavaClass(), - methodDiscovery.configurator().getAnnotated().getJavaMember(), - discovery.annotation().annotationType())) { - // This endpoint should not give rise to a gRPC-inspired metric. - discovery.deactivate(); - } else { - // This endpoint SHOULD give rise to a gRPC-inspired metric. - discovery.disableDefaultInterceptor(); - discoveriesByMethod.computeIfAbsent(methodDiscovery.configurator().getAnnotated().getJavaMember(), - key -> new HashMap<>()) - .putIfAbsent(discovery.annotation().annotationType(), methodDiscovery); - } - } - } - - static Map, MetricAnnotationDiscovery.OfMethod> discoveries(Method method) { - return INSTANCE.get().discoveriesByMethod.get(method); - } - - static boolean isDiscovered(Method method) { - return INSTANCE.get().discoveriesByMethod.containsKey(method); - } - - /** - * Determine whether a method is annotated with both a metrics annotation - * and an annotation of type {@link io.helidon.microprofile.grpc.core.GrpcMethod}. - * - * @param configurator the {@link jakarta.enterprise.inject.spi.configurator.AnnotatedMethodConfigurator} representing - * the annotated method - * - * @return {@code true} if the method is a timed gRPC method - */ - private static boolean isRpcMethod(AnnotatedMethodConfigurator configurator, Class type) { - AnnotatedMethod method = AnnotatedMethod.create(configurator.getAnnotated().getJavaMember()); - GrpcMethod rpcMethod = method.firstAnnotationOrMetaAnnotation(GrpcMethod.class); - if (rpcMethod != null) { - Annotation annotation = method.firstAnnotationOrMetaAnnotation(type); - return annotation != null; - } - return false; - } - -} diff --git a/microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/GrpcMetricRegistrationObserver.java b/microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/GrpcMetricRegistrationObserver.java deleted file mode 100644 index d803a8872ae..00000000000 --- a/microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/GrpcMetricRegistrationObserver.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2022 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.helidon.microprofile.grpc.metrics; - -import java.util.HashMap; -import java.util.Map; - -import io.helidon.common.LazyValue; -import io.helidon.microprofile.metrics.MetricAnnotationDiscovery; -import io.helidon.microprofile.metrics.spi.MetricRegistrationObserver; - -import org.eclipse.microprofile.metrics.Metadata; -import org.eclipse.microprofile.metrics.Metric; -import org.eclipse.microprofile.metrics.MetricID; - -/** - * The gRPC implementation of {@link io.helidon.microprofile.metrics.spi.MetricRegistrationObserver} with a static factory method. - */ -public class GrpcMetricRegistrationObserver implements MetricRegistrationObserver { - - private static final LazyValue INSTANCE - = LazyValue.create(GrpcMetricRegistrationObserver::new); - - private final Map metadataByDiscovery = new HashMap<>(); - - private GrpcMetricRegistrationObserver() { - } - - static GrpcMetricRegistrationObserver instance() { - return INSTANCE.get(); - } - - @Override - public void onRegistration(MetricAnnotationDiscovery discovery, - Metadata metadata, - MetricID metricId, - Metric metric) { - metadataByDiscovery.put(discovery, metadata); - } - - static Metadata metadata(MetricAnnotationDiscovery discovery) { - return INSTANCE.get().metadataByDiscovery.get(discovery); - } -} diff --git a/microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/GrpcMetricsCdiExtension.java b/microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/GrpcMetricsCdiExtension.java deleted file mode 100644 index e70a7d078ae..00000000000 --- a/microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/GrpcMetricsCdiExtension.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2019, 2022 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.metrics; - -import io.helidon.microprofile.metrics.MetricsCdiExtension; - -import jakarta.enterprise.event.Observes; -import jakarta.enterprise.inject.spi.BeanManager; -import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; -import jakarta.enterprise.inject.spi.Extension; - -/** - * A CDI extension for gRPC metrics. - *

- * This extension instantiates and enrolls with the metrics CDI extension a metrics annotation discovery observer and a metrics - * registration observer. It records them for later use by the {@code MetricsConfigurer}. - */ -public class GrpcMetricsCdiExtension implements Extension { - - private void before(@Observes BeforeBeanDiscovery bbd, BeanManager beanManager) { - MetricsCdiExtension metricsCdiExtension = beanManager.getExtension(MetricsCdiExtension.class); - metricsCdiExtension.enroll(GrpcMetricAnnotationDiscoveryObserver.instance()); - metricsCdiExtension.enroll(GrpcMetricRegistrationObserver.instance()); - } -} diff --git a/microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/MetricsConfigurer.java b/microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/MetricsConfigurer.java deleted file mode 100644 index 043e03cfcf3..00000000000 --- a/microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/MetricsConfigurer.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2019, 2022 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.metrics; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.Map; -import java.util.function.Supplier; -import java.util.logging.Level; -import java.util.logging.Logger; - -import io.helidon.grpc.metrics.GrpcMetrics; -import io.helidon.grpc.server.ServiceDescriptor; -import io.helidon.microprofile.grpc.core.AnnotatedMethod; -import io.helidon.microprofile.grpc.core.AnnotatedMethodList; -import io.helidon.microprofile.grpc.core.GrpcMethod; -import io.helidon.microprofile.grpc.server.AnnotatedServiceConfigurer; -import io.helidon.microprofile.grpc.server.GrpcServiceBuilder; - -import org.eclipse.microprofile.metrics.Counter; -import org.eclipse.microprofile.metrics.Metadata; -import org.eclipse.microprofile.metrics.Meter; -import org.eclipse.microprofile.metrics.Metric; -import org.eclipse.microprofile.metrics.MetricType; -import org.eclipse.microprofile.metrics.SimpleTimer; -import org.eclipse.microprofile.metrics.Timer; -import org.eclipse.microprofile.metrics.annotation.ConcurrentGauge; -import org.eclipse.microprofile.metrics.annotation.Counted; -import org.eclipse.microprofile.metrics.annotation.Metered; -import org.eclipse.microprofile.metrics.annotation.SimplyTimed; -import org.eclipse.microprofile.metrics.annotation.Timed; - -/** - * A {@link AnnotatedServiceConfigurer} that adds a - * {@link io.helidon.grpc.metrics.GrpcMetrics gRPC metrics interceptor} - * to an annotated gRPC service. - *

- * Metric interceptors are only added to services where the method on the - * service class is annotated with a metric annotation. Any metric annotations - * on super classes or interfaces will be ignored. - */ -public class MetricsConfigurer - implements AnnotatedServiceConfigurer { - - private static final Logger LOGGER = Logger.getLogger(MetricsConfigurer.class.getName()); - - static final Map, MetricInfo> METRIC_ANNOTATION_INFO = Map.of( - Counted.class, MetricInfo.create(GrpcMetrics::counted, Counter.class), - Metered.class, MetricInfo.create(GrpcMetrics::metered, Meter.class), - Timed.class, MetricInfo.create(GrpcMetrics::timed, Timer.class), - ConcurrentGauge.class, MetricInfo.create(GrpcMetrics::concurrentGauge, - org.eclipse.microprofile.metrics.ConcurrentGauge.class), - SimplyTimed.class, MetricInfo.create(GrpcMetrics::simplyTimed, SimpleTimer.class) - ); - - @Override - public void accept(Class serviceClass, Class annotatedClass, ServiceDescriptor.Builder builder) { - - AnnotatedMethodList methodList = AnnotatedMethodList.create(serviceClass); - - // For each annotated method: - // Retrieve all discoveries of metric annotations on that method, and for each: - // Get the metric registration for it (which has the metric metadata). - // Add the interceptor for the annotation associated with the annotation site that was discovered. - methodList.stream() - .filter(am -> GrpcMetricAnnotationDiscoveryObserver.isDiscovered(am.method())) - .forEach(annotatedMethod -> - GrpcMetricAnnotationDiscoveryObserver.discoveries(annotatedMethod.method()) - .forEach((annotationClass, discovery) -> { - if (isServiceAnnotated(serviceClass, - annotatedMethod.declaredMethod(), - annotationClass)) { - processMetricAnnotationSite( - builder, - annotatedMethod, - METRIC_ANNOTATION_INFO - .get(annotationClass) - .grpcMetricsSupplier - .get(), - discovery.annotation(), - GrpcMetricRegistrationObserver.metadata(discovery) - ); - } - }) - ); - } - - static boolean isServiceAnnotated(Class cls, - Method method, - Class annotation) { - return method.getDeclaringClass().equals(cls) && method.isAnnotationPresent(annotation); - } - - record MetricInfo(Supplier grpcMetricsSupplier, - Class metricClass) { - private static MetricInfo create(Supplier grpcMetricsSupplier, Class metricClass) { - return new MetricInfo(grpcMetricsSupplier, metricClass); - } - } - - - - // Package-private for testing. - - private void processMetricAnnotationSite(ServiceDescriptor.Builder builder, - AnnotatedMethod annotatedMethod, - GrpcMetrics interceptor, - Annotation annotation, - Metadata metadata) { - - GrpcMethod rpcMethod = annotatedMethod.firstAnnotationOrMetaAnnotation(GrpcMethod.class); - if (rpcMethod != null) { - String grpcMethodName = GrpcServiceBuilder.determineMethodName(annotatedMethod, rpcMethod); - - LOGGER.log(Level.FINE, () -> String.format("Adding gRPC '%s' metric interceptor to service '%s' method '%s'", - annotation.annotationType().getSimpleName(), - builder.name(), - grpcMethodName)); - - if (METRIC_ANNOTATION_INFO.containsKey(annotation.annotationType()) - && annotation.annotationType().isInstance(annotation)) { - String candidateDescription = metadata.getDescription(); - if (candidateDescription != null && !candidateDescription.trim().isEmpty()) { - interceptor = interceptor.description(candidateDescription.trim()); - } - String candidateDisplayName = metadata.getDisplayName(); - if (candidateDisplayName != null && !candidateDisplayName.trim().isEmpty()) { - interceptor = interceptor.displayName(candidateDisplayName.trim()); - } - interceptor = interceptor - .units(metadata.getUnit()); - } - - builder.intercept(grpcMethodName, interceptor.nameFunction(new ConstantNamingFunction(metadata.getName()))); - } - } - - /** - * A {@link GrpcMetrics.NamingFunction} that returns a constant name. - */ - private static class ConstantNamingFunction - implements GrpcMetrics.NamingFunction { - private final String name; - - private ConstantNamingFunction(String name) { - this.name = name; - } - - @Override - public String createName(ServiceDescriptor service, String methodName, MetricType metricType) { - return name; - } - } -} diff --git a/microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/package-info.java b/microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/package-info.java deleted file mode 100644 index cdf4c466b98..00000000000 --- a/microprofile/grpc/metrics/src/main/java/io/helidon/microprofile/grpc/metrics/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2019, 2023 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * gRPC microprofile metrics. - */ -package io.helidon.microprofile.grpc.metrics; diff --git a/microprofile/grpc/metrics/src/main/java/module-info.java b/microprofile/grpc/metrics/src/main/java/module-info.java deleted file mode 100644 index 5ff244bd6c9..00000000000 --- a/microprofile/grpc/metrics/src/main/java/module-info.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2019, 2022 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * gRPC microprofile metrics module - */ -module io.helidon.microprofile.grpc.metrics { - exports io.helidon.microprofile.grpc.metrics; - - requires transitive io.helidon.grpc.metrics; - requires transitive io.helidon.microprofile.grpc.server; - requires transitive io.helidon.microprofile.metrics; - requires transitive io.helidon.microprofile.server; - - requires io.helidon.servicecommon.restcdi; - - requires java.logging; - requires jakarta.interceptor.api; - - provides io.helidon.microprofile.grpc.server.AnnotatedServiceConfigurer - with io.helidon.microprofile.grpc.metrics.MetricsConfigurer; - - provides jakarta.enterprise.inject.spi.Extension - with io.helidon.microprofile.grpc.metrics.GrpcMetricsCdiExtension; -} \ No newline at end of file diff --git a/microprofile/grpc/metrics/src/main/resources/META-INF/beans.xml b/microprofile/grpc/metrics/src/main/resources/META-INF/beans.xml deleted file mode 100644 index c7fe79b85a9..00000000000 --- a/microprofile/grpc/metrics/src/main/resources/META-INF/beans.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - diff --git a/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanBase.java b/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanBase.java deleted file mode 100644 index ac730586645..00000000000 --- a/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanBase.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.helidon.microprofile.grpc.metrics; - -import jakarta.enterprise.context.Dependent; - -@Dependent -public class CoverageTestBeanBase { -} diff --git a/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanConcurrentGauge.java b/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanConcurrentGauge.java deleted file mode 100644 index 3a5a3d40366..00000000000 --- a/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanConcurrentGauge.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.helidon.microprofile.grpc.metrics; - -import io.helidon.microprofile.grpc.core.GrpcMethod; - -import org.eclipse.microprofile.metrics.annotation.ConcurrentGauge; - -public class CoverageTestBeanConcurrentGauge extends CoverageTestBeanBase { - - @ConcurrentGauge - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.UNARY) - public void measuredMethod() { - } -} diff --git a/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanCounted.java b/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanCounted.java deleted file mode 100644 index e55ddf0730f..00000000000 --- a/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanCounted.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.helidon.microprofile.grpc.metrics; - -import io.helidon.microprofile.grpc.core.GrpcMethod; - -import org.eclipse.microprofile.metrics.annotation.Counted; - -public class CoverageTestBeanCounted extends CoverageTestBeanBase { - - @Counted - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.UNARY) - public void measuredMethod() { - } -} diff --git a/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanMetered.java b/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanMetered.java deleted file mode 100644 index 40051f6edaa..00000000000 --- a/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanMetered.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.helidon.microprofile.grpc.metrics; - -import io.helidon.microprofile.grpc.core.GrpcMethod; - -import org.eclipse.microprofile.metrics.annotation.Metered; - -public class CoverageTestBeanMetered extends CoverageTestBeanBase { - - @Metered - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.UNARY) - public void measuredMethod() { - } -} diff --git a/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanSimplyTimed.java b/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanSimplyTimed.java deleted file mode 100644 index beaa1694ac0..00000000000 --- a/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanSimplyTimed.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.helidon.microprofile.grpc.metrics; - -import io.helidon.microprofile.grpc.core.GrpcMethod; - -import org.eclipse.microprofile.metrics.annotation.SimplyTimed; - -public class CoverageTestBeanSimplyTimed extends CoverageTestBeanBase { - - @SimplyTimed - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.UNARY) - public void measuredMethod() { - } -} diff --git a/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanTimed.java b/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanTimed.java deleted file mode 100644 index 4fbc3f5d777..00000000000 --- a/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/CoverageTestBeanTimed.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.helidon.microprofile.grpc.metrics; - -import io.helidon.microprofile.grpc.core.GrpcMethod; - -import org.eclipse.microprofile.metrics.annotation.Timed; - -public class CoverageTestBeanTimed extends CoverageTestBeanBase { - - @Timed - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.UNARY) - public void measuredMethod() { - } -} diff --git a/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/GrpcMetricsCoverageTestCdiExtension.java b/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/GrpcMetricsCoverageTestCdiExtension.java deleted file mode 100644 index 91b68ef9224..00000000000 --- a/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/GrpcMetricsCoverageTestCdiExtension.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2021, 2022 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.helidon.microprofile.grpc.metrics; - -import java.lang.annotation.Annotation; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -import io.helidon.microprofile.grpc.core.GrpcMethod; - -import jakarta.annotation.Priority; -import jakarta.enterprise.event.Observes; -import jakarta.enterprise.inject.spi.AnnotatedMethod; -import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; -import jakarta.enterprise.inject.spi.Extension; -import jakarta.enterprise.inject.spi.ProcessAnnotatedType; -import jakarta.enterprise.inject.spi.ProcessManagedBean; -import jakarta.enterprise.inject.spi.WithAnnotations; -import jakarta.interceptor.Interceptor; - -public class GrpcMetricsCoverageTestCdiExtension implements Extension { - - private static final int OBSERVER_PRIORITY = Interceptor.Priority.APPLICATION; - - private static final Logger LOGGER = Logger.getLogger(GrpcMetricsCoverageTestCdiExtension.class.getName()); - - private final Set> metricsAnnotationsUsed = new HashSet<>(); - - private final Map, Set>> remainingTestBeanMethodAnnotations = - new HashMap<>(); - - private final Set> annotationClassesNotCoveredByTestBeans = new HashSet<>(); - - void before(@Observes BeforeBeanDiscovery bbd) { - - metricsAnnotationsUsed.clear(); - remainingTestBeanMethodAnnotations.clear(); - annotationClassesNotCoveredByTestBeans.clear(); - - String testBeanClassBaseName = CoverageTestBeanBase.class.getName(); - String testBeanClassNamePrefix = testBeanClassBaseName.substring(0, testBeanClassBaseName.indexOf("Base")); - - MetricsConfigurer.METRIC_ANNOTATION_INFO.forEach((annotationClass, metricInfo) -> { - String testBeanClassName = testBeanClassNamePrefix + annotationClass.getSimpleName(); - try { - Class testBeanClass = Class.forName(testBeanClassName); - bbd.addAnnotatedType(testBeanClass, testBeanClassName); - } catch (ClassNotFoundException e) { - annotationClassesNotCoveredByTestBeans.add(annotationClass); - } - }); - } - - /** - * Collects all the metrics annotations that are used on methods in the {@code CoverageTestBeanXXX} classes. - *

- * A test retrieves this collection and makes sure that all the metric annotations known to the main Helidon metrics - * module are accounted for on methods on the test beans. That's because another test makes sure that the gRPC - * extension, which removes metrics annotations from methods that also have {@code @GrpcMethod}, correctly removes all - * of those metrics annotations. We want to make sure that all known annotations are covered by the test beans so we - * can check that the gRPC extension is properly handling all of them. - *

- *

- * And, because the main gRPC extension removes metrics annotations that way, this observer needs to run before that - * one so we get an accurate collection of metrics annotations actually used in the test bean class. - *

- * @param pat - */ - void recordMetricsAnnotationsOnTestBean(@Observes @Priority(OBSERVER_PRIORITY - 10) - @WithAnnotations(GrpcMethod.class) ProcessAnnotatedType pat) { - - pat.getAnnotatedType() - .getMethods() - .forEach(m -> { - Set> metricsAnnotationClassesForThisMethod = - m.getAnnotations().stream() - .map(Annotation::annotationType) - .collect(Collectors.toSet()); - - metricsAnnotationClassesForThisMethod.retainAll(MetricsConfigurer.METRIC_ANNOTATION_INFO.keySet()); - LOGGER.log(Level.FINE, () -> String.format("Recording annotation(s) %s on %s", - metricsAnnotationClassesForThisMethod, m.getJavaMember().toString())); - metricsAnnotationsUsed.addAll(metricsAnnotationClassesForThisMethod); - }); - } - - /** - * Tracks which methods on the test bean still have any metrics annotations, given that the gRPC extension should have - * removed them. - * - * @param pmb the ProcessManagedBean event - */ - void checkForMetricsAnnotations(@Observes ProcessManagedBean pmb) { - - pmb.getAnnotatedBeanClass().getMethods().forEach(m -> { - Set> remainingMetricsAnnotationsForThisMethod = - m.getAnnotations().stream() - .map(Annotation::annotationType) - .collect(Collectors.toSet()); - - remainingMetricsAnnotationsForThisMethod.retainAll(MetricsConfigurer.METRIC_ANNOTATION_INFO.keySet()); - if (!remainingMetricsAnnotationsForThisMethod.isEmpty()) { - remainingTestBeanMethodAnnotations.put(m, remainingMetricsAnnotationsForThisMethod); - } - }); - } - - Map, Set>> remainingTestBeanMethodAnnotations() { - return remainingTestBeanMethodAnnotations; - } - - Set> metricsAnnotationsUsed() { - return metricsAnnotationsUsed; - } - - Set> annotationClassesNotCoveredByTestBeans() { - return annotationClassesNotCoveredByTestBeans; - } -} diff --git a/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/TestMetricsCoverage.java b/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/TestMetricsCoverage.java deleted file mode 100644 index ddbec44084a..00000000000 --- a/microprofile/grpc/metrics/src/test/java/io/helidon/microprofile/grpc/metrics/TestMetricsCoverage.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2021, 2022 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.helidon.microprofile.grpc.metrics; - -import java.lang.annotation.Annotation; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import io.helidon.microprofile.tests.junit5.AddBean; -import io.helidon.microprofile.tests.junit5.AddExtension; -import io.helidon.microprofile.tests.junit5.HelidonTest; - -import jakarta.enterprise.inject.spi.AnnotatedMethod; -import jakarta.inject.Inject; -import org.eclipse.microprofile.metrics.MetricType; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.empty; -import static org.hamcrest.Matchers.is; - -@HelidonTest -@AddExtension(GrpcMetricsCoverageTestCdiExtension.class) -@AddBean(CoverageTestBeanCounted.class) -public class TestMetricsCoverage { - - @Inject - GrpcMetricsCoverageTestCdiExtension extension; - - @Test - public void checkThatAllMetricsAnnotationsAreCoveredByTestBeans() { - assertThat("Metrics annotations not covered by test beans", - extension.annotationClassesNotCoveredByTestBeans(), is(empty())); - } - - @Test - public void checkThatAllMetricsAnnotationsWereEncountered() { - - Set> metricsAnnotationsUnused = - new HashSet<>(MetricsConfigurer.METRIC_ANNOTATION_INFO.keySet()); - metricsAnnotationsUnused.removeAll(extension.metricsAnnotationsUsed()); - - assertThat("Known annotations not covered by CoverageTestBeanBase subclasses", metricsAnnotationsUnused, - is(empty())); - } - - /** - * Checks that {@code MetricsConfigurer} deals with all metrics annotations that are known to the main Helidon metrics CDI - * extension. - *

- * The {@code MetricsConfigurer} class has been changed to be data-driven. The - * {@code metricInfo} map contains all the metric-specific code (mostly as method references) so adding support for a new - * metrics (if more are added) happens on that one table. - *

- *

- * This test makes sure that the map created there contains an entry for every type of metric annotation known to - * Helidon - * Microprofile metrics. - *

- */ - @Test - public void checkForAllMetricsInMetricInfo() { - var metricTypesSupportedByGrpc = new HashSet<>(List.of(MetricType.values())); - metricTypesSupportedByGrpc.removeAll(Set.of(MetricType.GAUGE, MetricType.HISTOGRAM, MetricType.INVALID)); - - var metricTypesAbsentFromMetricsConfigurer = new HashSet<>(metricTypesSupportedByGrpc); - - // Remove metrics types represented in the MetricsConfigurer's annotation info. - MetricsConfigurer.METRIC_ANNOTATION_INFO.forEach((annotationClass, metricInfo) -> { - metricTypesAbsentFromMetricsConfigurer.remove(MetricType.from(metricInfo.metricClass())); - }); - - assertThat("Metrics types not supported in MetricsConfigurer but should be", - metricTypesAbsentFromMetricsConfigurer, is(empty())); - } - - /** - * Makes sure that all metrics types that have corresponding annotations we process are present in the type-to-annotation - * EnumMap. - */ - @Test - public void checkForAllMetricTypesMappedToAnnotationType() { - Set ignoredMetricTypes = Set.of(MetricType.INVALID, // ignore this - MetricType.GAUGE, // we don't process gauge annotations - MetricType.HISTOGRAM // there is no histogram annotation for the histogram metric type - ); - - Set incorrectlySkippedMetricTypes = new HashSet<>(Arrays.asList(MetricType.values())); - incorrectlySkippedMetricTypes.removeAll(ignoredMetricTypes); - - MetricsConfigurer.METRIC_ANNOTATION_INFO.values() - .stream() - .map(MetricsConfigurer.MetricInfo::metricClass) - .map(MetricType::from) - .toList() - .forEach(incorrectlySkippedMetricTypes::remove); - assertThat("At least one MicroProfile metric with an annotation exists that is not present in " - + "MetricsConfigurer.METRIC_ANNOTATION_INFO", - incorrectlySkippedMetricTypes, is(empty())); - } -} diff --git a/microprofile/grpc/metrics/src/test/resources/META-INF/services/io.helidon.microprofile.grpc.metrics.TestMetricsCoverage$GeneratedBeanCatalog b/microprofile/grpc/metrics/src/test/resources/META-INF/services/io.helidon.microprofile.grpc.metrics.TestMetricsCoverage$GeneratedBeanCatalog deleted file mode 100644 index 48946a78e5b..00000000000 --- a/microprofile/grpc/metrics/src/test/resources/META-INF/services/io.helidon.microprofile.grpc.metrics.TestMetricsCoverage$GeneratedBeanCatalog +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2021 Oracle and/or its affiliates. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# The service class is generated. -io.helidon.microprofile.grpc.metrics.CoverageTestBeanCatalog \ No newline at end of file diff --git a/microprofile/grpc/pom.xml b/microprofile/grpc/pom.xml index 8343724e443..0168d936e7b 100644 --- a/microprofile/grpc/pom.xml +++ b/microprofile/grpc/pom.xml @@ -32,9 +32,6 @@ core - server - client - metrics diff --git a/microprofile/grpc/server/pom.xml b/microprofile/grpc/server/pom.xml deleted file mode 100644 index 818fac81d5e..00000000000 --- a/microprofile/grpc/server/pom.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - - - 4.0.0 - - io.helidon.microprofile.grpc - helidon-microprofile-grpc - 4.0.0-SNAPSHOT - - - helidon-microprofile-grpc-server - Helidon Microprofile gRPC Server - The microprofile gRPC Server implementation - - - - io.helidon.microprofile.grpc - helidon-microprofile-grpc-core - - - io.helidon.grpc - helidon-grpc-server - - - - jakarta.enterprise - jakarta.enterprise.cdi-api - provided - - - io.helidon.microprofile.config - helidon-microprofile-config - - - io.helidon.microprofile.server - helidon-microprofile-server - - - org.slf4j - slf4j-api - - - - org.slf4j - slf4j-jdk14 - - - org.junit.jupiter - junit-jupiter-api - test - - - org.hamcrest - hamcrest-all - test - - - org.mockito - mockito-core - test - - - io.reactivex.rxjava2 - rxjava - test - - - - javax.annotation - javax.annotation-api - provided - true - - - - - - - kr.motd.maven - os-maven-plugin - ${version.plugin.os} - - - - - - org.xolstice.maven.plugins - protobuf-maven-plugin - - - - test-compile - test-compile-custom - - - - - - - diff --git a/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/AnnotatedServiceConfigurer.java b/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/AnnotatedServiceConfigurer.java deleted file mode 100644 index 500f9d4cf67..00000000000 --- a/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/AnnotatedServiceConfigurer.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.server; - -import io.helidon.grpc.server.ServiceDescriptor; - -/** - * A class that may apply modifications to a {@link ServiceDescriptor.Builder} - * for an annotated gRPC service class. - *

- * Implementations of this class are called by the {@link GrpcServiceBuilder} when - * it builds a {@link ServiceDescriptor} from an annotated class. Instances of - * {@link AnnotatedServiceConfigurer} are discovered using the - * {@link io.helidon.common.serviceloader.HelidonServiceLoader}. This service - * loader supports ordering of configurers. - */ -@FunctionalInterface -public interface AnnotatedServiceConfigurer { - /** - * Apply modifications to a {@link ServiceDescriptor.Builder}. - * @param serviceClass the annotated gRPC service class - * @param annotatedClass the class with the {@link io.helidon.microprofile.grpc.core.Grpc} annotation - * @param builder the builder to modify - */ - void accept(Class serviceClass, Class annotatedClass, ServiceDescriptor.Builder builder); -} diff --git a/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/GrpcServerCdiExtension.java b/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/GrpcServerCdiExtension.java deleted file mode 100644 index 9d02652808d..00000000000 --- a/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/GrpcServerCdiExtension.java +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.server; - -import java.lang.annotation.Annotation; -import java.util.ServiceLoader; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.TimeUnit; -import java.util.function.Supplier; -import java.util.logging.Level; -import java.util.logging.Logger; - -import io.helidon.common.serviceloader.HelidonServiceLoader; -import io.helidon.config.Config; -import io.helidon.config.mp.MpConfig; -import io.helidon.grpc.server.GrpcRouting; -import io.helidon.grpc.server.GrpcServer; -import io.helidon.grpc.server.GrpcServerConfiguration; -import io.helidon.grpc.server.GrpcService; -import io.helidon.microprofile.grpc.core.Grpc; -import io.helidon.microprofile.grpc.core.InProcessGrpcChannel; -import io.helidon.microprofile.grpc.server.spi.GrpcMpContext; -import io.helidon.microprofile.grpc.server.spi.GrpcMpExtension; - -import io.grpc.BindableService; -import io.grpc.Channel; -import io.grpc.inprocess.InProcessChannelBuilder; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.enterprise.context.Initialized; -import jakarta.enterprise.event.Observes; -import jakarta.enterprise.inject.Any; -import jakarta.enterprise.inject.Instance; -import jakarta.enterprise.inject.Produces; -import jakarta.enterprise.inject.spi.AfterDeploymentValidation; -import jakarta.enterprise.inject.spi.Bean; -import jakarta.enterprise.inject.spi.BeanManager; -import jakarta.enterprise.inject.spi.BeforeShutdown; -import jakarta.enterprise.inject.spi.Extension; -import org.eclipse.microprofile.config.ConfigProvider; - -/** - * A CDI extension that will start the {@link GrpcServer gRPC server}. - *

- * The server is started when the {@link AfterDeploymentValidation} event - * is received and will be stopped when the {@link BeforeShutdown} event - * is received. - *

- * If no gRPC services are discovered the gRPC server will not be started. - */ -public class GrpcServerCdiExtension - implements Extension { - - private static final Logger LOGGER = Logger.getLogger(GrpcServerCdiExtension.class.getName()); - private static final Logger STARTUP_LOGGER = Logger.getLogger("io.helidon.microprofile.startup.server"); - - private GrpcServer server; - - - private void startServer(@Observes @Initialized(ApplicationScoped.class) Object event, BeanManager beanManager) { - GrpcRouting.Builder routingBuilder = discoverGrpcRouting(beanManager); - - Config config = MpConfig.toHelidonConfig(ConfigProvider.getConfig()); - GrpcServerConfiguration.Builder serverConfiguration = GrpcServerConfiguration.builder(config.get("grpc")); - CompletableFuture startedFuture = new CompletableFuture<>(); - CompletableFuture shutdownFuture = new CompletableFuture<>(); - - loadExtensions(beanManager, config, routingBuilder, serverConfiguration, startedFuture, shutdownFuture); - server = GrpcServer.create(serverConfiguration.build(), routingBuilder.build()); - long beforeT = System.nanoTime(); - - server.start() - .whenComplete((grpcServer, throwable) -> { - if (null != throwable) { - STARTUP_LOGGER.log(Level.SEVERE, throwable, () -> "gRPC server startup failed"); - startedFuture.completeExceptionally(throwable); - } else { - long t = TimeUnit.MILLISECONDS.convert(System.nanoTime() - beforeT, TimeUnit.NANOSECONDS); - - int port = grpcServer.port(); - STARTUP_LOGGER.finest("gRPC server started up"); - LOGGER.info(() -> "gRPC server started on localhost:" + port + " (and all other host addresses) " - + "in " + t + " milliseconds."); - - grpcServer.whenShutdown() - .whenComplete((server, error) -> { - if (error == null) { - shutdownFuture.complete(server); - } else { - shutdownFuture.completeExceptionally(error); - } - }); - - startedFuture.complete(grpcServer); - } - }); - - // inject the server into the producer so that it can be discovered later - ServerProducer serverProducer = beanManager.createInstance().select(ServerProducer.class).get(); - serverProducer.server(server); - } - - private void stopServer(@Observes BeforeShutdown event) { - if (server != null) { - LOGGER.info("Stopping gRPC server"); - long beforeT = System.nanoTime(); - server.shutdown() - .whenComplete((webServer, throwable) -> { - if (null != throwable) { - LOGGER.log(Level.SEVERE, throwable, () -> "An error occurred stopping the gRPC server"); - } else { - long t = TimeUnit.MILLISECONDS.convert(System.nanoTime() - beforeT, TimeUnit.NANOSECONDS); - LOGGER.info(() -> "gRPC Server stopped in " + t + " milliseconds."); - } - }); - } - } - - /** - * Discover the services and interceptors to use to configure the - * {@link GrpcRouting}. - * - * @param beanManager the CDI bean manager - * @return the {@link GrpcRouting} to use or {@code null} if no services - * or routing were discovered - */ - private GrpcRouting.Builder discoverGrpcRouting(BeanManager beanManager) { - Instance instance = beanManager.createInstance(); - GrpcRouting.Builder builder = GrpcRouting.builder(); - - // discover @Grpc annotated beans - // we use the bean manager to do this as we need the actual bean class - beanManager.getBeans(Object.class, Any.Literal.INSTANCE) - .stream() - .filter(this::hasGrpcQualifier) - .forEach(bean -> { - Class beanClass = bean.getBeanClass(); - Annotation[] qualifiers = bean.getQualifiers().toArray(new Annotation[0]); - Object service = instance.select(beanClass, qualifiers).get(); - register(service, builder, beanClass, beanManager); - }); - - // discover beans of type GrpcService - beanManager.getBeans(GrpcService.class) - .forEach(bean -> { - Class beanClass = bean.getBeanClass(); - Annotation[] qualifiers = bean.getQualifiers().toArray(new Annotation[0]); - Object service = instance.select(beanClass, qualifiers).get(); - builder.register((GrpcService) service); - }); - - // discover beans of type BindableService - beanManager.getBeans(BindableService.class) - .forEach(bean -> { - Class beanClass = bean.getBeanClass(); - Annotation[] qualifiers = bean.getQualifiers().toArray(new Annotation[0]); - Object service = instance.select(beanClass, qualifiers).get(); - builder.register((BindableService) service); - }); - - return builder; - } - - private boolean hasGrpcQualifier(Bean bean) { - return bean.getQualifiers() - .stream() - .anyMatch(q -> Grpc.class.isAssignableFrom(q.annotationType())); - } - - /** - * Load any instances of {@link GrpcMpExtension} discovered by the - * {@link ServiceLoader} and allow them to further configure the - * gRPC server. - * - * @param beanManager the {@link BeanManager} - * @param config the Helidon configuration - * @param routingBuilder the {@link GrpcRouting.Builder} - * @param serverConfiguration the {@link GrpcServerConfiguration} - */ - private void loadExtensions(BeanManager beanManager, - Config config, - GrpcRouting.Builder routingBuilder, - GrpcServerConfiguration.Builder serverConfiguration, - CompletionStage whenStarted, - CompletionStage whenShutdown) { - - GrpcMpContext context = new GrpcMpContext() { - @Override - public Config config() { - return config; - } - - @Override - public GrpcServerConfiguration.Builder grpcServerConfiguration() { - return serverConfiguration; - } - - @Override - public GrpcRouting.Builder routing() { - return routingBuilder; - } - - @Override - public BeanManager beanManager() { - return beanManager; - } - - @Override - public CompletionStage whenStarted() { - return whenStarted; - } - - @Override - public CompletionStage whenShutdown() { - return whenShutdown; - } - }; - - HelidonServiceLoader.create(ServiceLoader.load(GrpcMpExtension.class)) - .forEach(ext -> ext.configure(context)); - - beanManager.createInstance() - .select(GrpcMpExtension.class) - .stream() - .forEach(ext -> ext.configure(context)); - } - - /** - * Register the service with the routing. - *

- * The service is actually a CDI proxy so the real service. - * - * @param service the service to register - * @param builder the gRPC routing - * @param beanManager the {@link BeanManager} to use to locate beans required by the service - */ - private void register(Object service, GrpcRouting.Builder builder, Class cls, BeanManager beanManager) { - GrpcServiceBuilder serviceBuilder = GrpcServiceBuilder.create(cls, () -> service, beanManager); - if (serviceBuilder.isAnnotatedService()) { - builder.register(serviceBuilder.build()); - } else { - LOGGER.log(Level.WARNING, - () -> "Discovered type is not a properly annotated gRPC service " + service.getClass()); - } - } - - /** - * A CDI producer that can supply the running {@link GrpcServer} - * an in-process {@link Channel}. - */ - @ApplicationScoped - public static class ServerProducer { - - private GrpcServer server; - - /** - * Produce the {@link GrpcServer}. - * - * @return the {@link GrpcServer} - */ - @Produces - public GrpcServer server() { - return server; - } - - /** - * Produce a {@link Supplier} that can supply the {@link GrpcServer}. - *

- * This could be useful where an injection point has the server injected - * before the {@link #startServer} method has actually started it. In that - * case a {@link Supplier Supplier<GrpcServer>} can be injected instead - * that will be able to lazily supply the server. - * - * @return a {@link Supplier} that can supply the {@link GrpcServer} - */ - @Produces - public Supplier supply() { - return this::server; - } - - /** - * Produces an in-process {@link Channel} to connect to the - * running gRPC server. - * - * @return an in-process {@link Channel} to connect to the - * running gRPC server - */ - @Produces - @InProcessGrpcChannel - public Channel channel() { - String name = server.configuration().name(); - return InProcessChannelBuilder.forName(name) - .usePlaintext() - .build(); - } - - /** - * Produces an in-process {@link InProcessChannelBuilder} to - * connect to the running gRPC server. - * - * @return an in-process {@link InProcessChannelBuilder} to - * connect to the running gRPC server - */ - @Produces - @InProcessGrpcChannel - public InProcessChannelBuilder channelBuilder() { - String name = server.configuration().name(); - return InProcessChannelBuilder.forName(name); - } - - void server(GrpcServer server) { - this.server = server; - } - } -} diff --git a/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/GrpcServiceBuilder.java b/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/GrpcServiceBuilder.java deleted file mode 100644 index 057a4323b72..00000000000 --- a/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/GrpcServiceBuilder.java +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.server; - -import java.lang.annotation.Annotation; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.ServiceLoader; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -import io.helidon.common.Builder; -import io.helidon.common.serviceloader.HelidonServiceLoader; -import io.helidon.grpc.core.ContextKeys; -import io.helidon.grpc.core.MethodHandler; -import io.helidon.grpc.server.MethodDescriptor; -import io.helidon.grpc.server.ServiceDescriptor; -import io.helidon.microprofile.grpc.core.AbstractServiceBuilder; -import io.helidon.microprofile.grpc.core.AnnotatedMethod; -import io.helidon.microprofile.grpc.core.AnnotatedMethodList; -import io.helidon.microprofile.grpc.core.GrpcInterceptor; -import io.helidon.microprofile.grpc.core.GrpcInterceptorBinding; -import io.helidon.microprofile.grpc.core.GrpcInterceptors; -import io.helidon.microprofile.grpc.core.GrpcMarshaller; -import io.helidon.microprofile.grpc.core.GrpcMethod; -import io.helidon.microprofile.grpc.core.Instance; -import io.helidon.microprofile.grpc.core.ModelHelper; - -import io.grpc.ServerInterceptor; -import jakarta.enterprise.inject.Any; -import jakarta.enterprise.inject.spi.BeanManager; - -/** - * A builder for constructing a {@link ServiceDescriptor} - * instances from an annotated POJOs. - */ -public class GrpcServiceBuilder - extends AbstractServiceBuilder - implements Builder { - - private static final Logger LOGGER = Logger.getLogger(GrpcServiceBuilder.class.getName()); - - private final BeanManager beanManager; - - /** - * Create a new introspection modeller for a given gRPC service class. - * - * @param serviceClass gRPC service (handler) class. - * @param instance the target instance to call gRPC handler methods on - * @param beanManager the {@link jakarta.enterprise.inject.spi.BeanManager} to use - * to look-up CDI beans. - * @throws java.lang.NullPointerException if the service or instance parameters are null - */ - private GrpcServiceBuilder(Class serviceClass, Supplier instance, BeanManager beanManager) { - super(serviceClass, instance); - this.beanManager = beanManager; - } - - /** - * Create a new introspection modeller for a given gRPC service. - * - * @param service the service to call gRPC handler methods on - * @param beanManager the {@link jakarta.enterprise.inject.spi.BeanManager} to use - * to look-up CDI beans. - * @throws java.lang.NullPointerException if the service is null - * @return a {@link GrpcServiceBuilder} - */ - public static GrpcServiceBuilder create(Object service, BeanManager beanManager) { - return new GrpcServiceBuilder(service.getClass(), Instance.singleton(service), beanManager); - } - - /** - * Create a new introspection modeller for a given gRPC service class. - * - * @param serviceClass gRPC service (handler) class. - * @param beanManager the {@link jakarta.enterprise.inject.spi.BeanManager} to use - * to look-up CDI beans. - * @throws java.lang.NullPointerException if the service class is null - * @return a {@link GrpcServiceBuilder} - */ - public static GrpcServiceBuilder create(Class serviceClass, BeanManager beanManager) { - return new GrpcServiceBuilder(Objects.requireNonNull(serviceClass), createInstanceSupplier(serviceClass), beanManager); - } - - /** - * Create a {@link GrpcServiceBuilder} for a given gRPC service class. - * - * @param serviceClass gRPC service (handler) class. - * @param instance the target instance to call gRPC handler methods on - * @param beanManager the {@link jakarta.enterprise.inject.spi.BeanManager} to use - * to look-up CDI beans. - * @throws java.lang.NullPointerException if the service or instance parameters are null - * @return a {@link GrpcServiceBuilder} - */ - public static GrpcServiceBuilder create(Class serviceClass, Supplier instance, BeanManager beanManager) { - return new GrpcServiceBuilder(serviceClass, instance, beanManager); - } - - /** - * Create a {@link ServiceDescriptor.Builder} introspected class. - * - * @return a {@link ServiceDescriptor.Builder} for the introspected class. - */ - @Override - public ServiceDescriptor build() { - checkForNonPublicMethodIssues(); - - Class annotatedServiceClass = annotatedServiceClass(); - AnnotatedMethodList methodList = AnnotatedMethodList.create(annotatedServiceClass); - String name = determineServiceName(annotatedServiceClass); - - ServiceDescriptor.Builder builder = ServiceDescriptor.builder(serviceClass(), name) - .marshallerSupplier(getMarshallerSupplier()); - - addServiceMethods(builder, methodList, beanManager); - configureServiceInterceptors(builder, beanManager); - - Class serviceClass = serviceClass(); - Class annotatedClass = annotatedServiceClass(); - HelidonServiceLoader.create(ServiceLoader.load(AnnotatedServiceConfigurer.class)) - .forEach(configurer -> configurer.accept(serviceClass, annotatedClass, builder)); - - return builder.build(); - } - - /** - * Add methods to the {@link ServiceDescriptor.Builder}. - * - * @param builder the {@link ServiceDescriptor.Builder} to add the method to - * @param methodList the list of methods to add - * @param beanManager the {@link jakarta.enterprise.inject.spi.BeanManager} to use - * to look-up CDI beans. - */ - private void addServiceMethods(ServiceDescriptor.Builder builder, AnnotatedMethodList methodList, BeanManager beanManager) { - for (AnnotatedMethod am : methodList.withAnnotation(GrpcMethod.class)) { - addServiceMethod(builder, am, beanManager); - } - for (AnnotatedMethod am : methodList.withMetaAnnotation(GrpcMethod.class)) { - addServiceMethod(builder, am, beanManager); - } - } - - /** - * Add a method to the {@link ServiceDescriptor.Builder}. - *

- * The method configuration will be determined by the annotations present on the - * method and the method signature. - * - * @param builder the {@link ServiceDescriptor.Builder} to add the method to - * @param method the {@link AnnotatedMethod} representing the method to add - * @param beanManager the {@link jakarta.enterprise.inject.spi.BeanManager} to use - * to look-up CDI beans. - */ - @SuppressWarnings("unchecked") - private void addServiceMethod(ServiceDescriptor.Builder builder, AnnotatedMethod method, BeanManager beanManager) { - GrpcMethod annotation = method.firstAnnotationOrMetaAnnotation(GrpcMethod.class); - String name = determineMethodName(method, annotation); - Supplier instanceSupplier = instanceSupplier(); - - MethodHandler handler = handlerSuppliers().stream() - .filter(supplier -> supplier.supplies(method)) - .findFirst() - .map(supplier -> supplier.get(name, method, instanceSupplier)) - .orElseThrow(() -> new IllegalArgumentException("Cannot locate a method handler supplier for method " + method)); - - Class requestType = handler.getRequestType(); - Class responseType = handler.getResponseType(); - List interceptors = lookupMethodInterceptors(beanManager, method); - - GrpcInterceptors grpcInterceptors = method.getAnnotation(GrpcInterceptors.class); - - if (grpcInterceptors != null) { - for (Class interceptorClass : grpcInterceptors.value()) { - ServerInterceptor interceptor = resolveInterceptor(beanManager, interceptorClass); - if (interceptor != null) { - interceptors.add(interceptor); - } - } - } - - AnnotatedMethodConfigurer configurer = new AnnotatedMethodConfigurer(method, - requestType, - responseType, - interceptors); - - switch (annotation.type()) { - case UNARY: - builder.unary(name, handler, configurer); - break; - case CLIENT_STREAMING: - builder.clientStreaming(name, handler, configurer); - break; - case SERVER_STREAMING: - builder.serverStreaming(name, handler, configurer); - break; - case BIDI_STREAMING: - builder.bidirectional(name, handler, configurer); - break; - case UNKNOWN: - default: - LOGGER.log(Level.SEVERE, () -> "Unrecognized method type " + annotation.type()); - } - } - - private void configureServiceInterceptors(ServiceDescriptor.Builder builder, BeanManager beanManager) { - if (beanManager != null) { - Class serviceClass = serviceClass(); - Class annotatedClass = annotatedServiceClass(); - - configureServiceInterceptors(builder, beanManager, serviceClass()); - - if (!serviceClass.equals(annotatedClass)) { - configureServiceInterceptors(builder, beanManager, annotatedServiceClass()); - } - } - } - - private void configureServiceInterceptors(ServiceDescriptor.Builder builder, BeanManager beanManager, Class cls) { - if (beanManager != null) { - for (Annotation annotation : cls.getAnnotations()) { - if (annotation.annotationType().isAnnotationPresent(GrpcInterceptorBinding.class)) { - builder.intercept(lookupInterceptor(annotation, beanManager)); - } - } - - GrpcInterceptors grpcInterceptors = cls.getAnnotation(GrpcInterceptors.class); - if (grpcInterceptors != null) { - for (Class interceptorClass : grpcInterceptors.value()) { - if (ServerInterceptor.class.isAssignableFrom(interceptorClass)) { - ServerInterceptor interceptor = resolveInterceptor(beanManager, interceptorClass); - if (interceptor != null) { - builder.intercept(interceptor); - } - } - } - } - } - } - - private List lookupMethodInterceptors(BeanManager beanManager, AnnotatedMethod method) { - if (beanManager == null) { - return Collections.emptyList(); - } - - List interceptors = new ArrayList<>(); - for (Annotation annotation : method.getAnnotations()) { - if (annotation.annotationType().isAnnotationPresent(GrpcInterceptorBinding.class)) { - interceptors.add(lookupInterceptor(annotation, beanManager)); - } - } - return interceptors; - } - - private ServerInterceptor lookupInterceptor(Annotation annotation, BeanManager beanManager) { - jakarta.enterprise.inject.Instance instance; - instance = beanManager.createInstance() - .select(ServerInterceptor.class, GrpcInterceptor.Literal.INSTANCE); - - List interceptors = instance.stream() - .filter(interceptor -> hasAnnotation(interceptor, annotation)) - .collect(Collectors.toList()); - - if (interceptors.size() == 1) { - return interceptors.get(0); - } else if (interceptors.size() > 1) { - throw new IllegalStateException("gRPC interceptor annotation" - + "resolves to ambiguous interceptor implementations " - + annotation); - } else { - throw new IllegalStateException("Cannot resolve a gRPC interceptor bean for annotation" - + annotation); - } - } - - private ServerInterceptor resolveInterceptor(BeanManager beanManager, Class cls) { - if (beanManager == null) { - return null; - } - - if (ServerInterceptor.class.isAssignableFrom(cls)) { - jakarta.enterprise.inject.Instance instance = beanManager.createInstance().select(cls, Any.Literal.INSTANCE); - if (instance.isResolvable()) { - return (ServerInterceptor) instance.get(); - } else { - try { - return (ServerInterceptor) cls.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - throw new IllegalArgumentException("Cannot create gRPC interceptor", e); - } - } - } else { - throw new IllegalArgumentException("Specified interceptor class " + cls + " is not a " + ServerInterceptor.class); - } - } - - private boolean hasAnnotation(ServerInterceptor interceptor, Annotation annotation) { - Annotation[] annotations = getClass(interceptor).getAnnotations(); - return Arrays.asList(annotations).contains(annotation); - } - - private Class getClass(Object o) { - Class cls = o.getClass(); - while (cls.isSynthetic()) { - cls = cls.getSuperclass(); - } - return cls; - } - /** - * A {@link Consumer} of {@link MethodDescriptor.Rules} that - * applies configuration changes based on annotations present - * on the gRPC method. - */ - private static class AnnotatedMethodConfigurer - implements MethodDescriptor.Configurer { - - private final AnnotatedMethod method; - private final Class requestType; - private final Class responseType; - private final List interceptors; - - private AnnotatedMethodConfigurer(AnnotatedMethod method, - Class requestType, - Class responseType, - List interceptors) { - this.method = method; - this.requestType = requestType; - this.responseType = responseType; - this.interceptors = interceptors; - } - - @Override - public void configure(MethodDescriptor.Rules rules) { - rules.addContextValue(ContextKeys.SERVICE_METHOD, method.declaredMethod()) - .requestType(requestType) - .responseType(responseType); - - if (method.isAnnotationPresent(GrpcMarshaller.class)) { - rules.marshallerSupplier(ModelHelper.getMarshallerSupplier(method.getAnnotation(GrpcMarshaller.class))); - } - - interceptors.forEach(rules::intercept); - } - } -} diff --git a/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/package-info.java b/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/package-info.java deleted file mode 100644 index ff28772fe25..00000000000 --- a/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Microprofile 1.0 gRPC server implementation. - */ -package io.helidon.microprofile.grpc.server; diff --git a/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/spi/GrpcMpContext.java b/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/spi/GrpcMpContext.java deleted file mode 100644 index 21a5954b206..00000000000 --- a/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/spi/GrpcMpContext.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.server.spi; - -import java.util.concurrent.CompletionStage; - -import io.helidon.config.Config; -import io.helidon.grpc.server.GrpcRouting; -import io.helidon.grpc.server.GrpcServer; -import io.helidon.grpc.server.GrpcServerConfiguration; - -import jakarta.enterprise.inject.spi.BeanManager; - -/** - * A context to allow a microprofile gRPC server extensions to configure additional - * services or components for the gRPC server or use the CDI bean manager. - */ -public interface GrpcMpContext { - - /** - * Obtain the Helidon configuration. - * - * @return the Helidon configuration - */ - Config config(); - - /** - * Obtain the {@link GrpcServerConfiguration}. - * - * @return the {@link GrpcServerConfiguration} - */ - GrpcServerConfiguration.Builder grpcServerConfiguration(); - - /** - * Obtain the {@link GrpcRouting.Builder} to allow modifications - * to be made to the routing before the server is configured. - * - * @return the {@link GrpcRouting.Builder} - */ - GrpcRouting.Builder routing(); - - /** - * Obtain the {@link jakarta.enterprise.inject.spi.BeanManager}. - * - * @return the {@link jakarta.enterprise.inject.spi.BeanManager} - */ - BeanManager beanManager(); - - /** - * Return a completion stage is completed when the gRPC server is started. - * - * @return a completion stage is completed when the gRPC server is started - */ - CompletionStage whenStarted(); - - /** - * Return a completion stage is completed when the gRPC server is shut down. - * - * @return a completion stage is completed when the gRPC server is shut down - */ - CompletionStage whenShutdown(); -} diff --git a/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/spi/GrpcMpExtension.java b/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/spi/GrpcMpExtension.java deleted file mode 100644 index f262e243635..00000000000 --- a/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/spi/GrpcMpExtension.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.server.spi; - -/** - * Microprofile service to extend features of the gRPC server. - */ -public interface GrpcMpExtension { - /** - * Allow the service to add configuration through the context. - * - * @param context context to obtain configuration objects - */ - void configure(GrpcMpContext context); -} diff --git a/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/spi/package-info.java b/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/spi/package-info.java deleted file mode 100644 index 83ec209a1cc..00000000000 --- a/microprofile/grpc/server/src/main/java/io/helidon/microprofile/grpc/server/spi/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Microprofile 1.0 gRPC server implementation. - */ -package io.helidon.microprofile.grpc.server.spi; diff --git a/microprofile/grpc/server/src/main/java/module-info.java b/microprofile/grpc/server/src/main/java/module-info.java deleted file mode 100644 index 9b28f9214b1..00000000000 --- a/microprofile/grpc/server/src/main/java/module-info.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2019, 2023 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * gRPC microprofile server module - */ -module io.helidon.microprofile.grpc.server { - exports io.helidon.microprofile.grpc.server; - exports io.helidon.microprofile.grpc.server.spi; - - requires transitive io.helidon.grpc.server; - requires transitive io.helidon.microprofile.grpc.core; - requires io.helidon.common.serviceloader; - requires io.helidon.microprofile.server; - requires io.helidon.config.mp; - - requires io.grpc.protobuf.lite; - requires com.google.protobuf; - - requires java.logging; - - uses io.helidon.microprofile.grpc.server.spi.GrpcMpExtension; - uses io.helidon.microprofile.grpc.server.GrpcServerCdiExtension; - uses io.helidon.microprofile.grpc.server.AnnotatedServiceConfigurer; - - provides jakarta.enterprise.inject.spi.Extension - with io.helidon.microprofile.grpc.server.GrpcServerCdiExtension; - - // needed when running with modules - to make private methods accessible - opens io.helidon.microprofile.grpc.server to weld.core.impl, io.helidon.microprofile.cdi; -} diff --git a/microprofile/grpc/server/src/main/resources/META-INF/beans.xml b/microprofile/grpc/server/src/main/resources/META-INF/beans.xml deleted file mode 100644 index f2f827007a8..00000000000 --- a/microprofile/grpc/server/src/main/resources/META-INF/beans.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - diff --git a/microprofile/grpc/server/src/test/java/io/helidon/microprofile/grpc/server/GrpcServiceBuilderTest.java b/microprofile/grpc/server/src/test/java/io/helidon/microprofile/grpc/server/GrpcServiceBuilderTest.java deleted file mode 100644 index 7effc490a43..00000000000 --- a/microprofile/grpc/server/src/test/java/io/helidon/microprofile/grpc/server/GrpcServiceBuilderTest.java +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (c) 2019, 2022 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.server; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import io.helidon.grpc.server.MethodDescriptor; -import io.helidon.grpc.server.ServiceDescriptor; -import io.helidon.microprofile.grpc.core.Grpc; -import io.helidon.microprofile.grpc.core.GrpcMarshaller; -import io.helidon.microprofile.grpc.core.GrpcMethod; - -import io.grpc.Metadata; -import io.grpc.ServerCall; -import io.grpc.ServerCallHandler; -import io.grpc.stub.StreamObserver; -import jakarta.enterprise.inject.Instance; -import jakarta.enterprise.inject.spi.BeanManager; -import jakarta.inject.Singleton; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.CoreMatchers.sameInstance; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - - -public class GrpcServiceBuilderTest { - - private BeanManager beanManager; - - @BeforeEach - public void setup() { - beanManager = mock(BeanManager.class); - Instance instance = mock(Instance.class); - - when(beanManager.createInstance()).thenReturn(instance); - } - - @Test - public void shouldUseServiceNameFromAnnotation() { - ServiceOne service = new ServiceOne(); - GrpcServiceBuilder modeller = GrpcServiceBuilder.create(service, beanManager); - ServiceDescriptor descriptor = modeller.build(); - - assertThat(descriptor.name(), is("ServiceOne/foo")); - } - - @Test - public void shouldCreateDescriptorFoServiceWithNestedGenericParameters() { - GrpcServiceBuilder modeller = GrpcServiceBuilder.create(ServiceSix.class, beanManager); - ServiceDescriptor descriptor = modeller.build(); - assertThat(descriptor.name(), is(ServiceSix.class.getSimpleName())); - } - - @Test - public void shouldUseDefaultServiceName() { - ServiceTwo service = new ServiceTwo(); - GrpcServiceBuilder modeller = GrpcServiceBuilder.create(service, beanManager); - ServiceDescriptor descriptor = modeller.build(); - - assertThat(descriptor.name(), is("ServiceTwo")); - } - - @Test - public void shouldCreateServiceFromInstance() { - ServiceOne service = new ServiceOne(); - assertServiceOne(GrpcServiceBuilder.create(service, beanManager)); - } - - @Test - public void shouldCreateServiceFromClass() { - assertServiceOne(GrpcServiceBuilder.create(ServiceOne.class, beanManager)); - } - - @Test - public void shouldCreateServiceFromClassWithoutBeanManager() { - assertServiceOne(GrpcServiceBuilder.create(ServiceOne.class, null)); - } - - public void assertServiceOne(GrpcServiceBuilder builder) { - ServiceDescriptor descriptor = builder.build(); - assertThat(descriptor.name(), is("ServiceOne/foo")); - assertThat(descriptor.methods().size(), is(4)); - - MethodDescriptor methodDescriptor; - io.grpc.MethodDescriptor grpcDescriptor; - - methodDescriptor = descriptor.method("unary"); - assertThat(methodDescriptor, is(notNullValue())); - assertThat(methodDescriptor.name(), is("unary")); - assertThat(methodDescriptor.callHandler(), is(notNullValue())); - - grpcDescriptor = methodDescriptor.descriptor(); - assertThat(grpcDescriptor, is(notNullValue())); - assertThat(grpcDescriptor.getFullMethodName(), is("ServiceOne/foo/unary")); - assertThat(grpcDescriptor.getType(), is(io.grpc.MethodDescriptor.MethodType.UNARY)); - assertThat(grpcDescriptor.getRequestMarshaller(), is(instanceOf(StubMarshaller.class))); - assertThat(grpcDescriptor.getResponseMarshaller(), is(instanceOf(StubMarshaller.class))); - - methodDescriptor = descriptor.method("clientStreaming"); - assertThat(methodDescriptor, is(notNullValue())); - assertThat(methodDescriptor.name(), is("clientStreaming")); - assertThat(methodDescriptor.callHandler(), is(notNullValue())); - - grpcDescriptor = methodDescriptor.descriptor(); - assertThat(grpcDescriptor, is(notNullValue())); - assertThat(grpcDescriptor.getFullMethodName(), is("ServiceOne/foo/clientStreaming")); - assertThat(grpcDescriptor.getType(), is(io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING)); - assertThat(grpcDescriptor.getRequestMarshaller(), is(instanceOf(StubMarshaller.class))); - assertThat(grpcDescriptor.getResponseMarshaller(), is(instanceOf(StubMarshaller.class))); - - methodDescriptor = descriptor.method("serverStreaming"); - assertThat(methodDescriptor, is(notNullValue())); - assertThat(methodDescriptor.name(), is("serverStreaming")); - assertThat(methodDescriptor.callHandler(), is(notNullValue())); - - grpcDescriptor = methodDescriptor.descriptor(); - assertThat(grpcDescriptor, is(notNullValue())); - assertThat(grpcDescriptor.getFullMethodName(), is("ServiceOne/foo/serverStreaming")); - assertThat(grpcDescriptor.getType(), is(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)); - assertThat(grpcDescriptor.getRequestMarshaller(), is(instanceOf(StubMarshaller.class))); - assertThat(grpcDescriptor.getResponseMarshaller(), is(instanceOf(StubMarshaller.class))); - - methodDescriptor = descriptor.method("bidiStreaming"); - assertThat(methodDescriptor, is(notNullValue())); - assertThat(methodDescriptor.name(), is("bidiStreaming")); - assertThat(methodDescriptor.callHandler(), is(notNullValue())); - - grpcDescriptor = methodDescriptor.descriptor(); - assertThat(grpcDescriptor, is(notNullValue())); - assertThat(grpcDescriptor.getFullMethodName(), is("ServiceOne/foo/bidiStreaming")); - assertThat(grpcDescriptor.getType(), is(io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING)); - assertThat(grpcDescriptor.getRequestMarshaller(), is(instanceOf(StubMarshaller.class))); - assertThat(grpcDescriptor.getResponseMarshaller(), is(instanceOf(StubMarshaller.class))); - } - - @Test - public void shouldCreateServiceWithMethodNamesFromAnnotation() { - ServiceTwo service = new ServiceTwo(); - GrpcServiceBuilder builder = GrpcServiceBuilder.create(service, beanManager); - - ServiceDescriptor descriptor = builder.build(); - assertThat(descriptor.name(), is("ServiceTwo")); - assertThat(descriptor.methods().size(), is(4)); - - MethodDescriptor methodDescriptor; - io.grpc.MethodDescriptor grpcDescriptor; - - methodDescriptor = descriptor.method("One"); - assertThat(methodDescriptor, is(notNullValue())); - assertThat(methodDescriptor.name(), is("One")); - assertThat(methodDescriptor.callHandler(), is(notNullValue())); - - grpcDescriptor = methodDescriptor.descriptor(); - assertThat(grpcDescriptor, is(notNullValue())); - assertThat(grpcDescriptor.getFullMethodName(), is("ServiceTwo/One")); - assertThat(grpcDescriptor.getType(), is(io.grpc.MethodDescriptor.MethodType.UNARY)); - assertThat(grpcDescriptor.getRequestMarshaller(), is(instanceOf(StubMarshaller.class))); - assertThat(grpcDescriptor.getResponseMarshaller(), is(instanceOf(StubMarshaller.class))); - - methodDescriptor = descriptor.method("Two"); - assertThat(methodDescriptor, is(notNullValue())); - assertThat(methodDescriptor.name(), is("Two")); - assertThat(methodDescriptor.callHandler(), is(notNullValue())); - - grpcDescriptor = methodDescriptor.descriptor(); - assertThat(grpcDescriptor, is(notNullValue())); - assertThat(grpcDescriptor.getFullMethodName(), is("ServiceTwo/Two")); - assertThat(grpcDescriptor.getType(), is(io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING)); - assertThat(grpcDescriptor.getRequestMarshaller(), is(instanceOf(StubMarshaller.class))); - assertThat(grpcDescriptor.getResponseMarshaller(), is(instanceOf(StubMarshaller.class))); - - methodDescriptor = descriptor.method("Three"); - assertThat(methodDescriptor, is(notNullValue())); - assertThat(methodDescriptor.name(), is("Three")); - assertThat(methodDescriptor.callHandler(), is(notNullValue())); - - grpcDescriptor = methodDescriptor.descriptor(); - assertThat(grpcDescriptor, is(notNullValue())); - assertThat(grpcDescriptor.getFullMethodName(), is("ServiceTwo/Three")); - assertThat(grpcDescriptor.getType(), is(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)); - assertThat(grpcDescriptor.getRequestMarshaller(), is(instanceOf(StubMarshaller.class))); - assertThat(grpcDescriptor.getResponseMarshaller(), is(instanceOf(StubMarshaller.class))); - - methodDescriptor = descriptor.method("Four"); - assertThat(methodDescriptor, is(notNullValue())); - assertThat(methodDescriptor.name(), is("Four")); - assertThat(methodDescriptor.callHandler(), is(notNullValue())); - - grpcDescriptor = methodDescriptor.descriptor(); - assertThat(grpcDescriptor, is(notNullValue())); - assertThat(grpcDescriptor.getFullMethodName(), is("ServiceTwo/Four")); - assertThat(grpcDescriptor.getType(), is(io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING)); - assertThat(grpcDescriptor.getRequestMarshaller(), is(instanceOf(StubMarshaller.class))); - assertThat(grpcDescriptor.getResponseMarshaller(), is(instanceOf(StubMarshaller.class))); - } - - @SuppressWarnings("unchecked") - public void assertSingleton(GrpcServiceBuilder builder) { - ServiceDescriptor descriptor = builder.build(); - - MethodDescriptor methodDescriptor = descriptor.method("unary"); - ServerCallHandler handler = methodDescriptor.callHandler(); - - ServerCall callOne = mock(ServerCall.class); - ServerCall callTwo = mock(ServerCall.class); - when(callOne.getMethodDescriptor()).thenReturn(methodDescriptor.descriptor()); - when(callTwo.getMethodDescriptor()).thenReturn(methodDescriptor.descriptor()); - - ServerCall.Listener listenerOne = handler.startCall(callOne, new Metadata()); - ServerCall.Listener listenerTwo = handler.startCall(callTwo, new Metadata()); - - listenerOne.onMessage("foo"); - listenerOne.onHalfClose(); - listenerTwo.onMessage("foo"); - listenerTwo.onHalfClose(); - - ArgumentCaptor captorOne = ArgumentCaptor.forClass(ServiceFive.class); - ArgumentCaptor captorTwo = ArgumentCaptor.forClass(ServiceFive.class); - - verify(callOne).sendMessage(captorOne.capture()); - verify(callTwo).sendMessage(captorTwo.capture()); - - assertThat(captorOne.getValue(), is(sameInstance(captorTwo.getValue()))); - } - - @Grpc(name = "ServiceOne/foo") - @GrpcMarshaller("stub") - public static class ServiceOne { - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.UNARY) - public void unary(String param, StreamObserver observer) { - } - - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING) - public StreamObserver clientStreaming(StreamObserver observer) { - return null; - } - - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) - public void serverStreaming(String param, StreamObserver observer) { - } - - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING) - public StreamObserver bidiStreaming(StreamObserver observer) { - return null; - } - } - - @Grpc - @GrpcMarshaller("stub") - public static class ServiceTwo { - @GrpcMethod(name = "One", type = io.grpc.MethodDescriptor.MethodType.UNARY) - public void unary(String param, StreamObserver observer) { - } - - @GrpcMethod(name = "Two", type = io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING) - public StreamObserver clientStreaming(StreamObserver observer) { - return null; - } - - @GrpcMethod(name = "Three", type = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) - public void serverStreaming(String param, StreamObserver observer) { - } - - @GrpcMethod(name = "Four", type = io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING) - public StreamObserver bidiStreaming(StreamObserver observer) { - return null; - } - } - - @Grpc - @GrpcMarshaller("stub") - public static class ServiceThree { - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.UNARY) - public void unary(String param, StreamObserver observer) { - } - } - - @Grpc - @GrpcMarshaller("stub") - public static class ServiceFour { - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.UNARY) - @GrpcMarshaller("stub") - public void unary(String param, StreamObserver observer) { - } - } - - @Grpc - @GrpcMarshaller("stub") - @Singleton - public static class ServiceFive { - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.UNARY) - @GrpcMarshaller("stub") - public void unary(String param, StreamObserver observer) { - observer.onNext(this); - observer.onCompleted(); - } - } - - @Grpc - @GrpcMarshaller("stub") - public static class ServiceSix { - @GrpcMethod(type = io.grpc.MethodDescriptor.MethodType.UNARY) - public List> unary(List> param) { - return Collections.singletonList(Collections.singletonMap(1, "One")); - } - } -} diff --git a/microprofile/grpc/server/src/test/java/io/helidon/microprofile/grpc/server/StubMarshaller.java b/microprofile/grpc/server/src/test/java/io/helidon/microprofile/grpc/server/StubMarshaller.java deleted file mode 100644 index 1a52af51c24..00000000000 --- a/microprofile/grpc/server/src/test/java/io/helidon/microprofile/grpc/server/StubMarshaller.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.microprofile.grpc.server; - -import java.io.InputStream; - -import io.helidon.grpc.core.MarshallerSupplier; - -import io.grpc.MethodDescriptor; -import jakarta.inject.Named; - -/** - * A stub {@link io.grpc.MethodDescriptor.Marshaller}. - *

- * This marshaller will not actually work and should not - * be used as a real marshaller. - */ -public class StubMarshaller - implements MethodDescriptor.Marshaller { - - @Override - public InputStream stream(T value) { - return null; - } - - @Override - public T parse(InputStream stream) { - return null; - } - - @Named("stub") - public static class Supplier - implements MarshallerSupplier { - @Override - public MethodDescriptor.Marshaller get(Class clazz) { - return new StubMarshaller<>(); - } - } -} diff --git a/microprofile/grpc/server/src/test/proto/services.proto b/microprofile/grpc/server/src/test/proto/services.proto deleted file mode 100644 index b4649ed08ad..00000000000 --- a/microprofile/grpc/server/src/test/proto/services.proto +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto3"; -option java_package = "io.helidon.microprofile.grpc.server.test"; - -service UnaryService { - rpc requestResponse (TestRequest) returns (TestResponse) {} - rpc responseOnly (Empty) returns (TestResponse) {} - rpc requestNoResponse (TestRequest) returns (Empty) {} - rpc noRequestNoResponse (Empty) returns (Empty) {} - rpc futureResponse (TestRequest) returns (TestResponse) {} - rpc futureResponseNoRequest (Empty) returns (TestResponse) {} - rpc unary (TestRequest) returns (TestResponse) {} - rpc unaryNoRequest (Empty) returns (TestResponse) {} - rpc unaryFuture (TestRequest) returns (TestResponse) {} - rpc unaryFutureNoRequest (Empty) returns (TestResponse) {} -} - -service ServerStreamingService { - rpc streaming (TestRequest) returns (stream TestResponse) {} - rpc stream (TestRequest) returns (stream TestResponse) {} - rpc streamingNoRequest (Empty) returns (stream TestResponse) {} - rpc streamNoRequest (Empty) returns (stream TestResponse) {} -} - -service ClientStreamingService { - rpc streaming (stream TestRequest) returns (TestResponse) {} - rpc futureResponse (stream TestRequest) returns (TestResponse) {} -} - -service BidiService { - rpc bidi (stream TestRequest) returns (stream TestResponse) {} -} - -message Empty { -} - -message TestRequest { - string message = 1; -} - -message TestResponse { - string message = 1; -} diff --git a/microprofile/grpc/server/src/test/resources/META-INF/beans.xml b/microprofile/grpc/server/src/test/resources/META-INF/beans.xml deleted file mode 100644 index c7fe79b85a9..00000000000 --- a/microprofile/grpc/server/src/test/resources/META-INF/beans.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - diff --git a/microprofile/grpc/server/src/test/resources/META-INF/services/io.helidon.grpc.core.MarshallerSupplier b/microprofile/grpc/server/src/test/resources/META-INF/services/io.helidon.grpc.core.MarshallerSupplier deleted file mode 100644 index 33d2c630d5a..00000000000 --- a/microprofile/grpc/server/src/test/resources/META-INF/services/io.helidon.grpc.core.MarshallerSupplier +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2019, 2021 Oracle and/or its affiliates. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -io.helidon.microprofile.grpc.server.StubMarshaller$Supplier diff --git a/microprofile/grpc/server/src/test/resources/META-INF/services/io.helidon.microprofile.grpc.server.spi.GrpcMpExtension b/microprofile/grpc/server/src/test/resources/META-INF/services/io.helidon.microprofile.grpc.server.spi.GrpcMpExtension deleted file mode 100644 index 021c9f92dc9..00000000000 --- a/microprofile/grpc/server/src/test/resources/META-INF/services/io.helidon.microprofile.grpc.server.spi.GrpcMpExtension +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2019, 2021 Oracle and/or its affiliates. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -io.helidon.microprofile.grpc.server.GrpcServerCdiExtensionIT$ExtensionTwo \ No newline at end of file diff --git a/microprofile/grpc/server/src/test/resources/logging.properties b/microprofile/grpc/server/src/test/resources/logging.properties deleted file mode 100644 index f9dfd25b9da..00000000000 --- a/microprofile/grpc/server/src/test/resources/logging.properties +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (c) 2019, 2021 Oracle and/or its affiliates. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Example Logging Configuration File -# For more information see $JAVA_HOME/jre/lib/logging.properties - -# Send messages to the console -handlers=io.helidon.common.HelidonConsoleHandler - -# HelidonConsoleHandler uses a SimpleFormatter subclass that replaces "!thread!" with the current thread -java.util.logging.SimpleFormatter.format=%1$tY.%1$tm.%1$td %1$tH:%1$tM:%1$tS %4$s %3$s !thread!: %5$s%6$s%n - -# Global logging level. Can be overridden by specific loggers -.level=INFO - -# Component specific log levels -#io.helidon.webserver.level=INFO -#io.helidon.config.level=INFO -#io.helidon.security.level=INFO -#io.helidon.common.level=INFO -#io.netty.level=INFO