Skip to content

Commit

Permalink
Adding Envoy gRPC bridge filter example (#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
Christopher Burnett authored and mattklein123 committed Sep 19, 2016
1 parent 8cb42e3 commit 4ce09ad
Show file tree
Hide file tree
Showing 30 changed files with 1,520 additions and 0 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions examples/grpc-bridge/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bin/service
.idea
7 changes: 7 additions & 0 deletions examples/grpc-bridge/Dockerfile-grpc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM lyft/envoy:latest

RUN mkdir /var/log/envoy/
COPY ./bin/service /usr/local/bin/srv
COPY ./script/grpc_start /etc/grpc_start
CMD /etc/grpc_start

8 changes: 8 additions & 0 deletions examples/grpc-bridge/Dockerfile-python
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM lyft/envoy:latest

RUN apt-get install -y python-dev
RUN pip install grpcio requests
ADD ./client /client
RUN chmod a+x /client/client.py
RUN mkdir /var/log/envoy/
CMD /usr/local/bin/envoy -c /etc/s2s-python-envoy.json
31 changes: 31 additions & 0 deletions examples/grpc-bridge/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# envoy-grpc

This is an example usage of the Envoy [gRPC bridge filter](https://lyft.github.io/envoy/docs/configuration/http_filters/grpc_http1_bridge_filter.html#config-http-filters-grpc-bridge). Included is a gRPC in memory Key/Value store with a Python HTTP client. The Python client makes HTTP/1 requests through the Envoy sidecar process which are upgraded into HTTP/2 gRPC requests. Response trailers are then buffered and sent back to the client as a HTTP/1 header payload.

## Building the Go service

```bash
script/bootstrap
script/build
```

## Docker compose

To run the docker compose file, and set up both the Python and the gRPC containers
run:

```bash
docker-compose up --build
```

## Sending requests to the Key/Value store

```bash
# set a key
docker-compose exec python /client/client.py set foo bar
=> setf foo to bar

# get a key
docker-compose exec python /client/client.py get foo
=> bar
```
Empty file.
78 changes: 78 additions & 0 deletions examples/grpc-bridge/client/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/python

import requests, sys
import kv_pb2 as kv
from struct import pack

HOST = "http://localhost:9001"
HEADERS = {'content-type': 'application/grpc','Host':'grpc'}
USAGE = """
envoy-python-client usage:
./client.py set <key> <value> - sets the <key> and <value>
./client.py get <key> - gets the value for <key>
"""

class KVClient():

def get(self, key):
r = kv.GetRequest(key=key)

# Build the gRPC frame
data = r.SerializeToString()
data = pack('!cI', b'\0', len(data)) + data

resp = requests.post(HOST + "/kv.KV/Get", data=data, headers=HEADERS)

return kv.GetResponse().FromString(resp.content[5:])


def set(self, key, value):
r = kv.SetRequest(key=key, value=value)
data = r.SerializeToString()
data = pack('!cI', b'\0', len(data)) + data

return requests.post(HOST + "/kv.KV/Set", data=data, headers=HEADERS)

def run():
if len(sys.argv) == 1:
print(USAGE)

sys.exit(0)

cmd = sys.argv[1]

client = KVClient()

if cmd == "get":
# ensure a key was provided
if len(sys.argv) != 3:
print(USAGE)
sys.exit(1)

# get the key to fetch
key = sys.argv[2]

# send the request to the server
response = client.get(key)

print(response.value)
sys.exit(0)

elif cmd == "set":
# ensure a key and value were provided
if len(sys.argv) < 4:
print(USAGE)
sys.exit(1)

# get the key and the full text of value
key = sys.argv[2]
value = " ".join(sys.argv[3:])

# send the request to the server
response = client.set(key, value)

print("setf %s to %s" % (key, value))

if __name__ == '__main__':
run()
Loading

0 comments on commit 4ce09ad

Please sign in to comment.