下面列出了com.google.protobuf.Descriptors#MethodDescriptor ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void writeServiceDescriptor(
Descriptors.ServiceDescriptor serviceDescriptor, PathLocation parent) {
PathLocation location = parent.addService(serviceDescriptor);
writeLeadingComment(commentIndexer.getLocation(location), 0);
writer.print("service ");
writer.print(serviceDescriptor.getName());
writer.println(" {");
writeOptionsForBlock(serviceDescriptor.getOptions(), 1, "Service");
for (Descriptors.MethodDescriptor method : serviceDescriptor.getMethods()) {
PathLocation methodLocation = location.addMethod(method);
writeLeadingComment(commentIndexer.getLocation(methodLocation), 1);
indent(1);
writer.print("rpc ");
writer.print(method.getName());
writer.print("(");
if (method.isClientStreaming()) {
writer.print("stream ");
}
writer.print(method.getInputType().getFullName());
writer.print(") returns (");
if (method.isServerStreaming()) {
writer.print("stream ");
}
writer.print(method.getOutputType().getFullName());
DescriptorProtos.MethodOptions options = method.getOptions();
if (options.getAllFields().size() == 0 && options.getUnknownFields().asMap().size() == 0) {
writer.print(") {}");
} else {
writer.println(") {");
writeOptionsForBlock(options, 2, "Method");
indent(1);
writer.print("}");
}
writeTrailingComment(commentIndexer.getLocation(methodLocation), 1);
}
writer.print("}");
writeTrailingComment(commentIndexer.getLocation(location), 0);
}
private static Map<String, Descriptors.MethodDescriptor> toMap4MethodDescriptor(
Collection<Descriptors.MethodDescriptor> in) {
Map<String, Descriptors.MethodDescriptor> out = new HashMap<>();
in.forEach(
descriptor -> {
out.put(String.valueOf(descriptor.getName()), descriptor);
});
return out;
}
/**
* {@inheritDoc}
*/
@Override
public <R extends Message> void batchCoprocessorService(Descriptors.MethodDescriptor methodDescriptor,
Message request, byte[] startKey, byte[] endKey, R responsePrototype,
Batch.Callback<R> callback) throws ServiceException {
throw new RuntimeException(this.getClass() + " does NOT implement this method.");
}
private boolean isDeprecated(Descriptors.MethodDescriptor fieldDescriptor) {
Map<Descriptors.FieldDescriptor, Object> allFields =
fieldDescriptor.getOptions().getAllFields();
if (allFields.size() > 0) {
for (Map.Entry<Descriptors.FieldDescriptor, Object> entry : allFields.entrySet()) {
Descriptors.FieldDescriptor f = entry.getKey();
switch (f.getFullName()) {
case "google.protobuf.MethodOptions.deprecated":
return true;
}
}
}
return false;
}
private Operation parseOperation(Descriptors.MethodDescriptor methodDescriptor) {
Operation operation = new Operation();
Descriptor inputType = methodDescriptor.getInputType();
Descriptor outputType = methodDescriptor.getOutputType();
operation.setDescription(methodDescriptor.getName());
List<Parameter> parameters = parseParameters(inputType);
parameters.add(buildHeaderParameter());
Map<String, ResponseObject> response = parseResponse(outputType);
operation.setParameters(parameters);
operation.setResponses(response);
return operation;
}
private Descriptors.MethodDescriptor resolveServiceMethod(
String serviceName, String methodName, String packageName) {
Descriptors.ServiceDescriptor service = findService(serviceName, packageName);
Descriptors.MethodDescriptor method = service.findMethodByName(methodName);
if (method == null) {
throw new IllegalArgumentException(
"Can't find method " + methodName + " in service " + serviceName);
}
return method;
}
/**
* List the methods on the service (the mothodFilter will be applied if non empty.
*/
private static void listMethods(
Map<String, Object> output,
Descriptors.ServiceDescriptor descriptor,
String methodFilter,
Boolean withMessage,
Boolean saveOutputInfo) {
List<Descriptors.MethodDescriptor> methodDescriptors = descriptor.getMethods();
methodDescriptors.forEach(method -> {
if (methodFilter.isEmpty() || method.getName().contains(methodFilter)) {
String key = descriptor.getFullName() + "/" + method.getName();
Map<String, Object> res = new HashMap<>();
res.put("file", descriptor.getFile().getName());
// If requested, add the message definition
if (withMessage) {
Map<String, Object> o = new HashMap<>();
o.put(method.getInputType().getName(), renderDescriptor(method.getInputType()));
res.put("input", o);
if (saveOutputInfo) {
Map<String, Object> oo = new HashMap<>();
oo.put(method.getOutputType().getName(), renderDescriptor(method.getOutputType()));
res.put("output", oo);
}
}
output.put(key, res);
}
});
}
static public HashMap<String, Object> dumpOptionsIntoHashMap(Descriptors.ServiceDescriptor msg_desc,
com.google.protobuf.ExtensionRegistry custom_extensions) {
HashMap<String, Object> msg_root = new HashMap<String, Object>();
boolean has_data = false;
HashMap<String, Object> options_data = dumpMessageExtensions(msg_desc.getOptions(),
msg_desc.getOptions().getAllFields(), custom_extensions);
if (options_data != null && !options_data.isEmpty()) {
has_data = true;
msg_root.put("options", options_data);
}
// method
HashMap<String, Object> child_message = null;
for (Descriptors.MethodDescriptor sub_desc : msg_desc.getMethods()) {
HashMap<String, Object> subset = dumpOptionsIntoHashMap(sub_desc, custom_extensions);
if (subset == null) {
continue;
}
if (child_message == null) {
child_message = new HashMap<String, Object>();
msg_root.put("method", child_message);
}
has_data = true;
child_message.put(sub_desc.getName(), subset);
}
if (has_data) {
msg_root.put("name", msg_desc.getName());
return msg_root;
}
return null;
}
@Override
public <R extends Message> Map<byte[], R> batchCoprocessorService(Descriptors.MethodDescriptor methodDescriptor,
Message request, byte[] startKey, byte[] endKey, R responsePrototype) throws ServiceException, Throwable {
throw new NotImplementedException();
}
void addResult(Descriptors.MethodDescriptor md, RuleInfo ruleInfo) {
ServiceResultContainer messageResult = getOrCreateService(md.getService());
messageResult.add(md, ruleInfo);
}
@Override
public <R extends Message> Map<byte[], R> batchCoprocessorService(Descriptors.MethodDescriptor methodDescriptor, Message message, byte[] bytes, byte[] bytes1, R r) throws ServiceException, Throwable {
throw new UnsupportedOperationException();
}
public void add(Descriptors.MethodDescriptor method, RuleInfo ruleInfo) {
MethodResultContainer methoddResultContainer = getOrCreateMethodContainer(method);
methoddResultContainer.add(ruleInfo);
}
public void addPatch(Descriptors.MethodDescriptor method, MethodChangeInfo patch) {
MethodResultContainer methodResultContainer = getOrCreateMethodContainer(method);
methodResultContainer.addPatch(patch);
}
@Override
public <R extends Message> Map<byte[], R> batchCoprocessorService(Descriptors.MethodDescriptor methodDescriptor, Message request,
byte[] startKey, byte[] endKey, R responsePrototype)
throws ServiceException, Throwable {
return null;
}
private GrpcToReactorMethodBinding findReactorMethod(MethodDescriptor<?, ?> methodDescriptor) {
String methodName = toMethodNameFromFullName(methodDescriptor.getFullMethodName());
Method reactorMethod = reactorMethodMap.get(methodName);
Preconditions.checkNotNull(reactorMethod, "Cannot find corresponding Reactor method for: {}", methodDescriptor);
ProtoMethodDescriptorSupplier methodDescriptorSupplier = (ProtoMethodDescriptorSupplier) methodDescriptor.getSchemaDescriptor();
Descriptors.MethodDescriptor md = methodDescriptorSupplier.getMethodDescriptor();
String inputTypeName = md.getInputType().getName();
String outputTypeName = md.getOutputType().getName();
Class<?> reactorReturnType = reactorMethod.getReturnType();
boolean isMono = reactorReturnType.isAssignableFrom(Mono.class);
boolean isFlux = !isMono && reactorReturnType.isAssignableFrom(Flux.class);
Preconditions.checkArgument(isMono || isFlux, "Mono or Flux return types allowed only");
Type[] returnTypeParameters = ((ParameterizedType) reactorMethod.getGenericReturnType()).getActualTypeArguments();
Preconditions.checkArgument(
returnTypeParameters != null && returnTypeParameters.length == 1,
"Expected one type parameter in the return type: %s", methodDescriptor.getFullMethodName()
);
Class returnTypeParameter = (Class) returnTypeParameters[0];
// Check return types
if (returnTypeParameter == Void.class) {
Preconditions.checkArgument(
outputTypeName.equals("Empty"),
"Reactor Mono<Void>/Flux<Void> can be mapped to GRPC/Empty only: %s", methodDescriptor.getFullMethodName()
);
} else {
Preconditions.checkArgument(
returnTypeParameter.getSimpleName().equals(outputTypeName),
"Different GRPC and Reactor API return types: %s", methodDescriptor.getFullMethodName()
);
}
// Check method arguments
if (reactorMethod.getParameterCount() == 0) {
Preconditions.checkArgument(
inputTypeName.equals(Empty.class.getSimpleName()),
"Only Empty request argument allowed for Reactor methods with no parameters: %s", methodDescriptor.getFullMethodName()
);
return new GrpcToReactorMethodBinding<>(methodDescriptor, reactorMethod, -1, isMono, returnTypeParameter);
}
if (reactorMethod.getParameterCount() == 1) {
if (reactorMethod.getParameterTypes()[0] == contextType) {
Preconditions.checkArgument(
inputTypeName.equals(Empty.class.getSimpleName()),
"Only Empty request argument allowed for Reactor methods with no parameters: %s", methodDescriptor.getFullMethodName()
);
return new GrpcToReactorMethodBinding<>(methodDescriptor, reactorMethod, 0, isMono, returnTypeParameter);
}
Preconditions.checkArgument(
inputTypeName.equals(reactorMethod.getParameterTypes()[0].getSimpleName()),
"Reactor and GRPC parameter types do not match: %s", methodDescriptor.getFullMethodName()
);
return new GrpcToReactorMethodBinding<>(methodDescriptor, reactorMethod, -1, isMono, returnTypeParameter);
}
if (reactorMethod.getParameterCount() == 2) {
Preconditions.checkArgument(
reactorMethod.getParameterTypes()[0] == contextType || reactorMethod.getParameterTypes()[1] == contextType,
"Expected one GRPC method argument, and one CallMetadata value in Reactor method mapped to: %s", methodDescriptor.getFullMethodName()
);
int callMetadataPos = reactorMethod.getParameterTypes()[0] == contextType ? 0 : 1;
int grpcArgumentPos = callMetadataPos == 0 ? 1 : 0;
Preconditions.checkArgument(
inputTypeName.equals(reactorMethod.getParameterTypes()[grpcArgumentPos].getSimpleName()),
"Reactor and GRPC parameter types do not match: %s", methodDescriptor.getFullMethodName()
);
return new GrpcToReactorMethodBinding<>(methodDescriptor, reactorMethod, callMetadataPos, isMono, returnTypeParameter);
}
throw new IllegalArgumentException("Cannot map GRPC method to any reactor method: " + methodDescriptor.getFullMethodName());
}
@Override
public <R extends Message> Map<byte[], R> batchCoprocessorService(Descriptors.MethodDescriptor var1, Message var2, byte[] var3, byte[] var4, R var5) throws ServiceException, Throwable {
throw new RuntimeException(this.getClass() + " does NOT implement this method.");
}
@Override
public <R extends Message> void batchCoprocessorService(Descriptors.MethodDescriptor methodDescriptor, Message request, byte[] startKey,
byte[] endKey, R responsePrototype, Callback<R> callback)
throws ServiceException, Throwable {
}
/**
* Creates a client for the supplied method, talking to the supplied endpoint.
*/
public static DynamicClient create(Descriptors.MethodDescriptor protoMethod, ManagedChannel channel) {
return new DynamicClient(protoMethod, channel);
}
/**
* Instantiate a new ServerRpcController that may later be completely invoked
* by calling {#link run}.
*
* @param requestMessage the request being handled
* @param backingService the backing service type
* @param serviceMethod the specific method within the backing service type
* @param loggedInUser the currently logged in user
* @param callback the destination where responses may be passed - may be
* called once (normal RPC) or 1-n times (streaming RPC), and will pass
* instances of RpcFinished as required (error cases, or streaming RPC
* shutdown); is also always called under the ServerRpcController's
* statusLock to ensure that consecutive calls (in the streaming case)
* are called in series
*/
ServerRpcControllerImpl(Message requestMessage, Service backingService,
Descriptors.MethodDescriptor serviceMethod, ParticipantId loggedInUser, RpcCallback<Message> callback) {
this.requestMessage = requestMessage;
this.backingService = backingService;
this.serviceMethod = serviceMethod;
this.loggedInUser = loggedInUser;
this.isStreamingRpc = serviceMethod.getOptions().getExtension(Rpc.isStreamingRpc);
this.callback = callback;
}
/**
* Instantiate a new ServerRpcController that may later be completely invoked
* by calling {#link run}.
*
* @param requestMessage the request being handled
* @param backingService the backing service type
* @param serviceMethod the specific method within the backing service type
* @param loggedInUser the currently logged in user
* @param callback the destination where responses may be passed - may be
* called once (normal RPC) or 1-n times (streaming RPC), and will pass
* instances of RpcFinished as required (error cases, or streaming RPC
* shutdown); is also always called under the ServerRpcController's
* statusLock to ensure that consecutive calls (in the streaming case)
* are called in series
*/
ServerRpcControllerImpl(Message requestMessage, Service backingService,
Descriptors.MethodDescriptor serviceMethod, ParticipantId loggedInUser, RpcCallback<Message> callback) {
this.requestMessage = requestMessage;
this.backingService = backingService;
this.serviceMethod = serviceMethod;
this.loggedInUser = loggedInUser;
this.isStreamingRpc = serviceMethod.getOptions().getExtension(Rpc.isStreamingRpc);
this.callback = callback;
}