connect cartservice

Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
This commit is contained in:
Ahmet Alp Balkan 2018-06-26 11:01:24 -07:00
parent 36b7b9eb65
commit f3fe6d42ad
8 changed files with 93 additions and 14 deletions

View file

@ -0,0 +1,39 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: cartservice
spec:
template:
metadata:
labels:
app: cartservice
spec:
containers:
- name: server
image: cartservice
ports:
- containerPort: 7070
env:
- name: REDIS_ADDR
value: "redis-cart:6379"
- name: CART_SERVICE_PORT
value: "7070"
resources:
requests:
cpu: 200m
memory: 64Mi
limits:
cpu: 300m
memory: 128Mi
---
apiVersion: v1
kind: Service
metadata:
name: cartservice
spec:
type: ClusterIP
selector:
app: cartservice
ports:
- port: 7070
targetPort: 7070

View file

@ -25,7 +25,7 @@ spec:
- name: CURRENCY_SERVICE_ADDR - name: CURRENCY_SERVICE_ADDR
value: "currencyservice:7000" value: "currencyservice:7000"
- name: CART_SERVICE_ADDR - name: CART_SERVICE_ADDR
value: "cartservice:9999" value: "cartservice:7070"
resources: resources:
requests: requests:
cpu: 100m cpu: 100m

View file

@ -16,6 +16,8 @@ build:
workspace: src/paymentservice workspace: src/paymentservice
- imageName: currencyservice - imageName: currencyservice
workspace: src/currencyservice workspace: src/currencyservice
- imageName: cartservice
workspace: src/cartservice
deploy: deploy:
kubectl: kubectl:
manifests: manifests:

View file

@ -43,15 +43,20 @@ func ensureSessionID(next http.HandlerFunc) http.HandlerFunc {
} }
func (fe *frontendServer) homeHandler(w http.ResponseWriter, r *http.Request) { func (fe *frontendServer) homeHandler(w http.ResponseWriter, r *http.Request) {
log.Printf("[home] session_id=%+v", r.Context().Value(ctxKeySessionID{})) log.Printf("[home] session_id=%+v", sessionID(r))
currencies, err := fe.getCurrencies(r.Context()) currencies, err := fe.getCurrencies(r.Context())
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, fmt.Sprintf("could not retrieve currencies: %+v", err), http.StatusInternalServerError)
return return
} }
products, err := fe.getProducts(r.Context()) products, err := fe.getProducts(r.Context())
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, fmt.Sprintf("could not retrieve products: %+v", err), http.StatusInternalServerError)
return
}
cart, err := fe.getCart(r.Context(), sessionID(r))
if err != nil {
http.Error(w, fmt.Sprintf("could not retrieve cart: %+v", err), http.StatusInternalServerError)
return return
} }
@ -76,7 +81,8 @@ func (fe *frontendServer) homeHandler(w http.ResponseWriter, r *http.Request) {
"user_currency": currentCurrency(r), "user_currency": currentCurrency(r),
"currencies": currencies, "currencies": currencies,
"products": ps, "products": ps,
"session_id": r.Context().Value(ctxKeySessionID{}), "session_id": sessionID(r),
"cart_size": len(cart),
}); err != nil { }); err != nil {
log.Println(err) log.Println(err)
} }
@ -97,7 +103,7 @@ func (fe *frontendServer) productHandler(w http.ResponseWriter, r *http.Request)
currencies, err := fe.getCurrencies(r.Context()) currencies, err := fe.getCurrencies(r.Context())
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, fmt.Sprintf("could not retrieve currencies: %+v", err), http.StatusInternalServerError)
return return
} }
@ -118,14 +124,14 @@ func (fe *frontendServer) productHandler(w http.ResponseWriter, r *http.Request)
"user_currency": currentCurrency(r), "user_currency": currentCurrency(r),
"currencies": currencies, "currencies": currencies,
"product": product, "product": product,
"session_id": r.Context().Value(ctxKeySessionID{}), "session_id": sessionID(r),
}); err != nil { }); err != nil {
log.Println(err) log.Println(err)
} }
} }
func (fe *frontendServer) logoutHandler(w http.ResponseWriter, r *http.Request) { func (fe *frontendServer) logoutHandler(w http.ResponseWriter, r *http.Request) {
log.Printf("[home] session_id=%+v", r.Context().Value(ctxKeySessionID{})) log.Printf("[home] session_id=%+v", sessionID(r))
for _, c := range r.Cookies() { for _, c := range r.Cookies() {
c.Expires = time.Now().Add(-time.Hour * 24 * 365) c.Expires = time.Now().Add(-time.Hour * 24 * 365)
c.MaxAge = -1 c.MaxAge = -1
@ -137,7 +143,7 @@ func (fe *frontendServer) logoutHandler(w http.ResponseWriter, r *http.Request)
func (fe *frontendServer) setCurrencyHandler(w http.ResponseWriter, r *http.Request) { func (fe *frontendServer) setCurrencyHandler(w http.ResponseWriter, r *http.Request) {
cur := r.FormValue("currency_code") cur := r.FormValue("currency_code")
log.Printf("[setCurrency] session_id=%+v code=%s", r.Context().Value(ctxKeySessionID{}), cur) log.Printf("[setCurrency] session_id=%+v code=%s", sessionID(r), cur)
if cur != "" { if cur != "" {
http.SetCookie(w, &http.Cookie{ http.SetCookie(w, &http.Cookie{
Name: cookieCurrency, Name: cookieCurrency,
@ -160,3 +166,11 @@ func currentCurrency(r *http.Request) string {
} }
return defaultCurrency return defaultCurrency
} }
func sessionID(r *http.Request) string {
v := r.Context().Value(ctxKeySessionID{})
if v != nil {
return v.(string)
}
return ""
}

View file

@ -50,7 +50,7 @@ func main() {
svc := new(frontendServer) svc := new(frontendServer)
mustMapEnv(&svc.productCatalogSvcAddr, "PRODUCT_CATALOG_SERVICE_ADDR") mustMapEnv(&svc.productCatalogSvcAddr, "PRODUCT_CATALOG_SERVICE_ADDR")
mustMapEnv(&svc.currencySvcAddr, "CURRENCY_SERVICE_ADDR") mustMapEnv(&svc.currencySvcAddr, "CURRENCY_SERVICE_ADDR")
// mustMapEnv(&svc.cartSvcAddr, "CART_SERVICE_ADDR") mustMapEnv(&svc.cartSvcAddr, "CART_SERVICE_ADDR")
var err error var err error
svc.currencySvcConn, err = grpc.DialContext(ctx, svc.currencySvcAddr, grpc.WithInsecure()) svc.currencySvcConn, err = grpc.DialContext(ctx, svc.currencySvcAddr, grpc.WithInsecure())
@ -61,6 +61,10 @@ func main() {
if err != nil { if err != nil {
log.Fatalf("failed to connect productcatalog service: %+v", err) log.Fatalf("failed to connect productcatalog service: %+v", err)
} }
svc.cartSvcConn, err = grpc.DialContext(ctx, svc.cartSvcAddr, grpc.WithInsecure())
if err != nil {
log.Fatalf("failed to connect cart service at %s: %+v", svc.cartSvcAddr, err)
}
r := mux.NewRouter() r := mux.NewRouter()
r.HandleFunc("/", ensureSessionID(svc.homeHandler)).Methods(http.MethodGet, http.MethodHead) r.HandleFunc("/", ensureSessionID(svc.homeHandler)).Methods(http.MethodGet, http.MethodHead)

View file

@ -3,7 +3,11 @@ package main
import ( import (
"context" "context"
"google.golang.org/grpc/codes"
pb "frontend/genproto" pb "frontend/genproto"
"google.golang.org/grpc/status"
) )
const ( const (
@ -37,6 +41,15 @@ func (fe *frontendServer) getProduct(ctx context.Context, id string) (*pb.Produc
return resp, err return resp, err
} }
func (fe *frontendServer) getCart(ctx context.Context, userID string) ([]*pb.CartItem, error) {
resp, err := pb.NewCartServiceClient(fe.cartSvcConn).GetCart(ctx, &pb.GetCartRequest{UserId: userID})
if status.Code(err) == codes.Canceled {
// TODO(ahmetb) remove this workaround when cartservice returns ok response to GetCart() with non-existing users
return nil, nil
}
return resp.GetItems(), err
}
func (fe *frontendServer) convertCurrency(ctx context.Context, money *pb.Money, currency string) (*pb.Money, error) { func (fe *frontendServer) convertCurrency(ctx context.Context, money *pb.Money, currency string) (*pb.Money, error) {
if avoidNoopCurrencyConversionRPC && money.GetCurrencyCode() == currency { if avoidNoopCurrencyConversionRPC && money.GetCurrencyCode() == currency {
return money, nil return money, nil

View file

@ -23,7 +23,7 @@
<option value="{{.}}" {{if eq . $.user_currency}}selected="selected"{{end}}>{{.}}</option> <option value="{{.}}" {{if eq . $.user_currency}}selected="selected"{{end}}>{{.}}</option>
{{end}} {{end}}
</select> </select>
<a class="btn btn-primary ml-1" href="/cart" role="button">View Cart</a> <a class="btn btn-primary ml-1" href="/cart" role="button">View Cart ({{$.cart_size}})</a>
</form> </form>
</div> </div>
</div> </div>

View file

@ -299,8 +299,16 @@ func testCartService() error {
defer conn.Close() defer conn.Close()
cl := pb.NewCartServiceClient(conn) cl := pb.NewCartServiceClient(conn)
log.Println("--- rpc AddItem()")
userID := "smoke-test-user" userID := "smoke-test-user"
log.Println("--- rpc GetCart()")
cartResp, err := cl.GetCart(context.TODO(), &pb.GetCartRequest{
UserId: userID})
if err != nil {
return err
}
log.Printf("--> %d items in cart for user %q", len(cartResp.Items), cartResp.UserId)
log.Println("--- rpc AddItem()")
_, err = cl.AddItem(context.TODO(), &pb.AddItemRequest{ _, err = cl.AddItem(context.TODO(), &pb.AddItemRequest{
UserId: userID, UserId: userID,
Item: &pb.CartItem{ProductId: "1", Quantity: 2}, Item: &pb.CartItem{ProductId: "1", Quantity: 2},
@ -319,14 +327,13 @@ func testCartService() error {
log.Printf("--> added item") log.Printf("--> added item")
log.Println("--- rpc GetCart()") log.Println("--- rpc GetCart()")
cartResp, err := cl.GetCart(context.TODO(), &pb.GetCartRequest{ cartResp, err = cl.GetCart(context.TODO(), &pb.GetCartRequest{
UserId: userID}) UserId: userID})
if err != nil { if err != nil {
return err return err
} }
log.Printf("--> %d items in cart for user %q", len(cartResp.Items), cartResp.UserId) log.Printf("--> %d items in cart for user %q", len(cartResp.Items), cartResp.UserId)
log.Printf("--> cart: %v", cartResp.Items) log.Printf("--> cart: %v", cartResp.Items)
log.Println("--- rpc EmptyCart()") log.Println("--- rpc EmptyCart()")
_, err = cl.EmptyCart(context.TODO(), &pb.EmptyCartRequest{ _, err = cl.EmptyCart(context.TODO(), &pb.EmptyCartRequest{
UserId: userID}) UserId: userID})