mirror of https://github.com/grpc/grpc-java.git
Add simple HelloWord example handling custom header
This commit is contained in:
parent
f3ccdd99f1
commit
63db06850e
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright 2015, Google Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package io.grpc.examples.header;
|
||||
|
||||
import io.grpc.Channel;
|
||||
import io.grpc.ChannelImpl;
|
||||
import io.grpc.ClientInterceptor;
|
||||
import io.grpc.ClientInterceptors;
|
||||
import io.grpc.examples.helloworld.GreeterGrpc;
|
||||
import io.grpc.examples.helloworld.HelloRequest;
|
||||
import io.grpc.examples.helloworld.HelloResponse;
|
||||
import io.grpc.transport.netty.NegotiationType;
|
||||
import io.grpc.transport.netty.NettyChannelBuilder;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* A simple client that like {@link io.grpc.examples.helloworld.HelloWorldClient}.
|
||||
* This client can help you create custom headers.
|
||||
*/
|
||||
public class CustomHeaderClient {
|
||||
private static final Logger logger = Logger.getLogger(CustomHeaderClient.class.getName());
|
||||
|
||||
private final ChannelImpl originChannel;
|
||||
private final GreeterGrpc.GreeterBlockingStub blockingStub;
|
||||
|
||||
/**
|
||||
* A custom client.
|
||||
*/
|
||||
private CustomHeaderClient(String host, int port) {
|
||||
originChannel =
|
||||
NettyChannelBuilder.forAddress(host, port).negotiationType(NegotiationType.PLAINTEXT)
|
||||
.build();
|
||||
ClientInterceptor interceptor = new HeaderClientInterceptor();
|
||||
Channel channel = ClientInterceptors.intercept(originChannel, interceptor);
|
||||
blockingStub = GreeterGrpc.newBlockingStub(channel);
|
||||
}
|
||||
|
||||
private void shutdown() throws InterruptedException {
|
||||
originChannel.shutdown().awaitTerminated(5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple client method that like {@link io.grpc.examples.helloworld.HelloWorldClient}.
|
||||
*/
|
||||
private void greet(String name) {
|
||||
try {
|
||||
logger.info("Will try to greet " + name + " ...");
|
||||
HelloRequest request = HelloRequest.newBuilder().setName(name).build();
|
||||
HelloResponse response = blockingStub.sayHello(request);
|
||||
logger.info("Greeting: " + response.getMessage());
|
||||
} catch (RuntimeException e) {
|
||||
logger.log(Level.WARNING, "RPC failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main start the client from the command line.
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
CustomHeaderClient client = new CustomHeaderClient("localhost", 50051);
|
||||
try {
|
||||
/* Access a service running on the local machine on port 50051 */
|
||||
String user = "world";
|
||||
if (args.length > 0) {
|
||||
user = args[0]; /* Use the arg as the name to greet if provided */
|
||||
}
|
||||
client.greet(user);
|
||||
} finally {
|
||||
client.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright 2015, Google Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package io.grpc.examples.header;
|
||||
|
||||
import io.grpc.ServerImpl;
|
||||
import io.grpc.ServerInterceptors;
|
||||
import io.grpc.examples.helloworld.GreeterGrpc;
|
||||
import io.grpc.examples.helloworld.HelloRequest;
|
||||
import io.grpc.examples.helloworld.HelloResponse;
|
||||
import io.grpc.stub.StreamObserver;
|
||||
import io.grpc.transport.netty.NettyServerBuilder;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* A simple server that like {@link io.grpc.examples.helloworld.HelloWorldServer}.
|
||||
* You can get and response any header in {@link io.grpc.examples.header.HeaderServerInterceptor}.
|
||||
*/
|
||||
public class CustomHeaderServer {
|
||||
private static final Logger logger = Logger.getLogger(CustomHeaderServer.class.getName());
|
||||
|
||||
/* The port on which the server should run */
|
||||
private static final int port = 50051;
|
||||
private ServerImpl server;
|
||||
|
||||
private void start() throws Exception {
|
||||
server = NettyServerBuilder.forPort(port).addService(ServerInterceptors
|
||||
.intercept(GreeterGrpc.bindService(new GreeterImpl()), new HeaderServerInterceptor()))
|
||||
.build().start();
|
||||
logger.info("Server started, listening on " + port);
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Use stderr here since the logger may have been reset by its JVM shutdown hook.
|
||||
System.err.println("*** shutting down gRPC server since JVM is shutting down");
|
||||
CustomHeaderServer.this.stop();
|
||||
System.err.println("*** server shut down");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void stop() {
|
||||
if (server != null) {
|
||||
server.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main launches the server from the command line.
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
final CustomHeaderServer server = new CustomHeaderServer();
|
||||
server.start();
|
||||
}
|
||||
|
||||
private class GreeterImpl implements GreeterGrpc.Greeter {
|
||||
|
||||
@Override
|
||||
public void sayHello(HelloRequest req, StreamObserver<HelloResponse> responseObserver) {
|
||||
HelloResponse reply = HelloResponse.newBuilder().setMessage("Hello " + req.getName()).build();
|
||||
responseObserver.onValue(reply);
|
||||
responseObserver.onCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright 2015, Google Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package io.grpc.examples.header;
|
||||
|
||||
import io.grpc.Call;
|
||||
import io.grpc.Channel;
|
||||
import io.grpc.ClientInterceptor;
|
||||
import io.grpc.ClientInterceptors;
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.MethodDescriptor;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* A interceptor to handle client header.
|
||||
*/
|
||||
public class HeaderClientInterceptor implements ClientInterceptor {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(HeaderClientInterceptor.class.getName());
|
||||
|
||||
private static Metadata.Key<String> customHeadKey =
|
||||
Metadata.Key.of("custom_client_header_key", Metadata.ASCII_STRING_MARSHALLER);
|
||||
|
||||
@Override
|
||||
public <ReqT, RespT> Call<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method,
|
||||
Channel next) {
|
||||
return new ClientInterceptors.ForwardingCall<ReqT, RespT>(next.newCall(method)) {
|
||||
|
||||
@Override
|
||||
public void start(Listener<RespT> responseListener, Metadata.Headers headers) {
|
||||
/* put custom header */
|
||||
headers.put(customHeadKey, "customRequestValue");
|
||||
super.start(new ClientInterceptors.ForwardingListener<RespT>(responseListener) {
|
||||
@Override
|
||||
public void onHeaders(Metadata.Headers headers) {
|
||||
/**
|
||||
* if you don't need receive header from server,
|
||||
* you can use {@link io.grpc.stub.MetadataUtils attachHeaders}
|
||||
* directly to send header
|
||||
*/
|
||||
logger.info("header received from server:" + headers.toString());
|
||||
super.onHeaders(headers);
|
||||
}
|
||||
}, headers);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright 2015, Google Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package io.grpc.examples.header;
|
||||
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.ServerCall;
|
||||
import io.grpc.ServerCallHandler;
|
||||
import io.grpc.ServerInterceptor;
|
||||
import io.grpc.ServerInterceptors;
|
||||
import io.grpc.Status;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* A interceptor to handle server header.
|
||||
*/
|
||||
public class HeaderServerInterceptor implements ServerInterceptor {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(HeaderServerInterceptor.class.getName());
|
||||
|
||||
private static Metadata.Key<String> customHeadKey =
|
||||
Metadata.Key.of("custom_server_header_key", Metadata.ASCII_STRING_MARSHALLER);
|
||||
|
||||
|
||||
@Override
|
||||
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
|
||||
String method,
|
||||
ServerCall<RespT> call,
|
||||
final Metadata.Headers requestHeaders,
|
||||
ServerCallHandler<ReqT, RespT> next) {
|
||||
logger.info("header received from client:" + requestHeaders.toString());
|
||||
return next.startCall(method, new ServerInterceptors.ForwardingServerCall<RespT>(call) {
|
||||
boolean sentHeaders = false;
|
||||
|
||||
@Override
|
||||
public void sendHeaders(Metadata.Headers responseHeaders) {
|
||||
responseHeaders.put(customHeadKey, "customRespondValue");
|
||||
super.sendHeaders(responseHeaders);
|
||||
sentHeaders = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPayload(RespT payload) {
|
||||
if (!sentHeaders) {
|
||||
sendHeaders(new Metadata.Headers());
|
||||
}
|
||||
super.sendPayload(payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(Status status, Metadata.Trailers trailers) {
|
||||
super.close(status, trailers);
|
||||
}
|
||||
}, requestHeaders);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue