Auteurs
Naam | Studentnummer |
---|---|
599907 | |
674152 | |
657079 | |
679586 | |
668329 | |
655269 |
Docenten
Naam | Functie |
---|---|
Procesbegeleider | |
Skillsbegeleider |
Klas | ITA-OOSE-A |
---|---|
Groepsnaam | Smalltalk |
Course | OOSE |
Datum |
|
Versie |
1. Introduction
1.1. Overall Description
You can find the description about the project in the introduction of our system requirements specification document.
See article: SRS Introduction
1.2. Purpose of this document
The purpose of this Software Design Description is to explain and justify the design choices that we have made during this project and the development of our product. The explaination for these design choices can be given to future programmers, so that they may have an idea of why some products have been designed in a certain way.
1.3. Definitions, acronyms, and abbreviations
Term |
Description |
---|---|
API | Application Programming Interface, a piece of software with a distinct function, for example being a link between a database and a front-end application. |
Gauge chart | A data visualization type used to display a single value of data in a quantitative way. |
table 1: detailed description of words, acronyms and abbreviations
2. Architectural Overview
This architectural overview is an overview that shows the building blocks of our project. It shows how we intend to build this project, besides that it helps the development team get a shared view.
figure 1: Architectural overview
Here you can see a description of what every building block of our project means. This makes the architectural overview better understandable.
DNS | The DNS also known as Domain Name System is Regterschot's website. |
---|---|
User Browser | Browser that's used by a user to access the website. |
CDN | Content Delivery Network is a service that distributes user requests to increase performance. |
Load Balancer | Load balancer is a REST-API that is used to distribute incoming traffic across virtual machines. |
Webapp Servers | This is the web application that we are making as the group Smalltalk. |
Database | The database is the place where we store our data. |
View Dashboards | To view a dashboard is an end goal so the user can see the relevant graphs. |
Broker | The broker is used to receive live data from the sensors on the race car |
Services | Services are the dependencies that our web application uses. |
table 2: glossary of architectural overview
3. Detailed Design Description
3.1. Deployment Diagram
figure 2: deployment diagram
3.2. Design Decisions related to Deployment Diagram
BrokerServer | A brokerserver is a server on which one or more brokers reside. In our case this will be just one broker which sends the data from the racecar to our website. The brokerservice will allow us to create large data-streams, sending data from one point to another. This way we can show dynamic graphs on the website with the actual data without using a database. This way the data will be arriving on the website much quicker, which definitely is important in our case. We connect to the broker over a websocket connection directly in the front end code. This way it will be as fast and reliable as possible. It will go through the least amount of code and layers that is possible. |
---|---|
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 its 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. That 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 run. This is the user end of our application. |
table 3: glossary of deployment diagram
3.3. Class Diagram
We made three different class diagrams to make the visual side of our program more understandable. The first one is for all our back-end code. The second one shows our data access object and data transfer object diagram and the last one is our front-end class diagram.
3.3.1. Class Diagram Backend
figure 3: class diagram back-end
3.3.2. Class Diagram DAO-DTO-generalisation
figure 4: class diagram DAO and DTO
For every resource we have made, there's a few extra classes that we have generalised here. The DTO classes are being used to model the data in a single format for easier use, this way we only need to edit data in one place. In the DAO classes we put all the logic that is needed to get the data from the database. Here we will process the data from a query result into the DTO and pass it back to the services. This way we create a layer pattern in our application which gives better readability and clarity for the next team that wants to alter our code after us.
3.3.3. Class Diagram Front-end
figure 5: class diagram front-end
4. Sequence Diagrams
4.1. Login
4.1.1. Sequence diagram login
figure 5: sequence diagram login
The loginResource should only return the response, since it's a resource and should apply the Single Responsibility rule. The loginService is an information expert, since it knows and keeps all the information from the classes. The userDAO sends a call to the database, which happens in the selectQuery method.
4.1.2. 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 a hashed password is stored in the database. This prevents hackers from seeing someone else's password. |
Alternatives | SHA-512, MD5, PBKDF2, BCrypt, and SCrypt (Millington, 2022) |
Arguments | From a comment in Baeldung (Millington, 2022). Argon2 being suggested. Going to the Supertokens website (Supertokens Team, 2022), There is a tool that detects how safely a password is. Supertokens also recommended to use this hashing tool in march 2022, 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. |
table 4: design decision login
Decision |
Description |
---|---|
Problem/Issue |
LoginService 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) |
table 5: design decision login
4.2. View Races
4.2.1. Sequence diagram view races
figure 6: 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 RaceService, because the resource is not allowed to have any logic in it. The RaceService decides the flow, that is why he is the controller. The RaceService delegates this to the raceDAO because getting the data from the database is not the responsibility of the service. 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 on the layer pattern.
4.2.2. Design decision
Decision |
Description |
---|---|
Problem/Issue |
The name of the race car is not stored in the database because this is not necessary at the moment |
Decision | In the constructor of RaceDTO the car gets 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 race car. |
table 6: design decision view races
4.3. Place Graph
4.3.1. Sequence diagram show sensor
figure 7: sequence diagram show sensor.
When a crewmember opens a tab, the front-end makes a call to the back-end. It sends a call to SensorWithGraphResource. The SensorWithGraphResource instantly gives it to the SensorService. That is because the SensorWithGraphResource should not contain any logic. The SensorService however is able to make send the call to the SensorWithGraphDAO. The SensorWithGraphDAO creates two DTO's. This is because the DAO uses them to send the data from the database to the resource.
4.3.2. 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 will instantly show the types of graphs linked to the sensor. This is something that happens on the front-end, that's why we decided it's unnecessary.
4.3.3. Sequence diagram select graph
figure 8: sequence diagram select graph.
The crewmember triggers a call on the front-end. 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 knows everything about GlobalComponent. GlobalComponent knows what is in the user's tabArray, which is why the push method on that array is called.
4.3.4. 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. |
table 7: design decision place graph.
4.4. Graph CRD
4.4.1. Sequence diagram deleteGraph
figure 9: sequence diagram delete 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 GraphService. The GraphService delegates this to the GraphDAO because deleting the data from the database is not the responsibility of the service. 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.
Decision |
Description |
---|---|
Problem/Issue |
graph and tab ID are not the same in the front and backend |
Decision | We use the ID from the front-end to get the right ID for the backend |
Alternatives | Use the ID from the database in the front-end |
Arguments |
Making them the same would break a lot of functionalities. We didn't have enough time so this was our only option to keep the functionalities. |
4.4.2. Sequence diagram addGraph
figure 10: sequence diagram add graph.
The crewmember adds a graph on the webpage. The front-end makes a call to the back-end. The resource is only responsible for returning the response so it gets delegated to GraphService. The GraphService delegates this to the GraphDAO because adding the data to the database is not the responsibility of the service. In the GraphDAO the graph gets added to 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 on the layer pattern.
4.5. Tab CRUD
4.5.1. Delete Tab
figure 11: sequence diagram delete tab.
The crewmember makes a call in the front end to the back-end. The TabResource receives this call and gives it instantly to the service, this is because the resource should only send something back and should not have any logic in the class. The TabService is able to make a call towards the TabDAO who can create the query to delete the tab. The service is used for this because it decides the flow of the deleting of the tab. The TabDAO sends the query to the database which deletes the tab from the storage.
4.5.2. Create tab
figure 12: sequence diagram create tab.
The crewmember makes a call in the front end to the back-end. The TabResource receives this call and sends it to the service, since the resource should only send something back and should not contain any logic. Tabresource does however receive a username from the clearToken method. This needs to happen, because the service should only delegate the function to the DAO and to successfully add a tab, a username is required to see where the tab needs to be added. The TabDAO makes a call to the database to execute the update with a query and parameters set up in de class. This call eventually creates the tab in the database.
5. Database and security
5.1. Database Design
The database design is made so every team member knows the structure of the database. It basically shows you the way we organize our data.
figure 13: 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 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 steppingstone.
5.1.1. 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. | |
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. |
|
NumberOfLaps | 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 a collection of all sensors. | |||
SensorID | int | Not null | The unique identifier of the sensor. | |
SensorName | varchar(255) | Not null | The name of the sensor. | |
Type | varchar(255) | Not null |
The type of graph, can be anything from the following:
|
|
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. | |
GaugeSettings | This table handles all the data needed to draw a gauge chart. | |||
SensorID | int | Not null | The unique identifier of the sensor. Also used here as unique identifier. | |
Min | int | Not null | The minimal value that the gauge chart has. | |
Max | int | Not null | The maximal value that the gauge chart has. | |
GreenTo | int | Not null | The value where the green zone ends. | |
YellowTo | int | Not null | The value where the yellow zone ends |
table 8: glossary database design
5.1.2. Design decisions related to the database
Decision 1 |
Description |
---|---|
Problem/Issue |
Throwing all 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. |
table 9: design decision database
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. |
table 10: design decision database
Decision 3 | Description |
---|---|
Problem/issue | When adding a new graph to a tab, the system must know what type of graph must be drawn for that sensor. |
Decision |
We decided to add the graph type to the sensor in the sensor table. |
Alternatives |
|
Arguments |
Currently every sensor will have one specific type of graph. Later this could be changed to a user having to make a choice. Using the code we currently have and using this database design this change has less impact compared to the alternative. Besides the change having less of an impact we can also make the adding process smoother since a user wouldn't have to choose from all the possible graphs but only from the graphs that make sense for this sensor. Lastly, we are able to make some query's faster and more compact this way. |
table 11: design decision database
Decision 4 | Description |
---|---|
Problem/issue | When adding a gauge graph to the database the settings need to be set as well such as its min and max value. |
Decision |
Adding the GaugeSettings table to the database. |
Alternatives |
|
Arguments |
We decided to add a specific table for the settings of the gauge since these can be very different. The other option would have been to use all the same settings. These settings would for example have been min: 0 max:100 and every value would probably be calculated to a percentage. Using this system it is fully customizable, there are no additional calculations and the zones (green yellow and red) can be set and customized using this. For example one gauge might need a red zone from 90 - 100 whilst another already starts at 50. It is some extra data to fetch from the database but it is still faster than calculating every value multiple times a second. Besides that the data in the gauge would be more reliable. |
table 12: design decision database
5.2. Security decisions
Regterschot indicated we do not have to worry too much about security yet, as they want to have a functional web application first. Therefore we are only implementing security measures for very high security risk scenarios. Because of this we have chosen to hash the password. We do this because we are legally obliged to do. In addition to this, 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. Furthermore we have choosen to make use of prepared statements. This is done to prevent SQL injections from happening. The prevention of SQL injections is implemented because it is seen as a very high security risk.
6. List of Resources
- Millington, S. (2022, January 12). Hashing a Password in Java. Baeldung. https://www.baeldung.com/java-password-hashing
- Supertokens Team. (2022, March 2). Hash, salt and verify passwords - Node, Python, Go and Java. Supertokens. https://supertokens.com/blog/password-hashing-salting
User | Edits | Comments | Last Update |
---|---|---|---|
Sem Gerrits | 81 | 5 | 658 days ago |
Jasper Kooy | 54 | 10 | 655 days ago |
Wijnand vanZyl | 31 | 4 | 655 days ago |
Thomas Droppert | 27 | 57 | 659 days ago |
Martin van Lijden | 20 | 7 | 661 days ago |
Auto Mation | 12 | 0 | 732 days ago |
Bram Bakker | 7 | 0 | 658 days ago |
2 Comments
Sem Gerrits
Thomas Droppert
Sequence diagrammen moeten nog verbeterd worden voor login en view data.