Merge pull request #861 from vnorigoog/props-in-file

Separate Core code from Examples and interop-test code.
This commit is contained in:
Vasu Nori 2020-06-23 13:12:59 -07:00 committed by GitHub
commit 88d70ecbdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 681 additions and 160 deletions

View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>grpc.testing.main</groupId>
<artifactId>grpcweb-java-examples-greeter</artifactId>
<version>0.1</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<grpc-port>7080</grpc-port>
<grpc-web-port>8080</grpc-web-port>
</properties>
<dependencies>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.11.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<dependency>
<groupId>com.google.grpcweb</groupId>
<artifactId>grpcweb-java</artifactId>
<version>0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
<version>4.5.12</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.0</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.4.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.7.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>write-project-properties</goal>
</goals>
<configuration>
<outputFile>${project.build.outputDirectory}/my.properties</outputFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,56 @@
/*
* Copyright 2020 The gRPC Authors
*
* 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.
*/
// ================================================
//
// This is for testing only. Just to demonstrate a simple
// Java client to send grpc-web request and receive response
//
// ================================================
package grpcweb.examples.greeter;
import grpcweb.examples.greeter.GreeterOuterClass.HelloRequest;
import java.io.IOException;
import org.apache.http.HttpVersion;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;
/**
* A simple client that requests a greeting from the {@link GreeterService}.
*/
public class GreeterClient {
static byte[] sendGrpcWebReqAndReceiveResponse() throws IOException {
// create a HelloRequest obj
HelloRequest reqObj = HelloRequest.newBuilder().setName("foo").build();
byte[] packagedBytes = Util.packageReqObjIntoGrpcwebProtocol(reqObj);
// send request to the grpc-web server
ContentType contentType = ContentType.create("application/grpc-web");
int grpcWebPort = Util.getGrpcwebServicePortNum();
return Request.Post("http://localhost:" + grpcWebPort +
"/grpcweb.examples.greeter.Greeter/SayHello")
.useExpectContinue()
.version(HttpVersion.HTTP_1_1)
.bodyByteArray(packagedBytes, contentType)
.execute().returnContent().asBytes();
}
public static void main(String[] args) throws Exception {
System.out.println("Response to Hello Request is: " +
new String(sendGrpcWebReqAndReceiveResponse()));
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright 2020 The gRPC Authors
*
* 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.
*/
// ================================================
//
// This is for testing only. Just to demonstrate a simple
// Java client to send grpc-web request and receive response
// and validate the response.
//
// ================================================
package grpcweb.examples.greeter;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import com.google.protobuf.InvalidProtocolBufferException;
import grpcweb.examples.greeter.GreeterOuterClass.HelloReply;
import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
import java.util.logging.Logger;
/**
* A simple client that requests a greeting from the {@link GreeterService}.
*/
public class GreeterClientTest {
private static final Logger LOG =
Logger.getLogger(MethodHandles.lookup().lookupClass().getName());
private static void validateResponse(byte[] response) throws InvalidProtocolBufferException {
LOG.info("Response length = " + response.length);
LOG.info("Response is: " + new String(response));
// validate the 1st byte
assertEquals((byte)0x00, response[0]);
int len = ByteBuffer.wrap(response, 1, 4).getInt();
assertEquals(11, len);
// copy len bytes into a byte array, which can be xlated into HelloResponse
byte[] protoBytes = new byte[len];
System.arraycopy(response, 5, protoBytes, 0, len);
HelloReply reply = HelloReply.parseFrom(protoBytes);
assertEquals("Hello foo", reply.getMessage());
// if there is more data in the response, it should be a trailer.
int offset = len + 5;
int trailerBlockLen = response.length - offset;
if (trailerBlockLen == 0) {
// don't have any more bytes. we are done
return;
}
assertEquals((byte)0x80, response[offset]);
offset++;
int trailerLen = ByteBuffer.wrap(response, offset, 4).getInt();
assertTrue(trailerLen > 0);
byte[] trailer = new byte[trailerLen];
System.arraycopy(response, offset+4, trailer, 0, trailerLen);
String trailerStr = new String(trailer);
LOG.info("received trailer: " + trailerStr);
assertTrue(trailerStr.startsWith("grpc-status:0"));
}
public static void main(String[] args) throws Exception {
new StartServiceAndGrpcwebProxy().start();
byte[] response = GreeterClient.sendGrpcWebReqAndReceiveResponse();
validateResponse(response);
System.exit(0);
}
}

View File

@ -0,0 +1,31 @@
/*
* Copyright 2020 The gRPC Authors
*
* 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 grpcweb.examples.greeter;
import grpcweb.examples.greeter.GreeterOuterClass.HelloReply;
import grpcweb.examples.greeter.GreeterOuterClass.HelloRequest;
import io.grpc.stub.StreamObserver;
public class GreeterService extends GreeterGrpc.GreeterImplBase {
@Override
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
System.out.println("Greeter Service responding in sayhello() method");
HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}

View File

@ -0,0 +1,39 @@
package grpcweb.examples.greeter;
import com.google.grpcweb.GrpcPortNumRelay;
import com.google.grpcweb.JettyWebserverForGrpcwebTraffic;
import io.grpc.BindableService;
import io.grpc.Server;
import io.grpc.ServerBuilder;
/**
* This class starts the service on a port (property: grpc-port)
* and starts the grpc-web proxy on a different port (property: grpc-web-port).
*/
class StartServiceAndGrpcwebProxy {
private void startGrpcService(int port) throws Exception {
Server grpcServer = ServerBuilder.forPort(port)
.addService((BindableService) new GreeterService())
.build();
grpcServer.start();
System.out.println("**** started gRPC Service on port# " + port);
}
void start() throws Exception {
int grpcPort = Util.getGrpcServicePortNum();
int grpcWebPort = Util.getGrpcwebServicePortNum();
// Start the Grpc service on grpc-port
startGrpcService(grpcPort);
// Start the grpc-web proxy on grpc-web-port.
(new JettyWebserverForGrpcwebTraffic(grpcWebPort)).start();
// grpc-web proxy needs to know the grpc-port# so it could connect to the grpc service.
GrpcPortNumRelay.setGrpcPortNum(grpcPort);
}
public static void main(String[] args) throws Exception {
new StartServiceAndGrpcwebProxy().start();
}
}

View File

@ -0,0 +1,36 @@
package grpcweb.examples.greeter;
import grpcweb.examples.greeter.GreeterOuterClass.HelloRequest;
import java.io.IOException;
import java.util.Properties;
class Util {
static byte[] packageReqObjIntoGrpcwebProtocol(HelloRequest req) {
byte[] reqObjBytes = req.toByteArray();
int len = reqObjBytes.length;
byte[] packagedBytes = new byte[5 + len];
packagedBytes[0] = (byte) 0x00;
packagedBytes[1] = (byte) ((len >> 24) & 0xff);
packagedBytes[2] = (byte) ((len >> 16) & 0xff);
packagedBytes[3] = (byte) ((len >> 8) & 0xff);
packagedBytes[4] = (byte) ((len >> 0) & 0xff);
System.arraycopy(reqObjBytes, 0, packagedBytes, 5, len);
return packagedBytes;
}
private static int getIntPropertyValue(String s) throws IOException {
java.io.InputStream inputStream =
Thread.currentThread().getContextClassLoader().getResourceAsStream("my.properties");
java.util.Properties properties = new Properties();
properties.load(inputStream);
return Integer.parseInt(properties.getProperty(s));
}
static int getGrpcServicePortNum() throws IOException {
return getIntPropertyValue("grpc-port");
}
static int getGrpcwebServicePortNum() throws IOException {
return getIntPropertyValue("grpc-web-port");
}
}

View File

@ -0,0 +1,45 @@
// Copyright 2020 The gRPC Authors
//
// 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.
// =======================================
//
// DO NOT EDIT
// this is copy of
// https://github.com/grpc/grpc-web/blob/master/net/grpc/gateway/
// examples/helloworld/helloworld.proto
//
// TODO: can the original be directly used without making copy here
// =======================================
syntax = "proto3";
option java_package = "grpcweb.examples.greeter";
package grpcweb.examples.greeter;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}

View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>grpc.testing.main</groupId>
<artifactId>grpcweb-java-examples-interop-test</artifactId>
<version>0.1</version>
<name>grpcweb-java-examples-interop-test</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<grpc-port>7080</grpc-port>
<grpc-web-port>8080</grpc-web-port>
</properties>
<dependencies>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.11.4</version>
</dependency>
<dependency>
<groupId>com.google.grpcweb</groupId>
<artifactId>grpcweb-java</artifactId>
<version>0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.0</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.4.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.7.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>write-project-properties</goal>
</goals>
<configuration>
<outputFile>${project.build.outputDirectory}/my.properties</outputFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<id>my-execution</id>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>grpcweb.examples.StartServiceAndGrpcwebProxy</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -18,7 +18,7 @@
// This is copy of the following:
// github.com/grpc/grpc-java/blob/master/interop-testing/src/main/java/io/grpc/testing/integration/TestServiceImpl.java
package grpc.testing.main;
package grpcweb.examples;
import com.google.common.base.Preconditions;
import com.google.common.collect.Queues;
@ -30,6 +30,7 @@ import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;
import io.grpc.Status;
import io.grpc.internal.LogExceptionRunnable;
import io.grpc.protobuf.lite.ProtoLiteUtils;
import io.grpc.stub.ServerCallStreamObserver;
import io.grpc.stub.StreamObserver;
import grpc.testing.EmptyProtos;
@ -59,16 +60,26 @@ import javax.annotation.concurrent.GuardedBy;
* Implementation of the business logic for the TestService. Uses an executor to schedule chunks
* sent in response streams.
*/
public class TestServiceImpl extends TestServiceGrpc.TestServiceImplBase {
public class InteropTestService extends TestServiceGrpc.TestServiceImplBase {
private final Random random = new Random();
private final ScheduledExecutorService executor;
private final ByteString compressableBuffer;
private static final Metadata.Key<Messages.SimpleContext> METADATA_KEY =
Metadata.Key.of(
"grpc.testing.SimpleContext" + Metadata.BINARY_HEADER_SUFFIX,
ProtoLiteUtils.metadataMarshaller(Messages.SimpleContext.getDefaultInstance()));
private static final Metadata.Key<String> ECHO_INITIAL_METADATA_KEY
= Metadata.Key.of("x-grpc-test-echo-initial", Metadata.ASCII_STRING_MARSHALLER);
private static final Metadata.Key<byte[]> ECHO_TRAILING_METADATA_KEY
= Metadata.Key.of("x-grpc-test-echo-trailing-bin", Metadata.BINARY_BYTE_MARSHALLER);
/**
* Constructs a controller using the given executor for scheduling response stream chunks.
*/
public TestServiceImpl(ScheduledExecutorService executor) {
public InteropTestService(ScheduledExecutorService executor) {
this.executor = executor;
this.compressableBuffer = ByteString.copyFrom(new byte[1024]);
}
@ -445,9 +456,9 @@ public class TestServiceImpl extends TestServiceGrpc.TestServiceImplBase {
/** Returns interceptors necessary for full service implementation. */
public static List<ServerInterceptor> interceptors() {
return Arrays.asList(
echoRequestHeadersInterceptor(Util.METADATA_KEY),
echoRequestMetadataInHeaders(Util.ECHO_INITIAL_METADATA_KEY),
echoRequestMetadataInTrailers(Util.ECHO_TRAILING_METADATA_KEY));
echoRequestHeadersInterceptor(METADATA_KEY),
echoRequestMetadataInHeaders(ECHO_INITIAL_METADATA_KEY),
echoRequestMetadataInTrailers(ECHO_TRAILING_METADATA_KEY));
}
/**

View File

@ -0,0 +1,44 @@
package grpcweb.examples;
import com.google.grpcweb.GrpcPortNumRelay;
import com.google.grpcweb.JettyWebserverForGrpcwebTraffic;
import io.grpc.BindableService;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.ServerInterceptors;
import java.util.concurrent.Executors;
/**
* This class starts the service on a port (property: grpc-port)
* and starts the grpc-web proxy on a different port (property: grpc-web-port).
*/
class StartServiceAndGrpcwebProxy {
private void startGrpcService(int port) throws Exception {
Server grpcServer = ServerBuilder.forPort(port)
.addService(
ServerInterceptors.intercept(
(BindableService) new InteropTestService(Executors.newSingleThreadScheduledExecutor()),
InteropTestService.interceptors()))
.build();
grpcServer.start();
System.out.println("**** started gRPC Service on port# " + port);
}
void start() throws Exception {
int grpcPort = Util.getGrpcServicePortNum();
int grpcWebPort = Util.getGrpcwebServicePortNum();
// Start the Grpc service on grpc-port
startGrpcService(grpcPort);
// Start the grpc-web proxy on grpc-web-port.
(new JettyWebserverForGrpcwebTraffic(grpcWebPort)).start();
// grpc-web proxy needs to know the grpc-port# so it could connect to the grpc service.
GrpcPortNumRelay.setGrpcPortNum(grpcPort);
}
public static void main(String[] args) throws Exception {
new StartServiceAndGrpcwebProxy().start();
}
}

View File

@ -0,0 +1,22 @@
package grpcweb.examples;
import java.io.IOException;
import java.util.Properties;
class Util {
private static int getIntPropertyValue(String s) throws IOException {
java.io.InputStream inputStream =
Thread.currentThread().getContextClassLoader().getResourceAsStream("my.properties");
java.util.Properties properties = new Properties();
properties.load(inputStream);
return Integer.parseInt(properties.getProperty(s));
}
static int getGrpcServicePortNum() throws IOException {
return getIntPropertyValue("grpc-port");
}
static int getGrpcwebServicePortNum() throws IOException {
return getIntPropertyValue("grpc-web-port");
}
}

View File

@ -13,9 +13,14 @@
// limitations under the License.
// An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses.
//
//
// ******************* DO NOT EDIT
//
// This is copy of the following:
// github.com/grpc/grpc-java/blob/master/interop-testing/src/main/proto/grpc/testing/test.proto
//
// *********************
syntax = "proto3";

View File

@ -5,10 +5,9 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.google.grpcweb</groupId>
<artifactId>grpcweb</artifactId>
<version>0.1</version>
<name>grpcweb</name>
<artifactId>grpcweb-java</artifactId>
<version>0.1-SNAPSHOT</version>
<name>grpcweb-java</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -91,39 +90,9 @@
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.0</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.4.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.7.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<id>my-execution</id>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>grpc.testing.main.TestServiceAndProxy</mainClass>
</configuration>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>

View File

@ -16,16 +16,18 @@
package com.google.grpcweb;
import java.lang.invoke.MethodHandles;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
class DebugInfo {
private static final Logger LOGGER = Logger.getLogger(DebugInfo.class.getName());
private static final Logger LOG =
Logger.getLogger(MethodHandles.lookup().lookupClass().getName());
static void printRequest(HttpServletRequest req) {
if (!LOGGER.isLoggable(Level.FINE)) return;
if (!LOG.isLoggable(Level.FINE)) return;
StringBuilder sb = new StringBuilder();
Enumeration<String> headerNames = req.getHeaderNames();
@ -54,6 +56,6 @@ class DebugInfo {
sb.append("\n\t ServerPort: ").append(req.getServerPort());
sb.append("\n\t ServletPath: ").append(req.getServletPath());
sb.append("\n\t Method: ").append(req.getMethod());
LOGGER.fine(sb.toString());
LOG.fine(sb.toString());
}
}

View File

@ -0,0 +1,14 @@
package com.google.grpcweb;
public class GrpcPortNumRelay {
private static int sGrpcPortNum = 0;
public static void setGrpcPortNum(int i) {
// make sure this is set only once
if (sGrpcPortNum == 0) sGrpcPortNum = i;
}
static int getGrpcPortNum() {
return sGrpcPortNum;
}
}

View File

@ -27,11 +27,10 @@ import io.grpc.Metadata;
import io.grpc.MethodDescriptor;
import io.grpc.Status;
import java.util.concurrent.CountDownLatch;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletResponse;
class GrpcWebClientInterceptor implements ClientInterceptor {
private static final Logger LOG = Logger.getLogger(GrpcWebClientInterceptor.class.getName());
private final CountDownLatch mLatch;
private final HttpServletResponse mResp;
private final SendResponse mSendResponse;
@ -72,8 +71,7 @@ class GrpcWebClientInterceptor implements ClientInterceptor {
// seems, sometimes onHeaders() is not called before this method is called!
// so far, they are the error cases. let onError() method in ClientListener
// handle this call. Could ignore this.
// TODO is this correct? what if onError() never gets called? maybe here it should
// be handled: send headers first and then send the trailers.
// TODO is this correct? what if onError() never gets called?
} else {
mSendResponse.writeTrailer(s, t);
mLatch.countDown();

View File

@ -17,16 +17,10 @@ package com.google.grpcweb;
import com.google.inject.AbstractModule;
public class GrpcWebGuiceModule extends AbstractModule {
private static int sGrpcPortNum = 0;
public static void setGrpcPortNum(int i) {
if (sGrpcPortNum == 0) sGrpcPortNum = i;
}
class GrpcWebGuiceModule extends AbstractModule {
@Override
protected void configure() {
bind(GrpcServiceConnectionManager.class)
.toInstance(new GrpcServiceConnectionManager(sGrpcPortNum));
.toInstance(new GrpcServiceConnectionManager(GrpcPortNumRelay.getGrpcPortNum()));
}
}

View File

@ -0,0 +1,38 @@
package com.google.grpcweb;
import java.lang.invoke.MethodHandles;
import java.util.EnumSet;
import java.util.logging.Logger;
import javax.servlet.DispatcherType;
import org.eclipse.jetty.servlet.ServletHandler;
public class JettyWebserverForGrpcwebTraffic {
private static final Logger LOG =
Logger.getLogger(MethodHandles.lookup().lookupClass().getName());
private final int mGrpcwebPort;
public JettyWebserverForGrpcwebTraffic(int grpcwebPort) {
mGrpcwebPort = grpcwebPort;
}
public org.eclipse.jetty.server.Server start() {
// Start a jetty server to listen on the grpc-web port#
org.eclipse.jetty.server.Server jServer = new org.eclipse.jetty.server.Server(mGrpcwebPort);
ServletHandler handler = new ServletHandler();
jServer.setHandler(handler);
handler.addFilterWithMapping(CorsFilter.class, "/*",
EnumSet.of(DispatcherType.REQUEST));
handler.addServletWithMapping(GrpcWebTrafficServlet.class, "/*");
try {
jServer.start();
} catch (Exception e) {
LOG.warning("Jetty Server couldn't be started. " + e.getLocalizedMessage());
e.printStackTrace();
return null;
}
LOG.info("**** started gRPC-web Service on port# " + mGrpcwebPort);
jServer.setStopAtShutdown(true);
return jServer;
}
}

View File

@ -18,6 +18,7 @@ package com.google.grpcweb;
import com.google.grpcweb.MessageHandler.ContentType;
import java.io.IOException;
import java.io.InputStream;
import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
@ -29,7 +30,9 @@ import org.apache.commons.io.IOUtils;
* Reads frames from the input bytes and returns a single message.
*/
class MessageDeframer {
private static final Logger LOGGER = Logger.getLogger(MessageDeframer.class.getName());
private static final Logger LOG =
Logger.getLogger(MethodHandles.lookup().lookupClass().getName());
static final byte DATA_BYTE = (byte) 0x00;
// TODO: fix this code to be able to handle upto 4GB input size.
@ -55,11 +58,11 @@ class MessageDeframer {
inBytes = IOUtils.toByteArray(inStream);
} catch (IOException e) {
e.printStackTrace();
LOGGER.warning("invalid input");
LOG.warning("invalid input");
return false;
}
if (inBytes.length < 5) {
LOGGER.fine("invalid input. Expected minimum of 5 bytes");
LOG.fine("invalid input. Expected minimum of 5 bytes");
return false;
}
@ -88,7 +91,7 @@ class MessageDeframer {
// Firstbyte should be 0x00 (for this to be a DATA frame)
int firstByteValue = inBytes[mReadSoFar] | DATA_BYTE;
if (firstByteValue != 0) {
LOGGER.fine("done with DATA bytes");
LOG.fine("done with DATA bytes");
return false;
}
@ -106,7 +109,7 @@ class MessageDeframer {
// Make sure we have enough bytes in the inputstream
int expectedNumBytes = len + 5 + mReadSoFar;
if (inBytes.length < expectedNumBytes) {
LOGGER.warning(String.format("input doesn't have enough bytes. expected: %d, found %d",
LOG.warning(String.format("input doesn't have enough bytes. expected: %d, found %d",
expectedNumBytes, inBytes.length));
return false;
}

View File

@ -16,7 +16,6 @@
package com.google.grpcweb;
import io.grpc.Metadata;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;

View File

@ -21,6 +21,7 @@ import io.grpc.Metadata;
import io.grpc.Status;
import io.grpc.stub.MetadataUtils;
import io.grpc.stub.StreamObserver;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@ -32,7 +33,8 @@ import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
class RequestHandler {
private static final Logger LOG = Logger.getLogger(RequestHandler.class.getName());
private static final Logger LOG =
Logger.getLogger(MethodHandles.lookup().lookupClass().getName());
private final MessageHandler mMessageHandler;
private final GrpcServiceConnectionManager mGrpcServiceConnectionManager;
@ -56,6 +58,7 @@ class RequestHandler {
String methodName = classAndMethodNames.getRight();
Class cls = getClassObject(className);
if (cls == null) {
LOG.info("incorrect classname in the request: " + className);
// incorrect classname specified in the request.
sendResponse.returnUnimplementedStatusCode();
return;

View File

@ -19,6 +19,7 @@ import com.google.grpcweb.MessageHandler.ContentType;
import io.grpc.Metadata;
import io.grpc.Status;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.Map;
import java.util.logging.Logger;
import javax.servlet.ServletOutputStream;
@ -27,7 +28,8 @@ import javax.servlet.http.HttpServletResponse;
import java.util.Base64;
class SendResponse {
private static final Logger LOG = Logger.getLogger(SendResponse.class.getName());
private static final Logger LOG =
Logger.getLogger(MethodHandles.lookup().lookupClass().getName());
private final String mContentType;
private final HttpServletResponse mResp;

View File

@ -1,55 +0,0 @@
package grpc.testing.main;
import com.google.grpcweb.CorsFilter;
import com.google.grpcweb.GrpcWebGuiceModule;
import com.google.grpcweb.GrpcWebTrafficServlet;
import io.grpc.BindableService;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.ServerInterceptors;
import java.util.EnumSet;
import java.util.concurrent.Executors;
import java.util.logging.Logger;
import javax.servlet.DispatcherType;
import org.eclipse.jetty.servlet.ServletHandler;
/**
* This class starts the service on a port (GRPC_PORT) and starts the grpc-web proxy on
* a different port (GRPC_WEB_PORT).
*/
public class TestServiceAndProxy {
private static final Logger LOGGER = Logger.getLogger(TestServiceAndProxy.class.getName());
private static final int GRPC_PORT = 7074;
private static final int GRPC_WEB_PORT = 8080;
private static Server startGrpcService(int port) throws Exception {
Server grpcServer = ServerBuilder.forPort(port)
.addService(
ServerInterceptors.intercept(
(BindableService) new TestServiceImpl(Executors.newSingleThreadScheduledExecutor()),
TestServiceImpl.interceptors()))
.build();
grpcServer.start();
LOGGER.info("**** started gRPC Service on port# " + port);
return grpcServer;
}
private static void listenForGrpcWebReq(int grpcWebPort) throws Exception {
// Start a jetty server to listen on the grpc-web port#
org.eclipse.jetty.server.Server jServer = new org.eclipse.jetty.server.Server(grpcWebPort);
ServletHandler handler = new ServletHandler();
jServer.setHandler(handler);
handler.addFilterWithMapping(CorsFilter.class, "/*",
EnumSet.of(DispatcherType.REQUEST));
handler.addServletWithMapping(GrpcWebTrafficServlet.class, "/*");
jServer.start();
LOGGER.info("**** started gRPC-web Service on port# " + grpcWebPort);
}
public static void main(String[] args) throws Exception {
GrpcWebGuiceModule.setGrpcPortNum(GRPC_PORT);
Server grpcServer = startGrpcService(GRPC_PORT);
listenForGrpcWebReq(GRPC_WEB_PORT);
grpcServer.awaitTermination();
}
}

View File

@ -1,39 +0,0 @@
/*
* Copyright 2020 The gRPC Authors
*
* 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.
*/
// ******************* DO NOT EDIT
// This is copy of the following:
// github.com/grpc/grpc-java/blob/master/interop-testing/src/main/java/io/grpc/testing/integration/Util.java
package grpc.testing.main;
import io.grpc.Metadata;
import io.grpc.protobuf.lite.ProtoLiteUtils;
import grpc.testing.Messages;
/**
* Utility methods to support integration testing.
*/
public class Util {
public static final Metadata.Key<Messages.SimpleContext> METADATA_KEY =
Metadata.Key.of(
"grpc.testing.SimpleContext" + Metadata.BINARY_HEADER_SUFFIX,
ProtoLiteUtils.metadataMarshaller(Messages.SimpleContext.getDefaultInstance()));
public static final Metadata.Key<String> ECHO_INITIAL_METADATA_KEY
= Metadata.Key.of("x-grpc-test-echo-initial", Metadata.ASCII_STRING_MARSHALLER);
public static final Metadata.Key<byte[]> ECHO_TRAILING_METADATA_KEY
= Metadata.Key.of("x-grpc-test-echo-trailing-bin", Metadata.BINARY_BYTE_MARSHALLER);
}