Git Product home page Git Product logo

rejoiner's Introduction

Rejoiner

Build Status Coverage Status

Maven Central

  • Creates a uniform GraphQL schema from microservices
  • Allows the GraphQL schema to be flexibly defined and composed as shared components
  • Generates GraphQL types from Proto definitions
  • Populates request Proto based on GraphQL query parameters
  • Supplies a DSL to modify the generated schema
  • Joins data sources by annotating methods that fetch data
  • Creates Proto FieldMasks based on GraphQL selectors

Rejoiner Overview

Experimental Features

These features are actively being developed.

  • Expose any GraphQL schema as a gRPC service.
  • Lossless end to end proto scalar types when using gRPC.
  • Relay support [Example]
  • GraphQL Stream (based on gRPC streaming) [Example]

Schema Module

SchemaModule is a Guice module that is used to generate parts of a GraphQL schema. It finds methods and fields that have Rejoiner annotations when it's instantiated. It then looks at the parameters and return type of these methods in order to generate the appropriate GraphQL schema. Examples of queries, mutations, and schema modifications are presented below.

GraphQL Query

final class TodoQuerySchemaModule extends SchemaModule {
  @Query("listTodo")
  ListenableFuture<ListTodoResponse> listTodo(ListTodoRequest request, TodoClient todoClient) {
    return todoClient.listTodo(request);
  }
}

In this example request is of type ListTodoRequest (a protobuf message), so it's used as a parameter in the generated GraphQL query. todoService isn't a protobuf message, so it's provided by the Guice injector.

This is useful for providing rpc services or database access objects for fetching data. Authentication data can also be provided here.

Common implementations for these annotated methods:

  • Make gRPC calls to microservices which can be implemented in any language
  • Load protobuf messages directly from storage
  • Perform arbitrary logic to produce the result

GraphQL Mutation

final class TodoMutationSchemaModule extends SchemaModule {
  @Mutation("createTodo")
  ListenableFuture<Todo> createTodo(
      CreateTodoRequest request, TodoService todoService, @AuthenticatedUser String email) {
    return todoService.createTodo(request, email);
  }
}

Adding edges between GraphQL types

In this example we are adding a reference to the User type on the Todo type.

final class TodoToUserSchemaModule extends SchemaModule {
  @SchemaModification(addField = "creator", onType = Todo.class)
  ListenableFuture<User> todoCreatorToUser(UserService userService, Todo todo) {
    return userService.getUserByEmail(todo.getCreatorEmail());
  }
}

In this case the Todo parameter is the parent object which can be referenced to get the creator's email.

This is how types are joined within and across APIs.

Rejoiner API Joining

Removing a field

final class TodoModificationsSchemaModule extends SchemaModule {
  @SchemaModification
  TypeModification removePrivateTodoData =
      Type.find(Todo.getDescriptor()).removeField("privateTodoData");
}

Building the GraphQL schema

import com.google.api.graphql.rejoiner.SchemaProviderModule;

public final class TodoModule extends AbstractModule {
  @Override
  protected void configure() {
    // Guice module that provides the generated GraphQLSchema instance
    install(new SchemaProviderModule());

    // Install schema modules
    install(new TodoQuerySchemaModule());
    install(new TodoMutationSchemaModule());
    install(new TodoModificationsSchemaModule());
    install(new TodoToUserSchemaModule());
  }
}

Getting started

Dependency information

Apache Maven

<dependency>
    <groupId>com.google.api.graphql</groupId>
    <artifactId>rejoiner</artifactId>
    <version>0.0.4</version>
</dependency>

Gradle/Grails compile 'com.google.api.graphql:rejoiner:0.0.4'

Scala SBT libraryDependencies += "com.google.api.graphql" % "rejoiner" % "0.0.4"

Supported return types

All generated proto messages extend Message.

  • Any subclass of Message
  • ImmutableList<? extends Message>
  • ListenableFuture<? extends Message>
  • ListenableFuture<ImmutableList<? extends Message>>

Project information

  • Rejoiner is built on top of GraphQL-Java which provides the core GraphQL capabilities such as query parsing, validation, and execution.
  • Java code is formatted using google-java-format.
  • Note: This is not an official Google product.

rejoiner's People

Contributors

dependabot[bot] avatar dianasuvorova avatar dsanders11 avatar dsborets avatar ebenoist avatar gurel avatar jaslong avatar primigenus avatar richard1122 avatar sheepdreamofandroids avatar siderakis avatar siderakis-at-google avatar sullis avatar wilder avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rejoiner's Issues

Usage from Kotlin

Hi.

Thanks for creating this great tool. I've been using it in a Kotlin application, which has been really simple and worked brilliantly for my requirement.

I have run into a little problem though. I am hoping to remove a field, from one of the GRPC types. I followed your documentation and examples, but think this may fall over in a difference between Kotlin and java. Kotlin by default creates a property getter when a read only var is declared. It looks to me as though you expect only field adding @SchemaModification annotations to be associated to methods, so it's reporting the following exception:

Jan 13, 2019 10:31:15 PM com.google.inject.internal.MessageProcessor visit
INFO: An exception was caught and reported. Message: java.lang.NoSuchMethodException: com.google.api.graphql.rejoiner.SchemaModification.getDescriptor()
java.lang.RuntimeException: java.lang.NoSuchMethodException: com.google.api.graphql.rejoiner.SchemaModification.getDescriptor()
at com.google.api.graphql.rejoiner.SchemaModule.configure(SchemaModule.java:228)

It is possible to annotate the variable definition with @JvmField which will prevent the getter creation and use a Java field, but then the @SchemaModification annotation seems to no longer be applied to the field.

I appreciate that this is a problem of using rejoiner from a language other than the intended, but wondered if you might be able to suggest any different approach to remove the field?

Thanks again
Chris

Metadata HTTP forwarding

Hello All !

I am currently planning to use rejoiner for exposing a single HTTP endpoint for a public API on one of my project.

In this context, I need to be able to retrieve the usual metadata which is inside an HTTP request (user-agent,etc...).

After looking quickly in the code I couldn't find any mention of it in the codebase.

  • Does rejoiner forward the HTTP metadata to the gRPC metadata ?

Reverse rejoiner

I think it would be useful to be able to analyze a GraphQL schema and produce a set of .proto files describing services that, when implemented, could be stitched together by Rejoiner to implement the specified schema. I'm not sure that all possible GraphQL schemas could be supported by this, but even a subset could be useful (particularly if the analyzer also generated warnings about what was unsupportable).

Unable to build Helloworld HTTP Server

OS : Archlinux
Bazel : Build label: 0.9.0- (@non-git)

Step to reproduce :

git clone https://github.com/google/rejoiner.git
cd rejoiner
bazel run examples/java/com/google/api/graphql/examples/helloworld/backend --script_path server.sh

The error :

..........
Unhandled exception thrown during build; message: java.lang.IllegalStateException: [WORKSPACE_NAME:#, FILE:[/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk]/[BUILD.bazel], PRECOMPUTED:default_visibility, PRECOMPUTED:skylark_semantics, AST_FILE_LOOKUP://tools/build_rules:prelude_bazel, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/ext/.jar excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/ext/.jar excludeDirs=true>, [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>], [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>], [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>], GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/** excludeDirs=true>, [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=/%/ excludeDirs=true>], GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=include/** excludeDirs=true>, [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/visualvm/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/missioncontrol/** excludeDirs=true>]] [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=/%/ excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=include/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/visualvm/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/missioncontrol/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/ext/.jar excludeDirs=true>] [WORKSPACE_NAME:#, FILE:[/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk]/[BUILD.bazel], PRECOMPUTED:default_visibility, PRECOMPUTED:skylark_semantics, AST_FILE_LOOKUP://tools/build_rules:prelude_bazel]
INFO: Elapsed time: 1.663s
FAILED: Build did NOT complete successfully (5 packages loaded)
java.lang.IllegalStateException: java.lang.IllegalStateException: [WORKSPACE_NAME:#, FILE:[/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk]/[BUILD.bazel], PRECOMPUTED:default_visibility, PRECOMPUTED:skylark_semantics, AST_FILE_LOOKUP://tools/build_rules:prelude_bazel, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/ext/
.jar excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/ext/.jar excludeDirs=true>, [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>], [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>], [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>], GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/** excludeDirs=true>, [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=**/%/** excludeDirs=true>], GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=include/** excludeDirs=true>, [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/visualvm/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/missioncontrol/** excludeDirs=true>]] [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=**/%/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=include/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/visualvm/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/missioncontrol/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/ext/.jar excludeDirs=true>] [WORKSPACE_NAME:#, FILE:[/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk]/[BUILD.bazel], PRECOMPUTED:default_visibility, PRECOMPUTED:skylark_semantics, AST_FILE_LOOKUP://tools/build_rules:prelude_bazel]
at com.google.devtools.build.lib.skyframe.SkyframeExecutor.evaluateSkyKeys(SkyframeExecutor.java:1558)
at com.google.devtools.build.lib.skyframe.SkyframeExecutor.getConfigurations(SkyframeExecutor.java:1400)
at com.google.devtools.build.lib.skyframe.SkyframeExecutor.createConfigurations(SkyframeExecutor.java:1110)
at com.google.devtools.build.lib.buildtool.BuildTool.buildTargets(BuildTool.java:200)
at com.google.devtools.build.lib.buildtool.BuildTool.processRequest(BuildTool.java:352)
at com.google.devtools.build.lib.runtime.commands.RunCommand.processRequest(RunCommand.java:125)
at com.google.devtools.build.lib.runtime.commands.RunCommand.exec(RunCommand.java:164)
at com.google.devtools.build.lib.runtime.BlazeCommandDispatcher.execExclusively(BlazeCommandDispatcher.java:485)
at com.google.devtools.build.lib.runtime.BlazeCommandDispatcher.exec(BlazeCommandDispatcher.java:218)
at com.google.devtools.build.lib.runtime.CommandExecutor.exec(CommandExecutor.java:58)
at com.google.devtools.build.lib.server.GrpcServerImpl.executeCommand(GrpcServerImpl.java:851)
at com.google.devtools.build.lib.server.GrpcServerImpl.access$2100(GrpcServerImpl.java:109)
at com.google.devtools.build.lib.server.GrpcServerImpl$2.lambda$run$0(GrpcServerImpl.java:916)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.lang.IllegalStateException: [WORKSPACE_NAME:#, FILE:[/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk]/[BUILD.bazel], PRECOMPUTED:default_visibility, PRECOMPUTED:skylark_semantics, AST_FILE_LOOKUP://tools/build_rules:prelude_bazel, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/ext/.jar excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/ext/.jar excludeDirs=true>, [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>], [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>], [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>], GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/** excludeDirs=true>, [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=/%/ excludeDirs=true>], GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=include/** excludeDirs=true>, [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/visualvm/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/missioncontrol/** excludeDirs=true>]] [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=/%/ excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=include/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/visualvm/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/missioncontrol/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/ext/.jar excludeDirs=true>] [WORKSPACE_NAME:#, FILE:[/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk]/[BUILD.bazel], PRECOMPUTED:default_visibility, PRECOMPUTED:skylark_semantics, AST_FILE_LOOKUP://tools/build_rules:prelude_bazel]
at com.google.common.base.Preconditions.checkState(Preconditions.java:836)
at com.google.devtools.build.lib.util.GroupedList.remove(GroupedList.java:372)
at com.google.devtools.build.lib.util.GroupedList.access$500(GroupedList.java:41)
at com.google.devtools.build.lib.util.GroupedList$GroupedListHelper.remove(GroupedList.java:448)
at com.google.devtools.build.skyframe.AbstractParallelEvaluator.registerNewlyDiscoveredDepsForDoneEntry(AbstractParallelEvaluator.java:607)
at com.google.devtools.build.skyframe.AbstractParallelEvaluator.access$100(AbstractParallelEvaluator.java:52)
at com.google.devtools.build.skyframe.AbstractParallelEvaluator$Evaluate.run(AbstractParallelEvaluator.java:398)
at com.google.devtools.build.lib.concurrent.AbstractQueueVisitor$WrappedRunnable.run(AbstractQueueVisitor.java:352)
... 3 more
java.lang.IllegalStateException: java.lang.IllegalStateException: [WORKSPACE_NAME:#, FILE:[/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk]/[BUILD.bazel], PRECOMPUTED:default_visibility, PRECOMPUTED:skylark_semantics, AST_FILE_LOOKUP://tools/build_rules:prelude_bazel, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/ext/
.jar excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/ext/.jar excludeDirs=true>, [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>], [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>], [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>], GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/** excludeDirs=true>, [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=**/%/** excludeDirs=true>], GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=include/** excludeDirs=true>, [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/visualvm/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/missioncontrol/** excludeDirs=true>]] [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=**/%/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=include/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/visualvm/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/missioncontrol/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/ext/.jar excludeDirs=true>] [WORKSPACE_NAME:#, FILE:[/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk]/[BUILD.bazel], PRECOMPUTED:default_visibility, PRECOMPUTED:skylark_semantics, AST_FILE_LOOKUP://tools/build_rules:prelude_bazel]
at com.google.devtools.build.lib.skyframe.SkyframeExecutor.evaluateSkyKeys(SkyframeExecutor.java:1558)
at com.google.devtools.build.lib.skyframe.SkyframeExecutor.getConfigurations(SkyframeExecutor.java:1400)
at com.google.devtools.build.lib.skyframe.SkyframeExecutor.createConfigurations(SkyframeExecutor.java:1110)
at com.google.devtools.build.lib.buildtool.BuildTool.buildTargets(BuildTool.java:200)
at com.google.devtools.build.lib.buildtool.BuildTool.processRequest(BuildTool.java:352)
at com.google.devtools.build.lib.runtime.commands.RunCommand.processRequest(RunCommand.java:125)
at com.google.devtools.build.lib.runtime.commands.RunCommand.exec(RunCommand.java:164)
at com.google.devtools.build.lib.runtime.BlazeCommandDispatcher.execExclusively(BlazeCommandDispatcher.java:485)
at com.google.devtools.build.lib.runtime.BlazeCommandDispatcher.exec(BlazeCommandDispatcher.java:218)
at com.google.devtools.build.lib.runtime.CommandExecutor.exec(CommandExecutor.java:58)
at com.google.devtools.build.lib.server.GrpcServerImpl.executeCommand(GrpcServerImpl.java:851)
at com.google.devtools.build.lib.server.GrpcServerImpl.access$2100(GrpcServerImpl.java:109)
at com.google.devtools.build.lib.server.GrpcServerImpl$2.lambda$run$0(GrpcServerImpl.java:916)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.lang.IllegalStateException: [WORKSPACE_NAME:#, FILE:[/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk]/[BUILD.bazel], PRECOMPUTED:default_visibility, PRECOMPUTED:skylark_semantics, AST_FILE_LOOKUP://tools/build_rules:prelude_bazel, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/ext/.jar excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/ext/.jar excludeDirs=true>, [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>], [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>], [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>], GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/** excludeDirs=true>, [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=/%/ excludeDirs=true>], GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=include/** excludeDirs=true>, [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/visualvm/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/missioncontrol/** excludeDirs=true>]] [GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=bin/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=/%/ excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=include/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/bin/plugin2/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/visualvm/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=lib/missioncontrol/** excludeDirs=true>, GLOB:<GlobDescriptor packageName=@local_jdk// packageRoot=/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk subdir= pattern=jre/lib/ext/*.jar excludeDirs=true>] [WORKSPACE_NAME:#, FILE:[/home/melkir/.cache/bazel/_bazel_melkir/a818f91d5b770ed78b81626297c71812/external/local_jdk]/[BUILD.bazel], PRECOMPUTED:default_visibility, PRECOMPUTED:skylark_semantics, AST_FILE_LOOKUP://tools/build_rules:prelude_bazel]
at com.google.common.base.Preconditions.checkState(Preconditions.java:836)
at com.google.devtools.build.lib.util.GroupedList.remove(GroupedList.java:372)
at com.google.devtools.build.lib.util.GroupedList.access$500(GroupedList.java:41)
at com.google.devtools.build.lib.util.GroupedList$GroupedListHelper.remove(GroupedList.java:448)
at com.google.devtools.build.skyframe.AbstractParallelEvaluator.registerNewlyDiscoveredDepsForDoneEntry(AbstractParallelEvaluator.java:607)
at com.google.devtools.build.skyframe.AbstractParallelEvaluator.access$100(AbstractParallelEvaluator.java:52)
at com.google.devtools.build.skyframe.AbstractParallelEvaluator$Evaluate.run(AbstractParallelEvaluator.java:398)
at com.google.devtools.build.lib.concurrent.AbstractQueueVisitor$WrappedRunnable.run(AbstractQueueVisitor.java:352)
... 3 more

Did I miss something ?

DataLoaders?

Can someone point me to how one would use DataLoaders with this library?

Go implementation

Hi,

rejoiner looks pretty cool. Just wondering if you plan to support other languages such as Go?

Thanks,

'oneof' fields are not injected on request

    message GetFooBySomeValRequest {
      oneof some_val{
        string val_a= 1;
        int32 val_b= 2;
      }
    }



    final class FooSchemaModule extends SchemaModule {
        @Query("getFooBySomeVal")
        Foo getFooBySomeVal(GetFooBySomeValRequest request,
                                 FooServiceGrpc.FooServiceBlockingStub client) {
            return client.getFooBySomeVal(request).getFoo();
        }
    }

Neither of the following graphql queries throw any syntax errors, but the some_val oneof field is not constructed on FooSchemaModule::getFooBySomeVal's request argument.


    curl -X POST localhost:8080/graphql -H "Content-Type: application/json" --data '{"query": "{getFooBySomeVal(input: {valA: \"abc"}){bar} }"}'
    
    curl -X POST localhost:8080/graphql -H "Content-Type: application/json" --data '{"query": "{getFooBySomeVal(input: {valB: 123}){bar} }"}'

Dynamic create server based on .proto file

Hello There!

I'm looking to dynamically create a schema or server listening on HTTP/gRPC based on a .proto file.

I can see the ProtoToGraphQL tests which look great, but curious how I can update the GraphQL server dynamically without taking it down so it can support new schemas.

The end goal is essentially creating a dynamic proxy on top of rejoiner to support an infinite growing microservice mesh ;)

Viewing Generated Schema

I have created my own example using the Library example as a reference. I have a graphql server, several gRPC services running and GraphiQL served up on 8080. It appears everything is in order based on the example.

However, I have not found anything that shows me what GraphQL queries are possible. Really, I would like to do introspection, but I know that is not supported by the underlying graphql-java library.

For example what would the following query be in GraphiQL:
@Query("getAthletesByCountry") fun getAthletesByCountry(request: AthletesByCountryRequest, client: AthleteServiceGrpc.AthleteServiceFutureStub): ListenableFuture<Athletes> { return client.getAthletesByCountry(request) }

Our ultimate goal is to have https://github.com/apollographql/apollo-android querying the server, but this would not be possible without a schema file.

I am probably missing something, so please forgive my ignorance.

Flattening out inputs

At where I work, we are interested in using Rejoiner. However, our standard for graphql schemas is to have the inputs be flattened out.

Is this something we could do? What are things that could make it tricky? (also is there a way to remove input fields in the same manner we can remove fields from the response? Struggling to figure out a way to do it).

If this is somewhat doable to enable , my colleague and I could be down to make a PR to make it happen (as well as add documentation for it)

Quick Start Guide

I'm sure there are a lot of people, myself included, excited to use Rejoiner, but are rusty with their Java tooling knowledge.

Would love to see a very easy copy/paste how-to to get rejoiner up and running with vanilla Java. A quick start guide would help immensely.

Status of the project?

Hi, I'm using rejoiner and I'm really impressed with the performance and what I can do with it right now.

Unfortunately there seems to be no progress lately and there are some things that I would like to change. I could simply fork and do whatever I feel like but I would prefer to contribute back here. That is of course, if you're still interested in pursuing this project.

example HelloWorld graphqlserver 404 not found

when following the example README

getting below on http://localhost:8080/
HTTP ERROR: 404
Problem accessing /. Reason:
Not Found

Powered by Jetty:// 9.3.8.v20160314

running the backend successfully
$ ./server.sh
Jan 24, 2018 7:40:42 AM com.google.api.graphql.examples.helloworld.backend.HelloWorldServer start
INFO: Server started, listening on 50051

graphql frontend starts ok as well
$ bazel run examples:helloworld_graphqlserver
...
[main] INFO org.eclipse.jetty.util.log - Logging initialized @192ms
[main] INFO org.eclipse.jetty.server.Server - jetty-9.3.8.v20160314
[main] INFO org.eclipse.jetty.server.ServerConnector - Started ServerConnector@4816278d{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
[main] INFO org.eclipse.jetty.server.Server - Started @1208ms

$ bazel version
Build label: 0.9.0
Build target: bazel-out/x64_windows-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Tue Dec 19 09:32:04 2017 (1513675924)
Build timestamp: 1513675924
Build timestamp as int: 1513675924

nicer JSON for standard wrappers

Wrappers.proto defines types for nullable scalars. When those are mapped to JSON you get a nullable object with a value field. That's a bit awkward and unnecessary.
It would be nicer if the wrapper would be mapped to a simple nullable JSON field.
This could be special cased or maybe there is some way of marking wrappers. Initially just the well-known ones would be OK, I guess.

I could make a PR if you like.

Schema Modification does not work on Input types

Hello,

We are trying to remove a field on an input by doing SchemaModification, but from this code it looks like proto modification only works on GraphQLObjectType instead of GraphQLInputObjectType:

if (mapping.get(key) instanceof GraphQLObjectType) {
GraphQLObjectType val = (GraphQLObjectType) mapping.get(key);
if (modifications.containsKey(key)) {
for (TypeModification modification : modifications.get(key)) {
val = modification.apply(val);
}
}
result.put(key, val);
} else {
result.put(key, mapping.get(key));
}

Is there any chance we can add support for type modification on the input type?

Rejoiner wraps grpc exception with InvocationTargetException and display it in the graphql error field

Issue :
When there is an exception from grpc services, it appears that the exception is being wrapped with "InvocationTargetException" and the graphql error field contains that one.

Expected Behaviour :
Is there a way that I can suppress "InvocationTargetException" and based on grpc exception, I can rewrite the graphql error fields.

Analysis :
While investigating, the "rejoiner"s "SchemaModule" covers the grpc exception with the "InvocationTargetException" and the graphql "error" fields always has error like below,

"Exception while fetching data (/someGrpcService) : java.lang.reflect.InvocationTargetException"

Tried GraphQl "ExecutionStrategy" to override "graphql.execution.SimpleDataFetcherExceptionHandler" in the "Handler" implementation, but for reason that never gets invoked.

Any idea how to do the error handling ?

Load balancing strategy

Hello! Wondering if you have in mind strategy which could be used to make load balancing for grpc services below rejoiner (One SchemaModule from rejoiner is using cluster 1-N grpc microservices)

Documentation question

Calling a GRPC service normally looks something like:

Point request = Point.newBuilder().setLatitude(lat).setLongitude(lon).build();
Feature feature;
try {
  feature = blockingStub.getFeature(request);
} catch (StatusRuntimeException e) {
  logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
  return;
}

The example given in the doc looks very different:

final class TodoToUserSchemaModule extends SchemaModule {
  @SchemaModification(addField = "creator", onType = Todo.class)
  ListenableFuture<User> todoCreatorToUser(UserService userService, Todo todo) {
    return userService.getUserByEmail(todo.getCreatorEmail());
  }
}

Is this example calling a GRPC service?

Breaking Changes for Version 0.1.0?

Trying to upgrade from 0.0.4 to 0.1.0, but running into issues.

None of the examples work with 0.1.0 for me either when I try to upgrade. While I am able to installDist, I get this error when I pull open localhost:8080:

<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>
<title>Error 500 </title>
</head>
<body>
<h2>HTTP ERROR: 500</h2>
<p>Problem accessing /graphql. Reason:
<pre>    java.lang.NoClassDefFoundError: com/google/api/graphql/execution/GuavaListenableFutureSupport$1</pre></p>
<hr /><a href="http://eclipse.org/jetty">Powered by Jetty:// 9.3.8.v20160314</a><hr/>
</body>
</html>

Plus I get this error in the logs:

java.lang.NoClassDefFoundError: graphql/execution/instrumentation/NoOpInstrumentation
	at java.lang.ClassLoader.defineClass1(Native Method)
java.lang.NoClassDefFoundError: com/google/api/graphql/execution/GuavaListenableFutureSupport$1```

Would appreciate if someone can help :) 

Question: Inject Request Context?

How would one go about implementing the @AuthenticatedUser Arg annotation shown in the examples? Can a Provider also have the Jetty request context injected to make headers/session values available?

This project is incredibly exciting and I'd be happy submit more documentation if someone can point me in the right general direction.

How to get Proto object from the parent arguments?

Hello,
I can't seem to find a way how to access current field parent arguments, and getting the actual resolved Proto object.
For example, we have this query:

query ($input: Input_proto_request_params)  {
  search(
    input: $input
  ) {
    item {
      specificProperty {
        value
      }
    }
  }
}

Now, field specificProperty is a SchemaModification kind of field, and we need the $input: Input_proto_request_params variable to be able to resolve it.
I found a way that by injecting DataFetchingEnvironment in the method we could get the list of parent arguments, like:

 dataFetchingEnvironment.executionStepInfo.parent.arguments

but with this, I get the LinkedHashMap, not the converted to Proto class object. I could create the Proto object manually, but that means the same object is constructed two times.
Is there a way to get access to the parent argument, but the already resolved Proto object one?

Thank you

P.S. Love the library, thank you very much for this awesome product ❤️

Library Example

First of all great stuff here. The code generation and simplicity based on protobufs is great. I've been able to successfully run the Hello World and Streaming example. However I'm having problems getting the Library example to work. It indicates it's still a work in progress so this might be a known issue. My steps locally are:

  • Run ./build/install/examples/bin/shelf-backend
  • Run ./build/install/examples/bin/book-backend
  • Run ./build/install/examples/bin/library-graphqlserver
  • Go to http://localhost:8080

Error:

Problem accessing /. Reason:

    Not Found
Powered by Jetty:// 9.3.8.v20160314

Admittedly I'm a Go programmer primarily, Java secondarily so there could be something I've done on my side related to configuration or misunderstanding that might be mistaken.

print current schema

HI - I am stoked about rejoiner, thank you... I am trying to debug my first implementation of a grpc service fronted by graphql and I am having some trouble figuring out what parameters are expected. I did what I thought was right. It is having an issue with the return value, I believe. Proto file and curl calls below...

Proto file:
service MathTest {
rpc MyAverage (MathRequest) returns (MathReply) {}
rpc MySum (MathRequest) returns (MathReply) {}
}
message MathRequest {
int32 x = 1;
int32 y = 2;
}
message MathReply {
int32 retVal = 1;
}

***curl call to service through rejoiner implementation without denoting return val name:

curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ myAverage (input: {x : 3, y : 4}) }" }' http://127.0.0.1:8081/graphql

reply snippet: "data":null,"errors":[{"message":"Validation error of type SubSelectionRequired: Sub selection required for type grpc_MathReply of field myAverage"

*** curl call with return value name:
curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ myAverage (input: {x : 3, y : 4}) { retVal } }" }' http://127.0.0.1:8081/graphql

reply snippet:
"message":"Validation error of type FieldUndefined: Field \u0027retVal\u0027 in type \u0027grpc_MathReply\u0027 is undefined"

It does not complain about the X and Y, just the return value... Any help would be appreciated. Thank you.

[DESIGN PROPOSAL] Generate a gRPC request/response based on a GraphQL query at build time

SUMMARY

With GraphQL the structure of a responses is influenced by the query (for example field names can be aliased) and thus a static proto cannot be used on the server at build time.

This design proposes having the client generate a proto definition at client build time from it’s GraphQL queries. The client can use this proto to generate standard Java, Js, etc code for use by the client. The server won’t have access to this generated proto but will infer and dynamically create its definition based on the received query and the GraphQL schema on the server.

GraphQL queries and mutations can declare variables which are usually encoded using JSON. These variables can be used to create a request proto for a query at build time.

In summary, request and response protos can be generated at build time for clients to use. The server will be able to respond to these requests without access to the generated protos by dynamically creating the proto response.

OBJECTIVE

  • Binary proto over the wire (gRPC)
  • Regular proto responses on the client
  • Support full GraphQL spec
  • Leverage existing open source libraries and tools
  • Work for all gRPC clients and languages
  • Only deps are GraphQL-Java and gRPC (Rejoiner isn’t required but recommend)

Non-goals

  • Use the same exact types as the underlying protos (future work)

BACKGROUND

Although GraphQL libraries usually return data as JSON, the GraphQL spec allows for any protocol/encoding that can accommodate dynamically structured responses. GraphQL queries can also define variables that are supplied as a JSON object alongside the string query.

DETAILED DESIGN

GraphQL Query & Mutation to proto mapping

Response message

Enum support
Options

  • Generate a single Enums.proto file for entire server schema
  • Generate enum on demand
    • Cons: Duplicates
  • Import it from source
    • Pros: simple in theory
    • Cons: proto visibility,

Request message

Static Proto
A bytes field can be used in a service definition to represent the data section of a GraphQL response. This would be ideal for clients using the binary wire format, and is how the Any type is implemented. For clients that want a JSON response the Struct type can be used to cleanly model the standard GraphQL JSON response.

message GraphQlResponse {
  repeated bytes data = 1;
  // errors, etc ...
}

Build time proto generation

A RelayJS compiler plugin will generate a response proto at build time. The Relay compiler can be used to generate artifacts for any language, in this case a simple proto definition. A build rule will be added to the Relay-compiler Skylark build rule to generate this proto.

Rather than using the Relay compiler (which is implemented in Js and runs in Node), the Java GraphQL library could be used to generate the proto. This approach would be simpler and should be compared to the Relay compiler. Relay is more powerful and it’s advantages show when constructing a query from composing multiple fragments.

The GraphQL API explorer has been updated to include a proto preview, which can be seen in the above screen shots.

Dynamic message

The server will dynamically construct the proto descriptor and populate the response based on the schema on the server and the run-time query.

The query is parsed into an AST, which is then transformed via a QueryTraversal into a DescriptorProto. Additional type information supplied from the Schema during query traversal. The same heuristics are used as those in the client when creating a proto from the query.

Creating response proto

public static DescriptorProto createProto(String query, GraphQLSchema schema) {
  DescriptorProtos.DescriptorProto.Builder descriptorProto =
      DescriptorProtos.DescriptorProto.newBuilder().setName("...");

  // add fields to descriptorProto …

  return descriptorProto.build();
}

Fill response

public static Message createResponse(
    DescriptorProto descriptor, Map<String,Object> response) {
  
  DynamicMessage.Builder responseBuilder =
      DynamicMessage.newBuilder(  descriptorProtoToDescriptor(descriptorProto));

  // build response ...

  return responseBuilder.build();
}

REJECTED ALTERNATIVES

The previous attempt at offering a proto based GraphQL API didn’t support the full GraphQL spec. It created a static proto based on the GraphQL schema for a GraphQL server. This resulted in a standard looking proto response, but didn’t support the full GraphQL spec.

Another attempt used the Struct, ListValue, etc prototypes to model the response similar to JSON. This resulted in proto that was difficult to consume on the client and a less than optimal over the wire encoding.

Question: How to solve N+1 problem with Rejoiner

I recently face a performance issue in a multi-level query using Rejoiner.
Here's an example similar to my data structure:

companyEmployees(startDate, endDate) {
  company {
    id
    department {
      id
      team {
        id
        employee {
          id
        }
      }
    }
  }
}

Assume each level is 1-many.
I have defined a set of gRPC APIs to get details at each level, and all the IDs are globally unique (e.g. team 123 only belongs to a specific department, which belongs to a specific company):

getCompanyList()
getDepartmentsByCompanyId()
getTeamsByDepartmentId()
getEmployeesByTeamId()

I then created a query called companyEmployees(companyId) which will use Rejoiner's SchemaModification to handle nested query based on the data structure. It goes like this:

    @Query("companyDepartments")
    ImmutableList<Department> getDepartmentsByCompany(DepartmentByCompanyRequest request,
                                                  DepartmentConfigServiceBlockingStub client) {
        List<Department> departments = client.getDepartmentsByCompany(request).getDepartmentsList();
        return ImmutableList.copyOf(departments);
    }

    @SchemaModification(addField = "teams", onType = Department.class)
    ImmutableList<Team> departmentTeams(DepartmentConfigServiceBlockingStub client, Department department) {
        // query team details by department ID
        request = TeamByDepartmentRequest.newBuilder().setDepartmentId(department.getId()).build();
        teams = client.getTeamsByDepartment(request).getTeamsList();
        return ImmutableList.copyOf(teams);
    }
    @SchemaModification(addField = "employees", onType = Team.class)
    ImmutableList<Employee> teamEmployees(DepartmentConfigServiceBlockingStub client, Team team) {
        // similar logic
    }

I added logs to trace the companyDepartments query and how it triggers SchemaModification. In my DB, I have 1 company, 2 departments, each department contains 2 teams, and each team contains 5 members. And I found out the following behavior:
It get the company first -> call SchemaModification to get first department -> call SchemaModification to get first team in first department ->...
It looks like a DFS, and the query time becomes linear, based on how much data is there in DB.

Is there any approach I can change my query time in to a constant time, let those queries happen parallel?

Facebook use Dataloader to solve this n+1 prob, I wonder how to solve it with rejoiner.
https://engineering.shopify.com/blogs/engineering/solving-the-n-1-problem-for-graphql-through-batching

errors

Rejoiner's errors make me feel inconvenient because I can't define valid data to let the front desk staff know what the current error is, what kind of error is, because the current valid information is only message, which is not good judgment, I hope in When you execute responseObserver.onError(), you can have some properties in the error message, you can customize it, and let the background personnel return their own defined errors.

Example is not working

I cloned master and follow the instruction here https://rejoiner.io/docs/examples.html
But got this error

{
  "errors": [
    {
      "message": "Exception while fetching data (/sayHello) : java.lang.IllegalArgumentException: argument type mismatch",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "sayHello"
      ]
    }
  ],
  "data": {
    "sayHello": null
  }
}

Inconsistency between input field and output field name conversion

We are using rejoiner in production and found that there is an inconsistency between generated output field's GraphqlFieldDefinition and input field's field GraphqlInputObjectField.
For example, for a message like:
message Account { string account_p_code = 1 }
The input graphql type generated will be
Input_qapi_Account { account_p_code: string }
The output graphql type generated will be
qapi_Account { accountPCode: string }
This seems to be an inconsistency.
The logic generating fullName to GraphqlType map is here in ProtoRegistry.java
And it generates input type here in GqlInputConverter.java, which lacks camel case conversion

generates output type here in ProtoToGql.java

Is this intentional? And i don't see there is a way to configure it.

I can submit a PR with tests to
(1) Fix this inconsistency, but this might break existing user's behavior
(2) Configure this behavior somewhere? I haven't looked carefully and not sure if we already have some machanisms to configure the mapping between protobuf field names and graphql field names.

Let me know if this make sense and if i can help on that :) thanks!

Question: How would rejoiner support getting grandparent context?

In the js counterpart, there's a way to add arbitrary context info to a resolve context and thus you can relay the information all the way down as described in this issue: graphql/graphql-js#1098

However in rejoiner since all fields are strictly typed to proto msgs or java native types, and there's no resolver exposed, it doesn't seem that use case is supported, unless one flattens the grandparent context onto the proto message (e.g. when schema is foo -> bar -> baz, let baz have foo's id), which is doable but doesn't seem like a good practice?

release of non-snapshots jars to maven

greetings,

really happy with the functionality and stability in as it is, would it be possible to release a at least a 0.0.1 non-snapshot jar to your maven repo?

is there anything outstanding that is blocking such a release, if so I'd be happy to help out.

Support generating GraphQLOutputType from ListenableFuture<Scalar> type

This relates to #57 but is for a more specific use case.

From the comment:

private GraphQLOutputType getReturnType(Method method)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
// Currently it's assumed the response is of type Message, ListenableFuture<? extends
// Message>, ImmutableList<Message>, ListenableFuture<ImmutableList<? extend Message>>, oe
// any Scalar type.

We support type Message, any Scalar type, ImmutableList<Message>, ListenableFuture<? extends Message>, and ListenableFuture<ImmutableList<? extend Message>>, and there is a TODO trying to support ImmutableList<Scalar type>.

Our system is currently using a String return type for a @SchemaModification, and is trying to use ListnableFuture to improve our performance, and we want to wrap a String in a ListenableFuture, which means the method will have ListenableFuture<String> as the return type, which is currently not supported by the getReturnType.

From looking at the code I believe it's quite possible to add ListenableFuture<Scalar type>. Is there any concern of adding the support?

Explain more about the FieldMasks usage

Hi,

this is not really an issue per say but I tried really hard to figure out how does rejoiner work with FieldMasks but failed... Could you maybe @siderakis explain more? It sounds like super awesome feature... (not just for this library, also for other proto use cases).

This is what is written in the readme...
Creates Proto FieldMasks based on GraphQL selectors

Thank you!

init client module error

when i init clientmodule ,use
ManagedChannel channel = ManagedChannelBuilder.forAddress("127.0.0.1",8446).usePlaintext(true).build();
but the grpc set usePlaintext(true) deperated,
so how to get grpc customer address here?

google_protobuf_Any value string

The data transferred for the google_protobuf_Any looks like the following:

     "reuslt": {
          "typeUrl": "correctTypeURL",
          "value": "<ByteString@756fc97d size=9>"
        }

typeUrl string is correct while the value is in the format that can't be decoded. This looks like a result of ByteString.toString().

Is there a way to do actual byte array to string decoding on rejoiner side and transfer it as a value.

modularization

I'm feeling that rejoiner could be split into some modules which would make it more generally useful and easier to adapt to different usecases. I'm thinking out loud here so please tell me I'm wrong before I start on a PR ;-)

  1. protobuf -> graphql schema conversion
  2. graphql schema modification (now depends on protobuf)
  3. annotations for 2
  4. binding with guice

Splitting these into maven modules would allow to add these for example:

  1. swagger -> graphql schema conversion
  2. binding with spring

I think the hardest work would be to make the modification part independent of protobuf without losing efficiency.

cheers

Support generating GraphQLOutputType from arbitrary method return types

Hi! I was playing around with rejoiner and I saw that there's support for returning simple Java scalars with a TODO: "handle collections of Java Scalars". Would there ever be a desire to support arbitrary return types?

Here's how another project, GLiTR, generates such a type from an input class.

I had success generating a GraphQLOutputType on the fly from a POJO inside of SchemaModule::configureSchema(), and then using that type in aGraphQLFieldDefinition which I pass to addQuery().

Maybe a good idea for a module in rejoiner?

@Arg does not add definition to schema

An @Arg annotation is not enough to add the specified proto definition to the GraphQL schema and will result in a runtime error if not referenced elsewhere.

Given the example:

  @Query("getNegotiation")
  ListenableFuture<NegotiationsResponse> getNegotiation(NegotiationsRequest request,
      CoreClient client, @Arg("token") AuthToken token) {

    return client.getNegotiation(request.getId(), token.getToken());
  }

Where AuthToken is in a different proto definition tree and not returned by any queries, the following will result:

1) Error in custom provider, graphql.AssertException: type Input_rql_AuthToken not found in schema
  while locating com.google.api.graphql.rejoiner.SchemaProviderModule$SchemaImpl
  while locating graphql.schema.GraphQLSchema annotated with interface com.google.api.graphql.rejoiner.Schema

1 error
	at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1028)
	at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1050)
	at com.reverb.rql.RQLHander.<clinit>(RQLHander.java:44)
	... 1 more
Caused by: graphql.AssertException: type Input_rql_AuthToken not found in schema
	at graphql.Assert.assertTrue(Assert.java:37)
	at graphql.schema.SchemaUtil.resolveTypeReference(SchemaUtil.java:221)
	at graphql.schema.GraphQLArgument.replaceTypeReferences(GraphQLArgument.java:48)
	at graphql.schema.SchemaUtil.resolveTypeReferencesForFieldsContainer(SchemaUtil.java:207)
	at graphql.schema.SchemaUtil.replaceTypeReferences(SchemaUtil.java:189)
	at graphql.schema.GraphQLSchema$Builder.build(GraphQLSchema.java:238)
	at graphql.schema.GraphQLSchema$Builder.build(GraphQLSchema.java:231)
	at com.google.api.graphql.rejoiner.SchemaProviderModule$SchemaImpl.get(SchemaProviderModule.java:91)
	at com.google.api.graphql.rejoiner.SchemaProviderModule$SchemaImpl.get(SchemaProviderModule.java:36)
	at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:81)
	at com.google.inject.internal.BoundProviderFactory.provision(BoundProviderFactory.java:72)
	at com.google.inject.internal.ProviderInternalFactory.circularGet(ProviderInternalFactory.java:61)
	at com.google.inject.internal.BoundProviderFactory.get(BoundProviderFactory.java:62)
	at com.google.inject.internal.InjectorImpl$2$1.call(InjectorImpl.java:1019)
	at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1085)
	at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1015)
	... 3 more

If I add a "fake" query that returns the token.

  @Query("tokenRequest")
  AuthToken getToken(AuthToken token) {
    return token;
  }

The proto def is discovered and converted into a type for the GraphQL Schema.

DefaultCacheMap question

I found that the cache you use is DefaultCacheMap, but I want to set the cache in redis. I don't know if you have any ideas or suggestions like that. In the future, would you consider adding redis to the project and adding redis to it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.