Skip to content

Are you building or do you support an e-commerce website? If so, then this content is for you! Worldwide digital sales in 2020 eclipsed four trillion dollars (USD). Businesses that want to compete, need a high performing e-commerce website. Here, we will demonstrate how to build a high performing persistence layer with DataStax ASTRA DB.

Notifications You must be signed in to change notification settings

datastaxdevs/workshop-ecommerce-app

Repository files navigation

πŸ”₯ Building an E-commerce Website πŸ”₯

Gitpod ready-to-code License Apache2 Discord

Materials for the Session

It doesn't matter if you join our workshop live or you prefer to do at your own pace, we have you covered. In this repository, you'll find everything you need for this workshop:

If you cannot attend this workshop live, recordings of this workshop and many more is available on Youtube.

Homework

Complete the homework to earn the badge for this workshop (awarded only at the end of the series).

  1. Implement Google login and take SCREENSHOT(s).
  2. Don't worry about submitting it just yet. We'll have instructions on how to do that at the end of the series!

πŸ“‹ Table of contents

  1. Introduction
  2. Create your Database
  3. Create your schema
  4. Populate the dataset
  5. Create a token
  6. Setup your application
  7. Enable Social Login
  8. Run Unit Tests
  9. Start the Application

1. Introduction

Are you building or do you support an e-commerce website? If so, then this content is for you!

Worldwide digital sales in 2020 eclipsed four trillion dollars (USD). Businesses that want to compete, need a high performing e-commerce website. Here, we will demonstrate how to build a high performing persistence layer with DataStax ASTRA DB.

Why does an e-commerce site need to be fast? Because most consumers will leave a web page or a mobile app if it takes longer than a few seconds to load. In the content below, we will cover how to build high-performing data models and services, helping you to build a e-commerce site with high throughput and low latency.

2. Create Astra DB and Streaming Instances

You can skip to step 2c if you have already created a keyspace ecommerce in database demos. Otherwise (if you did not attend the previous installment of the e-commerce worksop):

ASTRA DB is the simplest way to run Cassandra with zero operations - just push the button and get your cluster. No credit card required, $25.00 USD credit every month, roughly 20M read/write operations, 80GB storage monthly - sufficient to run small production workloads.

βœ… 2a. Register

If you do not have an account yet, register and sign in to Astra DB: This is FREE and NO CREDIT CARD is required. https://astra.datastax.com: You can use your Github, Google accounts or register with an email.

Make sure to chose a password with minimum 8 characters, containing upper and lowercase letters, at least one number and special character

βœ… 2b. Create a DB on the "FREE" plan

Follow this guide, to set up a pay as you go database with a free $25 monthly credit. You will find below recommended values to enter:

  • For the database name - demos

  • For the keyspace name - ecommerce

You can technically use whatever name(s) you want and update the code to reflect the keyspace. This is really to get you on a happy path for the first run.

  • For provider and region: For Astra DB, select GCP as a provider and then the related region is where your database will reside physically (choose one close to you or your users).

  • Create the database. Review all the fields to make sure they are as shown, and click the Create Database button.

πŸ‘οΈ Walkthrough

The Walkthrough mentions a different keyspace, make sure to use ecommerce

image You will see your new database pending in the Dashboard.

my-pic

βœ… 2c. Ensure the database turns to active state

To connect to the database programmatically, you need to make sure the status will change to Active. This happens when the database is ready, and will only take 2-3 minutes. You will also receive an email when it is ready.

πŸ‘οΈ Expected Output

my-pic

If it's in a standby state you can hit Connect and CQL Console on top.

You should see a message something like below.

πŸ‘οΈ Expected Output

{"message":"Resuming your database, please try again shortly."}

βœ… 2d. Create a Streaming Tenant and Topics on the "FREE" plan

Here we will walk through how to create an Astra Streaming Tenant. Start by clicking the "Create Stream" button in the left navigation pane.

image

On the next page, provide a name for your tenant and select a provider/region. Click the blue "Create Tenant" button when complete.

image

Note that Tenant Names must be unique across providers. To ensure uniqueness, name it "ecommerce-" followed by your name or company.

Now we need to create topics within our tenant. Click on the link or on the "Topics" tab. You should see the "default" namespace with an "Add Topic" button (on the right). Click the "Add Topic" button.

image

Name the topic "pending-orders" and make sure that the "Persistent" switch is selected. Don't worry about the "Partitioned" switch for now. Click the "Add Topic" button when ready.

image

Repeat this process to add 3 more topics:

  • picked-orders
  • shipped-orders
  • completed-orders

When you are done, your "Topics" tab should look similar to this:

image

🏠 Back to Table of Contents

3. Create your schema

Introduction This section will provide DDL to create three tables inside the "ecommerce" keyspace: category, price, and product.

Session 1 - Product data model

The product table supports all product data queries, and uses product_id as a single key. It has a few columns for specific product data, but any ad-hoc or non-standard properties can be added to the specifications map.

The category table will support all product navigation service calls. It is designed to provide recursive, hierarchical navigation without a pre-set limit on the number of levels. The top-most level only exists as a parent_id, and the bottom-most level contains products.

The price table was intentionally split-off from product. There are several reasons for this. Price data is much more likely to change than pure product data (different read/write patterns). Also, large enterprises typically have separate teams for product and price, meaning they will usually have different micro-service layers and data stores.

The featured_product_groups table was a late-add, to be able to provide some extra "atmosphere" of an e-commerce website. This way, the UI has a means by which to highlight a few, select products.

Session 2 - Shopping Cart data model

The user_carts table supports cart metadata. Carts are not expected to be long-lived, so they have a default TTL (time to live) of 60 days (5,184,000 seconds). Carts also have a name as a part of the key, so that the user can have multiple carts (think "wish lists").

The cart_products table holds data on the products added to the cart. The cart uses product_timestamp as the first clustering key in descending order; this way products in the cart will be listed with the most-recently-added products at the top. Like user_carts, each entry has a 60 day TTL.

Session 3 - User Profile data model

The user table holds all data on the user, keyed by a single PRIMARY KEY on user_id. It's main features contain TEXT (string) data for common user properties, as well as a collection of addresses. This is because users (especially B-to-B) may have multiple addresses (mail-to, ship-to, bill-to, etc). The addresses collection is built on a special user defined type (UDT) and FROZEN to treat the collection as a Binary Large OBject (BLOB) to reduce tombstones (required by CQL).

As mentioned above, the address UDT contains properties used for postal contacts. All properties are of the TEXT datatype.

The user_by_email table is intended to be used as a "manual index" on email address. Essentially, it is a lookup table returning the user_id associated with an email address. This is necessary as user_email is nigh-unique (in terms of cardinality of values), and thus a CQL secondary index would perform quite poorly.

Session 4 - Order Processing System data model

The order_by_id table holds detail on each order. It partitions on order_id for optimal data distribution, and clusters on product_name and product_id for sort order. The columns specific to the order itself (and not a product) are STATIC so that they are only stored once (with the partition key).

The order_by_user table holds a reference to each order by user_id. The idea, is that this table is queried by user_id and the results are shown on an "order history" page for that user. Then, each order can be clicked-on, revealing the detail contained in the order_by_id table. order_id is a TimeUUID (version 1 UUID) type, which is converted into a human-readable timestamp in the service layer.

The order_status_history table maintains a history of each status for an order. It is meant to be used with queries to the order_by_id table, so that a user may see the status progression of their order.

βœ… 3a. Open the CqlConsole on Astra

use ecommerce;

βœ… 3b. Execute the following CQL script to create the schema

/* Session 1 - Product data model */
/* category table */
CREATE TABLE IF NOT EXISTS category (
    parent_id UUID,
    category_id UUID,
    name TEXT,
    image TEXT,
    products LIST<TEXT>,
PRIMARY KEY (parent_id,category_id));

/* price table */
CREATE TABLE IF NOT EXISTS price (
    product_id TEXT,
    store_id TEXT,
    value DECIMAL,
PRIMARY KEY(product_id,store_id));

/* product table */
CREATE TABLE IF NOT EXISTS product (
    product_id TEXT,
    product_group TEXT,
    name TEXT,
    brand TEXT,
    model_number TEXT,
    short_desc TEXT,
    long_desc TEXT,
    specifications MAP<TEXT,TEXT>,
    linked_documents MAP<TEXT,TEXT>,
    images SET<TEXT>,
PRIMARY KEY(product_id));

/* featured product groups table */
CREATE TABLE IF NOT EXISTS featured_product_groups (
    feature_id INT,
    category_id UUID,
    name TEXT,
    image TEXT,
    parent_id UUID,
    price DECIMAL,
PRIMARY KEY (feature_id,category_id));

/* Session 2 - Shopping Cart data model */
CREATE TABLE IF NOT EXISTS user_carts (
    user_id uuid,
    cart_name text,
    cart_id uuid,
    cart_is_active boolean,
    user_email text,
    PRIMARY KEY (user_id, cart_name, cart_id)
) WITH default_time_to_live = 5184000;

CREATE TABLE IF NOT EXISTS cart_products (
    cart_id uuid,
    product_timestamp timestamp,
    product_id text,
    product_description text,
    product_name text,
    quantity int,
    PRIMARY KEY (cart_id, product_timestamp, product_id)
) WITH CLUSTERING ORDER BY (product_timestamp DESC, product_id ASC)
  AND default_time_to_live = 5184000;

/* Session 3 - User Profile data model */
CREATE TYPE IF NOT EXISTS address (
  type TEXT,
  mailto_name TEXT,
  street TEXT,
  street2 TEXT,
  city TEXT,
  state_province TEXT,
  postal_code TEXT,
  country TEXT
);

CREATE TABLE IF NOT EXISTS user (
  user_id UUID,
  user_email TEXT,
  picture_url TEXT,
  first_name TEXT,
  last_name TEXT,
  locale TEXT,
  addresses LIST<FROZEN<address>>,
  session_id TEXT,
  password TEXT,
  password_timestamp TIMESTAMP,
  PRIMARY KEY (user_id)
);

CREATE TABLE IF NOT EXISTS user_by_email (
  user_email TEXT PRIMARY KEY,
  user_id UUID
);

/* Session 4 - Order Processing System data model */
CREATE TABLE IF NOT EXISTS order_by_id (
    order_id timeuuid,
    product_name text,
    product_id text,
    order_shipping_handling decimal static,
    order_status text static,
    order_subtotal decimal static,
    order_tax decimal static,
    order_total decimal static,
    payment_method text static,
    product_price decimal,
    product_qty int,
    shipping_address address static,
    PRIMARY KEY (order_id, product_name, product_id)
) WITH CLUSTERING ORDER BY (product_name ASC, product_id ASC);

CREATE TABLE IF NOT EXISTS order_by_user (
    user_id uuid,
    order_id timeuuid,
    order_status text,
    order_total decimal,
    PRIMARY KEY (user_id, order_id)
) WITH CLUSTERING ORDER BY (order_id DESC);

CREATE TABLE IF NOT EXISTS order_status_history (
    order_id timeuuid,
    status_timestamp timestamp,
    order_status text,
    PRIMARY KEY (order_id, status_timestamp)
) WITH CLUSTERING ORDER BY (status_timestamp DESC);

🏠 Back to Table of Contents

4. Populate the Data

βœ… 4a. Execute the following script to populate the tables with the data below

Session 1 - Product data

INSERT INTO category (name,category_id,image,parent_id) VALUES ('Clothing',18105592-77aa-4469-8556-833b419dacf4,'ls534.png',ffdac25a-0244-4894-bb31-a0884bc82aa9);
INSERT INTO category (name,category_id,image,parent_id) VALUES ('Tech Accessories',5929e846-53e8-473e-8525-80b666c46a83,'',ffdac25a-0244-4894-bb31-a0884bc82aa9);
INSERT INTO category (name,category_id,image,parent_id) VALUES ('Cups and Mugs',675cf3a2-2752-4de7-ae2e-849471c29f51,'',ffdac25a-0244-4894-bb31-a0884bc82aa9);
INSERT INTO category (name,category_id,image,parent_id) VALUES ('Wall Decor',591bf485-de09-4b46-8fd2-5d9dc7ca101e,'bh001.png',ffdac25a-0244-4894-bb31-a0884bc82aa9);
INSERT INTO category (name,category_id,image,parent_id) VALUES ('T-Shirts',91455473-212e-4c6e-8bec-1da06779ae10,'ls534.png',18105592-77aa-4469-8556-833b419dacf4);
INSERT INTO category (name,category_id,image,parent_id) VALUES ('Hoodies',6a4d86aa-ceb5-4c6f-b9b9-80e9a8c58ad1,'',18105592-77aa-4469-8556-833b419dacf4);
INSERT INTO category (name,category_id,image,parent_id) VALUES ('Jackets',d887b049-d16c-46e1-8c94-0a1280dedc30,'',18105592-77aa-4469-8556-833b419dacf4);
INSERT INTO category (name,category_id,image,parent_id) VALUES ('Mousepads',d04dfb5b-69c6-4e97-b572-e9e390165a84,'',5929e846-53e8-473e-8525-80b666c46a83);
INSERT INTO category (name,category_id,image,parent_id) VALUES ('Wrist Rests',aa161129-d456-45ba-b1f0-fac7898b6d06,'',5929e846-53e8-473e-8525-80b666c46a83);
INSERT INTO category (name,category_id,image,parent_id) VALUES ('Laptop Covers',1c4b8599-78df-4f93-9c52-578bd959a3a5,'',5929e846-53e8-473e-8525-80b666c46a83);
INSERT INTO category (name,category_id,image,parent_id) VALUES ('Cups',7536fdef-fcd9-44a3-9360-0bffd2904408,'',675cf3a2-2752-4de7-ae2e-849471c29f51);
INSERT INTO category (name,category_id,image,parent_id) VALUES ('Coffee Mugs',20374300-185c-4ee5-b0bc-77fbdc3a21ed,'',675cf3a2-2752-4de7-ae2e-849471c29f51);
INSERT INTO category (name,category_id,image,parent_id) VALUES ('Travel Mugs',0660483e-2fad-447b-b19a-63ab4935e482,'',675cf3a2-2752-4de7-ae2e-849471c29f51);
INSERT INTO category (name,category_id,image,parent_id) VALUES ('Posters',fdbe9dcb-6878-4216-a64d-27c094b1b075,'',591bf485-de09-4b46-8fd2-5d9dc7ca101e);
INSERT INTO category (name,category_id,image,parent_id) VALUES ('Wall Art',943482f9-070c-4390-bb30-2107b6fe653a,'bh001.png',591bf485-de09-4b46-8fd2-5d9dc7ca101e);
INSERT INTO category (name,category_id,image,parent_id,products) VALUES ('Men''s "Go Away...Annotation" T-Shirt',99c4d825-d262-4a95-a04e-cc72e7e273c1,'ls534.png',91455473-212e-4c6e-8bec-1da06779ae10,['LS534S','LS534M','LS534L','LS534XL','LS5342XL','LS5343XL']);
INSERT INTO category (name,category_id,image,parent_id,products) VALUES ('Men''s "Your Face...Autowired" T-Shirt',3fa13eee-d057-48d0-b0ae-2d83af9e3e3e,'ln355.png',91455473-212e-4c6e-8bec-1da06779ae10,['LN355S','LN355M','LN355L','LN355XL','LN3552XL','LN3553XL']);
INSERT INTO category (name,category_id,image,parent_id,products) VALUES ('Bigheads',2f25a732-0744-406d-baee-3e8131cbe500,'bh001.png',943482f9-070c-4390-bb30-2107b6fe653a,['bh001','bh002','bh003']);
INSERT INTO category (name,category_id,image,parent_id,products) VALUES ('DataStax Gray Track Jacket',f629e107-b219-4563-a852-6909fd246949,'dss821.jpg',d887b049-d16c-46e1-8c94-0a1280dedc30,['DSS821S','DSS821M','DSS821L','DSS821XL']);
INSERT INTO category (name,category_id,image,parent_id,products) VALUES ('DataStax Vintage 2015 MVP Hoodie',86d234a4-6b97-476c-ada8-efb344d39743,'dsh915.jpg',6a4d86aa-ceb5-4c6f-b9b9-80e9a8c58ad1,['DSH915S','DSH915M','DSH915L','DSH915XL']);
INSERT INTO category (name,category_id,image,parent_id,products) VALUES ('DataStax Black Hoodie',b9bed3c0-0a76-44ea-bce6-f5f21611a3f1,'dsh916.jpg',6a4d86aa-ceb5-4c6f-b9b9-80e9a8c58ad1,['DSH916S','DSH916M','DSH916L','DSH916XL']);
INSERT INTO category (name,category_id,image,parent_id,products) VALUES ('Apache Cassandra 3.0 Contributor T-Shirt',95ae4613-0184-46ee-b4b0-adfe882754a8,'apc30a.jpg',91455473-212e-4c6e-8bec-1da06779ae10,['APC30S','APC30M','APC30L','APC30XL','APC302XL','APC303XL']);
INSERT INTO category (name,category_id,image,parent_id,products) VALUES ('DataStax Astra "One Team" Long Sleeve Tee',775be203-1a84-4822-9645-4da98ca2b2d8,'dsa1121.jpg',91455473-212e-4c6e-8bec-1da06779ae10,['DSA1121S','DSA1121M','DSA1121L','DSA1121XL','DSA11212XL','DSA11213XL']);

INSERT INTO price(product_id,store_id,value) VALUES ('LS534S','web',14.99);
INSERT INTO price(product_id,store_id,value) VALUES ('LS534M','web',14.99);
INSERT INTO price(product_id,store_id,value) VALUES ('LS534L','web',14.99);
INSERT INTO price(product_id,store_id,value) VALUES ('LS534XL','web',14.99);
INSERT INTO price(product_id,store_id,value) VALUES ('LS5342XL','web',16.99);
INSERT INTO price(product_id,store_id,value) VALUES ('LS5343XL','web',16.99);
INSERT INTO price(product_id,store_id,value) VALUES ('LN355S','web',14.99);
INSERT INTO price(product_id,store_id,value) VALUES ('LN355M','web',14.99);
INSERT INTO price(product_id,store_id,value) VALUES ('LN355L','web',14.99);
INSERT INTO price(product_id,store_id,value) VALUES ('LN355XL','web',14.99);
INSERT INTO price(product_id,store_id,value) VALUES ('LN3552XL','web',16.99);
INSERT INTO price(product_id,store_id,value) VALUES ('LN3553XL','web',16.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSA1121S','web',21.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSA1121M','web',21.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSA1121L','web',21.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSA1121XL','web',21.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSA11212XL','web',23.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSA11213XL','web',23.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSS821S','web',44.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSS821M','web',44.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSS821L','web',44.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSS821XL','web',44.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSH915S','web',35.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSH915M','web',35.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSH915L','web',35.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSH915XL','web',35.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSH916S','web',35.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSH916M','web',35.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSH916L','web',35.99);
INSERT INTO price(product_id,store_id,value) VALUES ('DSH916XL','web',35.99);
INSERT INTO price(product_id,store_id,value) VALUES ('APC30S','web',15.99);
INSERT INTO price(product_id,store_id,value) VALUES ('APC30M','web',15.99);
INSERT INTO price(product_id,store_id,value) VALUES ('APC30L','web',15.99);
INSERT INTO price(product_id,store_id,value) VALUES ('APC30XL','web',15.99);
INSERT INTO price(product_id,store_id,value) VALUES ('APC302XL','web',17.99);
INSERT INTO price(product_id,store_id,value) VALUES ('APC303XL','web',17.99);

INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('LS534S','LS534','Go Away Annotation T-Shirt','NerdShirts','NS101','Men''s Small "Go Away...Annotation" T-Shirt','Having to answer support questions when you really want to get back to coding?  Wear this to work, and let there be no question as to what you''d rather be doing.',{'size':'Small','material':'cotton, polyester','cut':'men''s','color':'black'},{'ls534.png'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('LS534M','LS534','Go Away Annotation T-Shirt','NerdShirts','NS101','Men''s Medium "Go Away...Annotation" T-Shirt','Having to answer support questions when you really want to get back to coding?  Wear this to work, and let there be no question as to what you''d rather be doing.',{'size':'Medium','material':'cotton, polyester','cut':'men''s','color':'black'},{'ls534.png'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('LS534L','LS534','Go Away Annotation T-Shirt','NerdShirts','NS101','Men''s Large "Go Away...Annotation" T-Shirt','Having to answer support questions when you really want to get back to coding?  Wear this to work, and let there be no question as to what you''d rather be doing.',{'size':'Large','material':'cotton, polyester','cut':'men''s','color':'black'},{'ls534.png'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('LS534XL','LS534','Go Away Annotation T-Shirt','NerdShirts','NS101','Men''s Extra Large "Go Away...Annotation" T-Shirt','Having to answer support questions when you really want to get back to coding?  Wear this to work, and let there be no question as to what you''d rather be doing.',{'size':'Extra Large','material':'cotton, polyester','cut':'men''s','color':'black'},{'ls534.png'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('LS5342XL','LS534','Go Away Annotation T-Shirt','NerdShirts','NS101','Men''s 2x Large "Go Away...Annotation" T-Shirt','Having to answer support questions when you really want to get back to coding?  Wear this to work, and let there be no question as to what you''d rather be doing.',{'size':'2x Large','material':'cotton, polyester','cut':'men''s','color':'black'},{'ls534.png'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('LS5343XL','LS534','Go Away Annotation T-Shirt','NerdShirts','NS101','Men''s 3x Large "Go Away...Annotation" T-Shirt','Having to answer support questions when you really want to get back to coding?  Wear this to work, and let there be no question as to what you''d rather be doing.',{'size':'3x Large','material':'cotton, polyester','cut':'men''s','color':'black'},{'ls534.png'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('LN355S','LN355','Your Face is an @Autowired @Bean T-Shirt','NerdShirts','NS102','Men''s Small "Your Face...Autowired" T-Shirt','Everyone knows that one person who overuses the "your face" jokes.',{'size':'Small','material':'cotton, polyester','cut':'men''s','color':'black'},{'ln355.png'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('LN355M','LN355','Your Face is an @Autowired @Bean T-Shirt','NerdShirts','NS102','Men''s Medium "Your Face...Autowired" T-Shirt','Everyone knows that one person who overuses the "your face" jokes.',{'size':'Medium','material':'cotton, polyester','cut':'men''s','color':'black'},{'ln355.png'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('LN355L','LN355','Your Face is an @Autowired @Bean T-Shirt','NerdShirts','NS102','Men''s Large "Your Face...Autowired" T-Shirt','Everyone knows that one person who overuses the "your face" jokes.',{'size':'Large','material':'cotton, polyester','cut':'men''s','color':'black'},{'ln355.png'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('LN355XL','LN355','Your Face is an @Autowired @Bean T-Shirt','NerdShirts','NS102','Men''s Extra Large "Your Face...Autowired" T-Shirt','Everyone knows that one person who overuses the "your face" jokes.',{'size':'Extra Large','material':'cotton, polyester','cut':'men''s','color':'black'},{'ln355.png'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('LN3552XL','LN355','Your Face is an @Autowired @Bean T-Shirt','NerdShirts','NS102','Men''s 2x Large "Your Face...Autowired" T-Shirt','Everyone knows that one person who overuses the "your face" jokes.',{'size':'2x Large','material':'cotton, polyester','cut':'men''s','color':'black'},{'ln355.png'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('LN355XL','LN355','Your Face is an @Autowired @Bean T-Shirt','NerdShirts','NS102','Men''s 3x Large "Your Face...Autowired" T-Shirt','Everyone knows that one person who overuses the "your face" jokes.',{'size':'3x Large','material':'cotton, polyester','cut':'men''s','color':'black'},{'ln355.png'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSA1121S','DSA1121','DataStax Astra "One Team" Long Sleeve Tee','DataStax','DSA1121','DataStax Astra "One Team" Long Sleeve Tee - Small','Given out at the internal summit, show how proud you are to talk about the world''s best multi-region, multi-cloud, serverless database!',{'size':'Small','material':'cotton, polyester','color':'black'},{'dsa1121.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSA1121M','DSA1121','DataStax Astra "One Team" Long Sleeve Tee','DataStax','DSA1121','DataStax Astra "One Team" Long Sleeve Tee - Medium','Given out at the internal summit, show how proud you are to talk about the world''s best multi-region, multi-cloud, serverless database!',{'size':'Medium','material':'cotton, polyester','color':'black'},{'dsa1121.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSA1121L','DSA1121','DataStax Astra "One Team" Long Sleeve Tee','DataStax','DSA1121','DataStax Astra "One Team" Long Sleeve Tee - Large','Given out at the internal summit, show how proud you are to talk about the world''s best multi-region, multi-cloud, serverless database!',{'size':'Large','material':'cotton, polyester','color':'black'},{'dsa1121.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSA1121XL','DSA1121','DataStax Astra "One Team" Long Sleeve Tee','DataStax','DSA1121','DataStax Astra "One Team" Long Sleeve Tee - Extra Large','Given out at the internal summit, show how proud you are to talk about the world''s best multi-region, multi-cloud, serverless database!',{'size':'Extra Large','material':'cotton, polyester','color':'black'},{'dsa1121.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSA11212XL','DSA1121','DataStax Astra "One Team" Long Sleeve Tee','DataStax','DSA1121','DataStax Astra "One Team" Long Sleeve Tee - 2X Large','Given out at the internal summit, show how proud you are to talk about the world''s best multi-region, multi-cloud, serverless database!',{'size':'2X Large','material':'cotton, polyester','color':'black'},{'dsa1121.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSA11213XL','DSA1121','DataStax Astra "One Team" Long Sleeve Tee','DataStax','DSA1121','DataStax Astra "One Team" Long Sleeve Tee - 3X Large','Given out at the internal summit, show how proud you are to talk about the world''s best multi-region, multi-cloud, serverless database!',{'size':'3X Large','material':'cotton, polyester','color':'black'},{'dsa1121.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('APC30S','APC30','Apache Cassandra 3.0 Contributor T-Shirt','Apache Foundation','APC30','Apache Cassandra 3.0 Contributor T-Shirt - Small','Own a piece of Cassandra history with this Apache Cassandra 3.0 "Contributor" shirt.  Given out to all of the contributors to the project in 2016, shows the unmistakable Cassandra Eye on the front, with the
engine rebuild" on the back.',{'size':'Small','material':'cotton, polyester','color':'black'},{'apc30.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('APC30M','APC30','Apache Cassandra 3.0 Contributor T-Shirt','Apache Foundation','APC30','Apache Cassandra 3.0 Contributor T-Shirt - Medium','Own a piece of Cassandra history with this Apache Cassandra 3.0 "Contributor" shirt.  Given out to all of the contributors to the project in 2016, shows the unmistakable Cassandra Eye on the front, with the
engine rebuild" on the back.',{'size':'Medium','material':'cotton, polyester','color':'black'},{'apc30.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('APC30L','APC30','Apache Cassandra 3.0 Contributor T-Shirt','Apache Foundation','APC30','Apache Cassandra 3.0 Contributor T-Shirt - Large','Own a piece of Cassandra history with this Apache Cassandra 3.0 "Contributor" shirt.  Given out to all of the contributors to the project in 2016, shows the unmistakable Cassandra Eye on the front, with the
engine rebuild" on the back.',{'size':'Large','material':'cotton, polyester','color':'black'},{'apc30.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('APC30XL','APC30','Apache Cassandra 3.0 Contributor T-Shirt','Apache Foundation','APC30','Apache Cassandra 3.0 Contributor T-Shirt - Extra Large','Own a piece of Cassandra history with this Apache Cassandra 3.0 "Contributor" shirt.  Given out to all of the contributors to the project in 2016, shows the unmistakable Cassandra Eye on the front, with the
engine rebuild" on the back.',{'size':'Extra Large','material':'cotton, polyester','color':'black'},{'apc30.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('APC302XL','APC30','Apache Cassandra 3.0 Contributor T-Shirt','Apache Foundation','APC30','Apache Cassandra 3.0 Contributor T-Shirt - 2X Large','Own a piece of Cassandra history with this Apache Cassandra 3.0 "Contributor" shirt.  Given out to all of the contributors to the project in 2016, shows the unmistakable Cassandra Eye on the front, with the
engine rebuild" on the back.',{'size':'2X Large','material':'cotton, polyester','color':'black'},{'apc30.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('APC303XL','APC30','Apache Cassandra 3.0 Contributor T-Shirt','Apache Foundation','APC30','Apache Cassandra 3.0 Contributor T-Shirt - 3X Large','Own a piece of Cassandra history with this Apache Cassandra 3.0 "Contributor" shirt.  Given out to all of the contributors to the project in 2016, shows the unmistakable Cassandra Eye on the front, with the
engine rebuild" on the back.',{'size':'3X Large','material':'cotton, polyester','color':'black'},{'apc30.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSS821S','DSS821','DataStax Gray Track Jacket','DataStax','DSS821','DataStax Gray Track Jacket - Small','This lightweight polyester jacket will be your favorite while hiking the trails or teeing off.',{'size':'Small','material':'polyester','color':'gray'},{'dss821.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSS821M','DSS821','DataStax Gray Track Jacket','DataStax','DSS821','DataStax Gray Track Jacket - Medium','This lightweight polyester jacket will be your favorite while hiking the trails or teeing off.',{'size':'Medium','material':'polyester','color':'gray'},{'dss821.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSS821L','DSS821','DataStax Gray Track Jacket','DataStax','DSS821','DataStax Gray Track Jacket - Large','This lightweight polyester jacket will be your favorite while hiking the trails or teeing off.',{'size':'Large','material':'polyester','color':'gray'},{'dss821.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSS821XL','DSS821','DataStax Gray Track Jacket','DataStax','DSS821','DataStax Gray Track Jacket - Extra Large','This lightweight polyester jacket will be your favorite while hiking the trails or teeing off.',{'size':'Extra Large','material':'polyester','color':'gray'},{'dss821.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSH915S','DSH915','DataStax Vintage 2015 MVP Hoodie','DataStax','DSS915','DataStax Vintage 2015 MVP Hoodie - Small','Given out to MVPs at the 2015 DataStax Cassandra Summit.  Warm!  You will underestimate how many times you will fall asleep wearing this!',{'size':'Small','color':'black'},{'dsh915.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSH915M','DSH915','DataStax Vintage 2015 MVP Hoodie','DataStax','DSS915','DataStax Vintage 2015 MVP Hoodie - Medium','Given out to MVPs at the 2015 DataStax Cassandra Summit.  Warm!  You will underestimate how many times you will fall asleep wearing this!',{'size':'Medium','color':'black'},{'dsh915.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSH915L','DSH915','DataStax Vintage 2015 MVP Hoodie','DataStax','DSS915','DataStax Vintage 2015 MVP Hoodie - Large','Given out to MVPs at the 2015 DataStax Cassandra Summit.  Warm!  You will underestimate how many times you will fall asleep wearing this!',{'size':'Large','color':'black'},{'dsh915.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSH915XL','DSH915','DataStax Vintage 2015 MVP Hoodie','DataStax','DSS915','DataStax Vintage 2015 MVP Hoodie - Extra Large','Given out to MVPs at the 2015 DataStax Cassandra Summit.  Warm!  You will underestimate how many times you will fall asleep wearing this!',{'size':'Extra Large','color':'black'},{'dsh915.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSH916S','DSH916','DataStax Black Hoodie','DataStax','DSS916','DataStax Black Hoodie - Small','Super warm!  You will underestimate how many times you will fall asleep wearing this!',{'size':'Small','color':'black'},{'dsh916.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSH916M','DSH916','DataStax Black Hoodie','DataStax','DSS916','DataStax Black Hoodie - Medium','Super warm!  You will underestimate how many times you will fall asleep wearing this!',{'size':'Medium','color':'black'},{'dsh916.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSH916L','DSH916','DataStax Black Hoodie','DataStax','DSS916','DataStax Black Hoodie - Large','Super warm!  You will underestimate how many times you will fall asleep wearing this!',{'size':'Large','color':'black'},{'dsh916.jpg'});
INSERT INTO product(product_id,product_group,name,brand,model_number,short_desc,long_desc,specifications,images)
VALUES ('DSH916XL','DSH916','DataStax Black Hoodie','DataStax','DSS916','DataStax Black Hoodie - Extra Large','Super warm!  You will underestimate how many times you will fall asleep wearing this!',{'size':'Extra Large','color':'black'},{'dsh916.jpg'});

INSERT INTO featured_product_groups (feature_id,name,category_id,image,price,parent_id) VALUES (202112,'DataStax Gray Track Jacket',f629e107-b219-4563-a852-6909fd246949,'dss821.jpg',44.99,d887b049-d16c-46e1-8c94-0a1280dedc30);
INSERT INTO featured_product_groups (feature_id,name,category_id,image,price,parent_id) VALUES (202112,'DataStax Black Hoodie',b9bed3c0-0a76-44ea-bce6-f5f21611a3f1,'dsh916.jpg',35.99,6a4d86aa-ceb5-4c6f-b9b9-80e9a8c58ad1);
INSERT INTO featured_product_groups (feature_id,name,category_id,image,price,parent_id) VALUES (202112,'Apache Cassandra 3.0 Contributor T-Shirt',95ae4613-0184-46ee-b4b0-adfe882754a8,'apc30a.jpg',15.99,91455473-212e-4c6e-8bec-1da06779ae10);
INSERT INTO featured_product_groups (feature_id,name,category_id,image,price,parent_id) VALUES (202112,'DataStax Astra "One Team" Long Sleeve Tee',775be203-1a84-4822-9645-4da98ca2b2d8,'dsa1121.jpg',21.99,91455473-212e-4c6e-8bec-1da06779ae10);

Although it's not advised to use wildcards as below, you can verify the data has been created with the following command.

select * from CATEGORY;

Notes:

  • The "top" categories of the product hierarchy can be retrieved using a parent_id of "ffdac25a-0244-4894-bb31-a0884bc82aa9".
  • Without specifying a category_id, all categories for the parent_id are returned.
  • When a category from the "bottom" of the hierarchy is queried, a populated products ArrayList will be returned. From there, the returned product_ids can be used with the /product service.
  • Category navigation is achieved by using the parent_id and category_id properties returned for each category (to build the "next level" category links).
  • /category/ffdac25a-0244-4894-bb31-a0884bc82aa9 => Category[Clothing, Cups and Mugs, Tech Accessories, Wall Decor]
  • /category/ffdac25a-0244-4894-bb31-a0884bc82aa9/18105592-77aa-4469-8556-833b419dacf4 => Category[Clothing]
  • /category/18105592-77aa-4469-8556-833b419dacf4 => Category[T-Shirts, Hoodies, Jackets]
  • /category/91455473-212e-4c6e-8bec-1da06779ae10 => Category[Men's "Your Face...Autowired" T-Shirt, Men's "Go Away...Annotation" T-Shirt]
  • The featured products table is a simple way for web marketers to promote small numbers of products, and have them appear in an organized fashion on the main page. The feature_id key is simply an integer, with the default being 202112 (for December, 2021). You can (of course) use other numeric naming schemes.

🏠 Back to Table of Contents

5. Create your tokens

βœ… 5a. Create the Astra DB token

Following the Manage Application Tokens docs create a token with Database Admnistrator roles.

  • Go the Organization Settings

  • Go to Token Management

  • Pick the role Database Administrator on the select box

  • Click Generate token

πŸ‘οΈ Walkthrough

image

This is what the token page looks like. You can now download the values as a CSV. We will need those values but you can also keep this window open for use later.

image

  • appToken: We will use it as a api token Key to interact with APIs.

βœ… 5b. Save your DB token locally

To know more about roles of each token you can have a look to this video.

Note: Make sure you don't close the window accidentally or otherwise - if you close this window before you copy the values, the application token is lost forever. They won't be available later for security reasons.

⚠️ Important

The instructor will show you on screen how to create a token
but will have to destroy to token immediately for security reasons.

We are now set with the database and credentials and will incorporate them into the application as we will see below.

🏠 Back to Table of Contents

βœ… 5c. View the Astra Streaming token and connection details

Click on the "Connect" tab. Take note of your tenant name and broker service URL. It's a good idea to copy/paste those into a text editor for now. When you're ready, click on the "Token Manager" link.

image

You should have one token created by default. Click on the copy icon on the right. Paste your token into a text editor for now.

image

Later on, we will use this information to populate environment variables, allowing us to connect to our Astra Streaming tenant. It will be similar to the example below:

export ASTRA_STREAM_TENANT=ecommerce-aaron
export ASTRA_STREAM_URL="pulsar+ssl://pulsar-gcp-uscentral1.streaming.datastax.com:6651"
export ASTRA_STREAM_TOKEN="eyJhMBhGYBlahBlahBlahNotARealToken37hOAv9t1fHIhJLAHw"

βœ… 5d. Save your Streaming token locally

6. Setup your application

Open in Gitpod

Know your Gitpod

Take a moment to read this entire section since it'll help you with the rest of the workshop as you'll be spending most of your time in Gitpod. If you're familiar with Gitpod, you can easily skip this entire section.

The extreme left side has the explorer view(1). The top left, middle to right is where you'll be editing files(2), etc. and the bottom left, middle to right is what we will refer to as the Gitpod terminal window(3) as shown below.

πŸ‘οΈ Expected output

gitpod

You can always get back to the file explorer view whenever by clicking on the hamburger menu on the top left followed by View and Explorer as shown below.

gitpod

You can allow cutting and pasting into the window by clicking on Allow as shown below.

gitpod

βœ… 6a: Enter the token

To run the application you need to provide the credentials and identifier to the application. you will have to provide 4 values in total as shown below

Copy the environment sample file as below.

cp .env.example .env

Open the .env file as below.

gp open .env
  • In Astra DB go back to home page by clicking the logo

  • Select you database demos in the left panel and then copy values for cloud-region and database-id (clusterID) from the details page as shown below.

  • The DatabaseID is located on the home page

Ecom Welcome Screen

  • The Database region (and keyspace) are located in the details page

Ecom Welcome Screen

  • Replace application-token with values shown on the Astra token screen or picking the values from the CSV token file your dowloaded before including the AstraCS: part of the token.

  • Make sure the Token looks something like (with AstraCS: preceeding AstraCS:xxxxxxxxxxx:yyyyyyyyyyy

# Copy this file to .env and fill in the appropriate values. Refer to README.md
# for instructions on where to find them.
export ASTRA_DB_ID=
export ASTRA_DB_REGION=
export ASTRA_DB_APP_TOKEN=
export ASTRA_DB_KEYSPACE=ecommerce
export ASTRA_STREAM_TENANT=
export ASTRA_STREAM_URL=
export ASTRA_STREAM_TOKEN=
export GOOGLE_CLIENT_ID=
export GOOGLE_CLIENT_SECRET=

Make sure to inject the environment variables by running the following command

source .env

Verify that the environment variables are properly setup with the following command

env | grep -i astra

You should see four environment variables (not shown here).

🏠 Back to Table of Contents

7. Enable Social Login

Now that we're done with tests, let's cd to the top directory.

/workspace/workshop-ecommerce-app/

On a tab in a browser navigate to https://console.cloud.google.com/apis/credentials.

Consent to using APIs and services and you should finally be presented a screen that looks like below and pick values as shown.

ouath

Pick the appropriate values as shown below and complete the consent.

ouath

Make sure the project is setup for internal testing (and not for production) as shown below with the "MAKE INTERNAL".

ouath

Now click on the credentials tab, + CREATE CREDENTIALS tab and finally the OAuth Client ID dropdown as shown in the following screen.

ouath

You will be presented with a screen for entering the Authorized JavaScript Origins and Authorized redirect URIs as shown below.

You'll need the following URIs. Make a note of this. We will use http instead of https as illustrated below.

For the Authorized JavaScript Origins use the following value from the Gitpod terminal window,

echo $(gp url 8080 | sed 's/https/http/')

For the Authorized redirect URIs use the following from the GitPod terminal window.

echo $(gp url 8080 | sed 's/https/http/')/login/oauth2/code/google

Enter the respective values as shown below which enables URI redirection and SSO for the app.

ouath

Make sure you enter the above values correctly as shown and hit CREATE on bottom as shown.

ouath

Now you're ready to fetch the credentials by using the copy 'n paste icons on right as shown below.

ouath

You can copy and paste them in the .env file as entries for Google GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET.

🏠 Back to Table of Contents

8. Run Unit Tests

The application is now set you should be able to interact with your DB. Let's demonstrate some capabilities.

βœ… 8a: Use CqlSession

Interaction with Cassandra are implemented in Java through drivers and the main Class is CqlSession.

Higher level frameworks like Spring, Spring Data, or even quarkus will rely on this object so let's make sure it is part of your Spring context with a @SpringBootTest.

Let's change to the sub-directory from the terminal window as shown below.

cd backend

Let's run the first test with the following command.

mvn test -Dtest=com.datastax.tutorials.Test01_Connectivity

πŸ‘οΈ Expected output

[..init...]
Execute some Cql (CqlSession)
+ Your Keyspace: sag_ecommerce
+ Product Categories:
Clothing
Cups and Mugs
Tech Accessories
Wall Decor
List Databases available in your Organization (AstraClient)
+ Your OrganizationID: e195fbea-79b6-4d60-9291-063d8c9e6364
+ Your Databases:
workshops	 : id=8c98b922-aeb0-4435-a0d5-a2788e23dff8, region=eu-central-1
sample_apps	 : id=c2d6bd3d-6112-47f6-9b66-b033e6174f0e, region=us-east-1
sdk_tests	 : id=a52f5879-3476-42d2-b5c9-81b18fc6d103, region=us-east-1
metrics	 : id=d7ded041-3cfb-4dd4-9957-e20003c3ebe2, region=us-east-1

βœ… 8b: Working With Spring Data

Spring Data allows Mapping Object <=> Table based on annotation at the java bean level. Then by convention CQL query will be executed under the hood.

mvn test -Dtest=com.datastax.tutorials.Test02_SpringData

πŸ‘οΈ Expected output

Categories:
- Clothing with children:[T-Shirts, Hoodies, Jackets]
- Cups and Mugs with children:[Cups, Coffee Mugs, Travel Mugs]
- Tech Accessories with children:[Mousepads, Wrist Rests, Laptop Covers]
- Wall Decor with children:[Posters, Wall Art]

βœ… 8c: Working With Rest Controller

TestRestTemplate is a neat way to test a web controller. The application will start on a random port with @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)

mvn test -Dtest=com.datastax.tutorials.Test03_RestController

πŸ‘οΈ Expected output

List Categories:
Clothing
Cups and Mugs
Tech Accessories
Wall Decor

🏠 Back to Table of Contents

9. Start the Application

You can install the backend with the credentials using the following command

cd /workspace/workshop-ecommerce-app
mvn install -f backend/pom.xml -DskipTests

βœ… 9a: Know your public URL

The workshop application has opened with an ephemeral URL. To know the URL where your application endpoint will be exposed you can run the following command in the terminal after the build has completed. **Please note this URL and we will open this up in a new browser window if required later **.

gp url 8080

πŸ‘οΈ Expected output

gitpod

βœ… 9b: Check APIs are not available (yet)

Run the following command in the Gitpod terminal window

curl localhost:8080/api/v1/products/product/LS534S

πŸ‘οΈ Expected output

curl: (7) Failed to connect to localhost port 8080: Connection refused

Not to be overly concerned as we're going to be starting the application that will be served from the port.

βœ… 9c: Start the application

To start the application, we've provided a very simple convenience script that can be run as below.

./start.sh

Pay attention to popups being blocked as shown below and allow the popups.

gitpod

You may encounter the following at different steps and although this may not be applicable right away, the steps are included in advance and summarized here so that you can keep an eye out for it. Different paths and different environments might be slightly different although Gitpod levels the playing field a bit.

Your e-commerce application should be up and running.

βœ… 9d: Check APIs are now available

Get back to Gitpod tab/window.

Leave the application running and open up another shell in the Gitpod terminal window by clicking on + and clicking on bash dropdown as shown below.

gitpod

This will bring up a new bash shell as shown below.

gitpod

Issue the following command in that shell as you did earlier.

curl localhost:8080/api/v1/products/product/LS534S

and you should see some output indicating that the API server is serving our ecommerce APIs.

πŸ‘οΈ Expected output

gitpod

Try a few other APIs (Hint: Look for the RestController java files in the respective sub-directories.).

βœ… 9e: OPTIONAL - Open in Gitpod preview window

This might be useful for troubleshooting if your application does not automatically open up a browser tab.

If you want, you can run the following command to open your application in the preview window of Gitpod (it's much easier to use the app running in browser, though).

gp preview $(gp url 8080)

As indicated in the output below it's a very Simple Browser.

πŸ‘οΈ Expected output

gitpod

If your application is running in the preview window but you have difficulty accessing it from the browser pay attention to popups being blocked by the browser as explained before.

βœ… 9f: Get the Open API specification

In the new shell window open the specification in the preview or browser with the following command

gp preview $(gp url 8080)/swagger-ui/index.html

The preview window looks like below. It might help to close all the tabs or open this URL in a browser by clicking on the open in browser tab on the top right as shown.

πŸ‘οΈ Expected output

image

Here's how it looks in the browser tab.

image

This is the docs for the open APIs that enables the frontend or any other program to obtain the data and manipulate it with REST-based CRUD operations.

The complete app is running in the browser as shown below.

image

βœ… 9g: Use your social login

Hit login as shown below

login

You should be presented with the Google SSO Login option. Click on the icon as shown below.

login

Pick the Google user account and proceed to login as you would with Google.

login

If all the values are wired properly you should see the following screen with the icon above showing that the authentication worked as below and the Logout button now available.

ouath

and voila, just like that we are done setting up user profile with Google. We can implement Github and other social logins similarly.

🏠 Back to Table of Contents

βœ… 9h: Process your order(s)

Did you put items in your cart and check out? You will likely have an order waiting in your "pending-orders" topic. To simulate moving the orders between topics, a small Order Processor was created. To build and run:

source .env
cd orderProcessor
mvn clean install

Once that process completes, have a look at the target/ directory. You should see a JAR named ecom-0.0.1-SNAPSHOT-spring-boot.jar. To process an order on the "pending-orders" topic, you need to have it "picked." To simulate a picking process, try this:

java -jar target/ecom-0.0.1-SNAPSHOT-spring-boot.jar pick

If an order is present, you should see the order JSON get processed and moved to the next topic:

{"cartId":"b8a5bd07-2337-44de-8890-582e88e29754","cartName":"b8a5bd07-2337-44de-8890-582e88e29754","orderId":"e8ecd3b0-498b-11ed-b5a7-fbd1f5143654","userId":"f1dbd2c0-bda4-4ccc-93dd-4aecd78758f5","productList":[{"productId":"DSS821XL","productName":"DataStax Gray Track Jacket","productQty":1,"productPrice":44.99},{"productId":"APC30XL","productName":"Apache Cassandra 3.0 Contributor T-Shirt","productQty":1,"productPrice":15.99}],"orderStatus":"PENDING","orderTimestamp":"Oct 11, 2022, 5:41:17 PM","orderSubtotal":60.98,"orderShippingHandling":4,"orderTax":3.05,"orderTotal":68.03,"shippingAddress":{"street":"123 Limon Gala Rd.","city":"Maple Grove","stateProvince":"Minnesota","postalCode":"55369","country":"United States"}}
Pushed order e8ecd3b0-498b-11ed-b5a7-fbd1f5143654 to ecommerce-aaron/default/picked-orders

🏠 Back to Table of Contents

Done?

Congratulations: you made it to the end of today's workshop. You will notice that the application is still incomplete as we're evolving it. More building to follow!!!

Badge

... and see you at our next workshop!

Sincerely yours, The DataStax Developers

About

Are you building or do you support an e-commerce website? If so, then this content is for you! Worldwide digital sales in 2020 eclipsed four trillion dollars (USD). Businesses that want to compete, need a high performing e-commerce website. Here, we will demonstrate how to build a high performing persistence layer with DataStax ASTRA DB.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages