-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding Envoy gRPC bridge filter example #78
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
bin/service | ||
.idea |
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 | ||
|
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 |
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. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To kill two birds with one stone we could also mention how we are doing authority based routing, which differs from how routing is done in the front-proxy example. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I talked to @twoism, and I will add this in a new PR. |
||
## 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 | ||
``` |
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() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we potentially put this in the real docs alongside the other example? That would be cool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I talked to @twoism, and I will add this in a new PR.