Detailed Design Description
Deployment Diagram
Design Decisions related to Deployment Diagram
BrokerServer | The brokerserver will run with a brokerservice on it. This brokerservice will allow us to create large data-streams. This will in turn allow us to create dynamic graphs on our webpage without having to consult a database twenty times a second. This brokerservice is connected via a broker connection to the Java application API. |
---|---|
DatabaseServer | The database will contain all data that is not required to be updated to show real-time data. This will thus include all sensor-data of past races, as well as all data required for logging in and creating race-views. The database system we use is MySQL, because of it's accessibility and relative ease to use. MySQL runs on a databaseServer, that is connected to the Java Application API with the use of a JDBC (Java Database Connectivity) Database Connection. |
ApplicationServer | The ApplicationServer will contain the API itself. This API will use Jakarta EE and Wildfly 25.0, which allows us to run an API with ease in a web environment. Using the REST API, this Java Application will connect to a webserver and deploy its .war artifact there. |
Webserver | The webserver is the link between user and API and is the part of our API that the user can interact with. This webserver could also be described as a simple website. |
User PC | The user PC is the eventual device on which the API and webpage will be run. This is the user end of our application. |
Class Diagram
Class Diagram Backend
Class Diagram DAO-DTO-generalisation
For every resource we have made, there's a few extra classes that we have generalised here. <insert uitleg dao en dto>
Class Diagram Frontend
With this design class diagram you can see the interactions happening between different classes of our program. The logincontroller makes sure it knows everything that has to do with logging in. The resource sends the requests to the controller and recieves data back from the controller.
The resource classes makes uses of the Response interface. This needs to happen, so that the user knows what went wrong.
Sequence diagram login
The LoginResource should only send requests to the controller and should return only one response, because the class is a resource class. The LoginController class is a controller and provides a link between the resource and the data classes. It sends the necessary methods to the other classes, so that LoginResource may not become a God class. The controller also returns the response to the LoginResource.
Design decisions
Decision | Description |
---|---|
Problem/Issue | The passwords can be seen by anyone who has access to the database. This is a huge security risk. |
Decision | Using Argon2, we can hash the passwords of users, so that a hashed password is stored in the database. This prevents hackers from seeing someone elses password. |
Alternatives | SHA-512, MD5, PBKDF2, BCrypt, and SCrypt (Millington, 2022) |
Arguments | From a comment in Baeldung (Millington, 2022), I saw Argon2 being suggested. Going to the Supertokens website (Supertokens Team, 2022), I found a tool that detects how safely a password is. With that Supertokens also recommended to use this hashing tool this march, which is quite recent. It uses more resources from your computer, but it makes a stronger password from it. Regterschot Racing required minimum security, that also includes a hashed password. |
Decision | Description |
---|---|
Problem/Issue | Logincontroller contains both the logic and sends the response |
Decision | Make a new class loginResource which is responsible for only sending the response |
Alternatives | Make a god class |
Arguments | If one class has to many responsibilities it doesn't obey the SOLID principle (BMC, 2022) |
View data per round
Sequence diagram view data per round
The crewmember interacts with the ModalComponent to create a new tab. In this component, the crewmember fills in the desired rounds that they want to see data from. The system will then add the new tab with the specified rounds to the application.
View Races
Sequence diagram view races
The crewmember goes to the rewatch race page where the front-end does a call to the back-end. This activates the getAllRaces method in the RaceResource. The resource is only responsible for returning the response so it gets delegated to the RaceController. The RaceController delegates this to the raceDAO because getting the data from the database is not the responsibility of the controller. In the RaceDAO a database connection is established to get all the data from the database. The benefit of this structure is that you can easily swap the classes which results in low cohesion and high coupling. This structure is based of the the layer pattern.
Design decision
Decision | Description |
---|---|
Problem/Issue | The name of the racecar is not stored in the database because this is not necessary at the moment |
Decision | In the constructor of RaceDTO the car get's the value "BMW 320 4fl E46" assigned |
Alternatives | Store it in the database, leave it empty |
Arguments | The BMW is the only car they intend to use in the near future so it's not necessary to make a new table for racecar. |
Place Graph
Sequence diagram add graph
When a crewmember opens the a tab, the front-end does a call to the back-end. It calls a method to SensorWithGraphResource. This is the controller of the SensorWithGraphDAO that gets the data which is needed for displaying graphs on the front-end. The SensorWithGraphDAO creates two DTO's. This is because the DAO uses them to send the data from the database to the resource.
Sequence diagram select sensor
We decided that making a sequence diagram is not needed for this user action to the system. The sensors will get loaded in when someone navigates to the website after which the crewmember will click on the desired sensor to view a graph from. After the user clicks on the sensor, it wil instantly show the types of graph linked to the sensor. This is something that happens on the front-end, thats why we decided its unnecessary.
Sequence diagram select graph
The crewmember interacts with the front-end by clicking on the desired graph type. This will call a method to create the graph on the sidebar component. This is because the sidebar component is the controller. The SidebarComponent will interact with GlobalComponent because the SidebarComponent is the information expert. GlobalComponent knows what is in the user's tabArray, which is why the push method on that array is called.
Design decision
Decision | Description |
---|---|
Problem/Issue | There is no graph linked to a sensor. |
Decision | There won't be an available graphs to add to a tab. |
Alternatives | Give every sensor a normal table (for example), so there is always a graph available. |
Arguments | Not every sensor has data that fits in a normal table. |
Delete Graph
sequence diagram graph
The crewmember deletes a graph on the webpage. the front-end does a call to the back-end. The resource is only responsible for returning the response so it gets delegated to GraphResource. The GraphService delegates this to the GraphDAO because getting the data from the database is not the responsibility of the controller. In the GraphDAO the graph gets deleted from the database. The benefit of this structure is that you can easily swap the classes which results in low cohesion and high coupling. This structure is based of the the layer pattern.
Tab CRUD
Delete Tab
Database Design
This is the database setup we will use for the RegterschotRacing API. A full description of every tables usage and datatypes can be found below. All green boxes will be made by Smalltalk in order to provide a sound foundation to build an API on. The red boxes could be implemented for future expansions, but they are out of our current scope. These have been placed here as an example to provide future developers with a stepping stone.
Database Glossary
Tablenames and formats are written in italic; Columns that contain the primary key are underlined.
Table | Column | Datatype | Null / Not Null | Comments |
---|---|---|---|---|
Graph | This table contains all data that is required to show a graph. It contains the sensor it is displaying the data for, and the type of graph it is. | |||
GraphID | int | Not null | This is the unique identifier of the graph. | |
Type | varchar(255) | Not null | The type of graph, can be anything from the following:
| |
SensorID | int | Not null | The unique identifier of the sensor that the graph is displaying the data of. | |
Race | This table contains all information relevant to a race. | |||
RaceID | int | Not null | The unique identifier of the race. | |
NumberOfRounds | int | Not null | The number of rounds that the race possesses. | |
RaceName | varchar(255) | Not null | The name of the race. | |
Date | DATETIME | Not null | The date of the start of the race. | |
Sensor | This table functions as collection of all sensors. | |||
SensorID | int | Not null | The unique identifier of the sensor. | |
SensorName | varchar(255) | Not null | The name of the sensor. | |
Tab | This table contains all information that is relevant to a Tab. | |||
TabID | int | Not null | The unique identifier of the tab. | |
TabName | varchar(255) | Not null | The name of the tab. The name is set when creating a new tab in the frontend web-application. | |
RaceID | int | Not null | The unique identifier of the race that the tab belongs to. | |
UserID | int | Not null | The unique identifier of the user that the tab belongs to. | |
User | This table handles all user data and other data relevant to have users that can interact with the application. | |||
UserID | int | Not null | The unique identifier of the user. | |
Username | varchar(255) | Not null | The unique name of a user that will be on display in the frontend web-application. | |
Password | varchar(255) | Not null | The hashed password of the user that is needed when logging in into the web-application. |
Design decisions related to the database
Decision 1 | Description |
---|---|
Problem/Issue | Throwing all of the different sensors and their data into one big table will quickly create a very clumped and hard-to-read table. |
Decision | Create a different table for every sensor and add a new table that contains all sensor IDs. |
Alternatives | - |
Arguments | By dividing data over multiple tables, query time can be shortened significantly and keeps all of our tables in line with the normalization principle. |
Decision 2 | Description |
---|---|
Problem/issue | A driver is only driving a couple of rounds in a race, which will create quite a confusing table if thrown into a single race tables. |
Decision | Divide the different datatypes into multiple tables: a rounds table, a race table and a driver table. Create a linking table that links all of these three tables together. |
Alternatives | - |
Arguments | By dividing the table into a multitude of different tables, there's three distinct tables that are in line with the normalization principle. |
Security decisions
Regterschot indicated at the beginning of the project that for security we only do the much needed security. Because of this we have chosen to hash the password, we do this because it is legally required and otherwise high fines can come from it.
In addition, we have chosen to use a Json Web Token. We do this to ensure that unwanted people cannot make calls to the API and only retrieve the data through the Web application.