Skip to content

Commit

Permalink
More optimizations
Browse files Browse the repository at this point in the history
- Add architecture diagram to readme
- Refactor proto interface, to inline fields
- Add build script
- Recompile proto files

Signed-off-by: encalada <[email protected]>
  • Loading branch information
qu1queee committed Dec 6, 2023
1 parent 9f120d8 commit 99de465
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 49 deletions.
19 changes: 11 additions & 8 deletions grpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,25 @@ A basic gRPC microservice architecture, involving a gRPC server and a
client, that allow users to buy items from an online store.

The ecommerce interface provided by the gRPC server, allows users to
list and buy grocery via the public client/server application.
list and buy groceries via the public client/server application.

The client/server application is deployed as a Code Engine application,
with a public endpoint. While the gRPC server is deployed as a Code Engine
application only exposed to the Code Engine project.

See image:
See architecture diagram:

![Alt text](images/grpc-architecture.png)

## Source code

Check the source code if you want to understand how this works. In general,
we provided three directories:

- `/ecommerce` directory hosts the protobuf files and declares the `grocery`
interface for a set of remote procedures that can be called by clients.
- `/server` directory hosts the `grocery` interface implementation and creates a server.
interface for a set of remote procedures that can be called by clients. This directory
can be regenerated upon changes to the `.proto` file, by calling the `./regenerate-grpc-code.sh`.
- `/server` directory hosts the `grocery` interface implementation and creates a gRPC server.
- `/client` directory defines an http server and calls the gRPC server via its different
handlers.

Expand All @@ -33,7 +35,8 @@ Once you have selected your Code Engine project, you only need to run:
./run
```

## Todo:
3. Extend initGroceryServer() content, in order to have more groceries.
4. Json Encoding on the client side, needs improvement
5. Error handling for queries validations, e.g. grocery not found, or category not found.
If you want to clean-up resources from this sample app, do not forget to run:

```sh
./run clean
```
21 changes: 21 additions & 0 deletions grpc/build
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

set -euo pipefail

# Env Vars:
# REGISTRY: name of the image registry/namespace to store the images
#
# NOTE: to run this you MUST set the REGISTRY environment variable to
# your own image registry/namespace otherwise the `docker push` commands
# will fail due to an auth failure. Which means, you also need to be logged
# into that registry before you run it.

export REGISTRY=${REGISTRY:-icr.io/codeengine}

# Build the images
docker build -f Dockerfile.client -t "${REGISTRY}"/grpc-client . --platform linux/amd64
docker build -f Dockerfile.server -t "${REGISTRY}"/grpc-server . --platform linux/amd64

# And push it
docker push "${REGISTRY}"/grpc-client
docker push "${REGISTRY}"/grpc-server
7 changes: 1 addition & 6 deletions grpc/client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,7 @@ func BuyHandler(w http.ResponseWriter, r *http.Request, groceryClient ec.Grocery
Item: item,
}

paymentResponse, _ := groceryClient.MakePayment(context.Background(), &paymentRequest)

// if !paymentResponse.Success {
// Fail(w, "failed to buy grocery, not enough money", errors.New("not enough money"))
// return
// }
paymentResponse, _ := groceryClient.BuyGrocery(context.Background(), &paymentRequest)

w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(paymentResponse)
Expand Down
24 changes: 12 additions & 12 deletions grpc/ecommerce/ecommerce.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion grpc/ecommerce/ecommerce.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ option go_package="github.com/qu1queee/CodeEngine/grpc/ecommerce";
service grocery {
rpc GetGrocery(Category) returns (Item) {};
rpc ListGrocery(Category) returns (ItemList) {};
rpc MakePayment(PaymentRequest) returns (PaymentResponse) {};
rpc BuyGrocery(PaymentRequest) returns (PaymentResponse) {};
}

message Category{
Expand Down
24 changes: 12 additions & 12 deletions grpc/ecommerce/ecommerce_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added grpc/images/grpc-architecture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions grpc/regenerate-grpc-code.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ BASEDIR="$(dirname "$0")"

if ! hash protoc >/dev/null 2>&1; then
echo "[ERROR] protoc compiler plugin is not installed, bailing out."
echo "[INFO] refer to https://grpc.io/docs/languages/go/quickstart/#prerequisites for instalation guidelines."
echo "[INFO] refer to https://grpc.io/docs/languages/go/quickstart/#prerequisites for installation guidelines."
echo
exit 1
fi

if ! hash protoc-gen-go >/dev/null 2>&1; then
echo "[ERROR] protoc-gen-go plugin is not installed, bailing out."
echo "[INFO] refer to https://grpc.io/docs/languages/go/quickstart/#prerequisites for instalation guidelines."
echo "[INFO] refer to https://grpc.io/docs/languages/go/quickstart/#prerequisites for installation guidelines."
echo "[INFO] ensure your GOPATH is in your PATH".
exit 1
fi
Expand Down
14 changes: 7 additions & 7 deletions grpc/run
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

set -euo pipefail
set -exuo pipefail

SERVER_APP_NAME="a-grpc-server"
CLIENT_APP_NAME="a-grpc-client"
Expand Down Expand Up @@ -37,18 +37,18 @@ echo "[INFO] Retrieving client/server public endpoint"
URL=$(ibmcloud ce app get -n "${CLIENT_APP_NAME}" -o url)
echo "[INFO] Endpoint is: ${URL}"

# Query the list of groceries by electronics category
echo "[INFO] Retrieving available electronic items"
curl -q "${URL}"/listgroceries/electronics
# Query the list of groceries by food category
echo "[INFO] Retrieving available food items"
curl -q "${URL}"/listgroceries/food

# Buy an item from food and pay with 5.0 dollars
echo "[INFO] Going to buy an apple, paying with 5.0 dollars"
JSON_REPONSE=$(curl -s "${URL}"/buygrocery/vegetables/apple/5.0 | jq '.success')
echo $JSON_REPONSE | jq .
JSON_RESPONSE=$(curl -s "${URL}"/buygrocery/food/apple/5.0 | jq '.success')
echo "${JSON_RESPONSE}" | jq .

# Validate payment operation
echo "[INFO] Validating payment operation state"
OPERATION_SUCCEEDED=$(echo $JSON_REPONSE | jq '.success')
OPERATION_SUCCEEDED=$(echo "${JSON_RESPONSE}" | jq '.success')
if [ "${OPERATION_SUCCEEDED}" == "null" ]
then
echo "[ERROR] Payment failed, bailing out."
Expand Down
2 changes: 1 addition & 1 deletion grpc/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func (gs *GroceryServer) ListGrocery(ctx context.Context, in *ec.Category) (*ec.
return &itemList, errors.New("category not found")
}

func (gs *GroceryServer) MakePayment(ctx context.Context, in *ec.PaymentRequest) (*ec.PaymentResponse, error) {
func (gs *GroceryServer) BuyGrocery(ctx context.Context, in *ec.PaymentRequest) (*ec.PaymentResponse, error) {
amount := in.GetAmount()
purchasedItem := in.GetItem()

Expand Down

0 comments on commit 99de465

Please sign in to comment.