diff --git a/README.md b/README.md index 2800a12..de4321c 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# Flight Advisor Service ![GitHub release (latest by date)](https://img.shields.io/github/v/release/mohamed-taman/Flight-Advisor) [![Release Codename](https://img.shields.io/badge/codename-Advisor_2.8-yellow.svg)](https://github.com/mohamed-taman/Flight-Advisor/releases) [![BCH compliance](https://bettercodehub.com/edge/badge/mohamed-taman/Flight-Advisor?branch=main)](https://bettercodehub.com/) [![Twitter Follow](https://img.shields.io/twitter/follow/_tamanm?label=follow%20me&style=social)](https://twitter.com/_tamanm) Flight advisor Service is a set of APIs for primarily finding the cheapest flight from city A to city B based on price, and as a result it's returning all the trip information alongside the distance(s). ## System Functionality - This project is developing a layered monolith **Spring Boot** based project (with the latest version 2.7.0.M3), on Java 18, and with an embedded database mode. - This project is an OAuth2 based project, using JWT token to secure endpoints. So you need to register first to continue using the system. - The functionality is reached based on user role, and there are three roles in the system. - **Admin**: user is a predefined user (*admin@traveladvisor.com/Admin1234*). - Admin needs to log-in first through `/login` API to get their token to contact the system. - This user can upload airports and flight routes. - Admin manages cities by adding, updating, or deleting them. - Actually, the admin can do anything in the system. - **Client**: Clients should register first before using the system through `/register` public API. - After successful registration, they can then use the public `/login` API to get a token to contact the system successfully. - Client can use all read API calls. - Clients can add, manage their comments for a city, add, update, delete their comments, and see other comments. - User can get the cheapest flight by calling `/cities/travel` API and provide airport codes for [from the city] and [to the city]. - **Public**: it is not a role, but anonymous users use APIs under public. - Use `/login` API call to log-in to the system, supplying the username and password. Then you will get a valid JWT token. - Use `/register` API call to register as a client to use the system functionalities related to the client, otherwise for he will receive *Not Authorized*. ## Getting started ### Project Management 1. I have used GitHub projects to manage my tasks in the **Flight-Advisor** project. [Project Link](https://github.com/mohamed-taman/Flight-Advisor/projects/1). 2. All MVP tasks are assigned to the **Flight Advisor API MVP** Milestone. [Milestone Link](https://github.com/mohamed-taman/Flight-Advisor/milestone/1?closed=1). 3. I used pull requests to manage and close assigned tasks. [Tasks Link](https://github.com/mohamed-taman/Flight-Advisor/issues?q=is%3Aclosed). 4. Finally, I have added releases to manage small features sprints until the final release v1.0. [Releases Link](https://github.com/mohamed-taman/Flight-Advisor/releases). 5. Have a look at opened issues for future enhancements. [Opened Issues](https://github.com/mohamed-taman/Flight-Advisor/issues?q=is%3Aopen). ### System components Structure Let's explain first the system layers structure to understand its components: ``` Flight-Advisor --> Parent folder. |- docs --> Contains system images. |- data --> Contains Airports and routes files. |- frontend --> Contains the frontend UI project. |- src/main/java - org.siriusxi.htec.fa (package) |- FlightAdvisorApplication.java --> The main starting point of the application. |- api --> Contains All REST API controllers that receive requests from the client, to process that request, and finally, return appropriate responses. |- repository --> All the database entities CRUD management services. |- domain --> Domain contains all the database modeled entities, all request and response DTOs, as well as the mappers. |- infra --> Contains all the configurations, exceptions, security management, and support utilities to the system. |- service --> Contains all the system business login, receives calls from Controllers, call repository to retrieve and manage data, then process them to return them to Controllers. ``` Now, as we have learned about different system layers and components, so it is the time then to play, let's play. ## Playing With Flight Advisor Service First things first, you need to download the following pieces of software to have fun with the project: ### Required software The following are the initially required software pieces: 1. **Maven**: it can be downloaded from https://maven.apache.org/download.cgi#. 2. **Git**: it can be downloaded from https://git-scm.com/downloads. 3. **Java 18.0.0**: it can be downloaded from https://www.oracle.com/java/technologies/downloads/#java18. 4. **Node.js 16.8+**: Latest features, and it can be downloaded from https://nodejs. org/en/download/current/. 5. **Angular CLI 12.2+**: Install it with the following command: `npm install -g @angular/cli@latest` Follow the installation guide for each software, on provided website link and check your software versions from the command line to verify that they are all installed correctly. ### Cloning It Now it is the time to open **terminal** or **git bash** command line, and then clone the project under any of your favorite places with the following command: ```bash > git clone https://github.com/mohamed-taman/Flight-Advisor.git ``` ### Using an IDE I recommend that you work with your Java code using an IDE that supports the development of Spring Boot applications such as **Spring Tool Suite** or **IntelliJ IDEA Community | Ultimate Edition**. All you have to do is fire up your favorite IDE **->** open or import the parent folder `Flight-Advisor,` and everything will be ready for you. ### Building & Running The System To build and run Flight Advisor (FA) system components, run the following command: #### Building FA Components ##### FA backend ```bash 👻 [mtaman]:Flight-Advisor ~~ ./mvnw clean package ``` Now you should expect output like this: ```JavaScript [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] [INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ flight-advisor --- [INFO] Building jar: /Flight-Advisor/target/flight-advisor-1.0.jar [INFO] [INFO] --- spring-boot-maven-plugin:2.4.0:repackage (repackage) @ flight-advisor --- [INFO] Replacing main artifact with repackaged archive [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 14.620 s [INFO] Finished at: 2021-08-15T13:40:50+01:00 [INFO] ----------------------------------------------------------------------- ``` ##### FA frontend ```bash 👻 [mtaman]:Flight-Advisor ~~ cd frontend 👻 [mtaman]:frontend ~~ npm istall && ng build ``` Now you should expect output like this: ```JavaScript removed 1 package and audited 1521 packages in 6.658s 85 packages are looking for funding run `npm fund` for details found 6 vulnerabilities (3 low, 1 moderate, 1 high, 1 critical) run `npm audit fix` to fix them, or `npm audit` for details ✔ Browser application bundle generation complete. ✔ Copying assets complete. ✔ Index html generation complete. Initial Chunk Files | Names | Size vendor.js | vendor | 4.37 MB scripts.js | scripts | 153.22 kB polyfills.js | polyfills | 149.77 kB styles.css | styles | 142.28 kB main.js | main | 13.32 kB runtime.js | runtime | 6.15 kB | Initial Total | 4.83 MB Build at: 2021-08-20T18:30:00.555Z - Hash: ccf039ad034c30696fdb - Time: 8608ms ``` #### Running the System Now it's the time to run the system, and it's straightforward, just hit the following commands: ##### FA backend ```bash 👻 [mtaman]:Flight-Advisor ~~ java --enable-preview -jar ./target/*.jar \ 👻 [mtaman]:Flight-Advisor ~+ --spring.profiles.active=prod ``` Or ```bash 👻 [mtaman]:Flight-Advisor ~~ ./mvnw spring-boot:run \ 👻 [mtaman]:Flight-Advisor ~+ -Dspring-boot.run.jvmArguments="--enable-preview" \ 👻 [mtaman]:Flight-Advisor ~+ -Dspring-boot.run.arguments="--spring.profiles.active=prod" ``` **Flight Advisor backend service** will run, with embedded H2 **database** that will be created under `db` folder and then the `flightDB.mv.db` file, and you should expect an output like this: ```javascript 2020-12-15 13:56:16.587 INFO 2981 --- [ restartedMain] o.s.b.a.h2.H2ConsoleAutoConfiguration: H2 console available at '/db-console'. Database available at 'jdbc:h2:./db/flightDB' 2020-12-15 13:56:18.081 INFO 2981 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer: Tomcat started on port(s): 8090 (http) with context path '/flight/service/api' 2020-12-15 13:56:18.581 INFO 2981 --- [ restartedMain] o.s.h.f.F.AppStartupRunner: Congratulations, Flight Advisor Application, is Up & Running :) ``` ##### FA frontend ```bash 👻 [mtaman]:frontend ~~ npm start ``` **Flight Advisor UI** will run, and you should expect an output like this: ```javascript ** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ ** ✔ Compiled successfully. ``` ### Access Flight Advisor System APIs You can play and test `Flight Advisor` APIs throughout its **OpenAPI** interface. 1. Go to the landing page at the following URL [http://localhost:8090/flight/service/api/](http://localhost:8090/flight/service/api/). 2. Follow the link on the page, and you should see the following: ![System APIs](docs/images/SystemAPI.png) 3. More beautifully with its UI at [http://localhost:4200/](http://localhost:4200/), and you expect this view for login: ![ClientLogin page](docs/images/FA-Login.png) And this view after login, to travel: ![System APIs](docs/images/FA-Travel.png) #### System Behaviour 1. First, if you want to upload airports or routes (in the data folder) using the **Files upload Management** section: 1. You need to log-in with the provided admin username/password to the `public/login` endpoint. 2. On a successful login, the response will contain an authorization token; copy it. 3. Click on the Authorize button and paste it in the only field out there, `value,` then click the `Authorize` button. 4. Now, all locks are closed, and you can use the secured APIs. 2. If you are a new client and want to access the system, you need first to register through the `/public/register` endpoint. Then follow previous point **1.1**. 3. When uploading the Airports file, countries and cities will be created automatically. 4. All search parameters are case-insensitive, and the system use like search by default. 5. To add a city, you need a country, so from the **country management** section, you can search for the country you want. 6. To manage comments, you need a city, so from the **city management** section, you can get all cities or search for a specific city. 7. You can search for all airports for a specific city to know their codes, so you can use travel service. 8. Use travel service to search for the cheapest flight from city to city, for example traveling from **CAI** (*Cairo International Airport, Egypt*) to **LAX** (*Los Angeles, USA*) the following results will be returned: ```JSON [ { "start": { "airport": "Cairo International Airport", "city": "Cairo", "country": "Egypt", "iata": "CAI" }, "through": [ { "airport": "Lester B. Pearson International Airport", "city": "Toronto", "country": "Canada", "iata": "YYZ" } ], "end": { "airport": "Los Angeles International Airport", "city": "Los Angeles", "country": "United States", "iata": "LAX" }, "price": { "total": 62.17, "currency": "US" }, "distance": { "total": 12722.2, "in": "KM" } } ] ``` ### Access Flight Advisor System Database You can access database through it online console from the following URL [http://localhost:8090/flight/service/api/db-console/](http://localhost:8090/flight/service/api/db-console/) with the following properties: - Driver class: `org.h2.Driver` - JDBC URL: `jdbc:h2:./db/flightDB` - user: `sa` - password: `Admin1234` ![System DB](docs/images/SystemDB.png) Hit test, and it should show a green bar for successful settings. So hit the **Connect** button and explore all data. ### Stopping The System Just press the `CTRL+C` keys on the terminal. ### Closing The Story Finally, I hope you enjoyed the application and find it useful. If you would like to enhance, please open **PR**, and yet give it a 🌟. ## The End Happy Coding 😊 ## License Copyright (C) 2020 Mohamed Taman, Licensed under the **MIT License**. \ No newline at end of file +# Flight Advisor Service ![GitHub release (latest by date)](https://img.shields.io/github/v/release/mohamed-taman/Flight-Advisor) [![Release Codename](https://img.shields.io/badge/codename-Advisor_3.0-yellow.svg)](https://github.com/mohamed-taman/Flight-Advisor/releases) [![BCH compliance](https://bettercodehub.com/edge/badge/mohamed-taman/Flight-Advisor?branch=main)](https://bettercodehub.com/) [![Twitter Follow](https://img.shields.io/twitter/follow/_tamanm?label=follow%20me&style=social)](https://twitter.com/_tamanm) Flight advisor Service is a set of APIs for primarily finding the cheapest flight from city A to city B based on price, and as a result it's returning all the trip information alongside the distance(s). ## System Functionality - This project is developing a layered monolith **Spring Boot** based project (with the latest version 3.0.0.M2), on Java 18, and with an embedded database mode. - This project is an OAuth2 based project, using JWT token to secure endpoints. So you need to register first to continue using the system. - The functionality is reached based on user role, and there are three roles in the system. - **Admin**: user is a predefined user (*admin@traveladvisor.com/Admin1234*). - Admin needs to log-in first through `/login` API to get their token to contact the system. - This user can upload airports and flight routes. - Admin manages cities by adding, updating, or deleting them. - Actually, the admin can do anything in the system. - **Client**: Clients should register first before using the system through `/register` public API. - After successful registration, they can then use the public `/login` API to get a token to contact the system successfully. - Client can use all read API calls. - Clients can add, manage their comments for a city, add, update, delete their comments, and see other comments. - User can get the cheapest flight by calling `/cities/travel` API and provide airport codes for [from the city] and [to the city]. - **Public**: it is not a role, but anonymous users use APIs under public. - Use `/login` API call to log-in to the system, supplying the username and password. Then you will get a valid JWT token. - Use `/register` API call to register as a client to use the system functionalities related to the client, otherwise for he will receive *Not Authorized*. ## Getting started ### Project Management 1. I have used GitHub projects to manage my tasks in the **Flight-Advisor** project. [Project Link](https://github.com/mohamed-taman/Flight-Advisor/projects/1). 2. All MVP tasks are assigned to the **Flight Advisor API MVP** Milestone. [Milestone Link](https://github.com/mohamed-taman/Flight-Advisor/milestone/1?closed=1). 3. I used pull requests to manage and close assigned tasks. [Tasks Link](https://github.com/mohamed-taman/Flight-Advisor/issues?q=is%3Aclosed). 4. Finally, I have added releases to manage small features sprints until the final release v1.0. [Releases Link](https://github.com/mohamed-taman/Flight-Advisor/releases). 5. Have a look at opened issues for future enhancements. [Opened Issues](https://github.com/mohamed-taman/Flight-Advisor/issues?q=is%3Aopen). ### System components Structure Let's explain first the system layers structure to understand its components: ``` Flight-Advisor --> Parent folder. |- docs --> Contains system images. |- data --> Contains Airports and routes files. |- frontend --> Contains the frontend UI project. |- src/main/java - org.siriusxi.htec.fa (package) |- FlightAdvisorApplication.java --> The main starting point of the application. |- api --> Contains All REST API controllers that receive requests from the client, to process that request, and finally, return appropriate responses. It contains all request and response DTOs. |- repository --> All the database entities CRUD management services. |- domain --> Domain contains all the database modeled entities. |- infra --> Contains all the configurations, exceptions, security management, support utilities, and dto<-->entities mappers, for the system support. |- service --> Contains all the system business login, receives calls from Controllers, call repository to retrieve and manage data, then process them to return back to the controllers. ``` Now, as we have learned about different system layers and components, so it is the time then to play, let's play. ## Playing With Flight Advisor Service First things first, you need to download the following pieces of software to have fun with the project: ### Required software The following are the initially required software pieces: 1. **Maven**: it can be downloaded from https://maven.apache.org/download.cgi#. 2. **Git**: it can be downloaded from https://git-scm.com/downloads. 3. **Java 18.0.0**: it can be downloaded from https://www.oracle.com/java/technologies/downloads/#java18. 4. **Node.js 17.8+**: Latest features, and it can be downloaded from https://nodejs. org/en/download/current/. 5. **Angular CLI 12.2+**: Install it with the following command: `npm install -g @angular/cli@latest` Follow the installation guide for each software, on provided website link and check your software versions from the command line to verify that they are all installed correctly. ### Cloning It Now it is the time to open **terminal** or **git bash** command line, and then clone the project under any of your favorite places with the following command: ```bash > git clone https://github.com/mohamed-taman/Flight-Advisor.git ``` ### Using an IDE I recommend that you work with your Java code using an IDE that supports the development of Spring Boot applications such as **Spring Tool Suite** or **IntelliJ IDEA Community | Ultimate Edition**. All you have to do is fire up your favorite IDE **->** open or import the parent folder `Flight-Advisor,` and everything will be ready for you. ### Building & Running The System To build and run Flight Advisor (FA) system components, run the following command: #### Building FA Components ##### FA backend ```bash 👻 [mtaman]:Flight-Advisor ~~ ./mvnw clean package ``` Now you should expect output like this: ```JavaScript [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] [INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ flight-advisor --- [INFO] Building jar: /Flight-Advisor/target/flight-advisor-3.0.jar [INFO] [INFO] --- spring-boot-maven-plugin:2.4.0:repackage (repackage) @ flight-advisor --- [INFO] Replacing main artifact with repackaged archive [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 14.620 s [INFO] Finished at: 2022-04-13T13:40:50+01:00 [INFO] ----------------------------------------------------------------------- ``` ##### FA frontend ```bash 👻 [mtaman]:Flight-Advisor ~~ cd frontend 👻 [mtaman]:frontend ~~ npm istall && ng build ``` Now you should expect output like this: ```JavaScript removed 1 package and audited 1521 packages in 6.658s 85 packages are looking for funding run `npm fund` for details found 6 vulnerabilities (3 low, 1 moderate, 1 high, 1 critical) run `npm audit fix` to fix them, or `npm audit` for details ✔ Browser application bundle generation complete. ✔ Copying assets complete. ✔ Index html generation complete. Initial Chunk Files | Names | Size vendor.js | vendor | 4.37 MB scripts.js | scripts | 153.22 kB polyfills.js | polyfills | 149.77 kB styles.css | styles | 142.28 kB main.js | main | 13.32 kB runtime.js | runtime | 6.15 kB | Initial Total | 4.83 MB Build at: 2022-04-13T18:30:00.555Z - Hash: ccf039ad034c30696fdb - Time: 8608ms ``` #### Running the System Now it's the time to run the system, and it's straightforward, just hit the following commands: ##### FA backend ```bash 👻 [mtaman]:Flight-Advisor ~~ java --enable-preview -jar ./target/*.jar \ 👻 [mtaman]:Flight-Advisor ~+ --spring.profiles.active=prod ``` Or ```bash 👻 [mtaman]:Flight-Advisor ~~ ./mvnw spring-boot:run \ 👻 [mtaman]:Flight-Advisor ~+ -Dspring-boot.run.jvmArguments="--enable-preview" \ 👻 [mtaman]:Flight-Advisor ~+ -Dspring-boot.run.arguments="--spring.profiles.active=prod" ``` **Flight Advisor backend service** will run, with embedded H2 **database** that will be created under `db` folder and then the `flightDB.mv.db` file, and you should expect an output like this: ```javascript 2022-04-13 13:56:16.587 INFO 2981 --- [ restartedMain] o.s.b.a.h2.H2ConsoleAutoConfiguration: H2 console available at '/db-console'. Database available at 'jdbc:h2:./db/flightDB' 2022-04-13 13:56:18.081 INFO 2981 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer: Tomcat started on port(s): 8090 (http) with context path 'api/v1/flight/service' 2022-04-13 13:56:18.581 INFO 2981 --- [ restartedMain] o.s.h.f.F.AppStartupRunner: Congratulations, Flight Advisor Application, is Up & Running :) ``` ##### FA frontend ```bash 👻 [mtaman]:frontend ~~ npm start ``` **Flight Advisor UI** will run, and you should expect an output like this: ```javascript ** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ ** ✔ Compiled successfully. ``` ### Access Flight Advisor System APIs You can play and test `Flight Advisor` APIs throughout its **OpenAPI** interface. 1. Go to the landing page at the following URL [http://localhost:8090/api/v1/flight/service/] (http://localhost:8090/api/v1/flight/service/). 2. Follow the link on the page, and you should see the following: ![System APIs](docs/images/SystemAPI.png) 3. More beautifully with its UI at [http://localhost:4200/](http://localhost:4200/), and you expect this view for login: ![ClientLogin page](docs/images/FA-Login.png) And this view after login, to travel: ![System APIs](docs/images/FA-Travel.png) #### System Behaviour 1. First, if you want to upload airports or routes (in the data folder) using the **Files upload Management** section: 1. You need to log-in with the provided admin username/password to the `public/login` endpoint. 2. On a successful login, the response will contain an authorization token; copy it. 3. Click on the Authorize button and paste it in the only field out there, `value,` then click the `Authorize` button. 4. Now, all locks are closed, and you can use the secured APIs. 2. If you are a new client and want to access the system, you need first to register through the `/public/register` endpoint. Then follow previous point **1.1**. 3. When uploading the Airports file, countries and cities will be created automatically. 4. All search parameters are case-insensitive, and the system use like search by default. 5. To add a city, you need a country, so from the **country management** section, you can search for the country you want. 6. To manage comments, you need a city, so from the **city management** section, you can get all cities or search for a specific city. 7. You can search for all airports for a specific city to know their codes, so you can use travel service. 8. Use travel service to search for the cheapest flight from city to city, for example traveling from **CAI** (*Cairo International Airport, Egypt*) to **LAX** (*Los Angeles, USA*) the following results will be returned: ```JSON [ { "start": { "airport": "Cairo International Airport", "city": "Cairo", "country": "Egypt", "iata": "CAI" }, "through": [ { "airport": "Lester B. Pearson International Airport", "city": "Toronto", "country": "Canada", "iata": "YYZ" } ], "end": { "airport": "Los Angeles International Airport", "city": "Los Angeles", "country": "United States", "iata": "LAX" }, "price": { "total": 62.17, "currency": "US" }, "distance": { "total": 12722.2, "in": "KM" } } ] ``` ### Access Flight Advisor System Database You can access database through it online console from the following URL [http://localhost:8090/api/v1/flight/service/db-console/] (http://localhost:8090/api/v1/flight/service/db-console/) with the following properties: - Driver class: `org.h2.Driver` - JDBC URL: `jdbc:h2:./db/flightDB` - user: `sa` - password: `Admin1234` ![System DB](docs/images/SystemDB.png) Hit test, and it should show a green bar for successful settings. So hit the **Connect** button and explore all data. ### Stopping The System Just press the `CTRL+C` keys on the terminal. ### Closing The Story Finally, I hope you enjoyed the application and find it useful. If you would like to enhance, please open **PR**, and yet give it a 🌟. ## The End Happy Coding 😊 ## License Copyright (C) 2022 Mohamed Taman, Licensed under the **MIT License**. \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index 2e7bca5..061ba06 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -31,35 +31,35 @@ "@angular/platform-browser": "~12.2.3", "@angular/platform-browser-dynamic": "~12.2.3", "@angular/router": "~12.2.3", - "@popperjs/core": "^2.9.3", - "bootstrap": "^4.6.0", + "@popperjs/core": "^2.6.0", + "bootstrap": "^4.5.3", "build": "^0.1.4", - "jquery": "^3.6.0", - "js-yaml": "^4.1.0", - "ngx-bootstrap-icons": "^1.5.3", + "jquery": "^3.5.1", + "js-yaml": "^3.14.1", + "ngx-bootstrap-icons": "^1.3.1", "popper.js": "^1.16.1", - "rxjs": "~7.3.0", - "tslib": "^2.3.1", - "uglify-js": "^3.14.1", + "rxjs": "~6.6.3", + "tslib": "^2.0.3", + "uglify-js": "^3.12.2", "zone.js": "~0.11.4" }, "devDependencies": { "@angular-devkit/build-angular": "~12.2.3", "@angular/cli": "~12.2.3", "@angular/compiler-cli": "~12.2.3", - "@types/jasmine": "~3.8.2", - "@types/node": "^16.7.6", - "codelyzer": "^6.0.2", - "jasmine-core": "~3.9.0", - "jasmine-spec-reporter": "~7.0.0", + "@types/jasmine": "~3.6.2", + "@types/node": "^14.14.14", + "codelyzer": "^6.0.1", + "jasmine-core": "~3.6.0", + "jasmine-spec-reporter": "~6.0.0", "karma": "~6.3.4", "karma-chrome-launcher": "~3.1.0", "karma-coverage": "~2.0.3", "karma-jasmine": "~4.0.1", - "karma-jasmine-html-reporter": "^1.7.0", + "karma-jasmine-html-reporter": "^1.5.4", "protractor": "~7.0.0", - "ts-node": "~10.2.1", + "ts-node": "~9.1.1", "tslint": "~6.1.3", "typescript": "~4.3.5" } -} +} \ No newline at end of file diff --git a/frontend/src/environments/environment.prod.ts b/frontend/src/environments/environment.prod.ts index 0dbf268..cb00606 100644 --- a/frontend/src/environments/environment.prod.ts +++ b/frontend/src/environments/environment.prod.ts @@ -1,4 +1,4 @@ export const environment = { production: true, - apiUrl: 'http://localhost:8090/flight/service/api' + apiUrl: 'http://localhost:8090/api/v1/flight/service' }; diff --git a/frontend/src/environments/environment.ts b/frontend/src/environments/environment.ts index 3363572..e27cc7b 100644 --- a/frontend/src/environments/environment.ts +++ b/frontend/src/environments/environment.ts @@ -5,7 +5,7 @@ export const environment = { production: false, //apiUrl: 'http://localhost:4200' - apiUrl: 'http://localhost:8090/flight/service/api' + apiUrl: 'http://localhost:8090/api/v1/flight/service' }; /* diff --git a/pom.xml b/pom.xml index 46d2208..b6f662d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,13 +6,13 @@ org.springframework.boot spring-boot-starter-parent - 2.7.0-M3 + 3.0.0-M2 org.siriusxi.htec flight-advisor - 2.8 + 3.0 Flight Advisor API Flight Advisor API Spring Boot based Application. jar @@ -58,7 +58,9 @@ - 18 + 18 + 18 + 18 UTF-8 UTF-8 @@ -67,7 +69,7 @@ 3.0.0-M5 0.11.2 1.5.0.RC1 - 1.6.7 + 2.0.0-M1 1.18.22 5.6 1.0.1 @@ -75,6 +77,8 @@ 1.4 2.11.0 4.4 + 5.6.5.Final + 2.13.2.2 @@ -91,15 +95,15 @@ org.hibernate - hibernate-core + hibernate-core-jakarta org.hibernate - hibernate-core - 5.6.5.Final + hibernate-core-jakarta + ${hibernate-core-jakarta.version} @@ -120,24 +124,45 @@ org.springframework.boot spring-boot-starter-web + + + + com.fasterxml.jackson.core + jackson-databind + + org.springdoc - springdoc-openapi-ui + springdoc-openapi-starter-webmvc-ui ${org.springdoc.version} + + + + com.fasterxml.jackson.core + jackson-databind + + - org.springframework.boot - spring-boot-starter-hateoas + com.fasterxml.jackson.core + jackson-databind + ${jackson-databind.version} - org.springdoc - springdoc-openapi-hateoas - ${org.springdoc.version} + org.springframework.boot + spring-boot-starter-hateoas + @@ -146,11 +171,6 @@ spring-boot-starter-security - - org.springdoc - springdoc-openapi-security - ${org.springdoc.version} - @@ -191,6 +211,7 @@ org.projectlombok lombok + ${lombok.version} true @@ -224,29 +245,6 @@ commons-collections4 ${commons-collections4.version} - - - commons-fileupload - commons-fileupload - ${commons-fileupload.version} - - - - commons-io - commons-io - - - - - - commons-io - commons-io - ${commons-io.version} - @@ -262,11 +260,13 @@ spring-boot-starter-test test + org.springframework.security spring-security-test test + org.hamcrest hamcrest-library @@ -300,9 +300,7 @@ maven-compiler-plugin - ${maven-compiler-plugin.version} - ${java.version} true diff --git a/src/main/java/org/siriusxi/htec/fa/FlightAdvisorApplication.java b/src/main/java/org/siriusxi/htec/fa/FlightAdvisorApplication.java index 8768628..5d1cc96 100644 --- a/src/main/java/org/siriusxi/htec/fa/FlightAdvisorApplication.java +++ b/src/main/java/org/siriusxi/htec/fa/FlightAdvisorApplication.java @@ -21,7 +21,7 @@ public static void main(String[] args) { } @Bean - public ApplicationRunner atStartup(){ + public ApplicationRunner atStartup() { return args -> log.info("Flight Advisor Application is Up & Running... "); } } diff --git a/src/main/java/org/siriusxi/htec/fa/api/AuthController.java b/src/main/java/org/siriusxi/htec/fa/api/controller/AuthController.java similarity index 77% rename from src/main/java/org/siriusxi/htec/fa/api/AuthController.java rename to src/main/java/org/siriusxi/htec/fa/api/controller/AuthController.java index 77e32d9..32c2611 100644 --- a/src/main/java/org/siriusxi/htec/fa/api/AuthController.java +++ b/src/main/java/org/siriusxi/htec/fa/api/controller/AuthController.java @@ -1,13 +1,14 @@ -package org.siriusxi.htec.fa.api; +package org.siriusxi.htec.fa.api.controller; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import lombok.extern.log4j.Log4j2; -import org.siriusxi.htec.fa.domain.dto.request.AuthRequest; -import org.siriusxi.htec.fa.domain.dto.request.CreateUserRequest; -import org.siriusxi.htec.fa.domain.dto.response.UserView; -import org.siriusxi.htec.fa.domain.mapper.UserMapper; -import org.siriusxi.htec.fa.domain.model.User; +import org.siriusxi.htec.fa.api.model.request.AuthRequest; +import org.siriusxi.htec.fa.api.model.request.CreateUserRequest; +import org.siriusxi.htec.fa.api.model.response.UserView; +import org.siriusxi.htec.fa.domain.User; +import org.siriusxi.htec.fa.infra.mapper.UserMapper; import org.siriusxi.htec.fa.infra.security.jwt.JwtTokenHelper; import org.siriusxi.htec.fa.service.UserService; import org.springframework.http.HttpHeaders; @@ -21,8 +22,6 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.HttpClientErrorException; -import javax.validation.Valid; - import static org.springframework.http.HttpStatus.UNAUTHORIZED; /** @@ -60,18 +59,18 @@ public AuthController(AuthenticationManager authenticationManager, public ResponseEntity authenticate(@RequestBody @Valid AuthRequest request) { try { var authenticate = authenticationManager - .authenticate(new UsernamePasswordAuthenticationToken( - request.username(), - request.password())); + .authenticate(new UsernamePasswordAuthenticationToken( + request.username(), + request.password())); User user = (User) authenticate.getPrincipal(); return ResponseEntity.ok() - .header(HttpHeaders.AUTHORIZATION, - JwtTokenHelper.generateAccessToken( - user.getId(), - user.getUsername())) - .body(userMapper.toView(user)); + .header(HttpHeaders.AUTHORIZATION, + JwtTokenHelper.generateAccessToken( + user.getId(), + user.getUsername())) + .body(userMapper.toView(user)); } catch (BadCredentialsException ex) { throw new HttpClientErrorException(UNAUTHORIZED, UNAUTHORIZED.getReasonPhrase()); } diff --git a/src/main/java/org/siriusxi/htec/fa/api/CityController.java b/src/main/java/org/siriusxi/htec/fa/api/controller/CityController.java similarity index 81% rename from src/main/java/org/siriusxi/htec/fa/api/CityController.java rename to src/main/java/org/siriusxi/htec/fa/api/controller/CityController.java index 9ee2fea..f9fcf1e 100644 --- a/src/main/java/org/siriusxi/htec/fa/api/CityController.java +++ b/src/main/java/org/siriusxi/htec/fa/api/controller/CityController.java @@ -1,30 +1,38 @@ -package org.siriusxi.htec.fa.api; +package org.siriusxi.htec.fa.api.controller; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.security.RolesAllowed; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Size; import lombok.extern.log4j.Log4j2; -import org.siriusxi.htec.fa.domain.dto.request.CreateCityRequest; -import org.siriusxi.htec.fa.domain.dto.request.SearchAirportRequest; -import org.siriusxi.htec.fa.domain.dto.request.SearchCityRequest; -import org.siriusxi.htec.fa.domain.dto.request.UpSrtCommentRequest; -import org.siriusxi.htec.fa.domain.dto.response.AirportView; -import org.siriusxi.htec.fa.domain.dto.response.CityView; -import org.siriusxi.htec.fa.domain.dto.response.CommentView; -import org.siriusxi.htec.fa.domain.dto.response.TripView; -import org.siriusxi.htec.fa.domain.model.Role; -import org.siriusxi.htec.fa.domain.model.User; +import org.siriusxi.htec.fa.api.model.request.CommentUpSrtRequest; +import org.siriusxi.htec.fa.api.model.request.CreateCityRequest; +import org.siriusxi.htec.fa.api.model.request.SearchAirportRequest; +import org.siriusxi.htec.fa.api.model.request.SearchCityRequest; +import org.siriusxi.htec.fa.api.model.response.AirportView; +import org.siriusxi.htec.fa.api.model.response.CityView; +import org.siriusxi.htec.fa.api.model.response.CommentView; +import org.siriusxi.htec.fa.api.model.response.TripView; +import org.siriusxi.htec.fa.domain.Role; +import org.siriusxi.htec.fa.domain.User; import org.siriusxi.htec.fa.service.CityMgmtService; import org.siriusxi.htec.fa.service.TravelService; import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; -import javax.annotation.security.RolesAllowed; -import javax.validation.Valid; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; -import javax.validation.constraints.Size; import java.util.List; /** @@ -101,7 +109,7 @@ public List travel(@RequestParam @Size(min = 3) String from, "You are traveling from and to the same destination [%s]", to)); return travelService - .travel(from.trim().toUpperCase(), to.trim().toUpperCase()); + .travel(from.trim().toUpperCase(), to.trim().toUpperCase()); } /* @@ -140,7 +148,7 @@ public List searchForCityOrCountryAirports( public CommentView addComment(@Parameter(description = "City Id") @PathVariable(name = "id") @Min(1) @Max(Integer.MAX_VALUE) int cityId, - @RequestBody @Valid UpSrtCommentRequest request) { + @RequestBody @Valid CommentUpSrtRequest request) { return cityMgmtService.addComment(getCurrentLoginUser(), cityId, request); } @@ -155,7 +163,7 @@ public void updateComment(@Parameter(description = "City Id") @Parameter(description = "Comment Id") @PathVariable("cid") @Min(1) @Max(Integer.MAX_VALUE) int commentId, - @RequestBody @Valid UpSrtCommentRequest request) { + @RequestBody @Valid CommentUpSrtRequest request) { cityMgmtService.updateComment(getCurrentLoginUser(), cityId, commentId, request); } diff --git a/src/main/java/org/siriusxi/htec/fa/api/CountryController.java b/src/main/java/org/siriusxi/htec/fa/api/controller/CountryController.java similarity index 74% rename from src/main/java/org/siriusxi/htec/fa/api/CountryController.java rename to src/main/java/org/siriusxi/htec/fa/api/controller/CountryController.java index d355275..b98bc6a 100644 --- a/src/main/java/org/siriusxi/htec/fa/api/CountryController.java +++ b/src/main/java/org/siriusxi/htec/fa/api/controller/CountryController.java @@ -1,20 +1,20 @@ -package org.siriusxi.htec.fa.api; +package org.siriusxi.htec.fa.api.controller; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.security.RolesAllowed; +import jakarta.validation.constraints.NotBlank; import lombok.extern.log4j.Log4j2; -import org.siriusxi.htec.fa.domain.dto.response.CountryView; -import org.siriusxi.htec.fa.domain.mapper.CountryMapper; -import org.siriusxi.htec.fa.domain.model.Role; +import org.siriusxi.htec.fa.api.model.response.CountryView; +import org.siriusxi.htec.fa.domain.Role; +import org.siriusxi.htec.fa.infra.mapper.CountryMapper; import org.siriusxi.htec.fa.repository.CountryRepository; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import javax.annotation.security.RolesAllowed; -import javax.validation.constraints.NotBlank; import java.util.Set; /** @@ -45,16 +45,16 @@ public CountryController(CountryRepository countryRepository, CountryMapper mapp @GetMapping public Set getAllCountries() { return mapper - .toViews(countryRepository - .findAllByNameIgnoreCaseIsLike("%%")); + .toViews(countryRepository + .findAllByNameIgnoreCaseIsLike("%%")); } @Operation(security = {@SecurityRequirement(name = "bearer-key")}) @GetMapping("search") public Set searchCountries(@RequestParam @NotBlank String name) { return mapper - .toViews(countryRepository - .findAllByNameIgnoreCaseIsLike("%" + name + "%")); + .toViews(countryRepository + .findAllByNameIgnoreCaseIsLike("%" + name + "%")); } } diff --git a/src/main/java/org/siriusxi/htec/fa/api/FileUploadController.java b/src/main/java/org/siriusxi/htec/fa/api/controller/FileUploadController.java similarity index 86% rename from src/main/java/org/siriusxi/htec/fa/api/FileUploadController.java rename to src/main/java/org/siriusxi/htec/fa/api/controller/FileUploadController.java index d721742..1bf8523 100644 --- a/src/main/java/org/siriusxi/htec/fa/api/FileUploadController.java +++ b/src/main/java/org/siriusxi/htec/fa/api/controller/FileUploadController.java @@ -1,4 +1,4 @@ -package org.siriusxi.htec.fa.api; +package org.siriusxi.htec.fa.api.controller; import com.opencsv.bean.BeanVerifier; import com.opencsv.bean.CsvToBean; @@ -10,15 +10,16 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.security.RolesAllowed; import lombok.extern.log4j.Log4j2; -import org.siriusxi.htec.fa.domain.dto.upload.airport.AirportDto; -import org.siriusxi.htec.fa.domain.dto.upload.airport.verifer.AirportBeanVerifier; -import org.siriusxi.htec.fa.domain.dto.upload.route.RouteDto; -import org.siriusxi.htec.fa.domain.dto.upload.route.verifer.RouteBeanVerifier; -import org.siriusxi.htec.fa.domain.mapper.AirportMapper; -import org.siriusxi.htec.fa.domain.mapper.RouteMapper; -import org.siriusxi.htec.fa.domain.model.Country; -import org.siriusxi.htec.fa.domain.model.Role; +import org.siriusxi.htec.fa.api.model.upload.airport.AirportDto; +import org.siriusxi.htec.fa.api.model.upload.airport.verifer.AirportBeanVerifier; +import org.siriusxi.htec.fa.api.model.upload.route.RouteDto; +import org.siriusxi.htec.fa.api.model.upload.route.verifer.RouteBeanVerifier; +import org.siriusxi.htec.fa.domain.Country; +import org.siriusxi.htec.fa.domain.Role; +import org.siriusxi.htec.fa.infra.mapper.AirportMapper; +import org.siriusxi.htec.fa.infra.mapper.RouteMapper; import org.siriusxi.htec.fa.repository.AirportRepository; import org.siriusxi.htec.fa.repository.CityRepository; import org.siriusxi.htec.fa.repository.CountryRepository; @@ -31,7 +32,6 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; -import javax.annotation.security.RolesAllowed; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -117,7 +117,7 @@ public ResponseEntity uploadAirports(@Parameter(name = "file", required .map(airportDto -> { Country country = countryRepository - .findOrSaveBy(airportDto.getCountry()); + .findOrSaveBy(airportDto.getCountry()); airportDto.setCountryId(country.getId()); @@ -182,15 +182,15 @@ else if (airportRepository.count() == 0) { */ routeRepository .saveAll(routes - .stream() - // filter routes doesn't exists - .filter(dto -> - airportRepository.findById(dto.getSrcAirportId()).isPresent() && - airportRepository.findById(dto.getDestAirportId()).isPresent()) - // converting to - .map(routeMapper::toModel) - // Then collect them to list - .toList()); + .stream() + // filter routes doesn't exists + .filter(dto -> + airportRepository.findById(dto.getSrcAirportId()).isPresent() && + airportRepository.findById(dto.getDestAirportId()).isPresent()) + // converting to + .map(routeMapper::toModel) + // Then collect them to list + .toList()); } catch (Exception ex) { log.error("Error while reading routes file.", ex); @@ -222,10 +222,10 @@ private List parseCsvContent(InputStream content, Class clazz, try (Reader reader = new BufferedReader(new InputStreamReader(content))) { // create csv bean reader CsvToBean csvToBeans = new CsvToBeanBuilder(reader) - .withType(clazz) - .withVerifier(beanVerifier) - .withIgnoreLeadingWhiteSpace(true) - .build(); + .withType(clazz) + .withVerifier(beanVerifier) + .withIgnoreLeadingWhiteSpace(true) + .build(); // convert `CsvToBean` object to a dto list dtoList = csvToBeans.parse(); diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/request/AuthRequest.java b/src/main/java/org/siriusxi/htec/fa/api/model/request/AuthRequest.java similarity index 69% rename from src/main/java/org/siriusxi/htec/fa/domain/dto/request/AuthRequest.java rename to src/main/java/org/siriusxi/htec/fa/api/model/request/AuthRequest.java index 0af41a8..6000b4c 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/request/AuthRequest.java +++ b/src/main/java/org/siriusxi/htec/fa/api/model/request/AuthRequest.java @@ -1,10 +1,9 @@ -package org.siriusxi.htec.fa.domain.dto.request; +package org.siriusxi.htec.fa.api.model.request; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; - -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; @JsonIgnoreProperties(ignoreUnknown = true) public record AuthRequest( diff --git a/src/main/java/org/siriusxi/htec/fa/api/model/request/CommentUpSrtRequest.java b/src/main/java/org/siriusxi/htec/fa/api/model/request/CommentUpSrtRequest.java new file mode 100644 index 0000000..66b2ec5 --- /dev/null +++ b/src/main/java/org/siriusxi/htec/fa/api/model/request/CommentUpSrtRequest.java @@ -0,0 +1,11 @@ +package org.siriusxi.htec.fa.api.model.request; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import jakarta.validation.constraints.NotBlank; + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonRootName("CommentRequest") +public record CommentUpSrtRequest(@JsonProperty("comment") @NotBlank String comment) { +} diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/request/CreateCityRequest.java b/src/main/java/org/siriusxi/htec/fa/api/model/request/CreateCityRequest.java similarity index 75% rename from src/main/java/org/siriusxi/htec/fa/domain/dto/request/CreateCityRequest.java rename to src/main/java/org/siriusxi/htec/fa/api/model/request/CreateCityRequest.java index a8eb97a..1e5ea75 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/request/CreateCityRequest.java +++ b/src/main/java/org/siriusxi/htec/fa/api/model/request/CreateCityRequest.java @@ -1,12 +1,11 @@ -package org.siriusxi.htec.fa.domain.dto.request; +package org.siriusxi.htec.fa.api.model.request; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.PositiveOrZero; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.PositiveOrZero; +import jakarta.validation.constraints.Size; @JsonIgnoreProperties(ignoreUnknown = true) @JsonPropertyOrder({"name", "country", "countryId", "description"}) diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/request/CreateUserRequest.java b/src/main/java/org/siriusxi/htec/fa/api/model/request/CreateUserRequest.java similarity index 79% rename from src/main/java/org/siriusxi/htec/fa/domain/dto/request/CreateUserRequest.java rename to src/main/java/org/siriusxi/htec/fa/api/model/request/CreateUserRequest.java index 518d7e4..e5d5b74 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/request/CreateUserRequest.java +++ b/src/main/java/org/siriusxi/htec/fa/api/model/request/CreateUserRequest.java @@ -1,11 +1,10 @@ -package org.siriusxi.htec.fa.domain.dto.request; +package org.siriusxi.htec.fa.api.model.request; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; - -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; @JsonIgnoreProperties(ignoreUnknown = true) public record CreateUserRequest(@JsonProperty("firstName") @NotBlank String firstName, diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/request/SearchAirportRequest.java b/src/main/java/org/siriusxi/htec/fa/api/model/request/SearchAirportRequest.java similarity index 72% rename from src/main/java/org/siriusxi/htec/fa/domain/dto/request/SearchAirportRequest.java rename to src/main/java/org/siriusxi/htec/fa/api/model/request/SearchAirportRequest.java index 3f9c1bc..da658e3 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/request/SearchAirportRequest.java +++ b/src/main/java/org/siriusxi/htec/fa/api/model/request/SearchAirportRequest.java @@ -1,9 +1,8 @@ -package org.siriusxi.htec.fa.domain.dto.request; +package org.siriusxi.htec.fa.api.model.request; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; - -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; @JsonIgnoreProperties(ignoreUnknown = true) public record SearchAirportRequest(@JsonProperty("byName") @NotBlank String name) { diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/request/SearchCityRequest.java b/src/main/java/org/siriusxi/htec/fa/api/model/request/SearchCityRequest.java similarity index 82% rename from src/main/java/org/siriusxi/htec/fa/domain/dto/request/SearchCityRequest.java rename to src/main/java/org/siriusxi/htec/fa/api/model/request/SearchCityRequest.java index 0f61b24..d81be8e 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/request/SearchCityRequest.java +++ b/src/main/java/org/siriusxi/htec/fa/api/model/request/SearchCityRequest.java @@ -1,4 +1,4 @@ -package org.siriusxi.htec.fa.domain.dto.request; +package org.siriusxi.htec.fa.api.model.request; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/response/AirportView.java b/src/main/java/org/siriusxi/htec/fa/api/model/response/AirportView.java similarity index 92% rename from src/main/java/org/siriusxi/htec/fa/domain/dto/response/AirportView.java rename to src/main/java/org/siriusxi/htec/fa/api/model/response/AirportView.java index 32fabae..3f00486 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/response/AirportView.java +++ b/src/main/java/org/siriusxi/htec/fa/api/model/response/AirportView.java @@ -1,4 +1,4 @@ -package org.siriusxi.htec.fa.domain.dto.response; +package org.siriusxi.htec.fa.api.model.response; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/response/CityView.java b/src/main/java/org/siriusxi/htec/fa/api/model/response/CityView.java similarity index 91% rename from src/main/java/org/siriusxi/htec/fa/domain/dto/response/CityView.java rename to src/main/java/org/siriusxi/htec/fa/api/model/response/CityView.java index c28bedc..ed183c6 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/response/CityView.java +++ b/src/main/java/org/siriusxi/htec/fa/api/model/response/CityView.java @@ -1,4 +1,4 @@ -package org.siriusxi.htec.fa.domain.dto.response; +package org.siriusxi.htec.fa.api.model.response; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/response/CommentView.java b/src/main/java/org/siriusxi/htec/fa/api/model/response/CommentView.java similarity index 93% rename from src/main/java/org/siriusxi/htec/fa/domain/dto/response/CommentView.java rename to src/main/java/org/siriusxi/htec/fa/api/model/response/CommentView.java index f5fbab4..c13843e 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/response/CommentView.java +++ b/src/main/java/org/siriusxi/htec/fa/api/model/response/CommentView.java @@ -1,4 +1,4 @@ -package org.siriusxi.htec.fa.domain.dto.response; +package org.siriusxi.htec.fa.api.model.response; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/response/CountryView.java b/src/main/java/org/siriusxi/htec/fa/api/model/response/CountryView.java similarity index 76% rename from src/main/java/org/siriusxi/htec/fa/domain/dto/response/CountryView.java rename to src/main/java/org/siriusxi/htec/fa/api/model/response/CountryView.java index aaa9337..ec2b014 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/response/CountryView.java +++ b/src/main/java/org/siriusxi/htec/fa/api/model/response/CountryView.java @@ -1,4 +1,4 @@ -package org.siriusxi.htec.fa.domain.dto.response; +package org.siriusxi.htec.fa.api.model.response; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/response/TripView.java b/src/main/java/org/siriusxi/htec/fa/api/model/response/TripView.java similarity index 93% rename from src/main/java/org/siriusxi/htec/fa/domain/dto/response/TripView.java rename to src/main/java/org/siriusxi/htec/fa/api/model/response/TripView.java index b3448a9..25ea819 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/response/TripView.java +++ b/src/main/java/org/siriusxi/htec/fa/api/model/response/TripView.java @@ -1,4 +1,4 @@ -package org.siriusxi.htec.fa.domain.dto.response; +package org.siriusxi.htec.fa.api.model.response; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/response/UserView.java b/src/main/java/org/siriusxi/htec/fa/api/model/response/UserView.java similarity index 89% rename from src/main/java/org/siriusxi/htec/fa/domain/dto/response/UserView.java rename to src/main/java/org/siriusxi/htec/fa/api/model/response/UserView.java index 62b4382..d9100ad 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/response/UserView.java +++ b/src/main/java/org/siriusxi/htec/fa/api/model/response/UserView.java @@ -1,4 +1,4 @@ -package org.siriusxi.htec.fa.domain.dto.response; +package org.siriusxi.htec.fa.api.model.response; import com.fasterxml.jackson.annotation.JsonProperty; @@ -32,6 +32,6 @@ public int hashCode() { @Override public String toString() { return "UserView{ id= %s, username= %s, firstName= %s, lastName= %s , authorities= %s}" - .formatted(id, username, firstName, lastName, Arrays.toString(authorities)); + .formatted(id, username, firstName, lastName, Arrays.toString(authorities)); } } diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/upload/airport/AirportDto.java b/src/main/java/org/siriusxi/htec/fa/api/model/upload/airport/AirportDto.java similarity index 92% rename from src/main/java/org/siriusxi/htec/fa/domain/dto/upload/airport/AirportDto.java rename to src/main/java/org/siriusxi/htec/fa/api/model/upload/airport/AirportDto.java index 1c0ed6c..9c4d257 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/upload/airport/AirportDto.java +++ b/src/main/java/org/siriusxi/htec/fa/api/model/upload/airport/AirportDto.java @@ -1,9 +1,9 @@ -package org.siriusxi.htec.fa.domain.dto.upload.airport; +package org.siriusxi.htec.fa.api.model.upload.airport; import com.opencsv.bean.CsvBindByPosition; import com.opencsv.bean.processor.PreAssignmentProcessor; import lombok.Data; -import org.siriusxi.htec.fa.domain.dto.upload.converter.ConvertUnwantedStringsToDefault; +import org.siriusxi.htec.fa.api.model.upload.converter.ConvertUnwantedStringsToDefault; import java.math.BigDecimal; diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/upload/airport/verifer/AirportBeanVerifier.java b/src/main/java/org/siriusxi/htec/fa/api/model/upload/airport/verifer/AirportBeanVerifier.java similarity index 68% rename from src/main/java/org/siriusxi/htec/fa/domain/dto/upload/airport/verifer/AirportBeanVerifier.java rename to src/main/java/org/siriusxi/htec/fa/api/model/upload/airport/verifer/AirportBeanVerifier.java index 3f39b05..0b66a71 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/upload/airport/verifer/AirportBeanVerifier.java +++ b/src/main/java/org/siriusxi/htec/fa/api/model/upload/airport/verifer/AirportBeanVerifier.java @@ -1,7 +1,7 @@ -package org.siriusxi.htec.fa.domain.dto.upload.airport.verifer; +package org.siriusxi.htec.fa.api.model.upload.airport.verifer; import com.opencsv.bean.BeanVerifier; -import org.siriusxi.htec.fa.domain.dto.upload.airport.AirportDto; +import org.siriusxi.htec.fa.api.model.upload.airport.AirportDto; public class AirportBeanVerifier implements BeanVerifier { @Override diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/upload/converter/ConvertUnwantedStringsToDefault.java b/src/main/java/org/siriusxi/htec/fa/api/model/upload/converter/ConvertUnwantedStringsToDefault.java similarity index 90% rename from src/main/java/org/siriusxi/htec/fa/domain/dto/upload/converter/ConvertUnwantedStringsToDefault.java rename to src/main/java/org/siriusxi/htec/fa/api/model/upload/converter/ConvertUnwantedStringsToDefault.java index 8a78be5..b5263ff 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/upload/converter/ConvertUnwantedStringsToDefault.java +++ b/src/main/java/org/siriusxi/htec/fa/api/model/upload/converter/ConvertUnwantedStringsToDefault.java @@ -1,4 +1,4 @@ -package org.siriusxi.htec.fa.domain.dto.upload.converter; +package org.siriusxi.htec.fa.api.model.upload.converter; import com.opencsv.bean.processor.StringProcessor; diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/upload/route/RouteDto.java b/src/main/java/org/siriusxi/htec/fa/api/model/upload/route/RouteDto.java similarity index 90% rename from src/main/java/org/siriusxi/htec/fa/domain/dto/upload/route/RouteDto.java rename to src/main/java/org/siriusxi/htec/fa/api/model/upload/route/RouteDto.java index d80a228..260b0c4 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/upload/route/RouteDto.java +++ b/src/main/java/org/siriusxi/htec/fa/api/model/upload/route/RouteDto.java @@ -1,9 +1,9 @@ -package org.siriusxi.htec.fa.domain.dto.upload.route; +package org.siriusxi.htec.fa.api.model.upload.route; import com.opencsv.bean.CsvBindByPosition; import com.opencsv.bean.processor.PreAssignmentProcessor; import lombok.Data; -import org.siriusxi.htec.fa.domain.dto.upload.converter.ConvertUnwantedStringsToDefault; +import org.siriusxi.htec.fa.api.model.upload.converter.ConvertUnwantedStringsToDefault; /** * @author Mohamed Taman diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/upload/route/verifer/RouteBeanVerifier.java b/src/main/java/org/siriusxi/htec/fa/api/model/upload/route/verifer/RouteBeanVerifier.java similarity index 72% rename from src/main/java/org/siriusxi/htec/fa/domain/dto/upload/route/verifer/RouteBeanVerifier.java rename to src/main/java/org/siriusxi/htec/fa/api/model/upload/route/verifer/RouteBeanVerifier.java index 2d20931..652263f 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/upload/route/verifer/RouteBeanVerifier.java +++ b/src/main/java/org/siriusxi/htec/fa/api/model/upload/route/verifer/RouteBeanVerifier.java @@ -1,7 +1,7 @@ -package org.siriusxi.htec.fa.domain.dto.upload.route.verifer; +package org.siriusxi.htec.fa.api.model.upload.route.verifer; import com.opencsv.bean.BeanVerifier; -import org.siriusxi.htec.fa.domain.dto.upload.route.RouteDto; +import org.siriusxi.htec.fa.api.model.upload.route.RouteDto; public class RouteBeanVerifier implements BeanVerifier { @Override diff --git a/src/main/java/org/siriusxi/htec/fa/domain/model/Airport.java b/src/main/java/org/siriusxi/htec/fa/domain/Airport.java similarity index 82% rename from src/main/java/org/siriusxi/htec/fa/domain/model/Airport.java rename to src/main/java/org/siriusxi/htec/fa/domain/Airport.java index 8a24f08..5f3e9fb 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/model/Airport.java +++ b/src/main/java/org/siriusxi/htec/fa/domain/Airport.java @@ -1,17 +1,30 @@ -package org.siriusxi.htec.fa.domain.model; +package org.siriusxi.htec.fa.domain; -import lombok.*; +import jakarta.persistence.Basic; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; import org.hibernate.Hibernate; -import javax.persistence.*; import java.io.Serial; import java.io.Serializable; import java.math.BigDecimal; import java.util.List; import java.util.Objects; -import static javax.persistence.EnumType.STRING; -import static javax.persistence.FetchType.LAZY; +import static jakarta.persistence.EnumType.STRING; +import static jakarta.persistence.FetchType.LAZY; /** * @author Mohamed Taman @@ -25,103 +38,81 @@ @RequiredArgsConstructor public class Airport implements Serializable { - public enum Dst { - E, A, S, O, Z, N, U - } - - public Airport(Integer airportId) { - this.airportId = airportId; - } - @Serial private static final long serialVersionUID = 6913599167936010779L; - @Id @Basic(optional = false) @Column(name = "AIRPORT_ID", nullable = false) private Integer airportId; - @NonNull @Basic(optional = false) @Column(nullable = false) private String name; - @NonNull @Basic(optional = false) @Column(name = "CITY", nullable = false, length = 100) private String cityName; - @NonNull @Basic(optional = false) @Column(name = "COUNTRY", nullable = false, length = 100) private String countryName; - @Column(length = 3) private String iata; - @Column(length = 4) private String icao; - @NonNull @Basic(optional = false) @Column(nullable = false, precision = 12, scale = 6) private BigDecimal latitude; - @NonNull @Basic(optional = false) @Column(nullable = false, precision = 12, scale = 6) private BigDecimal longitude; - @NonNull private Integer altitude; - @NonNull private Float timezone; - @NonNull @Enumerated(STRING) @Basic(optional = false) @Column(nullable = false) private Dst dst; - @NonNull @Column(length = 50) private String tz; - @NonNull @Basic(optional = false) @Column(nullable = false, length = 50) private String type; - @NonNull @Basic(optional = false) @Column(name = "DATA_SOURCE", nullable = false) private String dataSource; - @OneToMany(mappedBy = "destinationAirport", fetch = LAZY) @ToString.Exclude private List destinationRoutes; - @OneToMany(mappedBy = "sourceAirport", fetch = LAZY) @ToString.Exclude private List sourceRoutes; - @JoinColumn(name = "CITY_ID", referencedColumnName = "ID", nullable = false) @ManyToOne(optional = false, fetch = LAZY) @ToString.Exclude private City city; - @JoinColumn(name = "COUNTRY_ID", referencedColumnName = "ID", nullable = false) @ManyToOne(optional = false, fetch = LAZY) @ToString.Exclude private Country country; + public Airport(Integer airportId) { + this.airportId = airportId; + } + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; - + return Objects.equals(airportId, ((Airport) o).airportId); } @@ -129,4 +120,8 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(latitude, longitude, altitude); } + + public enum Dst { + E, A, S, O, Z, N, U + } } diff --git a/src/main/java/org/siriusxi/htec/fa/domain/model/City.java b/src/main/java/org/siriusxi/htec/fa/domain/City.java similarity index 72% rename from src/main/java/org/siriusxi/htec/fa/domain/model/City.java rename to src/main/java/org/siriusxi/htec/fa/domain/City.java index 0566471..9ada762 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/model/City.java +++ b/src/main/java/org/siriusxi/htec/fa/domain/City.java @@ -1,17 +1,30 @@ -package org.siriusxi.htec.fa.domain.model; +package org.siriusxi.htec.fa.domain; -import lombok.*; +import jakarta.persistence.Basic; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; import org.hibernate.Hibernate; -import javax.persistence.*; import java.io.Serial; import java.io.Serializable; import java.util.List; import java.util.Objects; -import static javax.persistence.CascadeType.ALL; -import static javax.persistence.FetchType.LAZY; -import static javax.persistence.GenerationType.IDENTITY; +import static jakarta.persistence.CascadeType.ALL; +import static jakarta.persistence.FetchType.LAZY; +import static jakarta.persistence.GenerationType.IDENTITY; /** * @author Mohamed Taman @@ -71,7 +84,7 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; - + return Objects.equals(id, ((City) o).id); } diff --git a/src/main/java/org/siriusxi/htec/fa/domain/model/Comment.java b/src/main/java/org/siriusxi/htec/fa/domain/Comment.java similarity index 73% rename from src/main/java/org/siriusxi/htec/fa/domain/model/Comment.java rename to src/main/java/org/siriusxi/htec/fa/domain/Comment.java index f0310b0..58a9eb7 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/model/Comment.java +++ b/src/main/java/org/siriusxi/htec/fa/domain/Comment.java @@ -1,17 +1,29 @@ -package org.siriusxi.htec.fa.domain.model; +package org.siriusxi.htec.fa.domain; -import lombok.*; +import jakarta.persistence.Basic; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; import org.hibernate.Hibernate; -import javax.persistence.*; import java.io.Serial; import java.io.Serializable; import java.time.LocalDateTime; import java.util.Objects; +import static jakarta.persistence.FetchType.LAZY; +import static jakarta.persistence.GenerationType.IDENTITY; import static java.time.LocalDateTime.now; -import static javax.persistence.FetchType.LAZY; -import static javax.persistence.GenerationType.IDENTITY; /** * @author Mohamed Taman @@ -62,7 +74,7 @@ public String toString() { return """ Comment{id= %d, comment= %s, createdAt= %s, \ updatedOn= %s, city= "%s", user= %s }""" - .formatted(id, comment, createdAt, updatedAt, city.getName(), user.getUserUuid()); + .formatted(id, comment, createdAt, updatedAt, city.getName(), user.getUserUuid()); } @Override diff --git a/src/main/java/org/siriusxi/htec/fa/domain/model/Country.java b/src/main/java/org/siriusxi/htec/fa/domain/Country.java similarity index 70% rename from src/main/java/org/siriusxi/htec/fa/domain/model/Country.java rename to src/main/java/org/siriusxi/htec/fa/domain/Country.java index df99409..5788565 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/model/Country.java +++ b/src/main/java/org/siriusxi/htec/fa/domain/Country.java @@ -1,16 +1,28 @@ -package org.siriusxi.htec.fa.domain.model; +package org.siriusxi.htec.fa.domain; -import lombok.*; +import jakarta.persistence.Basic; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; import org.hibernate.Hibernate; -import javax.persistence.*; import java.io.Serial; import java.io.Serializable; import java.util.List; import java.util.Objects; -import static javax.persistence.CascadeType.ALL; -import static javax.persistence.FetchType.LAZY; +import static jakarta.persistence.CascadeType.ALL; +import static jakarta.persistence.FetchType.LAZY; /** * @author Mohamed Taman @@ -25,32 +37,28 @@ @RequiredArgsConstructor public class Country implements Serializable { - public Country(Integer id) { - this.id = id; - } - @Serial private static final long serialVersionUID = -9057344199173138205L; - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Basic(optional = false) @Column(nullable = false) private Integer id; - @NonNull @Basic(optional = false) @Column(nullable = false, length = 100) private String name; - @OneToMany(cascade = ALL, mappedBy = "country", fetch = LAZY) @ToString.Exclude private List airports; - @OneToMany(cascade = ALL, mappedBy = "country", fetch = LAZY) @ToString.Exclude private List cities; + public Country(Integer id) { + this.id = id; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/org/siriusxi/htec/fa/domain/model/Role.java b/src/main/java/org/siriusxi/htec/fa/domain/Role.java similarity index 76% rename from src/main/java/org/siriusxi/htec/fa/domain/model/Role.java rename to src/main/java/org/siriusxi/htec/fa/domain/Role.java index 2da2f58..1fac7a0 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/model/Role.java +++ b/src/main/java/org/siriusxi/htec/fa/domain/Role.java @@ -1,10 +1,19 @@ -package org.siriusxi.htec.fa.domain.model; +package org.siriusxi.htec.fa.domain; -import lombok.*; +import jakarta.persistence.Basic; +import jakarta.persistence.Column; +import jakarta.persistence.EmbeddedId; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; import org.hibernate.Hibernate; import org.springframework.security.core.GrantedAuthority; -import javax.persistence.*; import java.io.Serial; import java.util.Objects; diff --git a/src/main/java/org/siriusxi/htec/fa/domain/model/RolePK.java b/src/main/java/org/siriusxi/htec/fa/domain/RolePK.java similarity index 74% rename from src/main/java/org/siriusxi/htec/fa/domain/model/RolePK.java rename to src/main/java/org/siriusxi/htec/fa/domain/RolePK.java index 8112f11..6d732ce 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/model/RolePK.java +++ b/src/main/java/org/siriusxi/htec/fa/domain/RolePK.java @@ -1,11 +1,16 @@ -package org.siriusxi.htec.fa.domain.model; +package org.siriusxi.htec.fa.domain; -import lombok.*; +import jakarta.persistence.Basic; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; import org.hibernate.Hibernate; -import javax.persistence.Basic; -import javax.persistence.Column; -import javax.persistence.Embeddable; import java.io.Serializable; import java.util.Objects; diff --git a/src/main/java/org/siriusxi/htec/fa/domain/model/Route.java b/src/main/java/org/siriusxi/htec/fa/domain/Route.java similarity index 76% rename from src/main/java/org/siriusxi/htec/fa/domain/model/Route.java rename to src/main/java/org/siriusxi/htec/fa/domain/Route.java index 142dcf5..760e595 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/model/Route.java +++ b/src/main/java/org/siriusxi/htec/fa/domain/Route.java @@ -1,16 +1,24 @@ -package org.siriusxi.htec.fa.domain.model; +package org.siriusxi.htec.fa.domain; -import lombok.*; +import jakarta.persistence.Column; +import jakarta.persistence.EmbeddedId; +import jakarta.persistence.Entity; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; import org.hibernate.Hibernate; -import javax.persistence.*; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; import java.io.Serial; import java.io.Serializable; import java.util.Objects; -import static javax.persistence.FetchType.LAZY; +import static jakarta.persistence.FetchType.LAZY; /** * @author Mohamed Taman diff --git a/src/main/java/org/siriusxi/htec/fa/domain/model/RoutePK.java b/src/main/java/org/siriusxi/htec/fa/domain/RoutePK.java similarity index 70% rename from src/main/java/org/siriusxi/htec/fa/domain/model/RoutePK.java rename to src/main/java/org/siriusxi/htec/fa/domain/RoutePK.java index 5cd348c..05fdf7d 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/model/RoutePK.java +++ b/src/main/java/org/siriusxi/htec/fa/domain/RoutePK.java @@ -1,11 +1,16 @@ -package org.siriusxi.htec.fa.domain.model; +package org.siriusxi.htec.fa.domain; -import lombok.*; +import jakarta.persistence.Basic; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; import org.hibernate.Hibernate; -import javax.persistence.Basic; -import javax.persistence.Column; -import javax.persistence.Embeddable; import java.io.Serializable; import java.util.Objects; @@ -24,7 +29,7 @@ public class RoutePK implements Serializable { @NonNull @Basic(optional = false) - @Column(name = "DESTINATION_AIRPORT",nullable = false) + @Column(name = "DESTINATION_AIRPORT", nullable = false) private String destination; @Override diff --git a/src/main/java/org/siriusxi/htec/fa/domain/model/User.java b/src/main/java/org/siriusxi/htec/fa/domain/User.java similarity index 78% rename from src/main/java/org/siriusxi/htec/fa/domain/model/User.java rename to src/main/java/org/siriusxi/htec/fa/domain/User.java index 16b822c..ebd159e 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/model/User.java +++ b/src/main/java/org/siriusxi/htec/fa/domain/User.java @@ -1,10 +1,24 @@ -package org.siriusxi.htec.fa.domain.model; +package org.siriusxi.htec.fa.domain; -import lombok.*; +import jakarta.persistence.Basic; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; import org.hibernate.Hibernate; import org.springframework.security.core.userdetails.UserDetails; -import javax.persistence.*; import java.io.Serial; import java.io.Serializable; import java.util.HashSet; @@ -12,9 +26,9 @@ import java.util.Objects; import java.util.Set; -import static javax.persistence.CascadeType.ALL; -import static javax.persistence.FetchType.EAGER; -import static javax.persistence.FetchType.LAZY; +import static jakarta.persistence.CascadeType.ALL; +import static jakarta.persistence.FetchType.EAGER; +import static jakarta.persistence.FetchType.LAZY; /** * Class represents User domain model, as JPA Entity. @@ -23,7 +37,7 @@ * @version 1.0 */ @Entity -@Table( name ="users", +@Table(name = "users", catalog = "FLIGHTDB", schema = "PUBLIC", uniqueConstraints = { @@ -36,56 +50,49 @@ @RequiredArgsConstructor public class User implements UserDetails, Serializable { - public User(Integer id) { this.id = id;} - @Serial private static final long serialVersionUID = 5666668516577592568L; - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Basic(optional = false) @Column(nullable = false) private Integer id; - @Basic(optional = false) @Column(name = "USER_UUID", nullable = false, updatable = false) @ToString.Exclude private String userUuid; - @NonNull @Basic(optional = false) @Column(name = "FIRST_NAME", nullable = false, length = 100) private String firstName; - @NonNull @Basic(optional = false) @Column(name = "LAST_NAME", nullable = false, length = 100) private String lastName; - @NonNull @Basic(optional = false) @Column(nullable = false) @ToString.Exclude private String username; - @NonNull @Basic(optional = false) @Column(nullable = false) @ToString.Exclude private String password; - @OneToMany(cascade = ALL, mappedBy = "user", fetch = LAZY) @ToString.Exclude private List comments; - @JoinColumn(name = "USER_ID", referencedColumnName = "ID", nullable = false, insertable = false, updatable = false) @OneToMany(cascade = ALL, fetch = EAGER) private Set authorities = new HashSet<>(); - @ToString.Exclude private boolean enabled = true; + public User(Integer id) { + this.id = id; + } + public void setAuthorities(Set roles) { for (Role role : roles) { role.setRolePK(new RolePK(this.getId(), role.getAuthority())); @@ -100,8 +107,8 @@ public void setAuthorities(String... authorities) { public String getFullName() { return getFirstName() - .concat(" ") - .concat(getLastName()); + .concat(" ") + .concat(getLastName()); } @Override diff --git a/src/main/java/org/siriusxi/htec/fa/domain/dto/request/UpSrtCommentRequest.java b/src/main/java/org/siriusxi/htec/fa/domain/dto/request/UpSrtCommentRequest.java deleted file mode 100644 index eb1b0d1..0000000 --- a/src/main/java/org/siriusxi/htec/fa/domain/dto/request/UpSrtCommentRequest.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.siriusxi.htec.fa.domain.dto.request; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -import javax.validation.constraints.NotBlank; - -@JsonIgnoreProperties(ignoreUnknown = true) -public record UpSrtCommentRequest(@JsonProperty("comment") @NotBlank String comment) { -} diff --git a/src/main/java/org/siriusxi/htec/fa/domain/model/vo/RouteView.java b/src/main/java/org/siriusxi/htec/fa/domain/vo/RouteView.java similarity index 62% rename from src/main/java/org/siriusxi/htec/fa/domain/model/vo/RouteView.java rename to src/main/java/org/siriusxi/htec/fa/domain/vo/RouteView.java index ccf5029..3d79c16 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/model/vo/RouteView.java +++ b/src/main/java/org/siriusxi/htec/fa/domain/vo/RouteView.java @@ -1,4 +1,4 @@ -package org.siriusxi.htec.fa.domain.model.vo; +package org.siriusxi.htec.fa.domain.vo; public record RouteView(String source, String destination, double price) { } diff --git a/src/main/java/org/siriusxi/htec/fa/infra/algorithm/distance/DistanceAlgorithm.java b/src/main/java/org/siriusxi/htec/fa/infra/algorithm/distance/DistanceAlgorithm.java index 3c3fe01..da49baf 100644 --- a/src/main/java/org/siriusxi/htec/fa/infra/algorithm/distance/DistanceAlgorithm.java +++ b/src/main/java/org/siriusxi/htec/fa/infra/algorithm/distance/DistanceAlgorithm.java @@ -15,38 +15,6 @@ */ public sealed interface DistanceAlgorithm permits HaversineAlgorithm, OrthodromicAlgorithm { - /** - * Enum to represent the implemented distance calculators algorithms. - */ - enum Type { - HAVERSINE, - ORTHODROMIC - } - - /** - * The Radius of earth measurements. - */ - enum MeasureType { - /** - * Earth radius in Mile. - */ - MILE(3_958.0), - /** - * Earth radius in Kilometer. - */ - KILOMETER(6_371.0); - - private final double value; - - MeasureType(double v) { - this.value = v; - } - - public double getValue() { - return value; - } - } - /** * A factory method to return the implementation of selected distance calculator algorithm. * @@ -80,4 +48,36 @@ static DistanceAlgorithm getAlgorithm(Type type) { */ double calculate(Point first, Point second); + /** + * Enum to represent the implemented distance calculators algorithms. + */ + enum Type { + HAVERSINE, + ORTHODROMIC + } + + /** + * The Radius of earth measurements. + */ + enum MeasureType { + /** + * Earth radius in Mile. + */ + MILE(3_958.0), + /** + * Earth radius in Kilometer. + */ + KILOMETER(6_371.0); + + private final double value; + + MeasureType(double v) { + this.value = v; + } + + public double getValue() { + return value; + } + } + } diff --git a/src/main/java/org/siriusxi/htec/fa/infra/algorithm/distance/HaversineAlgorithm.java b/src/main/java/org/siriusxi/htec/fa/infra/algorithm/distance/HaversineAlgorithm.java index 487552e..d54c27f 100644 --- a/src/main/java/org/siriusxi/htec/fa/infra/algorithm/distance/HaversineAlgorithm.java +++ b/src/main/java/org/siriusxi/htec/fa/infra/algorithm/distance/HaversineAlgorithm.java @@ -1,6 +1,11 @@ package org.siriusxi.htec.fa.infra.algorithm.distance; -import static java.lang.Math.*; +import static java.lang.Math.asin; +import static java.lang.Math.cos; +import static java.lang.Math.pow; +import static java.lang.Math.sin; +import static java.lang.Math.sqrt; +import static java.lang.Math.toRadians; import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNullElse; diff --git a/src/main/java/org/siriusxi/htec/fa/infra/algorithm/distance/OrthodromicAlgorithm.java b/src/main/java/org/siriusxi/htec/fa/infra/algorithm/distance/OrthodromicAlgorithm.java index 292813d..e0f01cd 100644 --- a/src/main/java/org/siriusxi/htec/fa/infra/algorithm/distance/OrthodromicAlgorithm.java +++ b/src/main/java/org/siriusxi/htec/fa/infra/algorithm/distance/OrthodromicAlgorithm.java @@ -1,6 +1,11 @@ package org.siriusxi.htec.fa.infra.algorithm.distance; -import static java.lang.Math.*; +import static java.lang.Math.asin; +import static java.lang.Math.cos; +import static java.lang.Math.pow; +import static java.lang.Math.sin; +import static java.lang.Math.sqrt; +import static java.lang.Math.toRadians; import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNullElse; diff --git a/src/main/java/org/siriusxi/htec/fa/infra/config/FileUploadConfig.java b/src/main/java/org/siriusxi/htec/fa/infra/config/FileUploadConfig.java deleted file mode 100644 index 1b5a601..0000000 --- a/src/main/java/org/siriusxi/htec/fa/infra/config/FileUploadConfig.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.siriusxi.htec.fa.infra.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.multipart.commons.CommonsMultipartResolver; - -/** - * File upload configuration, is to manage the upload of large files. - * - *

As we cannot use Spring Boot’s default StandardServletMultipartResolver or - * CommonsMultipartResolver, since the server has limited resources (disk space) - * or memory for buffering. - * So we need to disable the default MultipartResolver and define our own - * MultipartResolver.

- * - * @author Mohamed Taman - */ - -@Configuration -public class FileUploadConfig { - - @Bean("multipartResolver") - public CommonsMultipartResolver multipartResolver() { - var multipartResolver = new CommonsMultipartResolver(); - multipartResolver.setMaxUploadSize(-1); - return multipartResolver; - } -} diff --git a/src/main/java/org/siriusxi/htec/fa/infra/config/GlobalExceptionHandler.java b/src/main/java/org/siriusxi/htec/fa/infra/config/GlobalExceptionHandler.java index 1564d94..00aab1d 100644 --- a/src/main/java/org/siriusxi/htec/fa/infra/config/GlobalExceptionHandler.java +++ b/src/main/java/org/siriusxi/htec/fa/infra/config/GlobalExceptionHandler.java @@ -1,28 +1,41 @@ package org.siriusxi.htec.fa.infra.config; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.ValidationException; import lombok.extern.log4j.Log4j2; import org.siriusxi.htec.fa.infra.exception.NotAllowedException; import org.siriusxi.htec.fa.infra.exception.NotFoundException; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.AccessDeniedException; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; -import javax.servlet.http.HttpServletRequest; -import javax.validation.ValidationException; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.FORBIDDEN; +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; +import static org.springframework.http.HttpStatus.NOT_ACCEPTABLE; +import static org.springframework.http.HttpStatus.NOT_FOUND; +import static org.springframework.http.HttpStatus.UNAUTHORIZED; @Log4j2 @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(NotFoundException.class) + @ResponseStatus(NOT_FOUND) public ResponseEntity> handleNotFoundException( HttpServletRequest request, NotFoundException ex) { @@ -30,11 +43,12 @@ public ResponseEntity> handleNotFoundException( log.error("NotFoundException {}\n", request.getRequestURI(), ex); return ResponseEntity - .status(HttpStatus.NOT_FOUND) - .body(new ApiCallError<>("Not found", List.of(ex.getMessage()))); + .status(NOT_FOUND) + .body(new ApiCallError<>("Not found", List.of(ex.getMessage()))); } @ExceptionHandler(NotAllowedException.class) + @ResponseStatus(NOT_ACCEPTABLE) public ResponseEntity> handleNotAllowedException(HttpServletRequest request, NotAllowedException ex) { @@ -42,11 +56,12 @@ public ResponseEntity> handleNotFoundException( log.error("NotAllowedException {}\n", request.getRequestURI(), ex); return ResponseEntity - .status(HttpStatus.NOT_ACCEPTABLE) - .body(new ApiCallError<>("Not Applicable", List.of(ex.getMessage()))); + .status(NOT_ACCEPTABLE) + .body(new ApiCallError<>("Not Applicable", List.of(ex.getMessage()))); } @ExceptionHandler(IllegalArgumentException.class) + @ResponseStatus(BAD_REQUEST) public ResponseEntity> handleIllegalArgumentException(HttpServletRequest request, IllegalArgumentException ex) { @@ -55,14 +70,15 @@ public ResponseEntity> handleNotFoundException( request.getRequestURI(), ex.getMessage()); return ResponseEntity - .badRequest() - .body(new ApiCallError<>( - "Illegal Arguments", - List.of(ex.getMessage()))); + .badRequest() + .body(new ApiCallError<>( + "Illegal Arguments", + List.of(ex.getMessage()))); } @ExceptionHandler(ValidationException.class) + @ResponseStatus(BAD_REQUEST) public ResponseEntity> handleValidationException(HttpServletRequest request, ValidationException ex) { @@ -70,13 +86,14 @@ public ResponseEntity> handleNotFoundException( log.error("ValidationException {}\n", request.getRequestURI(), ex); return ResponseEntity - .badRequest() - .body(new ApiCallError<>( - "Validation exception", - List.of(ex.getMessage()))); + .badRequest() + .body(new ApiCallError<>( + "Validation exception", + List.of(ex.getMessage()))); } @ExceptionHandler(MissingServletRequestParameterException.class) + @ResponseStatus(BAD_REQUEST) public ResponseEntity> handleMissingServletRequestParameterException(HttpServletRequest request, MissingServletRequestParameterException ex) { @@ -84,12 +101,13 @@ public ResponseEntity> handleNotFoundException( log.error("handleMissingServletRequestParameterException {}\n", request.getRequestURI(), ex); return ResponseEntity - .badRequest() - .body(new ApiCallError<>("Missing request parameter", - List.of(Objects.requireNonNull(ex.getMessage())))); + .badRequest() + .body(new ApiCallError<>("Missing request parameter", + List.of(Objects.requireNonNull(ex.getMessage())))); } @ExceptionHandler(MethodArgumentTypeMismatchException.class) + @ResponseStatus(BAD_REQUEST) public ResponseEntity>> handleMethodArgumentTypeMismatchException(HttpServletRequest request, MethodArgumentTypeMismatchException ex) { @@ -102,13 +120,14 @@ public ResponseEntity> handleNotFoundException( details.put("errorMessage", ex.getMessage()); return ResponseEntity - .badRequest() - .body(new ApiCallError<>( - "Method argument type mismatch", - List.of(details))); + .badRequest() + .body(new ApiCallError<>( + "Method argument type mismatch", + List.of(details))); } @ExceptionHandler(MethodArgumentNotValidException.class) + @ResponseStatus(BAD_REQUEST) public ResponseEntity>> handleMethodArgumentNotValidException(HttpServletRequest request, MethodArgumentNotValidException ex) { @@ -128,49 +147,53 @@ public ResponseEntity> handleNotFoundException( }); return ResponseEntity - .badRequest() - .body(new ApiCallError<>( - "Method argument validation failed", - details)); + .badRequest() + .body(new ApiCallError<>( + "Method argument validation failed", + details)); } @ExceptionHandler(AccessDeniedException.class) + @ResponseStatus(FORBIDDEN) public ResponseEntity> handleAccessDeniedException(HttpServletRequest request, AccessDeniedException ex) { log.error("handleAccessDeniedException {}\n", request.getRequestURI(), ex); return ResponseEntity - .status(HttpStatus.FORBIDDEN) - .body(new ApiCallError<>("Access denied!", List.of(ex.getMessage()))); + .status(FORBIDDEN) + .body(new ApiCallError<>("Access denied!", List.of(ex.getMessage()))); } @ExceptionHandler(HttpClientErrorException.class) + @ResponseStatus(UNAUTHORIZED) public ResponseEntity> handleUnauthorizedException(HttpServletRequest request, HttpClientErrorException ex) { log.error("handleUnauthorizedException {}\n", request.getRequestURI(), ex); return ResponseEntity - .status(HttpStatus.UNAUTHORIZED) - .body(new ApiCallError<>("Unauthorized Access, check your credentials!", - List.of(ex.getMessage() != null ? ex.getMessage() : ""))); + .status(UNAUTHORIZED) + .body(new ApiCallError<>("Unauthorized Access, check your credentials!", + List.of(ex.getMessage() != null ? ex.getMessage() : ""))); } @ExceptionHandler(Exception.class) + @ResponseStatus(INTERNAL_SERVER_ERROR) public ResponseEntity> handleInternalServerError(HttpServletRequest request, Exception ex) { log.error("handleInternalServerError {}\n", request.getRequestURI(), ex); return ResponseEntity - .status(HttpStatus.INTERNAL_SERVER_ERROR) - .body(new ApiCallError<>( - "Internal server error", - List.of(ex.getMessage()))); + .status(INTERNAL_SERVER_ERROR) + .body(new ApiCallError<>( + "Internal server error", + List.of(ex.getMessage()))); } } +@JsonRootName("ApiError") record ApiCallError( @JsonProperty("message") String message, @JsonProperty("details") List details) { diff --git a/src/main/java/org/siriusxi/htec/fa/infra/config/SwaggerConfig.java b/src/main/java/org/siriusxi/htec/fa/infra/config/SwaggerConfig.java index 3465d3b..5280003 100644 --- a/src/main/java/org/siriusxi/htec/fa/infra/config/SwaggerConfig.java +++ b/src/main/java/org/siriusxi/htec/fa/infra/config/SwaggerConfig.java @@ -5,27 +5,31 @@ import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; import io.swagger.v3.oas.models.security.SecurityScheme; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class SwaggerConfig { + @Value("${app.version}") + private String appVersion; + @Bean public OpenAPI customOpenAPI() { return new OpenAPI() - .components(new Components() - .addSecuritySchemes("bearer-key", - new SecurityScheme() - .type(SecurityScheme.Type.HTTP) - .scheme("bearer") - .bearerFormat("JWT"))) - .info(new Info() - .title("REST API for Flight Advisor Service.") - .version("2.8") - .license(new License() - .name("MIT License") - .url("https://springdoc.org"))); + .components(new Components() + .addSecuritySchemes("bearer-key", + new SecurityScheme() + .type(SecurityScheme.Type.HTTP) + .scheme("bearer") + .bearerFormat("JWT"))) + .info(new Info() + .title("REST API for Flight Advisor Service.") + .version(appVersion) + .license(new License() + .name("MIT License") + .url("https://springdoc.org"))); } } diff --git a/src/main/java/org/siriusxi/htec/fa/domain/mapper/AirportMapper.java b/src/main/java/org/siriusxi/htec/fa/infra/mapper/AirportMapper.java similarity index 84% rename from src/main/java/org/siriusxi/htec/fa/domain/mapper/AirportMapper.java rename to src/main/java/org/siriusxi/htec/fa/infra/mapper/AirportMapper.java index 2db3f43..9e9d3ea 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/mapper/AirportMapper.java +++ b/src/main/java/org/siriusxi/htec/fa/infra/mapper/AirportMapper.java @@ -1,10 +1,10 @@ -package org.siriusxi.htec.fa.domain.mapper; +package org.siriusxi.htec.fa.infra.mapper; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import org.siriusxi.htec.fa.domain.dto.response.AirportView; -import org.siriusxi.htec.fa.domain.dto.upload.airport.AirportDto; -import org.siriusxi.htec.fa.domain.model.Airport; +import org.siriusxi.htec.fa.api.model.response.AirportView; +import org.siriusxi.htec.fa.api.model.upload.airport.AirportDto; +import org.siriusxi.htec.fa.domain.Airport; import java.util.List; diff --git a/src/main/java/org/siriusxi/htec/fa/domain/mapper/CityMapper.java b/src/main/java/org/siriusxi/htec/fa/infra/mapper/CityMapper.java similarity index 79% rename from src/main/java/org/siriusxi/htec/fa/domain/mapper/CityMapper.java rename to src/main/java/org/siriusxi/htec/fa/infra/mapper/CityMapper.java index eb79dbe..d539082 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/mapper/CityMapper.java +++ b/src/main/java/org/siriusxi/htec/fa/infra/mapper/CityMapper.java @@ -1,11 +1,11 @@ -package org.siriusxi.htec.fa.domain.mapper; +package org.siriusxi.htec.fa.infra.mapper; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import org.siriusxi.htec.fa.domain.dto.request.CreateCityRequest; -import org.siriusxi.htec.fa.domain.dto.response.CityView; -import org.siriusxi.htec.fa.domain.model.City; -import org.siriusxi.htec.fa.domain.model.Country; +import org.siriusxi.htec.fa.api.model.request.CreateCityRequest; +import org.siriusxi.htec.fa.api.model.response.CityView; +import org.siriusxi.htec.fa.domain.City; +import org.siriusxi.htec.fa.domain.Country; import org.springframework.beans.factory.annotation.Autowired; import java.util.Collections; diff --git a/src/main/java/org/siriusxi/htec/fa/domain/mapper/CommentMapper.java b/src/main/java/org/siriusxi/htec/fa/infra/mapper/CommentMapper.java similarity index 68% rename from src/main/java/org/siriusxi/htec/fa/domain/mapper/CommentMapper.java rename to src/main/java/org/siriusxi/htec/fa/infra/mapper/CommentMapper.java index cae2fe0..4ea6b11 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/mapper/CommentMapper.java +++ b/src/main/java/org/siriusxi/htec/fa/infra/mapper/CommentMapper.java @@ -1,12 +1,12 @@ -package org.siriusxi.htec.fa.domain.mapper; +package org.siriusxi.htec.fa.infra.mapper; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import org.siriusxi.htec.fa.domain.dto.request.UpSrtCommentRequest; -import org.siriusxi.htec.fa.domain.dto.response.CommentView; -import org.siriusxi.htec.fa.domain.model.City; -import org.siriusxi.htec.fa.domain.model.Comment; -import org.siriusxi.htec.fa.domain.model.User; +import org.siriusxi.htec.fa.api.model.request.CommentUpSrtRequest; +import org.siriusxi.htec.fa.api.model.response.CommentView; +import org.siriusxi.htec.fa.domain.City; +import org.siriusxi.htec.fa.domain.Comment; +import org.siriusxi.htec.fa.domain.User; import java.time.LocalDateTime; import java.util.List; @@ -19,14 +19,14 @@ public interface CommentMapper { @Mapping(target = "createdAt", ignore = true) @Mapping(target = "user", source = "user") @Mapping(target = "city", source = "city") - Comment toNewModel(UpSrtCommentRequest request, User user, City city); + Comment toNewModel(CommentUpSrtRequest request, User user, City city); @Mapping(target = "createdAt", ignore = true) @Mapping(target = "updatedAt", expression = "java( LocalDateTime.now() )") @Mapping(target = "user", source = "user") @Mapping(target = "city", source = "city") @Mapping(target = "id", source = "commentId") - Comment toUpdateModel(UpSrtCommentRequest request, int commentId, User user, City city); + Comment toUpdateModel(CommentUpSrtRequest request, int commentId, User user, City city); @Mapping(target = "id", source = "id") @Mapping(target = "by", source = "user.fullName") diff --git a/src/main/java/org/siriusxi/htec/fa/domain/mapper/CountryMapper.java b/src/main/java/org/siriusxi/htec/fa/infra/mapper/CountryMapper.java similarity index 59% rename from src/main/java/org/siriusxi/htec/fa/domain/mapper/CountryMapper.java rename to src/main/java/org/siriusxi/htec/fa/infra/mapper/CountryMapper.java index fe59331..75329e3 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/mapper/CountryMapper.java +++ b/src/main/java/org/siriusxi/htec/fa/infra/mapper/CountryMapper.java @@ -1,8 +1,8 @@ -package org.siriusxi.htec.fa.domain.mapper; +package org.siriusxi.htec.fa.infra.mapper; import org.mapstruct.Mapper; -import org.siriusxi.htec.fa.domain.dto.response.CountryView; -import org.siriusxi.htec.fa.domain.model.Country; +import org.siriusxi.htec.fa.api.model.response.CountryView; +import org.siriusxi.htec.fa.domain.Country; import java.util.Set; diff --git a/src/main/java/org/siriusxi/htec/fa/domain/mapper/RouteMapper.java b/src/main/java/org/siriusxi/htec/fa/infra/mapper/RouteMapper.java similarity index 75% rename from src/main/java/org/siriusxi/htec/fa/domain/mapper/RouteMapper.java rename to src/main/java/org/siriusxi/htec/fa/infra/mapper/RouteMapper.java index 4a7b064..7e722bf 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/mapper/RouteMapper.java +++ b/src/main/java/org/siriusxi/htec/fa/infra/mapper/RouteMapper.java @@ -1,9 +1,9 @@ -package org.siriusxi.htec.fa.domain.mapper; +package org.siriusxi.htec.fa.infra.mapper; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import org.siriusxi.htec.fa.domain.dto.upload.route.RouteDto; -import org.siriusxi.htec.fa.domain.model.Route; +import org.siriusxi.htec.fa.api.model.upload.route.RouteDto; +import org.siriusxi.htec.fa.domain.Route; @Mapper(componentModel = "spring") public interface RouteMapper { diff --git a/src/main/java/org/siriusxi/htec/fa/domain/mapper/UserMapper.java b/src/main/java/org/siriusxi/htec/fa/infra/mapper/UserMapper.java similarity index 73% rename from src/main/java/org/siriusxi/htec/fa/domain/mapper/UserMapper.java rename to src/main/java/org/siriusxi/htec/fa/infra/mapper/UserMapper.java index 6d069be..df34ad3 100644 --- a/src/main/java/org/siriusxi/htec/fa/domain/mapper/UserMapper.java +++ b/src/main/java/org/siriusxi/htec/fa/infra/mapper/UserMapper.java @@ -1,11 +1,11 @@ -package org.siriusxi.htec.fa.domain.mapper; +package org.siriusxi.htec.fa.infra.mapper; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import org.siriusxi.htec.fa.domain.dto.request.CreateUserRequest; -import org.siriusxi.htec.fa.domain.dto.response.UserView; -import org.siriusxi.htec.fa.domain.model.Role; -import org.siriusxi.htec.fa.domain.model.User; +import org.siriusxi.htec.fa.api.model.request.CreateUserRequest; +import org.siriusxi.htec.fa.api.model.response.UserView; +import org.siriusxi.htec.fa.domain.Role; +import org.siriusxi.htec.fa.domain.User; import org.siriusxi.htec.fa.infra.Utils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.password.PasswordEncoder; @@ -31,8 +31,8 @@ public abstract class UserMapper { protected String[] map(Set authorities) { return authorities - .stream() - .map(Role::getAuthority) - .toArray(String[]::new); + .stream() + .map(Role::getAuthority) + .toArray(String[]::new); } } diff --git a/src/main/java/org/siriusxi/htec/fa/infra/security/JwtTokenFilter.java b/src/main/java/org/siriusxi/htec/fa/infra/security/JwtTokenFilter.java index 9735f2b..59d432c 100644 --- a/src/main/java/org/siriusxi/htec/fa/infra/security/JwtTokenFilter.java +++ b/src/main/java/org/siriusxi/htec/fa/infra/security/JwtTokenFilter.java @@ -1,5 +1,9 @@ package org.siriusxi.htec.fa.infra.security; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import lombok.extern.log4j.Log4j2; import org.siriusxi.htec.fa.infra.security.jwt.JwtTokenHelper; import org.siriusxi.htec.fa.repository.UserRepository; @@ -10,10 +14,6 @@ import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; import java.util.Optional; @@ -37,7 +37,7 @@ protected void doFilterInternal(HttpServletRequest request, // Get authorization header and validate var authToken = getJwtTokenIfValid(request - .getHeader(HttpHeaders.AUTHORIZATION)); + .getHeader(HttpHeaders.AUTHORIZATION)); String token; @@ -48,8 +48,8 @@ protected void doFilterInternal(HttpServletRequest request, // Get user identity and set it on the spring security context var userDetails = userRepository - .findByUsernameIgnoreCase(JwtTokenHelper.getUsername(token)) - .orElse(null); + .findByUsernameIgnoreCase(JwtTokenHelper.getUsername(token)) + .orElse(null); var authentication = new UsernamePasswordAuthenticationToken( userDetails, null, diff --git a/src/main/java/org/siriusxi/htec/fa/infra/security/SecurityConfig.java b/src/main/java/org/siriusxi/htec/fa/infra/security/SecurityConfig.java index ab971e1..deb0532 100644 --- a/src/main/java/org/siriusxi/htec/fa/infra/security/SecurityConfig.java +++ b/src/main/java/org/siriusxi/htec/fa/infra/security/SecurityConfig.java @@ -19,8 +19,8 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; +import static jakarta.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; import static java.lang.String.format; -import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; import static org.springframework.security.core.context.SecurityContextHolder.MODE_INHERITABLETHREADLOCAL; import static org.springframework.security.core.context.SecurityContextHolder.setStrategyName; @@ -35,18 +35,15 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { private final UserRepository userRepository; private final JwtTokenFilter jwtTokenFilter; - private final String appVersion; private final String allowedOrigins; public SecurityConfig(UserRepository userRepository, JwtTokenFilter jwtTokenFilter, - @Value("${app.version:v1}") String appVersion, @Value("${app.allowedOrigins:*}") String allowedOrigins) { super(); this.userRepository = userRepository; this.jwtTokenFilter = jwtTokenFilter; - this.appVersion = "/".concat(appVersion); this.allowedOrigins = allowedOrigins; // Inherit security context in async function calls @@ -77,9 +74,8 @@ protected void configure(HttpSecurity http) throws Exception { // List of Swagger URLs var swaggerAuthList = new String[]{ - appVersion.concat("/api-docs/**"), - "/webjars/**", "/swagger-ui/**", - appVersion.concat("/doc/**")}; + "/api-docs/**", "/webjars/**", + "/swagger-ui/**", "/doc/**"}; http // Enable CORS diff --git a/src/main/java/org/siriusxi/htec/fa/infra/security/jwt/JwtTokenHelper.java b/src/main/java/org/siriusxi/htec/fa/infra/security/jwt/JwtTokenHelper.java index eef5ce3..f2c2541 100644 --- a/src/main/java/org/siriusxi/htec/fa/infra/security/jwt/JwtTokenHelper.java +++ b/src/main/java/org/siriusxi/htec/fa/infra/security/jwt/JwtTokenHelper.java @@ -1,6 +1,11 @@ package org.siriusxi.htec.fa.infra.security.jwt; -import io.jsonwebtoken.*; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.UnsupportedJwtException; import io.jsonwebtoken.security.Keys; import lombok.extern.log4j.Log4j2; @@ -33,16 +38,16 @@ private JwtTokenHelper() { public static String generateAccessToken(int id, String username) { var now = System.currentTimeMillis(); return Jwts - .builder() - .setId(String.valueOf(id)) - .setSubject(format("%d,%s", id, username)) - .setIssuer(JwtConfig.ISSUER) - .setIssuedAt(new Date(now)) - .setExpiration(Date.from(ZonedDateTime.now() - .plusDays(JwtConfig.TOKEN_EXPIRY_DURATION) - .toInstant())) - .signWith(JwtConfig.key(), JwtConfig.SIGNATURE_ALGORITHM) - .compact(); + .builder() + .setId(String.valueOf(id)) + .setSubject(format("%d,%s", id, username)) + .setIssuer(JwtConfig.ISSUER) + .setIssuedAt(new Date(now)) + .setExpiration(Date.from(ZonedDateTime.now() + .plusDays(JwtConfig.TOKEN_EXPIRY_DURATION) + .toInstant())) + .signWith(JwtConfig.key(), JwtConfig.SIGNATURE_ALGORITHM) + .compact(); } /** @@ -53,8 +58,8 @@ public static String generateAccessToken(int id, String username) { */ public static int getUserId(String token) { return Integer.parseInt(getClaims(token) - .getSubject() - .split(",")[0]); + .getSubject() + .split(",")[0]); } /** @@ -65,8 +70,8 @@ public static int getUserId(String token) { */ public static String getUsername(String token) { return getClaims(token) - .getSubject() - .split(",")[1]; + .getSubject() + .split(",")[1]; } /** @@ -77,7 +82,7 @@ public static String getUsername(String token) { */ public static Date tokenExpiredAt(String token) { return getClaims(token) - .getExpiration(); + .getExpiration(); } /** @@ -88,11 +93,11 @@ public static Date tokenExpiredAt(String token) { */ private static Claims getClaims(String token) { return Jwts - .parserBuilder() - .setSigningKey(JwtConfig.key()) - .build() - .parseClaimsJws(token.replace(JwtConfig.TOKEN_PREFIX, "")) - .getBody(); + .parserBuilder() + .setSigningKey(JwtConfig.key()) + .build() + .parseClaimsJws(token.replace(JwtConfig.TOKEN_PREFIX, "")) + .getBody(); } /** diff --git a/src/main/java/org/siriusxi/htec/fa/infra/security/password/PasswordGenerator.java b/src/main/java/org/siriusxi/htec/fa/infra/security/password/PasswordGenerator.java index 4031fa9..cf26c3a 100644 --- a/src/main/java/org/siriusxi/htec/fa/infra/security/password/PasswordGenerator.java +++ b/src/main/java/org/siriusxi/htec/fa/infra/security/password/PasswordGenerator.java @@ -51,6 +51,6 @@ public static String sha1Random() { public static String bcrypt(String password) { return new BCryptPasswordEncoder() - .encode(password); + .encode(password); } } diff --git a/src/main/java/org/siriusxi/htec/fa/repository/AirportRepository.java b/src/main/java/org/siriusxi/htec/fa/repository/AirportRepository.java index 8a46caa..df0912c 100644 --- a/src/main/java/org/siriusxi/htec/fa/repository/AirportRepository.java +++ b/src/main/java/org/siriusxi/htec/fa/repository/AirportRepository.java @@ -1,7 +1,7 @@ package org.siriusxi.htec.fa.repository; -import org.siriusxi.htec.fa.domain.model.Airport; -import org.siriusxi.htec.fa.domain.model.City; +import org.siriusxi.htec.fa.domain.Airport; +import org.siriusxi.htec.fa.domain.City; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.jpa.repository.Query; diff --git a/src/main/java/org/siriusxi/htec/fa/repository/CityRepository.java b/src/main/java/org/siriusxi/htec/fa/repository/CityRepository.java index 00921d0..6a9691b 100644 --- a/src/main/java/org/siriusxi/htec/fa/repository/CityRepository.java +++ b/src/main/java/org/siriusxi/htec/fa/repository/CityRepository.java @@ -1,7 +1,7 @@ package org.siriusxi.htec.fa.repository; -import org.siriusxi.htec.fa.domain.model.City; -import org.siriusxi.htec.fa.domain.model.Country; +import org.siriusxi.htec.fa.domain.City; +import org.siriusxi.htec.fa.domain.Country; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.repository.CrudRepository; @@ -27,7 +27,7 @@ public interface CityRepository extends CrudRepository { */ default City findOrSaveBy(Country country, String name, String description) { return findByCountryAndNameIgnoreCaseIsLike(country, name.trim()) - .orElseGet(() -> save(new City(name, description, country))); + .orElseGet(() -> save(new City(name, description, country))); } @Cacheable diff --git a/src/main/java/org/siriusxi/htec/fa/repository/CommentRepository.java b/src/main/java/org/siriusxi/htec/fa/repository/CommentRepository.java index 0622111..1dc0975 100644 --- a/src/main/java/org/siriusxi/htec/fa/repository/CommentRepository.java +++ b/src/main/java/org/siriusxi/htec/fa/repository/CommentRepository.java @@ -1,8 +1,8 @@ package org.siriusxi.htec.fa.repository; -import org.siriusxi.htec.fa.domain.model.City; -import org.siriusxi.htec.fa.domain.model.Comment; -import org.siriusxi.htec.fa.domain.model.User; +import org.siriusxi.htec.fa.domain.City; +import org.siriusxi.htec.fa.domain.Comment; +import org.siriusxi.htec.fa.domain.User; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; diff --git a/src/main/java/org/siriusxi/htec/fa/repository/CountryRepository.java b/src/main/java/org/siriusxi/htec/fa/repository/CountryRepository.java index f6cf9d3..198c309 100644 --- a/src/main/java/org/siriusxi/htec/fa/repository/CountryRepository.java +++ b/src/main/java/org/siriusxi/htec/fa/repository/CountryRepository.java @@ -1,6 +1,6 @@ package org.siriusxi.htec.fa.repository; -import org.siriusxi.htec.fa.domain.model.Country; +import org.siriusxi.htec.fa.domain.Country; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.repository.CrudRepository; @@ -27,6 +27,6 @@ public interface CountryRepository extends CrudRepository { @Cacheable default Country findOrSaveBy(String name) { return findByNameIgnoreCaseIsLike(name.trim()) - .orElseGet(() -> save(new Country(name))); + .orElseGet(() -> save(new Country(name))); } } diff --git a/src/main/java/org/siriusxi/htec/fa/repository/RouteRepository.java b/src/main/java/org/siriusxi/htec/fa/repository/RouteRepository.java index 0053b00..0090825 100644 --- a/src/main/java/org/siriusxi/htec/fa/repository/RouteRepository.java +++ b/src/main/java/org/siriusxi/htec/fa/repository/RouteRepository.java @@ -1,8 +1,8 @@ package org.siriusxi.htec.fa.repository; -import org.siriusxi.htec.fa.domain.model.Route; -import org.siriusxi.htec.fa.domain.model.RoutePK; -import org.siriusxi.htec.fa.domain.model.vo.RouteView; +import org.siriusxi.htec.fa.domain.Route; +import org.siriusxi.htec.fa.domain.RoutePK; +import org.siriusxi.htec.fa.domain.vo.RouteView; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheEvict; import org.springframework.data.jpa.repository.Query; @@ -18,7 +18,7 @@ public interface RouteRepository extends CrudRepository { @Query(value = """ - SELECT new org.siriusxi.htec.fa.domain.model.vo.RouteView + SELECT new org.siriusxi.htec.fa.domain.vo.RouteView (routePK.source, routePK.destination, price) FROM Route ORDER BY routePK.source ASC diff --git a/src/main/java/org/siriusxi/htec/fa/repository/UserRepository.java b/src/main/java/org/siriusxi/htec/fa/repository/UserRepository.java index 86e3918..4f607c0 100644 --- a/src/main/java/org/siriusxi/htec/fa/repository/UserRepository.java +++ b/src/main/java/org/siriusxi/htec/fa/repository/UserRepository.java @@ -1,6 +1,6 @@ package org.siriusxi.htec.fa.repository; -import org.siriusxi.htec.fa.domain.model.User; +import org.siriusxi.htec.fa.domain.User; import org.siriusxi.htec.fa.infra.exception.NotFoundException; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheEvict; diff --git a/src/main/java/org/siriusxi/htec/fa/service/CityMgmtService.java b/src/main/java/org/siriusxi/htec/fa/service/CityMgmtService.java index fd8a54d..5eacfe8 100644 --- a/src/main/java/org/siriusxi/htec/fa/service/CityMgmtService.java +++ b/src/main/java/org/siriusxi/htec/fa/service/CityMgmtService.java @@ -1,22 +1,22 @@ package org.siriusxi.htec.fa.service; import lombok.extern.log4j.Log4j2; -import org.siriusxi.htec.fa.domain.dto.request.CreateCityRequest; -import org.siriusxi.htec.fa.domain.dto.request.SearchAirportRequest; -import org.siriusxi.htec.fa.domain.dto.request.SearchCityRequest; -import org.siriusxi.htec.fa.domain.dto.request.UpSrtCommentRequest; -import org.siriusxi.htec.fa.domain.dto.response.AirportView; -import org.siriusxi.htec.fa.domain.dto.response.CityView; -import org.siriusxi.htec.fa.domain.dto.response.CommentView; -import org.siriusxi.htec.fa.domain.mapper.AirportMapper; -import org.siriusxi.htec.fa.domain.mapper.CityMapper; -import org.siriusxi.htec.fa.domain.mapper.CommentMapper; -import org.siriusxi.htec.fa.domain.model.City; -import org.siriusxi.htec.fa.domain.model.Comment; -import org.siriusxi.htec.fa.domain.model.Country; -import org.siriusxi.htec.fa.domain.model.User; +import org.siriusxi.htec.fa.api.model.request.CommentUpSrtRequest; +import org.siriusxi.htec.fa.api.model.request.CreateCityRequest; +import org.siriusxi.htec.fa.api.model.request.SearchAirportRequest; +import org.siriusxi.htec.fa.api.model.request.SearchCityRequest; +import org.siriusxi.htec.fa.api.model.response.AirportView; +import org.siriusxi.htec.fa.api.model.response.CityView; +import org.siriusxi.htec.fa.api.model.response.CommentView; +import org.siriusxi.htec.fa.domain.City; +import org.siriusxi.htec.fa.domain.Comment; +import org.siriusxi.htec.fa.domain.Country; +import org.siriusxi.htec.fa.domain.User; import org.siriusxi.htec.fa.infra.exception.NotAllowedException; import org.siriusxi.htec.fa.infra.exception.NotFoundException; +import org.siriusxi.htec.fa.infra.mapper.AirportMapper; +import org.siriusxi.htec.fa.infra.mapper.CityMapper; +import org.siriusxi.htec.fa.infra.mapper.CommentMapper; import org.siriusxi.htec.fa.repository.AirportRepository; import org.siriusxi.htec.fa.repository.CityRepository; import org.siriusxi.htec.fa.repository.CommentRepository; @@ -28,6 +28,8 @@ import java.util.ArrayList; import java.util.List; +import static java.util.Objects.isNull; + @Log4j2 @Service public class CityMgmtService { @@ -83,14 +85,15 @@ public CityView addCity(CreateCityRequest cityRequest) { @Transactional(readOnly = true) public List searchCities(SearchCityRequest request, int cLimit) { - List cities = new ArrayList<>(); - String searchWord = LIKE.concat(request.name()).concat(LIKE); - if (cLimit != 0) + String searchWord = isNull(request.name()) ? "" : request.name(); + searchWord = LIKE.concat(searchWord).concat(LIKE); + + if (cLimit > 0) for (City city : cityRepository.findByNameIgnoreCaseIsLike(searchWord)) { city.setComments(commentRepository - .findByCity(city, PageRequest.of(0, cLimit))); + .findByCity(city, PageRequest.of(0, cLimit))); cities.add(city); } else @@ -102,31 +105,33 @@ public List searchCities(SearchCityRequest request, int cLimit) { // Airport management public List searchAirports(SearchAirportRequest request, int cityId) { - String searchWord = LIKE.concat(request.name()).concat(LIKE); + + String searchWord = isNull(request.name()) ? "" : request.name(); + searchWord = LIKE.concat(searchWord).concat(LIKE); + return airportMapper - .toView(airportRepository - .findAirportsByCityAndNameIgnoreCaseIsLike( - new City(cityId), - searchWord)); + .toView(airportRepository + .findAirportsByCityAndNameIgnoreCaseIsLike( + new City(cityId), searchWord)); } // City Comments management @Transactional public CommentView addComment(User user, int cityId, - UpSrtCommentRequest request) { + CommentUpSrtRequest request) { // Chick if the city is already exists City city = getCityIfExists(cityId); return commentMapper - .toView(commentRepository - .save(commentMapper - .toNewModel(request, user, city))); + .toView(commentRepository + .save(commentMapper + .toNewModel(request, user, city))); } @Transactional public void updateComment(User user, int cityId, int commentId, - UpSrtCommentRequest request) { + CommentUpSrtRequest request) { // Chick if the city is already exists City city = getCityIfExists(cityId); @@ -143,9 +148,9 @@ public void updateComment(User user, int cityId, int commentId, .orElseThrow(() -> new NotAllowedException(Comment.class, found.getId(), "Update"))) .ifPresent(comment -> commentMapper - .toView(commentRepository - .save(commentMapper - .toUpdateModel(request, comment.getId(), user, city)))); + .toView(commentRepository + .save(commentMapper + .toUpdateModel(request, comment.getId(), user, city)))); } public void deleteComment(User user, int cityId, int commentId) { @@ -159,14 +164,14 @@ public void deleteComment(User user, int cityId, int commentId) { .flatMap(comment -> commentRepository.findByIdAndCity(comment.getId(), city)) // If exist check if user is allowed to delete it .ifPresent(found -> commentRepository.delete(commentRepository - .findByIdAndCityAndUser(found.getId(), city, user) - // If user is not allowed throw exception - .orElseThrow(() -> new NotAllowedException(Comment.class, found.getId(), "Delete")))); + .findByIdAndCityAndUser(found.getId(), city, user) + // If user is not allowed throw exception + .orElseThrow(() -> new NotAllowedException(Comment.class, found.getId(), "Delete")))); } private City getCityIfExists(int cityId) { return cityRepository - .findById(cityId) - .orElseThrow(() -> new NotFoundException(City.class, cityId)); + .findById(cityId) + .orElseThrow(() -> new NotFoundException(City.class, cityId)); } } diff --git a/src/main/java/org/siriusxi/htec/fa/service/TravelService.java b/src/main/java/org/siriusxi/htec/fa/service/TravelService.java index 7748a91..8ae102f 100644 --- a/src/main/java/org/siriusxi/htec/fa/service/TravelService.java +++ b/src/main/java/org/siriusxi/htec/fa/service/TravelService.java @@ -6,14 +6,14 @@ import es.usc.citius.hipster.graph.GraphSearchProblem; import es.usc.citius.hipster.model.impl.WeightedNode; import lombok.extern.log4j.Log4j2; -import org.siriusxi.htec.fa.domain.dto.response.AirportView; -import org.siriusxi.htec.fa.domain.dto.response.TripView; -import org.siriusxi.htec.fa.domain.mapper.AirportMapper; -import org.siriusxi.htec.fa.domain.model.Airport; -import org.siriusxi.htec.fa.domain.model.Route; -import org.siriusxi.htec.fa.domain.model.RoutePK; +import org.siriusxi.htec.fa.api.model.response.AirportView; +import org.siriusxi.htec.fa.api.model.response.TripView; +import org.siriusxi.htec.fa.domain.Airport; +import org.siriusxi.htec.fa.domain.Route; +import org.siriusxi.htec.fa.domain.RoutePK; import org.siriusxi.htec.fa.infra.algorithm.distance.DistanceAlgorithm; import org.siriusxi.htec.fa.infra.algorithm.distance.Point; +import org.siriusxi.htec.fa.infra.mapper.AirportMapper; import org.siriusxi.htec.fa.repository.AirportRepository; import org.siriusxi.htec.fa.repository.RouteRepository; import org.springframework.cache.annotation.CacheConfig; @@ -157,13 +157,13 @@ private List buildFinalTripViews(FinalTrip trip) { private double calculateDistance(Route route) { return orthodromicAlgorithm - .calculate( - new Point( - route.getSourceAirport().getLatitude().doubleValue(), - route.getSourceAirport().getLongitude().doubleValue()), - new Point( - route.getDestinationAirport().getLatitude().doubleValue(), - route.getDestinationAirport().getLongitude().doubleValue())); + .calculate( + new Point( + route.getSourceAirport().getLatitude().doubleValue(), + route.getSourceAirport().getLongitude().doubleValue()), + new Point( + route.getDestinationAirport().getLatitude().doubleValue(), + route.getDestinationAirport().getLongitude().doubleValue())); } private TripView newTripView(Airport src, Airport dest, @@ -192,9 +192,9 @@ private FinalTrip findShortestPath(String from, String to) { // Create the search problem. For graph problems, just use // the GraphSearchProblem util class to generate the problem with ease. var problem = GraphSearchProblem - .startingFrom(from).in(graph) - .takeCostsFromEdges() - .build(); + .startingFrom(from).in(graph) + .takeCostsFromEdges() + .build(); // Search the shortest path from source to destination final var result = Hipster.createDijkstra(problem).search(to); @@ -217,8 +217,8 @@ private GraphBuilder buildGraph(GraphBuilder gra public List findAirportsForCityOrCountry(String name) { return airportMapper - .toView(airportRepository - .findAirportsByCityOrCountryName(name.toLowerCase())); + .toView(airportRepository + .findAirportsByCityOrCountryName(name.toLowerCase())); } private record FinalTrip(String start, diff --git a/src/main/java/org/siriusxi/htec/fa/service/UserService.java b/src/main/java/org/siriusxi/htec/fa/service/UserService.java index 8aad725..2b370a1 100644 --- a/src/main/java/org/siriusxi/htec/fa/service/UserService.java +++ b/src/main/java/org/siriusxi/htec/fa/service/UserService.java @@ -1,10 +1,11 @@ package org.siriusxi.htec.fa.service; +import jakarta.validation.ValidationException; import lombok.extern.log4j.Log4j2; -import org.siriusxi.htec.fa.domain.dto.request.CreateUserRequest; -import org.siriusxi.htec.fa.domain.dto.response.UserView; -import org.siriusxi.htec.fa.domain.mapper.UserMapper; -import org.siriusxi.htec.fa.domain.model.User; +import org.siriusxi.htec.fa.api.model.request.CreateUserRequest; +import org.siriusxi.htec.fa.api.model.response.UserView; +import org.siriusxi.htec.fa.domain.User; +import org.siriusxi.htec.fa.infra.mapper.UserMapper; import org.siriusxi.htec.fa.repository.UserRepository; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; @@ -12,10 +13,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import javax.validation.ValidationException; - import static java.lang.String.format; -import static org.siriusxi.htec.fa.domain.model.Role.CLIENT; +import static org.siriusxi.htec.fa.domain.Role.CLIENT; @Log4j2 @Service @@ -57,9 +56,9 @@ public UserView create(CreateUserRequest request) { @Override public UserDetails loadUserByUsername(String username) { return repository - .findByUsernameIgnoreCase(username) - .orElseThrow( - () -> new UsernameNotFoundException( - format("User with username - %s, not found", username))); + .findByUsernameIgnoreCase(username) + .orElseThrow( + () -> new UsernameNotFoundException( + format("User with username - %s, not found", username))); } } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 7599d0a..7732bd8 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1,7 +1,9 @@ # Development profile ## Custom application properties app: - version: 'v1' + version: @project.version@ + api: + version: 'v1' # Spring properties spring: @@ -10,7 +12,7 @@ spring: servlet: multipart: - enabled: false + enabled: true max-file-size: 10MB # Database configurations datasource: @@ -55,7 +57,7 @@ server: include-message: always include-binding-errors: always servlet: - context-path: /flight/service/api + context-path: /api/${app.api.version}/flight/service # Application health and information management management: @@ -86,7 +88,7 @@ logging.level: springdoc: # swagger-ui custom path swagger-ui: - path: /${app.version}/doc/index.html + path: /doc/index.html operationsSorter: alpha tagsSorter: alpha displayRequestDuration: true @@ -94,6 +96,6 @@ springdoc: theme: arta # /api-docs endpoint custom path api-docs: - path: /${app.version}/api-docs + path: /api-docs # to display the actuator endpoints. show-actuator: false diff --git a/src/test/java/org/siriusxi/htec/fa/CsvToBeanTests.java b/src/test/java/org/siriusxi/htec/fa/CsvToBeanTests.java index 0fafbf9..da26a1e 100644 --- a/src/test/java/org/siriusxi/htec/fa/CsvToBeanTests.java +++ b/src/test/java/org/siriusxi/htec/fa/CsvToBeanTests.java @@ -2,60 +2,63 @@ import com.opencsv.bean.CsvToBean; import com.opencsv.bean.CsvToBeanBuilder; -import lombok.SneakyThrows; import lombok.extern.log4j.Log4j2; import org.assertj.core.api.Assertions; -import org.siriusxi.htec.fa.domain.dto.upload.airport.AirportDto; -import org.siriusxi.htec.fa.domain.dto.upload.airport.verifer.AirportBeanVerifier; -import org.siriusxi.htec.fa.domain.dto.upload.route.RouteDto; -import org.siriusxi.htec.fa.domain.dto.upload.route.verifer.RouteBeanVerifier; +import org.siriusxi.htec.fa.api.model.upload.airport.AirportDto; +import org.siriusxi.htec.fa.api.model.upload.airport.verifer.AirportBeanVerifier; +import org.siriusxi.htec.fa.api.model.upload.route.RouteDto; +import org.siriusxi.htec.fa.api.model.upload.route.verifer.RouteBeanVerifier; +import java.io.FileNotFoundException; import java.io.FileReader; +import java.io.IOException; import java.io.Reader; import java.util.List; @Log4j2 class CsvToBeanTests { - @SneakyThrows //@Test void parseRoutesCSVFileToBeans() { try (Reader fileReader = new FileReader("./data/routes.txt")) { CsvToBean csvToRouteBeans = new CsvToBeanBuilder(fileReader) - .withType(RouteDto.class) - .withVerifier(new RouteBeanVerifier()) - .withIgnoreLeadingWhiteSpace(true) - .build(); + .withType(RouteDto.class) + .withVerifier(new RouteBeanVerifier()) + .withIgnoreLeadingWhiteSpace(true) + .build(); // convert `CsvToBean` object to list of airports List routes = csvToRouteBeans.parse(); System.out.println(routes.size()); - Assertions.assertThat(routes.size()).isEqualTo(66754); + Assertions.assertThat(routes).hasSize(66754); + } catch (IOException e) { + throw new RuntimeException(e); } } - @SneakyThrows - // @Test - void parseAirportsCSVFileToBeans() { + // @Test + void parseAirportsCSVFileToBeans() throws FileNotFoundException { try (Reader fileReader = new FileReader("./data/airports.txt")) { CsvToBean csvToAirportBeans = new CsvToBeanBuilder(fileReader) - .withType(AirportDto.class) - .withVerifier(new AirportBeanVerifier()) - .withIgnoreLeadingWhiteSpace(true) - .build(); + .withType(AirportDto.class) + .withVerifier(new AirportBeanVerifier()) + .withIgnoreLeadingWhiteSpace(true) + .build(); // convert `CsvToBean` object to list of airports List airports = csvToAirportBeans.parse(); System.out.println(airports.size()); - Assertions.assertThat(airports.size()).isEqualTo(7140); + Assertions.assertThat(airports).hasSize(7140); + } catch (IOException e) { + throw new RuntimeException(e); } } } diff --git a/src/test/java/org/siriusxi/htec/fa/FlightAdvisorApplicationTests.java b/src/test/java/org/siriusxi/htec/fa/FlightAdvisorApplicationTests.java index 9c70523..c8df0b6 100644 --- a/src/test/java/org/siriusxi/htec/fa/FlightAdvisorApplicationTests.java +++ b/src/test/java/org/siriusxi/htec/fa/FlightAdvisorApplicationTests.java @@ -1,13 +1,21 @@ package org.siriusxi.htec.fa; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationContext; + +import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest class FlightAdvisorApplicationTests { - - @Test - void contextLoads() { - } - + + @Autowired + private ApplicationContext context; + + @Test + void contextLoads() { + assertThat(context).isNotNull(); + } + }