Skip to content

Homework 1: Weather Forecast

Madhavan K R edited this page Mar 12, 2022 · 2 revisions

Project Overview

Build a full-stack distributed system that enables users to query and visualize weather data from NEXRAD.

Following are the functionalities that our system must provide:

  1. A web based front-end that users can use to access our services.
  2. Aunthentication system to login to our system
  3. Detect storms
  4. Perform storm clustering
  5. Perform weather forecasts.

Napkin Diagram

Napkin Diagram

High-Level Architecture

Architecture Diagram

The components of the architecture and their functionalities are as follows:

  • UI: Acts as the interface for the users to interact with our system.
  • API Gateway: An API gateway is an API management tool that sits between a client and a collection of backend services. An API gateway acts as a reverse proxy to accept all application programming interface (API) calls, aggregate the various services required to fulfill them, and return the appropriate result.
  • Data Ingestor: Microservice that accepts user inputs - Date, Time, and NEXRAD station name - and outputs a URL corresponding to file containing weather data.
  • Registry Service: A central microservice that registers every action performed by the system and logs it. Also, it makes these logs queriable by users.
  • Forecast Service: Microservice that gives a weather data file, analyses it and detects a storm using characteristics such as reflectivity. This can be done using existing C++ libraries or approaches such as Connected Component Analysis. This Microservice also groups all the storm events detected into spatial clusters using a Density-based clustering algorithm. It can be achieved using existing C++ libraries. Further, it determines whether or not to run weather forecasts and performs actual weather forecasts based on the trigger by forecast trigger service.

Task Breakdown

For all the microservices following are the common tasks.

  • Decide on programming language
  • Figure out the build framework and how to containerize it.
  • Decide on communication to and from this service.
  • Come up with API input and output formats.

Following lists specific tasks related to each microservice.

UI and User Authentication (Navkar Shah)

  • Create a draft of the User Interface and decide the library or framework to be used.
  • Decide how to work with Authentication
  • Advanced track: using - http://arm-doe.github.io/pyart/ to plot weather data.

About:

  • The User Interface is a web application that is the point of entry for any user who wishes to use our service.
  • The web app has been developed using JavaScript's popular library React.
  • This web app provides an interface for the user to fetch weather data by providing the desired date, time, and radar station.
  • We have used Google's OAuth for user authentication. This allows users to fetch their previous search logs.
  • Once the user provides valid input and hits the Find button, the app communicates with our API gateway to retrieve the relevant data and display it on our UI.
  • Here is an outline diagram of what our web app looks like. UI Diagram

Registry (Madhavan Kalkunte Ramachandra)

  • Decide on the database used and finalize database design.
  • Come up with APIs to be used to expose data available in the database.

Functionalities:

  • Exposes API to query user details and log details.
  • Exposes API to log user activity.
  • API exposed can be consumed via HTTP Rest
  • Integrated with Postgres as backend database.

Design diagram

Registry Diagram

API Gateway (Madhavan Kalkunte Ramachandra)

  • Understand how API gateways work and their functionalities.
  • Figure out what are the available options and decide which suits our use case.
  • How to configure and deploy it in a containerized fashion

Functionalities:

  • Exposes API to consume downstream services like forecaster, ingestor
  • Logs user activity using registry microservices
  • API exposed can be consumed via HTTP Rest
  • Integrated with Google OAuth to validate user tokens.

Design diagram

Registry Diagram

Data Ingestor (Ayush Sanghavi)

  • Figure out the URL formation to access weather data given user input and validate the formed URL.
  • Determine how to pass this information along to storm detecter microservice

About :

  • The Data Ingestor microservice will fetch data from Nexrad's AWS S3 Bucket according to the user's query.
  • It will then validate the query and download first four scans of the specified hour of the date.
  • Downloads the desired data, and plots it accordingly and downloads the plot in the server side file system.
  • Below is the visual of the service:

Diagram

Forecast (Ayush Sanghavi)

  • Understand how to decide whether to run forecasts or not.
  • Understand how to mock these decisions.
  • Understand how to group storm events into spatial clusters using a Density-based clustering algorithm.
  • Basic track: Understand the output data format and how to mock it
  • Understand how to run weather forecasts and what the output will look like.
  • Mock the output for weather forecast data.

Intercommunication between microservices

All the microservices use REST protocol to communicate with each other. All the message exchanges take place in JSON format.

Cloud Events was explored to maintain standard of communication. However, to maintain simplicity in the first project, it was decided to go ahead with a simpler data model which only represents the core data being communicated - corresponds to the "data" attribute in cloud event.

Message queue-based communication was also explored RMQ.

API Docs:

APIs provided by gateway

Note: All the apis must include the following headers:

id_token: google authentication token
name: username ACC. to google
email: user's gmail id

/data (POST request)

Provides the weather data

Request:

{
    "year": 2022,
    "month": 2,
    "day": 2,
    "startTime": 1643807400279,
    "endTime": 1643807400279,
    "radarStation": "KAKQ"
}

Response:

{
  "imageUrl": "url-of-plot",
  "stormExists": True/False,
  "weatherForecast": {
                       "min_temp": 10,
                       "max_temp": 50,
                       "humidity": 100,
                       "pressure": 15,
                       "weather_description": "clear"
                     } 
}

/getUser

api provides user details

sample usage: http://localhost:8082/getUser?userId=madhkr

Request parameters:

userId: userId for whom details is requested for.

Response:

{
    "userId": "madhkr",
    "userEmail": "[email protected]",
    "name": "madhavan",
    "timestamp": "2022-01-31",
    "active": true
}

/getLogs

api provides a list of user activity logs

sample usage: http://localhost:8082/getLogs?userId=madhkr

Request parameters:

userId: userId for whom details is requested for.

Response:

[
    {
        "id": "4864b6ef-c3ef-4c6c-a03f-db255a7ed8ab",
        "userId": "madhkr",
        "serviceId": "registry",
        "action": "addUser",
        "timestamp": "2022-01-31",
        "comments": "successfully added user",
        "status": 0
    },
    {
        "id": "91acdc6f-a7b3-4940-8e11-d7220166e0fa",
        "userId": "madhkr",
        "serviceId": "registry",
        "action": "getUser",
        "timestamp": "2022-01-31",
        "comments": "successfully queried user details",
        "status": 0
    },
    {
        "id": "87ae0e08-4c71-4f7c-bba4-afee1633727f",
        "userId": "madhkr",
        "serviceId": "registry",
        "action": "getAppLogs",
        "timestamp": "2022-01-31",
        "comments": "successfully queried logs",
        "status": 0
    }
]

APIs provided by the registry microservice

/getAppLog

returns activity log for a specified user

Request parameters:

userId: userId for whom log is requested

Response:

[
    {
        "id": "4864b6ef-c3ef-4c6c-a03f-db255a7ed8ab",
        "userId": "madhkr",
        "serviceId": "registry",
        "action": "addUser",
        "timestamp": "2022-01-31",
        "comments": "successfully added user",
        "status": 0
    },
    {
        "id": "91acdc6f-a7b3-4940-8e11-d7220166e0fa",
        "userId": "madhkr",
        "serviceId": "registry",
        "action": "getUser",
        "timestamp": "2022-01-31",
        "comments": "successfully queried user details",
        "status": 0
    },
    {
        "id": "87ae0e08-4c71-4f7c-bba4-afee1633727f",
        "userId": "madhkr",
        "serviceId": "registry",
        "action": "getAppLogs",
        "timestamp": "2022-01-31",
        "comments": "successfully queried logs",
        "status": 0
    }
]

/addAppLog

Adds a user activity log to database

Request:

{
    "id": "sample-id",
    "userId": "madhkr1",
    "serviceId": "sample-service-id",
    "action": "sample-action",
    "timestamp": 1643534040000,
    "status": 1,
    "comments": "sample-comments"
}

Response:

{
   "message": "successfully added applog",
   "status": "201 CREATED"
}

/addUser

Adds a user to database

Request:

{
    "userId": "madhkr",
    "userEmail": "[email protected]",
    "timestamp": "1643538067000"
    "name": "Madhavan"
}

Response:

{
   "message": "successfully added user",
   "status": "201 CREATED"
}

APIs provided by the data ingestor microservice

/getdata

API gets the data from the S3 bucket for further processing

sample usage: http://localhost:8000/getdata?year=2000&month=03&day=31&starttime=17&endtime=19&radar=KTLX&id=292

Request parameters:

year : year for the data requested

month : month for the data requested

day : day for the data requested

starttime : starttime for the data requested

endtime : endtime for the data requested

radar : radar (station) for the data requested

id : id for the data requested

Response:

{ "data": "id.png" }

/getimage

API gets the filename of the image

Request

sample usage: http://localhost:8000/getimage

Request parameters:

filename : name of the file

Response:

The output will be the id.png file

/health

API returns an OK message

sample usage: http://localhost:8000/health

Request parameters:

No request parameters

Response:

{
    "Health": OK
}

APIs provided by weather forecasting microservice

/stormclustering

API returns a random boolean value to detect storm clustering

sample usage: http://localhost:8001/stormclustering

Request parameters:

No request parameters

Response:

{
    "storm_detected": true
}

Response will switch between true and false

/forecast

API returns weather data

Request

sample usage: http://localhost:8001/forecast

Request parameters:

No request parameters

Response:

{
    "weather data": {
        "min_temp": 60,
        "max_temp": 108,
        "pressure": 0,
        "humidity": 160
    }
}

/health

API returns an OK message

sample usage: http://localhost:8001/health

Request parameters:

No request parameters

Response:

{
    "Health": OK
}

Prerequisites for installing weather forecast system:

Deploying the weather forecast system:

NOTE : GO TO YOUR DOCKER DESKTOP --> GO TO SETTINGS --> GO TO RESOURCES --> INCREASE MEMORY TO 8 GB

Creating a local bridge

docker network create elves-network

Database setup

We are using postgres as our database to store user details and logs of user activities.

Postgres can be set up in a docker container with following steps:

pull the docker image

docker pull postgres

run the docker container

docker run --net elves-network --name elves-postgres -p 5001:5432 -e POSTGRES_PASSWORD=cloudelves -d postgres

Registry Microservice

Next, we must set up the registry microservice, which is responsible for storing user details and logs of user activities.

To set up the registry first clone the CloudElves repository and checkout Homework1-release-registry branch by running the below commands:

git clone https://github.com/airavata-courses/CloudElves.git
cd CloudElves
git checkout Homework1-release-registry

Then, run the following command to build a runnable jar and docker container from it.

Note: Following commands needs to be executed from the root directory of project (same level as pom.xml)

mvn clean package -Dmaven.test.skip 

this will create a runnable jar in the target/ folder

create the docker image with the following command:

docker build -t cloud-elves/registry .

The docker image can be executed with the following command

docker run -d -e db.host=elves-postgres -e db.port=5432 -p 8080:8080 --net elves-network --name registry  cloud-elves/registry

PS: above command will run registry microservice on port 8080, you can verify by hitting the health endpoint

Ingestor Microservice

git clone https://github.com/airavata-courses/CloudElves.git
cd CloudElves
git checkout Homework1-release-ingestor
docker build -t cloud-elves/ingestor .

The docker image can be executed with the following command

docker run --rm -d --net elves-network -p 8000:8000 --name ingestor  cloud-elves/ingestor

PS: above command will run ingestor microservice on port 8000, you can verify by hitting the health endpoint

Forecast Microservice

git clone https://github.com/airavata-courses/CloudElves.git
cd CloudElves
git checkout Homework1-release-forecast
docker build -t cloud-elves/forecast .

The docker image can be executed with the following command

docker run --rm -d --net elves-network -p 8001:8001 --name forecast  cloud-elves/forecast

PS: above command will run forecast microservice on port 8001, you can verify by hitting the health endpoint

Gateway Microservice

Next, we must set up the gateway microservice, which is responsible for exposing user-facing APIS.

To set up the gateway first clone the CloudElves repository and checkout Homework1-release-gateway branch by running the below commands:

git clone https://github.com/airavata-courses/CloudElves.git
cd CloudElves
git checkout Homework1-release-gateway

Then, run the following command to build a runnable jar and docker container from it.

Note: Following commands needs to be executed from the root directory of the project (same level as pom.xml)

mvn clean package

this will create a runnable jar in the target/ folder

create the docker image with the following command:

docker build -t cloud-elves/gateway .

The docker image can be executed with the following command

docker run --rm -d --net elves-network -e forecaster.host=forecast -p 8082:8082 --name gateway cloud-elves/gateway

PS: above command will run gateway microservice on port 8082, you can verify by hitting the health endpoint

Frontend / UI

Finally, we can deploy the UI with the following commands

To set up the UI which is a React App first clone the CloudElves repository and checkout Homework1-release-ui branch by running the below commands:

git clone https://github.com/airavata-courses/CloudElves.git
cd CloudElves
git checkout Homework1-release-ui

create the docker image with the following command:

docker build -t cloud-elves/ui . 

The docker image can be executed with the following command:

docker run -it -d --net elves-network --rm -p 3001:3001 --name ui  cloud-elves/ui

PS: above command will run cloud weather app on port 3001, you can verify by hitting the UI endpoint

Clone this wiki locally