All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.helidon.webclient.grpc.GrpcClientMethodDescriptor Maven / Gradle / Ivy

/*
 * Copyright (c) 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.webclient.grpc;

import java.util.Arrays;
import java.util.Objects;

import io.helidon.grpc.core.InterceptorWeights;
import io.helidon.grpc.core.MarshallerSupplier;
import io.helidon.grpc.core.MethodHandler;
import io.helidon.grpc.core.WeightedBag;

import io.grpc.CallCredentials;
import io.grpc.ClientInterceptor;
import io.grpc.MethodDescriptor;

/**
 * Encapsulates all metadata necessary to define a gRPC method. In addition to wrapping
 * a {@link io.grpc.MethodDescriptor}, this class also holds the request and response
 * types of the gRPC method. A {@link io.helidon.webclient.grpc.GrpcServiceDescriptor}
 * can contain zero or more {@link io.grpc.MethodDescriptor}.
 * 

* An instance of ClientMethodDescriptor can be created either from an existing * {@link io.grpc.MethodDescriptor} or from one of the factory methods * {@link #bidirectional(String, String)}, {@link #clientStreaming(String, String)}, * {@link #serverStreaming(String, String)} or {@link #unary(String, String)}. */ public final class GrpcClientMethodDescriptor { /** * The simple name of the method. */ private final String name; /** * The {@link io.grpc.MethodDescriptor} for this method. This is usually obtained from * protocol buffer method getDescriptor (from service getDescriptor). */ private final MethodDescriptor descriptor; /** * The list of client interceptors for this method. */ private WeightedBag interceptors; /** * The {@link io.grpc.CallCredentials} for this method. */ private final CallCredentials callCredentials; /** * The method handler for this method. */ private final MethodHandler methodHandler; private GrpcClientMethodDescriptor(String name, MethodDescriptor descriptor, WeightedBag interceptors, CallCredentials callCredentials, MethodHandler methodHandler) { this.name = name; this.descriptor = descriptor; this.interceptors = interceptors; this.callCredentials = callCredentials; this.methodHandler = methodHandler; } /** * Creates a new {@link GrpcClientMethodDescriptor.Builder} with the * specified name and {@link io.grpc.MethodDescriptor}. * * @param serviceName the name of the owning gRPC service * @param name the simple method name * @param descriptor the underlying gRPC {@link io.grpc.MethodDescriptor.Builder} * @return A new instance of a {@link GrpcClientMethodDescriptor.Builder} */ public static Builder builder(String serviceName, String name, MethodDescriptor.Builder descriptor) { return new Builder(serviceName, name, descriptor); } /** * Creates a new {@link GrpcClientMethodDescriptor.Builder} with the * specified name and {@link io.grpc.MethodDescriptor}. * * @param serviceName the name of the owning gRPC service * @param name the simple method name * @param descriptor the underlying gRPC {@link io.grpc.MethodDescriptor.Builder} * @return a new instance of a {@link GrpcClientMethodDescriptor.Builder} */ public static GrpcClientMethodDescriptor create(String serviceName, String name, MethodDescriptor.Builder descriptor) { return builder(serviceName, name, descriptor).build(); } /** * Creates a new unary {@link GrpcClientMethodDescriptor.Builder} with * the specified name. * * @param serviceName the name of the owning gRPC service * @param name the method name * @return a new instance of a {@link GrpcClientMethodDescriptor.Builder} */ public static Builder unary(String serviceName, String name) { return builder(serviceName, name, MethodDescriptor.MethodType.UNARY); } /** * Creates a new client Streaming {@link GrpcClientMethodDescriptor.Builder} with * the specified name. * * @param serviceName the name of the owning gRPC service * @param name the method name * @return a new instance of a {@link GrpcClientMethodDescriptor.Builder} */ public static Builder clientStreaming(String serviceName, String name) { return builder(serviceName, name, MethodDescriptor.MethodType.CLIENT_STREAMING); } /** * Creates a new server streaming {@link GrpcClientMethodDescriptor.Builder} with * the specified name. * * @param serviceName the name of the owning gRPC service * @param name the method name * @return a new instance of a {@link GrpcClientMethodDescriptor.Builder} */ public static Builder serverStreaming(String serviceName, String name) { return builder(serviceName, name, MethodDescriptor.MethodType.SERVER_STREAMING); } /** * Creates a new bidirectional {@link GrpcClientMethodDescriptor.Builder} with * the specified name. * * @param serviceName the name of the owning gRPC service * @param name the method name * @return a new instance of a {@link GrpcClientMethodDescriptor.Builder} */ public static Builder bidirectional(String serviceName, String name) { return builder(serviceName, name, MethodDescriptor.MethodType.BIDI_STREAMING); } /** * Obtain the {@link ClientInterceptor}s to use for this method. * * @return the {@link ClientInterceptor}s to use for this method */ WeightedBag interceptors() { return interceptors.readOnly(); } /** * Return the {@link io.grpc.CallCredentials} set on this service. * * @return the {@link io.grpc.CallCredentials} set on this service */ public CallCredentials callCredentials() { return this.callCredentials; } /** * Creates a new {@link GrpcClientMethodDescriptor.Builder} with the specified name. * * @param serviceName the name of the owning gRPC service * @param name the method name * @param methodType the gRPC method type * @return a new instance of a {@link GrpcClientMethodDescriptor.Builder} */ public static Builder builder(String serviceName, String name, MethodDescriptor.MethodType methodType) { MethodDescriptor.Builder builder = MethodDescriptor.newBuilder() .setFullMethodName(serviceName + "/" + name) .setType(methodType); return new Builder(serviceName, name, builder) .requestType(Object.class) .responseType(Object.class); } /** * Returns the simple name of the method. * * @return The simple name of the method. */ public String name() { return name; } /** * Returns the {@link io.grpc.MethodDescriptor} of this method. * * @param the request type * @param the response type * @return The {@link io.grpc.MethodDescriptor} of this method. */ @SuppressWarnings("unchecked") public MethodDescriptor descriptor() { return (MethodDescriptor) descriptor; } /** * Returns the {@link MethodDescriptor.MethodType} of this method. * * @return the method type */ public MethodDescriptor.MethodType type() { return descriptor.getType(); } /** * Obtain the {@link MethodHandler} to use to make client calls. * * @return the {@link MethodHandler} to use to make client calls */ public MethodHandler methodHandler() { return methodHandler; } /** * ClientMethod configuration API. */ public interface Rules { /** * Sets the type of parameter of this method. * * @param type The type of parameter of this method. * @return this {@link GrpcClientMethodDescriptor.Rules} instance for * fluent call chaining */ Rules requestType(Class type); /** * Sets the type of parameter of this method. * * @param type The type of parameter of this method. * @return this {@link GrpcClientMethodDescriptor.Rules} instance for * fluent call chaining */ Rules responseType(Class type); /** * Register one or more {@link ClientInterceptor interceptors} for the method. * * @param interceptors the interceptor(s) to register * @return this {@link Rules} instance for fluent call chaining */ Rules intercept(ClientInterceptor... interceptors); /** * Register one or more {@link ClientInterceptor interceptors} for the method. *

* The added interceptors will be applied using the specified priority. * * @param weight the weight to assign to the interceptors * @param interceptors one or more {@link ClientInterceptor}s to register * @return this {@link Rules} to allow fluent method chaining */ Rules intercept(double weight, ClientInterceptor... interceptors); /** * Register the {@link MarshallerSupplier} for the method. *

* If not set the default {@link MarshallerSupplier} from the service will be used. * * @param marshallerSupplier the {@link MarshallerSupplier} for the service * @return this {@link GrpcClientMethodDescriptor.Rules} instance * for fluent call chaining */ Rules marshallerSupplier(MarshallerSupplier marshallerSupplier); /** * Register the specified {@link io.grpc.CallCredentials} to be used for this method. * This overrides any {@link io.grpc.CallCredentials} set on the * {@link GrpcClientMethodDescriptor}. * * @param callCredentials the {@link io.grpc.CallCredentials} to set. * @return this {@link GrpcClientMethodDescriptor.Rules} instance * for fluent call chaining */ Rules callCredentials(CallCredentials callCredentials); /** * Set the {@link MethodHandler} that can be used to invoke the method. * * @param methodHandler the {2link MethodHandler} to use * @return this {@link GrpcClientMethodDescriptor.Rules} instance * for fluent call chaining */ Rules methodHandler(MethodHandler methodHandler); } /** * {@link io.grpc.MethodDescriptor} builder implementation. */ public static class Builder implements Rules, io.helidon.common.Builder { private String name; private final MethodDescriptor.Builder descriptor; private Class requestType; private Class responseType; private final WeightedBag interceptors = WeightedBag.create(InterceptorWeights.USER); private MarshallerSupplier defaultMarshallerSupplier = MarshallerSupplier.create(); private MarshallerSupplier marshallerSupplier; private CallCredentials callCredentials; private MethodHandler methodHandler; /** * Constructs a new Builder instance. * * @param serviceName The name of the service ths method belongs to * @param name the name of this method * @param descriptor The gRPC method descriptor builder */ Builder(String serviceName, String name, MethodDescriptor.Builder descriptor) { this.name = name; this.descriptor = descriptor.setFullMethodName(serviceName + "/" + name); } @Override public Builder requestType(Class type) { this.requestType = type; return this; } @Override public Builder responseType(Class type) { this.responseType = type; return this; } @Override public Builder intercept(ClientInterceptor... interceptors) { this.interceptors.addAll(Arrays.asList(interceptors)); return this; } @Override public Builder intercept(double weight, ClientInterceptor... interceptors) { this.interceptors.addAll(Arrays.asList(interceptors), weight); return this; } @Override public Builder marshallerSupplier(MarshallerSupplier supplier) { this.marshallerSupplier = supplier; return this; } Builder defaultMarshallerSupplier(MarshallerSupplier supplier) { this.defaultMarshallerSupplier = Objects.requireNonNullElseGet(supplier, MarshallerSupplier::create); return this; } @Override public Builder methodHandler(MethodHandler methodHandler) { this.methodHandler = methodHandler; return this; } /** * Sets the full name of this Method. * * @param fullName the full name of the method * @return this builder instance for fluent API */ Builder fullName(String fullName) { descriptor.setFullMethodName(fullName); this.name = fullName.substring(fullName.lastIndexOf('/') + 1); return this; } @Override public Rules callCredentials(CallCredentials callCredentials) { this.callCredentials = callCredentials; return this; } /** * Builds and returns a new instance of {@link GrpcClientMethodDescriptor}. * * @return a new instance of {@link GrpcClientMethodDescriptor} */ @Override @SuppressWarnings("unchecked") public GrpcClientMethodDescriptor build() { MarshallerSupplier supplier = this.marshallerSupplier; if (supplier == null) { supplier = defaultMarshallerSupplier; } if (requestType != null) { descriptor.setRequestMarshaller((MethodDescriptor.Marshaller) supplier.get(requestType)); } if (responseType != null) { descriptor.setResponseMarshaller((MethodDescriptor.Marshaller) supplier.get(responseType)); } return new GrpcClientMethodDescriptor(name, descriptor.build(), interceptors, callCredentials, methodHandler); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy