Skip to content

Commit

Permalink
From PR review
Browse files Browse the repository at this point in the history
Addressing all good feedback, to inline with other CE samples
  • Loading branch information
qu1queee committed Dec 5, 2023
1 parent adfab6d commit 14c152b
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 35 deletions.
4 changes: 2 additions & 2 deletions grpc/Dockerfile.client
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:latest AS stage
FROM icr.io/codeengine/golang:latest AS stage

WORKDIR /app/src

Expand All @@ -12,7 +12,7 @@ COPY go.sum .

RUN CGO_ENABLED=0 GOOS=linux go build -o client ./client

FROM golang:latest
FROM icr.io/codeengine/golang:latest

WORKDIR /app/src

Expand Down
4 changes: 2 additions & 2 deletions grpc/Dockerfile.server
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:latest AS stage
FROM icr.io/codeengine/golang:latest AS stage

WORKDIR /app/src

Expand All @@ -12,7 +12,7 @@ COPY go.sum .

RUN CGO_ENABLED=0 GOOS=linux go build -o server ./server

FROM golang:latest
FROM icr.io/codeengine/golang:latest

WORKDIR /app/src

Expand Down
2 changes: 1 addition & 1 deletion grpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ You can try to deploy this microservice architecture in your Code Engine project
Once you have selected your Code Engine project, you only need to run:

```sh
./run.sh
./run
```

## Todo:
Expand Down
39 changes: 21 additions & 18 deletions grpc/client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ func BuyGroceryHandler(groceryClient ec.GroceryClient) func(w http.ResponseWrite
}
}

func Fail(w http.ResponseWriter, msg string, err error) {
fmt.Printf("%s: %v\n", msg, err)
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(fmt.Sprintf("%s\n", msg)))
}

func GetHandler(w http.ResponseWriter, r *http.Request, groceryClient ec.GroceryClient) {

// Contact the server and print out its response.
Expand All @@ -49,17 +55,12 @@ func GetHandler(w http.ResponseWriter, r *http.Request, groceryClient ec.Grocery

itemList, err := groceryClient.ListGrocery(ctx, &category)
if err != nil {
fmt.Printf("failed to list grocery: %v", err)
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("failed to list grocery"))
Fail(w, "failed to list groceries", err)
return
}

for _, item := range itemList.Item {
json.NewEncoder(w).Encode(fmt.Sprintf("Item Name: %v\n", item.Name))
}

w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(itemList.Item)
}

func BuyHandler(w http.ResponseWriter, r *http.Request, groceryClient ec.GroceryClient) {
Expand All @@ -71,7 +72,7 @@ func BuyHandler(w http.ResponseWriter, r *http.Request, groceryClient ec.Grocery

amount, err := strconv.ParseFloat(pAmount, 64)
if err != nil {
http.Error(w, "invalid amount parameter", http.StatusBadRequest)
Fail(w, "invalid amount parameter", err)
}

category := ec.Category{
Expand All @@ -81,26 +82,28 @@ func BuyHandler(w http.ResponseWriter, r *http.Request, groceryClient ec.Grocery

item, err := groceryClient.GetGrocery(context.Background(), &category)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
Fail(w, fmt.Sprintf("failed to get grocery item by name: %v", category.Itemname), err)
return
}

json.NewEncoder(w).Encode(fmt.Sprintf("Grocery: \n Item: %v \n Quantity: %v\n", item.GetName(), item.GetQuantity()))

paymentRequest := ec.PaymentRequest{
Amount: amount,
Item: item,
}

paymentResponse, _ := groceryClient.MakePayment(context.Background(), &paymentRequest)
json.NewEncoder(w).Encode(fmt.Sprintf("Payment Response: \n Purchase: %v \n Details: %v \n State: %v \n Change: %v\n", paymentResponse.PurchasedItem, paymentResponse.Details, paymentResponse.Success, paymentResponse.Change))
w.WriteHeader(http.StatusOK)
}

func main() {
// if !paymentResponse.Success {
// Fail(w, "failed to buy grocery, not enough money", errors.New("not enough money"))
// return
// }

serverLocalEndpoint := "LOCAL_ENDPOINT_WITH_PORT"
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(paymentResponse)
}

localEndpoint := os.Getenv(serverLocalEndpoint)
func main() {
localEndpoint := os.Getenv("LOCAL_ENDPOINT_WITH_PORT")

fmt.Printf("using local endpoint: %s\n", localEndpoint)
conn, err := grpc.Dial(localEndpoint, grpc.WithTransportCredentials(insecure.NewCredentials()))
Expand Down
25 changes: 25 additions & 0 deletions grpc/regenerate-grpc-code.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash

set -euo pipefail

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
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] ensure your GOPATH is in your PATH".
exit 1
fi


echo "[INFO] Recompiling .proto file, this will regenerate the *.pb.go files."
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
${BASEDIR}/ecommerce/ecommerce.proto
34 changes: 31 additions & 3 deletions grpc/run.sh → grpc/run
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ set -euo pipefail
SERVER_APP_NAME="a-grpc-server"
CLIENT_APP_NAME="a-grpc-client"

# Clean up previous run
function clean() {
echo "[INFO] Deleting CE client/server application ${CLIENT_APP_NAME}"
ibmcloud ce app delete --name $CLIENT_APP_NAME --force --ignore-not-found > /dev/null 2>&1
echo "[INFO] Deleting CE gRPC server application ${SERVER_APP_NAME}"
ibmcloud ce app delete --name $SERVER_APP_NAME --force --ignore-not-found > /dev/null 2>&1
}

if [ $# -ge 1 ] && [ -n "$1" ]
then
echo "[INFO] going to clean existing project resources"
clean
exit 0
fi

# Create the gRPC server app
echo "[INFO] Creating CE gRPC server application ${SERVER_APP_NAME}"
ibmcloud ce app create --name "${SERVER_APP_NAME}" --port h2c:8080 --min-scale 1 --build-source . --build-dockerfile Dockerfile.server
Expand All @@ -26,6 +41,19 @@ echo "[INFO] Endpoint is: ${URL}"
echo "[INFO] Retrieving available electronic items"
curl -q "${URL}"/listgroceries/electronics

# Buy an item from electronics and pay with 2000
echo "[INFO] Going to buy an iphone"
curl -q "${URL}"/buygrocery/electronics/iphone/2000.0
# 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 .

# Validate payment operation
echo "[INFO] Validating payment operation state"
OPERATION_SUCCEEDED=$(echo $JSON_REPONSE | jq '.success')
if [ "${OPERATION_SUCCEEDED}" == "null" ]
then
echo "[ERROR] Payment failed, bailing out."
exit 1
else
echo "[INFO] Successful payment operation."
exit 0
fi
58 changes: 49 additions & 9 deletions grpc/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,59 @@ func initGroceryServer() *GroceryServer {
return &GroceryServer{
Products: []Product{
{
Category: "vegetables",
Category: "food",
Name: "carrot",
Quantity: "4",
Quantity: "1",
Price: 0.5,
},
{
Category: "fruit",
Category: "food",
Name: "apple",
Quantity: "3",
Price: 0.6,
Quantity: "1",
Price: 0.5,
},
{
Category: "food",
Name: "banana",
Quantity: "1",
Price: 0.5,
},
{
Category: "food",
Name: "lemon",
Quantity: "1",
Price: 0.5,
},
{
Category: "clothes",
Name: "tshirt",
Quantity: "1",
Price: 25.0,
},
{
Category: "clothes",
Name: "pants",
Quantity: "1",
Price: 65.0,
},
{
Category: "clothes",
Name: "socks",
Quantity: "1",
Price: 5.0,
},
{
Category: "electronics",
Name: "iphone",
Quantity: "1",
Price: 1200.99,
},
{
Category: "electronics",
Name: "keyboard",
Quantity: "1",
Price: 100.99,
},
{
Category: "electronics",
Name: "usb",
Expand All @@ -68,7 +104,7 @@ func (gs *GroceryServer) GetGrocery(ctx context.Context, in *ec.Category) (*ec.I
}
}

return &ec.Item{}, nil
return &ec.Item{}, errors.New("category item not found")
}

func (gs *GroceryServer) ListGrocery(ctx context.Context, in *ec.Category) (*ec.ItemList, error) {
Expand All @@ -95,14 +131,18 @@ func (gs *GroceryServer) MakePayment(ctx context.Context, in *ec.PaymentRequest)
transactionSuccessfull := true
var transactionDetails string

change := amount - purchasedItem.Price

if change < 0 {
transactionSuccessfull = false
}

if transactionSuccessfull {
transactionDetails = fmt.Sprintf("Transaction of amount %v is successful", amount)
} else {
transactionDetails = fmt.Sprintf("Transaction of amount %v failed", amount)
transactionDetails = fmt.Sprintf("Transaction of amount %v failed, payment missmatch", amount)
}

change := amount - purchasedItem.Price

return &ec.PaymentResponse{
Success: transactionSuccessfull,
PurchasedItem: purchasedItem,
Expand Down

0 comments on commit 14c152b

Please sign in to comment.