From 97e7bd2f92b417f5fabbc42cd3218dd67bca867c Mon Sep 17 00:00:00 2001 From: madhead Date: Sun, 20 Nov 2022 05:28:14 +0100 Subject: [PATCH] Fix #586: Pass product's `categories` as an input for the Ad service --- CHANGELOG.md | 2 ++ src/frontend/components/Ad/Ad.tsx | 5 ++--- src/frontend/gateways/Api.gateway.ts | 4 ++-- src/frontend/gateways/rpc/Ad.gateway.ts | 4 ++-- src/frontend/pages/api/data.ts | 4 ++-- .../pages/cart/checkout/[orderId]/index.tsx | 11 +++++++++-- src/frontend/pages/cart/index.tsx | 5 ++++- .../pages/product/[productId]/index.tsx | 13 +++++++++++-- src/frontend/providers/Ad.provider.tsx | 19 +++++++++++++++---- src/frontend/tsconfig.json | 2 +- src/loadgenerator/locustfile.py | 10 +++++++++- 11 files changed, 59 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 865de2a372..bf5b05b289 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -142,3 +142,5 @@ significant modifications will be credited to OpenTelemetry Authors. ([#583](https://github.com/open-telemetry/opentelemetry-demo/pull/583)) * Change ZipCode data type from int to string ([#587](https://github.com/open-telemetry/opentelemetry-demo/pull/587)) +* Pass product's `categories` as an input for the Ad service +([#600](https://github.com/open-telemetry/opentelemetry-demo/pull/600)) diff --git a/src/frontend/components/Ad/Ad.tsx b/src/frontend/components/Ad/Ad.tsx index 4c480296da..ec705037c2 100644 --- a/src/frontend/components/Ad/Ad.tsx +++ b/src/frontend/components/Ad/Ad.tsx @@ -3,9 +3,8 @@ import { useAd } from '../../providers/Ad.provider'; import * as S from './Ad.styled'; const Ad = () => { - const { - adList: [{ text, redirectUrl } = { text: '', redirectUrl: '' }], - } = useAd(); + const { adList } = useAd(); + const { text, redirectUrl } = adList[Math.floor(Math.random() * adList.length)] || { text: '', redirectUrl: '' }; return ( diff --git a/src/frontend/gateways/Api.gateway.ts b/src/frontend/gateways/Api.gateway.ts index 1b754084d3..407ab98b29 100644 --- a/src/frontend/gateways/Api.gateway.ts +++ b/src/frontend/gateways/Api.gateway.ts @@ -78,11 +78,11 @@ const ApiGateway = () => ({ }, }); }, - listAds(productIds: string[]) { + listAds(contextKeys: string[]) { return request({ url: `${basePath}/data`, queryParams: { - productIds, + contextKeys, }, }); }, diff --git a/src/frontend/gateways/rpc/Ad.gateway.ts b/src/frontend/gateways/rpc/Ad.gateway.ts index 84d4e069c9..8a640888ae 100644 --- a/src/frontend/gateways/rpc/Ad.gateway.ts +++ b/src/frontend/gateways/rpc/Ad.gateway.ts @@ -6,9 +6,9 @@ const { AD_SERVICE_ADDR = '' } = process.env; const client = new AdServiceClient(AD_SERVICE_ADDR, ChannelCredentials.createInsecure()); const AdGateway = () => ({ - listAds(productIds: string[]) { + listAds(contextKeys: string[]) { return new Promise((resolve, reject) => - client.getAds({ contextKeys: productIds }, (error, response) => (error ? reject(error) : resolve(response))) + client.getAds({ contextKeys: contextKeys }, (error, response) => (error ? reject(error) : resolve(response))) ); }, }); diff --git a/src/frontend/pages/api/data.ts b/src/frontend/pages/api/data.ts index 69662ebdc8..071d31d7ae 100644 --- a/src/frontend/pages/api/data.ts +++ b/src/frontend/pages/api/data.ts @@ -8,8 +8,8 @@ type TResponse = Ad[] | Empty; const handler = async ({ method, query }: NextApiRequest, res: NextApiResponse) => { switch (method) { case 'GET': { - const { productIds = [] } = query; - const { ads: adList } = await AdGateway.listAds(productIds as string[]); + const { contextKeys = [] } = query; + const { ads: adList } = await AdGateway.listAds(Array.isArray(contextKeys) ? contextKeys : contextKeys.split(',')); return res.status(200).json(adList); } diff --git a/src/frontend/pages/cart/checkout/[orderId]/index.tsx b/src/frontend/pages/cart/checkout/[orderId]/index.tsx index 84eb46ee42..7778eb7d25 100644 --- a/src/frontend/pages/cart/checkout/[orderId]/index.tsx +++ b/src/frontend/pages/cart/checkout/[orderId]/index.tsx @@ -16,7 +16,10 @@ const Checkout: NextPage = () => { const { items = [], shippingAddress } = JSON.parse((query.order || '{}') as string) as IProductCheckout; return ( - item?.productId || '')}> + item?.productId || '')} + contextKeys={[...new Set(items.flatMap(({ item }) => item.product.categories))]} + > @@ -25,7 +28,11 @@ const Checkout: NextPage = () => { {items.map(checkoutItem => ( - + ))} diff --git a/src/frontend/pages/cart/index.tsx b/src/frontend/pages/cart/index.tsx index 7e30e565ba..0735fe5e42 100644 --- a/src/frontend/pages/cart/index.tsx +++ b/src/frontend/pages/cart/index.tsx @@ -14,7 +14,10 @@ const Cart: NextPage = () => { } = useCart(); return ( - productId)}> + productId)} + contextKeys={[...new Set(items.flatMap(({ product }) => product.categories))]} + > {(!!items.length && ) || } diff --git a/src/frontend/pages/product/[productId]/index.tsx b/src/frontend/pages/product/[productId]/index.tsx index 8da41d1750..3fbd8d095c 100644 --- a/src/frontend/pages/product/[productId]/index.tsx +++ b/src/frontend/pages/product/[productId]/index.tsx @@ -30,7 +30,13 @@ const ProductDetail: NextPage = () => { const productId = query.productId as string; const { - data: { name, picture, description, priceUsd = { units: 0, currencyCode: 'USD', nanos: 0 } } = {} as Product, + data: { + name, + picture, + description, + priceUsd = { units: 0, currencyCode: 'USD', nanos: 0 }, + categories, + } = {} as Product, } = useQuery( ['product', productId, 'selectedCurrency', selectedCurrency], () => ApiGateway.getProduct(productId, selectedCurrency), @@ -48,7 +54,10 @@ const ProductDetail: NextPage = () => { }, [addItem, productId, quantity, push]); return ( - productId)]}> + productId)]} + contextKeys={[...new Set(categories)]} + > diff --git a/src/frontend/providers/Ad.provider.tsx b/src/frontend/providers/Ad.provider.tsx index c78647b9d2..092b319ae2 100644 --- a/src/frontend/providers/Ad.provider.tsx +++ b/src/frontend/providers/Ad.provider.tsx @@ -17,15 +17,26 @@ export const Context = createContext({ interface IProps { children: React.ReactNode; productIds: string[]; + contextKeys: string[]; } export const useAd = () => useContext(Context); -const AdProvider = ({ children, productIds }: IProps) => { +const AdProvider = ({ children, productIds, contextKeys }: IProps) => { const { selectedCurrency } = useCurrency(); - const { data: adList = [] } = useQuery(['ads', productIds], () => ApiGateway.listAds(productIds), { - refetchOnWindowFocus: false, - }); + const { data: adList = [] } = useQuery( + ['ads', contextKeys], + () => { + if (contextKeys.length === 0) { + return Promise.resolve([]); + } else { + return ApiGateway.listAds(contextKeys); + } + }, + { + refetchOnWindowFocus: false, + } + ); const { data: recommendedProductList = [] } = useQuery( ['recommendations', productIds, 'selectedCurrency', selectedCurrency], () => ApiGateway.listRecommendations(productIds, selectedCurrency), diff --git a/src/frontend/tsconfig.json b/src/frontend/tsconfig.json index 99710e8578..434562d893 100755 --- a/src/frontend/tsconfig.json +++ b/src/frontend/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es5", + "target": "ES2015", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, diff --git a/src/loadgenerator/locustfile.py b/src/loadgenerator/locustfile.py index afcf29cb78..9fccce597f 100644 --- a/src/loadgenerator/locustfile.py +++ b/src/loadgenerator/locustfile.py @@ -33,6 +33,14 @@ RequestsInstrumentor().instrument() URLLib3Instrumentor().instrument() +categories = [ + "binoculars", + "telescopes", + "accessories", + "assembly", + "travel", +] + products = [ "0PUK6V6EV0", "1YMWWN1N4O", @@ -223,7 +231,7 @@ def get_recommendations(self): @task(3) def get_ads(self): params = { - "productIds": [random.choice(products)], + "contextKeys": [random.choice(categories)], } self.client.get("/api/data/", params=params)