Skip to content

Commit

Permalink
Rebrand Hipstershop as OnlineBoutique (#328)
Browse files Browse the repository at this point in the history
* update productcatalog, frontend, readme

* revert productcatalog

* restore currency logic and ad display

* footer cleanup

* Resize header image

* screenshots

* Center align header image in readme

* Show platform flag on every page

* style fixes

* fix currency in UI, remove extra USD

* cart bug, fixing

* attempt to fix breaking build

* fix cart size in handler

* replace images

* # items in cart is total quantity

* Add link to 0.1.4 manifests in readme
  • Loading branch information
askmeegs committed Apr 23, 2020
1 parent 5aa38ad commit 814088f
Show file tree
Hide file tree
Showing 47 changed files with 1,617 additions and 248 deletions.
19 changes: 13 additions & 6 deletions README.md
@@ -1,7 +1,12 @@
# Hipster Shop: Cloud-Native Microservices Demo Application
<p align="center">
<img src="src/frontend/static/icons/Hipster_HeroLogoCyan.svg" width="300"/>
</p>

This project contains a 10-tier microservices application. The application is a
web-based e-commerce app called **“Hipster Shop”** where users can browse items,


**Online Boutique** is a cloud-native microservices demo application.
Online Boutique consists of a 10-tier microservices application. The application is a
web-based e-commerce app where users can browse items,
add them to the cart, and purchase them.

**Google uses this application to demonstrate use of technologies like
Expand All @@ -15,15 +20,17 @@ If you’re using this demo, please **★Star** this repository to show your int
> [go/microservices-demo](http://go/microservices-demo) if you are using this
> application.
Looking for the old Hipster Shop frontend interface? Use the [manifests](https://github.com/GoogleCloudPlatform/microservices-demo/tree/v0.1.4/kubernetes-manifests) in release [v0.1.4](https://github.com/GoogleCloudPlatform/microservices-demo/releases/v0.1.4).

## Screenshots

| Home Page | Checkout Screen |
| ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| [![Screenshot of store homepage](./docs/img/hipster-shop-frontend-1.png)](./docs/img/hipster-shop-frontend-1.png) | [![Screenshot of checkout screen](./docs/img/hipster-shop-frontend-2.png)](./docs/img/hipster-shop-frontend-2.png) |
| [![Screenshot of store homepage](./docs/img/online-boutique-frontend-1.png)](./docs/img/online-boutique-frontend-1.png) | [![Screenshot of checkout screen](./docs/img/online-boutique-frontend-2.png)](./docs/img/online-boutique-frontend-2.png) |

## Service Architecture

**Hipster Shop** is composed of many microservices written in different
**Online Boutique** is composed of many microservices written in different
languages that talk to each other over gRPC.

[![Architecture of
Expand Down Expand Up @@ -310,7 +317,7 @@ If you've deployed the application with `kubectl apply -f [...]`, you can
run `kubectl delete -f [...]` with the same argument to clean up the deployed
resources.

## Conferences featuring Hipster Shop
## Conferences featuring Online Boutique

- [Google Cloud Next'18 London – Keynote](https://youtu.be/nIq2pkNcfEI?t=3071)
showing Stackdriver Incident Response Management
Expand Down
Binary file removed docs/img/hipster-shop-frontend-1.png
Binary file not shown.
Binary file removed docs/img/hipster-shop-frontend-2.png
Binary file not shown.
Binary file added docs/img/online-boutique-frontend-1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/online-boutique-frontend-2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions kubernetes-manifests/frontend.yaml
Expand Up @@ -65,6 +65,8 @@ spec:
value: "checkoutservice:5050"
- name: AD_SERVICE_ADDR
value: "adservice:9555"
- name: ENV_PLATFORM
value: "gcp"
# - name: DISABLE_TRACING
# value: "1"
# - name: DISABLE_PROFILER
Expand Down
62 changes: 58 additions & 4 deletions src/frontend/handlers.go
Expand Up @@ -22,6 +22,7 @@ import (
"net/http"
"os"
"strconv"
"strings"
"time"

"github.com/gorilla/mux"
Expand All @@ -32,11 +33,17 @@ import (
"github.com/GoogleCloudPlatform/microservices-demo/src/frontend/money"
)

type platformDetails struct {
css string
provider string
}

var (
templates = template.Must(template.New("").
Funcs(template.FuncMap{
Funcs(template.FuncMap{
"renderMoney": renderMoney,
}).ParseGlob("templates/*.html"))
plat platformDetails
)

func (fe *frontendServer) homeHandler(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -72,20 +79,43 @@ func (fe *frontendServer) homeHandler(w http.ResponseWriter, r *http.Request) {
ps[i] = productView{p, price}
}

//get env and render correct platform banner.
var env = os.Getenv("ENV_PLATFORM")
plat = platformDetails{}
plat.setPlatformDetails(strings.ToLower(env))

if err := templates.ExecuteTemplate(w, "home", map[string]interface{}{
"session_id": sessionID(r),
"request_id": r.Context().Value(ctxKeyRequestID{}),
"user_currency": currentCurrency(r),
"currencies": currencies,
"products": ps,
"cart_size": len(cart),
"cart_size": cartSize(cart),
"banner_color": os.Getenv("BANNER_COLOR"), // illustrates canary deployments
"ad": fe.chooseAd(r.Context(), []string{}, log),
"platform_css": plat.css,
"platform_name": plat.provider,
}); err != nil {
log.Error(err)
}
}

func (plat *platformDetails) setPlatformDetails(env string) {
if env == "aws" {
plat.provider = "AWS"
plat.css = "aws-platform"
} else if env == "onprem" {
plat.provider = "On-Premises"
plat.css = "onprem-platform"
} else if env == "azure" {
plat.provider = "Azure"
plat.css = "azure-platform"
} else {
plat.provider = "Google Cloud"
plat.css = "gcp-platform"
}
}

func (fe *frontendServer) productHandler(w http.ResponseWriter, r *http.Request) {
log := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger)
id := mux.Vars(r)["id"]
Expand Down Expand Up @@ -138,7 +168,9 @@ func (fe *frontendServer) productHandler(w http.ResponseWriter, r *http.Request)
"currencies": currencies,
"product": product,
"recommendations": recommendations,
"cart_size": len(cart),
"cart_size": cartSize(cart),
"platform_css": plat.css,
"platform_name": plat.provider,
}); err != nil {
log.Println(err)
}
Expand Down Expand Up @@ -234,18 +266,22 @@ func (fe *frontendServer) viewCartHandler(w http.ResponseWriter, r *http.Request
}
totalPrice = money.Must(money.Sum(totalPrice, *shippingCost))

log.Info("🌈 ITEMS: %v", items)

year := time.Now().Year()
if err := templates.ExecuteTemplate(w, "cart", map[string]interface{}{
"session_id": sessionID(r),
"request_id": r.Context().Value(ctxKeyRequestID{}),
"user_currency": currentCurrency(r),
"currencies": currencies,
"recommendations": recommendations,
"cart_size": len(cart),
"cart_size": cartSize(cart),
"shipping_cost": shippingCost,
"total_cost": totalPrice,
"items": items,
"expiration_years": []int{year, year + 1, year + 2, year + 3, year + 4},
"platform_css": plat.css,
"platform_name": plat.provider,
}); err != nil {
log.Println(err)
}
Expand Down Expand Up @@ -299,13 +335,22 @@ func (fe *frontendServer) placeOrderHandler(w http.ResponseWriter, r *http.Reque
totalPaid = money.Must(money.Sum(totalPaid, *v.GetCost()))
}

currencies, err := fe.getCurrencies(r.Context())
if err != nil {
renderHTTPError(log, r, w, errors.Wrap(err, "could not retrieve currencies"), http.StatusInternalServerError)
return
}

if err := templates.ExecuteTemplate(w, "order", map[string]interface{}{
"session_id": sessionID(r),
"request_id": r.Context().Value(ctxKeyRequestID{}),
"user_currency": currentCurrency(r),
"currencies": currencies,
"order": order.GetOrder(),
"total_paid": &totalPaid,
"recommendations": recommendations,
"platform_css": plat.css,
"platform_name": plat.provider,
}); err != nil {
log.Println(err)
}
Expand Down Expand Up @@ -392,6 +437,15 @@ func cartIDs(c []*pb.CartItem) []string {
return out
}

// get total # of items in cart
func cartSize(c []*pb.CartItem) int {
cartSize := 0
for _, item := range c {
cartSize += int(item.GetQuantity())
}
return cartSize
}

func renderMoney(money pb.Money) string {
return fmt.Sprintf("%s %d.%02d", money.GetCurrencyCode(), money.GetUnits(), money.GetNanos()/10000000)
}
Binary file added src/frontend/static/favicon.ico
Binary file not shown.

0 comments on commit 814088f

Please sign in to comment.