- Designed and developed an interactive web page for users to search a nearby delivery dispatcher and allocate a delivery path with React JS and Redux.
- Implemented features such as “Set up from location”, “Set up destination”, “Selected a delivery route” with Ant Design, GeoCoding API and Google Map API.
- Visualized the delivery route, including route distance, total time estimation.
Utilized
: React & Redux, Ant Design
- Designed five Java Servlets with RESTful APIs to handle http requests, in order to achieve “Search history record”, “Check deliver availability”, “make a delivery order” functionality.
- Generated delivery routes and returned to front-end with Google Directions API.
- Build MySQL database onAmazon RDS to store users’ order history and ongoing order.
- Deployed to AWS EC2 and managed version control with Docker.
Utilized
: Java, RESTful API, Full Stack Development, MySQL, AWS
Intro
This project’s mission is to help people deliver their objects as fast as possible by auto allocate android or drone delivery within San Francisco (884,363 ppl). The entire process is a door-to-door service that is all managed by autonomous driving drones and/or robots. The drone or robot will get to your place, collect your items and talk it to your destination. We believe that through our project, we can significantly reduce the time of entire process and costs from human source on delivering within a city every day
Requirements
- Users should be able to register an account and our system should be able to store all history order records.
- After a customer sends a request, our system should be able to allocate a drone/android, based on the customer’s location for a customer’s service
- Once a delivery service is ordered, we should be able to notify the user (sender or receiver) to pic up the object; Save this record and let users give us a rate therefore we can analyze the service in the future.
Front End
Components Details
Intro
: User Login and RegistrationUser-Profile
: User can starts a new order or check his/her history orderMain1
: You can view 3 dispatchers around you through a map window. Set up your starting location and deliver locations, deliver weight.
Main2
: After your selections, there will be 2 (for now) routes generated by Google Direction API (from backend) to present. It is an interactive page that user can pick a single one route from the map component, while you make a selection, it’s also changing the page on the right side, then move on to next page.
Main3
: Present the final selection of user.
Final
: Order has been sent, order is ready.
React Components
Map
Used third party api react-google-maps.
- Wrapped with GoogleMap.
- Use Marker (MapDistriStatMarker, MapUserMarker) to spot markers on map.
- Use Polyline (MapRoute) to draw lines.
Geocoding API - In OrderDetails
The Geocoding API is a service that provides geocoding and reverse geocoding of addresses.
1 | //take the place id and return me lat lon |
Places - Used in SearchBar with AutoComplete
Based on a given address (still typing), return a list of guessed location.
1 | service = new google.maps.places.AutocompleteService(); |
React-Redux
index.js : store all reducers, export them as combined Reducers.
distributionLocationReducer
state:
- locations: []; stores a list of lat&lng object
action:
- set(locations[]) : reset the entire list
Use Case: Used in Main1, once /availability is done, store all 3 dispatchers location locally.
1 | //store data - in availability promise |
orderReducer
states
- startingLoc : String
- destination: String
- weight: float
- deliverType: String
- orderID: String
- price: float
- distance: float
- usageTime: float
- markers: []
Action
- setStartLoc
- setDestination
- setWeight
- setBoth: for startingLoc, destination, weight
- setDistance
- setPrice
- setUsageTime
- setMarkers
- setDeliverType
- setOrderID
Use case
- OrderRoute (Main2)
- Retrieve startingLoc, destination, weight
- Saved distance, price, usageTime, deliverType, order_id,
- OrderDetials (Main1)
- Retrieve startinglocation, destination, weight
- Set starting location, destination, markers(for dispatcher), weight
- OrderRoute (Main2)
routeInfoReducer
- state
- route_id : String
- route : [], a list of lat lng object
- action
- select: reset route_id, to tell me which one user has selected
- setRoute
- setRouteInfo: for both route_id and route
- Use Case
- MapRoute(Map) : once user selected a route, store the route info globally
- retrieve route_id
- set route_id and route spots details
- MapRoute(Map) : once user selected a route, store the route info globally
Back End
Ayalysis
Traffic Analysis
- User in the city 884,363 (1 M )
- Estimated no more than 1M Daily Active User(DAU)
- For Registration and Login (MySQL) :
- Total number of request per person per day: 0.1
- Average: 1 QPS
- Peak: 3 QPS
- Order Delivery Request (NoSQL):
- total number of request per person per day: 50
- Order: 0.5 QPS
- Peak: 1.5 QPS (total 3 QPS for read and write)
- Summary: MySQL AWS Aurora is scalable; multi-master; if it’s 15k, Aurora won’t be useful
Storage Estimation
- Request for an order QPD: 50M
- in half year: 50M * 30 Days * 6 months = 9000M = 9 Billion
- in one year: 18 Billion
- Assume each stored object is approximately 500 bytes
- in half year: 9 billion * 500 bytes = 4.5 TB
- in one year: 5TB
Method 1: 热储存 in memory
- Expensive
- redis (disk - consistency) vs memcache (cache) high frequency
Method 2: 冷储存
- AWS s3 1tb
- cheap
- latency is high (user profile is not allowed this)
- read only
Java Servlet
Allocate : “/allocate” ; Once the user choose two location on Main2, this call will be sent.
Availability : “/availability”; Main1 will call this as long as the component is ready.
History: “/history”; TBD, used to check user’s history order
Login: “/login”; TBD
Payment: “/payment”; Once user click the confirm button on Main3, this call will be sent
Register: “/register”; TBD
DB-Tables
- User Table : Store user personal information
- Dispatchers A, B, C : current availabel deliver info
- History Table : Store user’s history record
- Order Table : Store a single one user’s on going purcharse record
- Route Info Table : Store a series temporary available route for a deliver
API
User Managment - Login/Register, Check History
Login
1 | POST /login |
Register
1 | POST /register |
DB - User Table
userid | uuid - varchar | Primary Key |
---|---|---|
username | varchar | |
varchar | ||
password | varchar |
- When user registers an account, user should give an user email and password to the backend, backend will save a new user record and generate UUID as Primary Key to the database, return the front-end as a response with userid as a Token
- When user logins an account, user sends useremail and password to backend, backend will check if there is an account that useremail == useremail && password == password. If yes, return 200 with user id (as Token); if it’s not, then just report as user login failed 4xx.
Extra
Even though this feature is not implemented but I still should say something more about it.
Authentication vs Authorization
Authentication: Am I?
Authorization: am I authrozied to do?
Why do we need Authentication?
- Access control: user can only access data that are authorized to that user.
- Logging: record user specific activity for book keeping, statistics, etc.
A process of Re-login
Check User’s History Record
Search history order for user_id (This is just for the test)
1 | GET /history?user_id=1111 |
DB - Delivery History Table (Finished Order)
order_id | varchar | Primary Key | Unique Id |
---|---|---|---|
user_id | Foreign Key from User Table | Should be existed in User table | |
from_location | varchar | ||
to_location | varchar | ||
deliver_id | Foreign Key from Deliver DB | Which Robot/Drone took the order | |
time_start | timestamp | when the order start | |
time_end | timestamp | when the user received the order | |
total_weight | float | ||
price | float | ||
route | string | StringfyJson | Specific route - a list of lat, lng |
- This is table for recording an order has been finished. So you can check the time_end and user-selected route.
- Order_id is not firsted generated in this api call -> order_id is first generated here
[NOT USING CURRENTLY] When User Make New Order
Insert a new history record into History Database
1 | POST /history |
Check Availability
Check the locations of 3 delivery dispatchers and get the real-time data about amount of delivery drone or robot
1 | GET /availability |
DB - Deliver Table for Dispatcher A
deliver_id | varchar | Primary Key | |
---|---|---|---|
type | varchar | {“DRONE”, “ANDROID”} | |
states | varchar | {delivering, available} |
- There is also table B, C
- This is used to check availability - count how many available Drone or Android
User’s Request
Make a request order
1 | POST /allocate |
DB - Delivery Order Table (On-going Order)
order_id | varchar | Primary Key | First Created Here |
---|---|---|---|
user_id | Foreign Key From User Table | ||
from_location | varchar | ||
to_location | varchar | ||
deliver_id | Foreign Key from Deliver DB | Empty until user confirmed | |
time_start | timestamp | Empty until user confirmed | |
total_weight | float | ||
price | float | Empty until user confirmed | |
route | string | Encoded Polylines | Empty until user confirmed |
DB - Route Table
route_id | varchar | Primary Key | |
---|---|---|---|
order_id | Foreign Key | ||
route | Set of Strings | Encoded Lat Lng | |
type | varchar | “DRONE” / “ROBOT” | |
price | float |
- Backend will receive from_location and to_location and use Google Direction API to generate a route (decoded string) illustrates a route between these two locations.
- A temporary order record is created here. But deliver_id, time_start, price, route will be empty as it is not determined yet.
- The available routes details will be saved into DB - Route Table first as a reference - to stores an estimated price - (yes, a route record after 15 days will be cleared out as it is not usaful)
And at this time ==a deliver hasn’t been allocated as we not sure if user has made a strong decision that he would purchase our service.== - Reply to Client : Unique Order_id for user to refer an order (to make it an confirmed), and available routes details.
Payment
User has confirmed the service
1 | POST /payment |
- Find route details by route_id, includes route, type, price from Route Table
- Based on the deliver type and location, allocate a deliver from A,B,C table, grab it by deliver_id, mark that deliver status to be delivering
- Re-insert route, deliver_id, price and take the current time as time_start into On-Going Order Table
End
User received the order, drone should get back
1 | POST /end |
- It is the time that an order has been finished.
- Transfer an record with id “OR_1234” from On-Going Order Table to History Order Table. Take the current timestamp and recorded it as “time_end”
- Make sure free the current deliver such that deliver_id status is available now
Conflicts
React layers vs React Redux
- React Layers
- Pros: Easy to implement
- Cons: Hard to maintain
- Cons: Hard to send message over 3 parent-child relationships (Main2 vs Map Route )
- React Redux
- Cons: Complexier to implement
- Pros: Easier to maintain
- Pros: Solve the problem of our issue - communicate between parents and children
- React Layers
Map Logic : Who decide the logic of retrieved the route; Should the React (frontend) determine a certain route between two locations and sent to the backend? ==It was about how to design a communication between front end and backend, which way is more efficient==
- There is a Google Map API for backend about determine the route info, and data type can be a list of {lat, lon}
- We should consider Light UI vs Heavy Backend, backend should handle the logic
When to Allocate a Drone? When user first time to make a wish or user has confirmed the order.
Solution | Pros | Cons |
---|---|---|
Solution A: allocate drone before payment (drone id is holded on Main 2) | After user make a payment, the order will be ready for sure - guaranteed a service is available | 1. If request is busy, could be none drone for user - easily be attacked if multiple users book a service but not paid 2. What if the page on Main 2 is closed, we should do extra step to let the backend know that the drone can be released. But how to determine when exactly that user clicked the close button. |
Solution B: allocate drone after payment | Solves the concerns of solution A | Latency for user to wait for a deliver to response* |
*Drone is not available, delay, time might be longer than robot and still more expensive than robot.
(Sol: merging request from other clients)
AWS
Feature of Cloud
Pros:
* Scalability: 1~2 server
* Flexibility : EC2; VM; 根据数据类型储存不同的打他
* On-demand: 按需求charge
Cons:
- Data safety and privacy : 自己的东西在别人的server上
- Cannot control downtime: 修server是别人的工作,自己很被动
EC2
Amazon EC2 Elastic Compute Cloud (EC2) allows scalable deployment of applications by providing a Web service through which a user can boot an Amazon Machine Image to create a virtual machine, which Amazon calls an “instance”, containing any software desired. ==A user can create, launch and determine server instances as needed, paying for the hour for active servers, hence the term “elastic”==.
EC2 is an Infrastructure as a service (iaas) : customer provide application , data, OS; Provider will determine the Virtualization, Servers, Storage, Networking.
Steps:
- Choose a service EC2, launch an instance
- select an Amazon Machine Image (choose Ubuntu Server)
- choose free type of instance type
- When it’s on configuration page, set the port 80, 8080, 22 for 0.0.0.0/0
- Make sure to generate a key pair
- Finailly, grab its public IP
- Connect it on terminal through public ip with the key pair
Docker
What is Docker?
- A platform for developers/sysadmins/etc to interact with Linux containers.
- Currently the most popular platform for handling Linux containers.
- 可以更快更敏捷的去部署应用程序。
Why Docker?
- Powerful & Platform Agnostic
- Lightweight : 不再需要vm, 不再需要在vm 装os(前提是登陆上)
- Trending
隔离强:
该容器包含了应用程序的代码、运行环境、依赖库、配置文件等必需的资源。
容器之间达到进程级别的隔离,在容器中的操作,不会影响道宿主机和其他容器,这样就不会出现应用之间相互影响的情形!
可移植性:自从用上docker容器后,可以实现开发、测试和生产环境的统一化和标准化。
轻量和高效:
- 和虚拟机相比,容器仅需要封装应用和应用需要的依赖文件,实现轻量的应用运行环境,且拥有比虚拟机更高的硬件资源利用率。
- 在微服务架构中,有些服务负载压力大,需要以集群部署,可能要部署几十台机器上,对于某些中小型公司来说,使用虚拟机,代价太大。
RDS
MySQL : MySQL is an open-source relational database management system (RDBMS).
MySQL Workbench : allows you to test your DB
1 | use YOUR_DB_NAME; |
Amazon RDS: Amazon Relational Database Service (Amazon RDS) makes it easy to set up, operate, and scale a relational database in the cloud.
Steps
- Click Security Group
- Create a Security Group
- Set up port 3306 for 0.0.0.0/0
- Choose type MYSQL/Aurora
- Create MySQL DB Instance on RDS
JDBC: JDBC (Java Database Connectivity) provides interfaces and classes for writing database operations. Technically speaking, JDBC is a standard API that defines how Java programs access database management systems.
Since JDBC is a standard specification, one Java program that uses the JDBC API can connect to any database management system(DBMS), as long as a driver exists for that particular DBMS.
SQL Syntax
- Syntax for DROP.
1 | DROP TABLE IF EXISTS table_name; |
- Syntax for CREATE.
1 | CREATE TABLE table_name (column1 datatype, column2 datatype, ....); |
Syntax for INSERT.
1
INSERT INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...);
in Our case, TicketMaster is replaced by Google Direction API