Skip to content

Commit

Permalink
Updating the library example.
Browse files Browse the repository at this point in the history
  • Loading branch information
siderakis committed Jan 3, 2018
1 parent dfc9a5d commit c9ab59b
Show file tree
Hide file tree
Showing 8 changed files with 283 additions and 12 deletions.
Expand Up @@ -8,8 +8,12 @@ java_library(
"//examples/proto/library:book_java_proto",
"//examples/proto/library:book_service_java_proto",
"//examples/proto/library:book_java_grpc",
"//examples/proto/library:shelf_java_proto",
"//examples/proto/library:shelf_service_java_proto",
"//examples/proto/library:shelf_java_grpc",
"//execution",
"//rejoiner",
"//rejoiner/src/main/java/com/google/api/graphql/grpc",
"@antlr//jar",
"@aop//jar",
"@com_google_guice_multibindings//jar",
Expand All @@ -33,3 +37,17 @@ java_library(
"@slf4j_simple//jar",
],
)

java_binary(
name = "LibraryProtoWriter",
main_class="com.google.api.graphql.examples.library.graphqlserver.LibraryProtoWriter",
runtime_deps = [
":graphqlserver",
],
)

load("//rejoiner:rejoiner.bzl", "graphql_proto")
graphql_proto(
name="schema",
proto_writer = ":LibraryProtoWriter",
)
Expand Up @@ -15,23 +15,18 @@
package com.google.api.graphql.examples.library.graphqlserver;

import com.google.api.graphql.execution.GuavaListenableFutureSupport;
import com.google.api.graphql.rejoiner.Schema;
import com.google.api.graphql.rejoiner.SchemaProviderModule;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.CharStreams;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.google.inject.Guice;
import com.google.inject.Key;
import graphql.ExecutionInput;
import graphql.ExecutionResult;
import graphql.GraphQL;
import graphql.execution.instrumentation.ChainedInstrumentation;
import graphql.execution.instrumentation.Instrumentation;
import graphql.execution.instrumentation.tracing.TracingInstrumentation;
import graphql.schema.GraphQLSchema;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
Expand All @@ -54,19 +49,14 @@ public class GraphQlServer extends AbstractHandler {
private static final TypeToken<Map<String, Object>> MAP_TYPE_TOKEN =
new TypeToken<Map<String, Object>>() {};

private static final GraphQLSchema SCHEMA =
Guice.createInjector(
new SchemaProviderModule(), new BookClientModule(), new BookSchemaModule())
.getInstance(Key.get(GraphQLSchema.class, Schema.class));

private static final Instrumentation instrumentation =
new ChainedInstrumentation(
Arrays.asList(
GuavaListenableFutureSupport.listenableFutureInstrumentation(),
new TracingInstrumentation()));

private static final GraphQL GRAPHQL =
GraphQL.newGraphQL(SCHEMA).instrumentation(instrumentation).build();
GraphQL.newGraphQL(LibrarySchema.SCHEMA).instrumentation(instrumentation).build();

public static void main(String[] args) throws Exception {
Server server = new Server(HTTP_PORT);
Expand Down
@@ -0,0 +1,37 @@
// Copyright 2017 Google LLC
//
// 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 com.google.api.graphql.examples.library.graphqlserver;

import com.google.api.graphql.grpc.SchemaToProto;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;

final class LibraryProtoWriter {
public static void main(String[] args) throws IOException {
if (args.length == 0) {
throw new RuntimeException("output path required");
}
String proto = SchemaToProto.toProto(LibrarySchema.SCHEMA);
BufferedWriter writer = Files.newWriter(new File(args[0]), Charsets.UTF_8);
try {
writer.write(proto);
} finally {
writer.close();
}
}
}
@@ -0,0 +1,34 @@
// Copyright 2017 Google LLC
//
// 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 com.google.api.graphql.examples.library.graphqlserver;

import com.google.api.graphql.rejoiner.Schema;
import com.google.api.graphql.rejoiner.SchemaProviderModule;
import com.google.inject.Guice;
import com.google.inject.Key;
import graphql.schema.GraphQLSchema;

final class LibrarySchema {
static final GraphQLSchema SCHEMA =
Guice.createInjector(
new SchemaProviderModule(),
new BookClientModule(),
new BookSchemaModule(),
new ShelfClientModule(),
new ShelfSchemaModule(),
new LibrarySchemaModule(),
new SeedLibrarySchemaModule())
.getInstance(Key.get(GraphQLSchema.class, Schema.class));
}
@@ -0,0 +1,56 @@
// Copyright 2017 Google LLC
//
// 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 com.google.api.graphql.examples.library.graphqlserver;

import com.google.api.graphql.rejoiner.Arg;
import com.google.api.graphql.rejoiner.Mutation;
import com.google.api.graphql.rejoiner.SchemaModification;
import com.google.api.graphql.rejoiner.SchemaModule;
import com.google.common.collect.ImmutableList;
import com.google.example.library.book.v1.Book;
import com.google.example.library.book.v1.BookServiceGrpc;
import com.google.example.library.book.v1.CreateBookRequest;
import com.google.example.library.book.v1.GetBookRequest;
import com.google.example.library.shelf.v1.GetShelfRequest;
import com.google.example.library.shelf.v1.Shelf;
import com.google.example.library.shelf.v1.ShelfServiceGrpc;

/** A GraphQL {@link SchemaModule} backed by a gRPC service. */
final class LibrarySchemaModule extends SchemaModule {

@Mutation("createBookAndAddToShelf")
Book createBookAndAddToShelf(
CreateBookRequest request,
@Arg("shelf") GetShelfRequest shelfRequest,
ShelfServiceGrpc.ShelfServiceBlockingStub shelfClient,
BookServiceGrpc.BookServiceBlockingStub bookClient) {
Book book = bookClient.createBook(request);
Shelf shelf = shelfClient.getShelf(shelfRequest);
// TODO: Add an update shelf RPC
// shelfClient.updateShelf(shelf.toBuilder().addBookIds(book.getId()).build());
return book;
}

@SchemaModification(addField = "books", onType = Shelf.class)
ImmutableList<Book> shelfToBooks(
Shelf shelf, BookServiceGrpc.BookServiceBlockingStub bookClient) {
// TODO: use a data loader or batch endpoint
return shelf
.getBookIdsList()
.stream()
.map(id -> bookClient.getBook(GetBookRequest.newBuilder().setId(id).build()))
.collect(ImmutableList.toImmutableList());
}
}
@@ -0,0 +1,129 @@
// Copyright 2017 Google LLC
//
// 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 com.google.api.graphql.examples.library.graphqlserver;

import com.google.api.graphql.rejoiner.Mutation;
import com.google.api.graphql.rejoiner.SchemaModule;
import com.google.common.collect.ImmutableList;
import com.google.example.library.book.v1.Book;
import com.google.example.library.book.v1.BookServiceGrpc;
import com.google.example.library.book.v1.CreateBookRequest;
import com.google.example.library.shelf.v1.CreateShelfRequest;
import com.google.example.library.shelf.v1.Shelf;
import com.google.example.library.shelf.v1.ShelfServiceGrpc;
import com.google.protobuf.Empty;

/** A GraphQL {@link SchemaModule} backed by a gRPC service. */
final class SeedLibrarySchemaModule extends SchemaModule {

@Mutation("seed")
Empty seed(
ShelfServiceGrpc.ShelfServiceBlockingStub shelfClient,
BookServiceGrpc.BookServiceBlockingStub bookClient) {

String greatExpectations =
bookClient
.createBook(
CreateBookRequest.newBuilder()
.setBook(
Book.newBuilder()
.setAuthor("Charles Dickens")
.setTitle("Great Expectations")
.setRead(false))
.build())
.getId();
String thinkingFastAndSlow =
bookClient
.createBook(
CreateBookRequest.newBuilder()
.setBook(
Book.newBuilder()
.setAuthor("Daniel Kahnemann")
.setTitle("Thinking, Fast and Slow")
.setRead(true))
.build())
.getId();
String theCatcherInTheRye =
bookClient
.createBook(
CreateBookRequest.newBuilder()
.setBook(
Book.newBuilder()
.setAuthor("J. D. Salinger")
.setTitle("The Catcher in the Rye")
.setRead(false))
.build())
.getId();
String huckleberryFinn =
bookClient
.createBook(
CreateBookRequest.newBuilder()
.setBook(
Book.newBuilder()
.setAuthor("Mark Twain")
.setTitle("The Adventures of Huckleberry Finn")
.setRead(false))
.build())
.getId();
String masterAndMargarita =
bookClient
.createBook(
CreateBookRequest.newBuilder()
.setBook(
Book.newBuilder()
.setAuthor("Mikhail Bulgakov")
.setTitle("The Master and Margarita")
.setRead(false))
.build())
.getId();
String warAndPeace =
bookClient
.createBook(
CreateBookRequest.newBuilder()
.setBook(
Book.newBuilder()
.setAuthor("Leo Tolstoy")
.setTitle("War and Peace")
.setRead(true))
.build())
.getId();

shelfClient.createShelf(
CreateShelfRequest.newBuilder()
.setShelf(
Shelf.newBuilder()
.setTheme("Satire")
.addAllBookIds(ImmutableList.of(greatExpectations, thinkingFastAndSlow))
.build())
.build());
shelfClient.createShelf(
CreateShelfRequest.newBuilder()
.setShelf(
Shelf.newBuilder()
.setTheme("Classics")
.addAllBookIds(ImmutableList.of(theCatcherInTheRye, huckleberryFinn))
.build())
.build());
shelfClient.createShelf(
CreateShelfRequest.newBuilder()
.setShelf(
Shelf.newBuilder()
.setTheme("Russian")
.addAllBookIds(ImmutableList.of(masterAndMargarita, warAndPeace))
.build())
.build());
return Empty.getDefaultInstance();
}
}
Expand Up @@ -22,6 +22,7 @@
import com.google.example.library.shelf.v1.GetShelfRequest;
import com.google.example.library.shelf.v1.ListShelvesRequest;
import com.google.example.library.shelf.v1.ListShelvesResponse;
import com.google.example.library.shelf.v1.MergeShelvesRequest;
import com.google.example.library.shelf.v1.Shelf;
import com.google.example.library.shelf.v1.ShelfServiceGrpc;

Expand All @@ -44,4 +45,10 @@ ListShelvesResponse listShelves(
ListShelvesRequest request, ShelfServiceGrpc.ShelfServiceBlockingStub client) {
return client.listShelves(request);
}

@Mutation("mergeShelves")
Shelf mergeShelves(
MergeShelvesRequest request, ShelfServiceGrpc.ShelfServiceBlockingStub client) {
return client.mergeShelves(request);
}
}
Expand Up @@ -63,7 +63,7 @@ public synchronized void deleteShelf(
}

@Override
public void listShelves(
public synchronized void listShelves(
ListShelvesRequest request, StreamObserver<ListShelvesResponse> responseObserver) {
NavigableMap<String, Shelf> cursor = shelfsById;

Expand Down

0 comments on commit c9ab59b

Please sign in to comment.