Skip to content

Commit 63db068

Browse files
zhaohaifengejona86
authored andcommitted
Add simple HelloWord example handling custom header
1 parent f3ccdd9 commit 63db068

File tree

4 files changed

+360
-0
lines changed

4 files changed

+360
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Copyright 2015, Google Inc. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions are
6+
* met:
7+
*
8+
* * Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above
11+
* copyright notice, this list of conditions and the following disclaimer
12+
* in the documentation and/or other materials provided with the
13+
* distribution.
14+
*
15+
* * Neither the name of Google Inc. nor the names of its
16+
* contributors may be used to endorse or promote products derived from
17+
* this software without specific prior written permission.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
package io.grpc.examples.header;
33+
34+
import io.grpc.Channel;
35+
import io.grpc.ChannelImpl;
36+
import io.grpc.ClientInterceptor;
37+
import io.grpc.ClientInterceptors;
38+
import io.grpc.examples.helloworld.GreeterGrpc;
39+
import io.grpc.examples.helloworld.HelloRequest;
40+
import io.grpc.examples.helloworld.HelloResponse;
41+
import io.grpc.transport.netty.NegotiationType;
42+
import io.grpc.transport.netty.NettyChannelBuilder;
43+
44+
import java.util.concurrent.TimeUnit;
45+
import java.util.logging.Level;
46+
import java.util.logging.Logger;
47+
48+
/**
49+
* A simple client that like {@link io.grpc.examples.helloworld.HelloWorldClient}.
50+
* This client can help you create custom headers.
51+
*/
52+
public class CustomHeaderClient {
53+
private static final Logger logger = Logger.getLogger(CustomHeaderClient.class.getName());
54+
55+
private final ChannelImpl originChannel;
56+
private final GreeterGrpc.GreeterBlockingStub blockingStub;
57+
58+
/**
59+
* A custom client.
60+
*/
61+
private CustomHeaderClient(String host, int port) {
62+
originChannel =
63+
NettyChannelBuilder.forAddress(host, port).negotiationType(NegotiationType.PLAINTEXT)
64+
.build();
65+
ClientInterceptor interceptor = new HeaderClientInterceptor();
66+
Channel channel = ClientInterceptors.intercept(originChannel, interceptor);
67+
blockingStub = GreeterGrpc.newBlockingStub(channel);
68+
}
69+
70+
private void shutdown() throws InterruptedException {
71+
originChannel.shutdown().awaitTerminated(5, TimeUnit.SECONDS);
72+
}
73+
74+
/**
75+
* A simple client method that like {@link io.grpc.examples.helloworld.HelloWorldClient}.
76+
*/
77+
private void greet(String name) {
78+
try {
79+
logger.info("Will try to greet " + name + " ...");
80+
HelloRequest request = HelloRequest.newBuilder().setName(name).build();
81+
HelloResponse response = blockingStub.sayHello(request);
82+
logger.info("Greeting: " + response.getMessage());
83+
} catch (RuntimeException e) {
84+
logger.log(Level.WARNING, "RPC failed", e);
85+
}
86+
}
87+
88+
/**
89+
* Main start the client from the command line.
90+
*/
91+
public static void main(String[] args) throws Exception {
92+
CustomHeaderClient client = new CustomHeaderClient("localhost", 50051);
93+
try {
94+
/* Access a service running on the local machine on port 50051 */
95+
String user = "world";
96+
if (args.length > 0) {
97+
user = args[0]; /* Use the arg as the name to greet if provided */
98+
}
99+
client.greet(user);
100+
} finally {
101+
client.shutdown();
102+
}
103+
}
104+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright 2015, Google Inc. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions are
6+
* met:
7+
*
8+
* * Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above
11+
* copyright notice, this list of conditions and the following disclaimer
12+
* in the documentation and/or other materials provided with the
13+
* distribution.
14+
*
15+
* * Neither the name of Google Inc. nor the names of its
16+
* contributors may be used to endorse or promote products derived from
17+
* this software without specific prior written permission.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
package io.grpc.examples.header;
33+
34+
import io.grpc.ServerImpl;
35+
import io.grpc.ServerInterceptors;
36+
import io.grpc.examples.helloworld.GreeterGrpc;
37+
import io.grpc.examples.helloworld.HelloRequest;
38+
import io.grpc.examples.helloworld.HelloResponse;
39+
import io.grpc.stub.StreamObserver;
40+
import io.grpc.transport.netty.NettyServerBuilder;
41+
42+
import java.util.logging.Logger;
43+
44+
/**
45+
* A simple server that like {@link io.grpc.examples.helloworld.HelloWorldServer}.
46+
* You can get and response any header in {@link io.grpc.examples.header.HeaderServerInterceptor}.
47+
*/
48+
public class CustomHeaderServer {
49+
private static final Logger logger = Logger.getLogger(CustomHeaderServer.class.getName());
50+
51+
/* The port on which the server should run */
52+
private static final int port = 50051;
53+
private ServerImpl server;
54+
55+
private void start() throws Exception {
56+
server = NettyServerBuilder.forPort(port).addService(ServerInterceptors
57+
.intercept(GreeterGrpc.bindService(new GreeterImpl()), new HeaderServerInterceptor()))
58+
.build().start();
59+
logger.info("Server started, listening on " + port);
60+
Runtime.getRuntime().addShutdownHook(new Thread() {
61+
@Override
62+
public void run() {
63+
// Use stderr here since the logger may have been reset by its JVM shutdown hook.
64+
System.err.println("*** shutting down gRPC server since JVM is shutting down");
65+
CustomHeaderServer.this.stop();
66+
System.err.println("*** server shut down");
67+
}
68+
});
69+
}
70+
71+
private void stop() {
72+
if (server != null) {
73+
server.shutdown();
74+
}
75+
}
76+
77+
/**
78+
* Main launches the server from the command line.
79+
*/
80+
public static void main(String[] args) throws Exception {
81+
final CustomHeaderServer server = new CustomHeaderServer();
82+
server.start();
83+
}
84+
85+
private class GreeterImpl implements GreeterGrpc.Greeter {
86+
87+
@Override
88+
public void sayHello(HelloRequest req, StreamObserver<HelloResponse> responseObserver) {
89+
HelloResponse reply = HelloResponse.newBuilder().setMessage("Hello " + req.getName()).build();
90+
responseObserver.onValue(reply);
91+
responseObserver.onCompleted();
92+
}
93+
}
94+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright 2015, Google Inc. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions are
6+
* met:
7+
*
8+
* * Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above
11+
* copyright notice, this list of conditions and the following disclaimer
12+
* in the documentation and/or other materials provided with the
13+
* distribution.
14+
*
15+
* * Neither the name of Google Inc. nor the names of its
16+
* contributors may be used to endorse or promote products derived from
17+
* this software without specific prior written permission.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
package io.grpc.examples.header;
33+
34+
import io.grpc.Call;
35+
import io.grpc.Channel;
36+
import io.grpc.ClientInterceptor;
37+
import io.grpc.ClientInterceptors;
38+
import io.grpc.Metadata;
39+
import io.grpc.MethodDescriptor;
40+
41+
import java.util.logging.Logger;
42+
43+
/**
44+
* A interceptor to handle client header.
45+
*/
46+
public class HeaderClientInterceptor implements ClientInterceptor {
47+
48+
private static final Logger logger = Logger.getLogger(HeaderClientInterceptor.class.getName());
49+
50+
private static Metadata.Key<String> customHeadKey =
51+
Metadata.Key.of("custom_client_header_key", Metadata.ASCII_STRING_MARSHALLER);
52+
53+
@Override
54+
public <ReqT, RespT> Call<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method,
55+
Channel next) {
56+
return new ClientInterceptors.ForwardingCall<ReqT, RespT>(next.newCall(method)) {
57+
58+
@Override
59+
public void start(Listener<RespT> responseListener, Metadata.Headers headers) {
60+
/* put custom header */
61+
headers.put(customHeadKey, "customRequestValue");
62+
super.start(new ClientInterceptors.ForwardingListener<RespT>(responseListener) {
63+
@Override
64+
public void onHeaders(Metadata.Headers headers) {
65+
/**
66+
* if you don't need receive header from server,
67+
* you can use {@link io.grpc.stub.MetadataUtils attachHeaders}
68+
* directly to send header
69+
*/
70+
logger.info("header received from server:" + headers.toString());
71+
super.onHeaders(headers);
72+
}
73+
}, headers);
74+
}
75+
};
76+
}
77+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright 2015, Google Inc. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions are
6+
* met:
7+
*
8+
* * Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above
11+
* copyright notice, this list of conditions and the following disclaimer
12+
* in the documentation and/or other materials provided with the
13+
* distribution.
14+
*
15+
* * Neither the name of Google Inc. nor the names of its
16+
* contributors may be used to endorse or promote products derived from
17+
* this software without specific prior written permission.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
package io.grpc.examples.header;
33+
34+
import io.grpc.Metadata;
35+
import io.grpc.ServerCall;
36+
import io.grpc.ServerCallHandler;
37+
import io.grpc.ServerInterceptor;
38+
import io.grpc.ServerInterceptors;
39+
import io.grpc.Status;
40+
41+
import java.util.logging.Logger;
42+
43+
/**
44+
* A interceptor to handle server header.
45+
*/
46+
public class HeaderServerInterceptor implements ServerInterceptor {
47+
48+
private static final Logger logger = Logger.getLogger(HeaderServerInterceptor.class.getName());
49+
50+
private static Metadata.Key<String> customHeadKey =
51+
Metadata.Key.of("custom_server_header_key", Metadata.ASCII_STRING_MARSHALLER);
52+
53+
54+
@Override
55+
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
56+
String method,
57+
ServerCall<RespT> call,
58+
final Metadata.Headers requestHeaders,
59+
ServerCallHandler<ReqT, RespT> next) {
60+
logger.info("header received from client:" + requestHeaders.toString());
61+
return next.startCall(method, new ServerInterceptors.ForwardingServerCall<RespT>(call) {
62+
boolean sentHeaders = false;
63+
64+
@Override
65+
public void sendHeaders(Metadata.Headers responseHeaders) {
66+
responseHeaders.put(customHeadKey, "customRespondValue");
67+
super.sendHeaders(responseHeaders);
68+
sentHeaders = true;
69+
}
70+
71+
@Override
72+
public void sendPayload(RespT payload) {
73+
if (!sentHeaders) {
74+
sendHeaders(new Metadata.Headers());
75+
}
76+
super.sendPayload(payload);
77+
}
78+
79+
@Override
80+
public void close(Status status, Metadata.Trailers trailers) {
81+
super.close(status, trailers);
82+
}
83+
}, requestHeaders);
84+
}
85+
}

0 commit comments

Comments
 (0)