225 lines
9.7 KiB
Markdown
Executable File
225 lines
9.7 KiB
Markdown
Executable File
# Developer Documentation - Spiri Simulator Backend
|
||
|
||
|
||
**Steps to install and access Backend server APIs:**
|
||
|
||
- System - Ubuntu 18.04
|
||
- Install maven and Java- 11 to your Ubuntu machine
|
||
- sudo apt update
|
||
- sudo apt install maven
|
||
- sudo apt install default-jdk
|
||
|
||
|
||
|
||
**Install mysql- 5.7 (https://www.digitalocean.com/community/tutorials/how-to-install-mysql-on-ubuntu-18-04)**
|
||
- $ sudo apt update
|
||
- $ sudo apt install mysql-server
|
||
- $ Configuring mysql
|
||
- $ sudo mysql_secure_installation
|
||
- Note: Set password plugin- Initially set it to ‘yes’ and level ‘0’ for validation policy
|
||
- Adjusting User Authentication and Privileges
|
||
|
||
|
||
|
||
**Add scripts to mysql server**
|
||
- Run below command to add scripts from (cloned**) backend folder into in installed my sql server
|
||
- mysql -u username -p database_name < file.sql
|
||
**Scripts are in the db table :https://gitlab.pleiadesrobotics.com/web-services/backend/-/tree/feature_base_code/db
|
||
- Install Eclipse
|
||
Download Eclipse from https://www.eclipse.org/downloads/
|
||
- Setup eclipse with tar xfz ~/Downloads/eclipse-inst-linux64.tar.gz ~/Downloads/eclipse-installer/eclipse-inst
|
||
- Setup eclipse for lombok getter & setter
|
||
- Copy lombok-1.18.6.jar from ../.m2/repository/org/projectlombok/lombok/1.18.6 to eclipse root folder(where eclipse.ini file is)
|
||
- cd <'eclipse root directory'>
|
||
- java -jar lombok-1.18.6.jar install ~/eclipse/jee-2020-03/eclipse/
|
||
- java -jar lombok.jar install ~/eclipse/jee-2020-03/eclipse/
|
||
|
||
#### Or
|
||
|
||
- cd <'eclipse root directory'>
|
||
- java -jar eclipse/lombok-1.18.6.jar
|
||
- install ~/Downloads/eclipse-java-2020-03-R-linux-gtk-x86_64/eclipse/
|
||
- Restart eclipse and build again the project
|
||
|
||
**Build & Run - Backend:**
|
||
- git clone git@gitlab.pleiadesrobotics.com:web-services/backend.git
|
||
- Update ~/backend/src/main/resources/application.yml with mysql password set
|
||
- cd backend
|
||
- mvn clean install
|
||
- mvn spring-boot:run
|
||
- Open localhost:8080/task/list/ to test everything runs OK. It will run the backend server at port 8080 default.
|
||
|
||
**Understanding Backend Codebase:**
|
||
|
||
***src/main/java***
|
||
|
||
###### com.example.springbootapp
|
||
- This is the main class to run your complete application.
|
||
|
||
###### Com.example.springbootapp.config
|
||
- Configuration files for adding the security
|
||
|
||
###### Com.example.springbootapp.controllers
|
||
- Once you want a new microservice add this to the package and create new class with the tag “Get
|
||
mapping” so basically on the hit to the URL the page is redirected as per the functionality written here.
|
||
Usually after a hit it opens up the specific implementation written in the package relevant to the
|
||
specific class in “com.example.springbootapp.services”.
|
||
|
||
###### com.example.springbootapp.model
|
||
- POJO (Plain OLd Java Objects) for all the functionality are added here these are basic getter and setter methods that you require.
|
||
|
||
###### Com.example.springbootapp.repository
|
||
- Here interfaces are defined which are extending JPA(database connection to your db) then these
|
||
|
||
###### com.example.springbootapp.schedulers
|
||
- service to stop the container spawned using AWS when not being used.
|
||
|
||
|
||
###### com.example.springbootapp.services
|
||
- This usually has an interface and an implementation of that interface which is for having the best
|
||
practise of loose coupling. So for example
|
||
|
||
CompetitionService.java is the interface and CompetitionServiceImpl.java is the class. So all the
|
||
methods that are defined in the interface are implemented in this service implementation.
|
||
/backend/src/main/java/com/example/springbootapp/services/CompetitionService.java
|
||
/backend/src/main/java/com/example/springbootapp/services/CompetitionServiceImpl.java
|
||
|
||
|
||
#### src/main/resources
|
||
- Here the application yml files and the properties file is kept
|
||
You can add the following things for example :
|
||
Set the mysql db
|
||
Set the okta Oauth 2 authentication etc
|
||
Example :- https://gitlab.spirirobotics.com/web-services/backend/-/blob/feature_base_code/src/main/resources/application.yml
|
||
|
||
|
||
#### src/test/java
|
||
- Use Junit or Mockito to add your unit test cases
|
||
Junit : https://junit.org/junit5/
|
||
Mockito: https://site.mockito.org/
|
||
|
||
|
||
**APIs details:**
|
||
- To CRUD applications (Competitions)
|
||
https://developer.okta.com/docs/reference/api/apps/
|
||
|
||
- To CRUD groups (Teams)
|
||
https://developer.okta.com/docs/reference/api/groups/
|
||
|
||
- To CRUD users
|
||
https://developer.okta.com/docs/reference/api/users/
|
||
|
||
- To get a user Id from our backend abstracted user API
|
||
[/api/user](url)
|
||
|
||
This Api returns current okta session user object from where you can retrieve userId from "sub"
|
||
|
||
{"at_hash":"cBwzHrq22cIYxBd1g3851g","sub":"00u21ycq02wVcoFxT357","zoneinfo":"America/Los_Angeles","ver":1,"email_verified":true,"amr":["pwd"],"iss":"https://dev-125890.okta.com/oauth2/default","preferred_username":"raga.amber@gmail.com","locale":"en-US","given_name":"Raghav","aud":["0oa21yqmlw0cI8weJ357"],"updated_at":1576023483,"idp":"00o21ycpwwDPVJJEi357","auth_time":1576967436,"name":"Raghav Sharma","exp":"2019-12-21T23:56:24Z","family_name":"Sharma","iat":"2019-12-21T22:56:24Z","email":"raga.amber@gmail.com","jti":"ID.LCHoKAbPBXVCs0LjnXY2v54q9wnUMQZXBW5o0poI8GQ"}
|
||
|
||
- To log out current user (Post)
|
||
[/api/logout](url) Pass idToken to be timed out, this api will call okta to make token invalid.
|
||
|
||
- To get competition progress (Get)
|
||
[/competition/progress/{user_id}/{comp_id}](url)
|
||
This will return you all tasks. Construct your task list using this response.
|
||
|
||
- To create a simulator (Get) (TODO: Change it to post call)
|
||
[/simulator/start/{user_id}/{name}/{pwd}](url) where user_id is student okta id, name is given_name, pwd is any constant.
|
||
This API returns 'publicIp' which is a Fargate container IP to access newly created simulator and shell.
|
||
|
||
- To update task (Get) (TODO: Change it to post call)
|
||
[/competition/update/${userId}/${compId}/${taskId}](url)
|
||
|
||
- To create/update master data task (Put)
|
||
[/task/update](url)
|
||
|
||
{
|
||
"user_id":11,"comp_id":13,"task_id":1,"task_name":"Is simulator launched ?","task_progress":"0", "task_action":"Launch Simulator"
|
||
}
|
||
|
||
- To log heart beat to active simulator against student id (Get) (TODO: Change it to post call)
|
||
[/simulator/logheartbeat/{user_id}](url)
|
||
|
||
- To stop/delete active simulator against student id (Get) (TODO: Change it to post call)
|
||
[/simulator/stop/{user_id}](url)
|
||
****
|
||
|
||
**Behavior flow:**
|
||
( 'Team <-> Okta Group'
|
||
'Competition <-> Okta Application(App)')
|
||
- Create a team in Okta.
|
||
- Create a user and add it to a team in Okta.
|
||
- Create a competition and add a team to competition in Okta.
|
||
- Front end can call any API as dummy API to pop up Okta login page.
|
||
- Once login passed, get userId from login session directly from Okta.
|
||
(OR)
|
||
Use Okta user API /api/v1/users/me
|
||
(OR)
|
||
Use abrstacted user api[/api/user] from backend.
|
||
|
||
- Get competition details from Okta apps api for the user by using below API:
|
||
|
||
{{url}}/api/v1/apps?filter=user.id+eq+"{{userId}}"
|
||
|
||
This will get you competitionId(appid)
|
||
- Now call competition progress API by passing user id and competition id to get competition tasks progress details
|
||
[/competition/progress/{user_id}/{comp_id}](url)
|
||
This will return you all tasks details for the competition. Construct your task list using this response.
|
||
|
||
- Create a simulator by calling [/simulator/start/{user_id}/{name}/{pwd}](url) and place the returned URI from API to your respective tasks buttons.
|
||
(Note: This API takes longer time to respond if simulator is getting created first time. Please use enough timeout at frontend.)
|
||
|
||
- Call simulator heart beat api periodically from frontend to keep the simulator active [/simulator/logheartbeat/{user_id}](url) which updates the timestamp of the simulator.
|
||
If heartbeat api is not called, then simulator would be deleted automatically after 1 hr.
|
||
There is a scheduler runs periodically at backend which checks the timestamp of created simulator and if simulator timestamp is 1 hr old then it makes an assumption that simulator is not in use.
|
||
|
||
- Stop/Delete simulator: To stop/delete simulator, use this api [/simulator/stop/{user_id}](url)
|
||
|
||
|
||
## Understand Cloud
|
||
|
||
- Credentials :
|
||
- SHELLINABOX_PASSWORD spiri-friend2019@
|
||
- SHELLINABOX_USER Raghav
|
||
- Gazebo http://3.235.54.48:8080/
|
||
- Shell terminal http://3.235.54.48:4200/
|
||
- Once you are inside the shell using the above credentials then you just need to run the following command to spawn a gazebo instance :
|
||
|
||
### AWS Fargate :
|
||
|
||
- ECR technology to deploy serevr less docker containers
|
||
- https://aws.amazon.com/fargate/
|
||
- Ask your network adimintrator at Spiri to give you the credentials and create a I AM USER account for you to do backend testing.
|
||
|
||
|
||
## Install Postman(For checking backend APIs)
|
||
|
||
- https://developer.okta.com/code/rest/
|
||
After you set all the global variables here then hit the following URL :
|
||
{{url}}/api/v1/users?limit=25
|
||
Output :
|
||
{
|
||
"id": "00u21ycq02wVcoFxT357",
|
||
"status": "ACTIVE",
|
||
"created": "2019-11-30T01:42:45.000Z",
|
||
"activated": null,
|
||
"statusChanged": "2019-11-30T01:44:07.000Z",
|
||
"lastLogin": "2020-05-19T16:35:09.000Z",
|
||
"lastUpdated": "2019-11-30T01:44:08.000Z",
|
||
"passwordChanged": "2019-11-30T01:44:07.000Z",
|
||
"type": {
|
||
"id": "oty21ycpxjH4TjHD1357"
|
||
|
||
## Redirect from backend :
|
||
- HttpHeaders headers = new HttpHeaders();
|
||
headers.add("Location", "localhost:3000/");
|
||
return new ResponseEntity(headers, HttpStatus.FOUND);
|
||
|
||
|
||
## Important articles and developer documentations :
|
||
|
||
- https://docs.google.com/document/d/1fABunlJQTq6DFNJTzCgDcGphiXBCHzwtk5RZju8drmk/edit?usp=sharing (If you cannot access this link then ask Patrick to add you to it)
|
||
- https://developer.okta.com/blog/2020/03/27/spring-oidc-logout-options
|
||
- https://developer.okta.com/code/rest/
|
||
|