diff --git a/README.md b/README.md index 991b41a..3fa57be 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Banking Application using Java8, Spring Boot, Spring Security and H2 DB +# Banking Application using Java 17, Spring Boot, Spring Security and H2 DB RESTful API to simulate simple banking operations. @@ -38,7 +38,7 @@ https://projectlombok.org/setup/eclipse ### Prerequisites -* Java 8 +* Java 17 * Spring Tool Suite 4 or similar IDE * [Maven](https://maven.apache.org/) - Dependency Management diff --git a/pom.xml b/pom.xml index 647e3ce..7818306 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.4.RELEASE + 3.3.13 com.coding.exercise @@ -15,7 +15,7 @@ Bank App Spring Boot Project - 1.8 + 17 @@ -41,31 +41,27 @@ spring-boot-devtools runtime - - com.h2database - h2 - runtime - - - org.projectlombok - lombok - true - - - io.springfox - springfox-swagger2 - 2.9.2 - - - io.springfox - springfox-swagger-ui - 2.9.2 - - - org.springframework.boot - spring-boot-starter-test - test - + + com.h2database + h2 + 2.2.224 + runtime + + + org.projectlombok + lombok + true + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.6.0 + + + org.springframework.boot + spring-boot-starter-test + test + org.springframework.security spring-security-test @@ -79,6 +75,14 @@ org.springframework.boot spring-boot-maven-plugin + + org.apache.maven.plugins + maven-compiler-plugin + + 17 + 17 + + diff --git a/src/main/java/com/coding/exercise/bankapp/config/ApplicationConfig.java b/src/main/java/com/coding/exercise/bankapp/config/ApplicationConfig.java index 67845f3..0df0ffe 100644 --- a/src/main/java/com/coding/exercise/bankapp/config/ApplicationConfig.java +++ b/src/main/java/com/coding/exercise/bankapp/config/ApplicationConfig.java @@ -3,29 +3,18 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; @Configuration -@EnableSwagger2 public class ApplicationConfig { @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2) - .apiInfo(apiInfo()) - .select() - .paths(PathSelectors.any()) - .build(); - } - - private ApiInfo apiInfo() { - return new ApiInfoBuilder().title("BANKING APPLICATION REST API") - .description("API for Banking Application.") - .version("1.0.0").build(); + public OpenAPI customOpenAPI() { + return new OpenAPI() + .info(new Info() + .title("BANKING APPLICATION REST API") + .description("API for Banking Application.") + .version("1.0.0")); } } diff --git a/src/main/java/com/coding/exercise/bankapp/config/SecurityConfig.java b/src/main/java/com/coding/exercise/bankapp/config/SecurityConfig.java index 1af7a3b..ec22069 100644 --- a/src/main/java/com/coding/exercise/bankapp/config/SecurityConfig.java +++ b/src/main/java/com/coding/exercise/bankapp/config/SecurityConfig.java @@ -1,26 +1,32 @@ package com.coding.exercise.bankapp.config; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.web.SecurityFilterChain; /** * - * Spring security denied access to h2-console. - * This configuration will resolve 403 forbidden error when accessing h2-console. + * Spring security configuration for H2 console access. + * This configuration resolves 403 forbidden error when accessing h2-console. * * @author sbathina * */ @Configuration -public class SecurityConfig extends WebSecurityConfigurerAdapter { +@EnableWebSecurity +public class SecurityConfig { - @Override - protected void configure(HttpSecurity httpSecurity) throws Exception { - httpSecurity.authorizeRequests().antMatchers("/").permitAll().and() - .authorizeRequests().antMatchers("/h2-console/**").permitAll(); - - httpSecurity.csrf().disable(); - httpSecurity.headers().frameOptions().disable(); + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http + .authorizeHttpRequests(auth -> auth + .anyRequest().permitAll() + ) + .csrf(csrf -> csrf.disable()) + .headers(headers -> headers.frameOptions(frame -> frame.disable())); + + return http.build(); } } diff --git a/src/main/java/com/coding/exercise/bankapp/controller/AccountController.java b/src/main/java/com/coding/exercise/bankapp/controller/AccountController.java index b35f625..8562076 100644 --- a/src/main/java/com/coding/exercise/bankapp/controller/AccountController.java +++ b/src/main/java/com/coding/exercise/bankapp/controller/AccountController.java @@ -17,36 +17,20 @@ import com.coding.exercise.bankapp.domain.TransferDetails; import com.coding.exercise.bankapp.service.BankingServiceImpl; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; - @RestController @RequestMapping("accounts") -@Api(tags = { "Accounts and Transactions REST endpoints" }) public class AccountController { @Autowired private BankingServiceImpl bankingService; @GetMapping(path = "/{accountNumber}") - @ApiOperation(value = "Get account details", notes = "Find account details by account number") - @ApiResponses(value = { @ApiResponse(code = 200, message = "Success"), - @ApiResponse(code = 400, message = "Bad Request"), - @ApiResponse(code = 500, message = "Internal Server Error") }) - public ResponseEntity getByAccountNumber(@PathVariable Long accountNumber) { return bankingService.findByAccountNumber(accountNumber); } @PostMapping(path = "/add/{customerNumber}") - @ApiOperation(value = "Add a new account", notes = "Create an new account for existing customer.") - @ApiResponses(value = { @ApiResponse(code = 200, message = "Success"), - @ApiResponse(code = 400, message = "Bad Request"), - @ApiResponse(code = 500, message = "Internal Server Error") }) - public ResponseEntity addNewAccount(@RequestBody AccountInformation accountInformation, @PathVariable Long customerNumber) { @@ -54,11 +38,6 @@ public ResponseEntity addNewAccount(@RequestBody AccountInformation acco } @PutMapping(path = "/transfer/{customerNumber}") - @ApiOperation(value = "Transfer funds between accounts", notes = "Transfer funds between accounts.") - @ApiResponses(value = { @ApiResponse(code = 200, message = "Success", response = Object.class), - @ApiResponse(code = 400, message = "Bad Request"), - @ApiResponse(code = 500, message = "Internal Server Error") }) - public ResponseEntity transferDetails(@RequestBody TransferDetails transferDetails, @PathVariable Long customerNumber) { @@ -66,11 +45,6 @@ public ResponseEntity transferDetails(@RequestBody TransferDetails trans } @GetMapping(path = "/transactions/{accountNumber}") - @ApiOperation(value = "Get all transactions", notes = "Get all Transactions by account number") - @ApiResponses(value = { @ApiResponse(code = 200, message = "Success"), - @ApiResponse(code = 400, message = "Bad Request"), - @ApiResponse(code = 500, message = "Internal Server Error") }) - public List getTransactionByAccountNumber(@PathVariable Long accountNumber) { return bankingService.findTransactionsByAccountNumber(accountNumber); diff --git a/src/main/java/com/coding/exercise/bankapp/controller/CustomerController.java b/src/main/java/com/coding/exercise/bankapp/controller/CustomerController.java index 58e9044..3c86e63 100644 --- a/src/main/java/com/coding/exercise/bankapp/controller/CustomerController.java +++ b/src/main/java/com/coding/exercise/bankapp/controller/CustomerController.java @@ -16,59 +16,32 @@ import com.coding.exercise.bankapp.domain.CustomerDetails; import com.coding.exercise.bankapp.service.BankingServiceImpl; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; - @RestController @RequestMapping("customers") -@Api(tags = { "Customer REST endpoints" }) public class CustomerController { @Autowired private BankingServiceImpl bankingService; @GetMapping(path = "/all") - @ApiOperation(value = "Find all customers", notes = "Gets details of all the customers") - @ApiResponses(value = { @ApiResponse(code = 200, message = "Success"), - @ApiResponse(code = 400, message = "Bad Request"), - @ApiResponse(code = 500, message = "Internal Server Error") }) - public List getAllCustomers() { return bankingService.findAll(); } @PostMapping(path = "/add") - @ApiOperation(value = "Add a Customer", notes = "Add customer and create an account") - @ApiResponses(value = { @ApiResponse(code = 200, message = "Success"), - @ApiResponse(code = 400, message = "Bad Request"), - @ApiResponse(code = 500, message = "Internal Server Error") }) - public ResponseEntity addCustomer(@RequestBody CustomerDetails customer) { return bankingService.addCustomer(customer); } @GetMapping(path = "/{customerNumber}") - @ApiOperation(value = "Get customer details", notes = "Get Customer details by customer number.") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Success", response = CustomerDetails.class, responseContainer = "Object"), - @ApiResponse(code = 400, message = "Bad Request"), - @ApiResponse(code = 500, message = "Internal Server Error") }) - public CustomerDetails getCustomer(@PathVariable Long customerNumber) { return bankingService.findByCustomerNumber(customerNumber); } @PutMapping(path = "/{customerNumber}") - @ApiOperation(value = "Update customer", notes = "Update customer and any other account information associated with him.") - @ApiResponses(value = { @ApiResponse(code = 200, message = "Success", response = Object.class), - @ApiResponse(code = 400, message = "Bad Request"), - @ApiResponse(code = 500, message = "Internal Server Error") }) - public ResponseEntity updateCustomer(@RequestBody CustomerDetails customerDetails, @PathVariable Long customerNumber) { @@ -76,11 +49,6 @@ public ResponseEntity updateCustomer(@RequestBody CustomerDetails custom } @DeleteMapping(path = "/{customerNumber}") - @ApiOperation(value = "Delete customer and related accounts", notes = "Delete customer and all accounts associated with him.") - @ApiResponses(value = { @ApiResponse(code = 200, message = "Success", response = Object.class), - @ApiResponse(code = 400, message = "Bad Request"), - @ApiResponse(code = 500, message = "Internal Server Error") }) - public ResponseEntity deleteCustomer(@PathVariable Long customerNumber) { return bankingService.deleteCustomer(customerNumber); diff --git a/src/main/java/com/coding/exercise/bankapp/model/Account.java b/src/main/java/com/coding/exercise/bankapp/model/Account.java index 9494ffe..474dc15 100644 --- a/src/main/java/com/coding/exercise/bankapp/model/Account.java +++ b/src/main/java/com/coding/exercise/bankapp/model/Account.java @@ -3,15 +3,15 @@ import java.util.Date; import java.util.UUID; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToOne; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/coding/exercise/bankapp/model/Address.java b/src/main/java/com/coding/exercise/bankapp/model/Address.java index 241a0df..648f85b 100644 --- a/src/main/java/com/coding/exercise/bankapp/model/Address.java +++ b/src/main/java/com/coding/exercise/bankapp/model/Address.java @@ -2,11 +2,11 @@ import java.util.UUID; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/coding/exercise/bankapp/model/BankInfo.java b/src/main/java/com/coding/exercise/bankapp/model/BankInfo.java index 2e9955b..eb36b4b 100644 --- a/src/main/java/com/coding/exercise/bankapp/model/BankInfo.java +++ b/src/main/java/com/coding/exercise/bankapp/model/BankInfo.java @@ -2,13 +2,13 @@ import java.util.UUID; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToOne; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/coding/exercise/bankapp/model/Contact.java b/src/main/java/com/coding/exercise/bankapp/model/Contact.java index c793bee..26cc66b 100644 --- a/src/main/java/com/coding/exercise/bankapp/model/Contact.java +++ b/src/main/java/com/coding/exercise/bankapp/model/Contact.java @@ -2,11 +2,11 @@ import java.util.UUID; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/coding/exercise/bankapp/model/Customer.java b/src/main/java/com/coding/exercise/bankapp/model/Customer.java index 5235a51..23efb8f 100644 --- a/src/main/java/com/coding/exercise/bankapp/model/Customer.java +++ b/src/main/java/com/coding/exercise/bankapp/model/Customer.java @@ -3,15 +3,15 @@ import java.util.Date; import java.util.UUID; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToOne; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/coding/exercise/bankapp/model/CustomerAccountXRef.java b/src/main/java/com/coding/exercise/bankapp/model/CustomerAccountXRef.java index 2c580ce..f3c37be 100644 --- a/src/main/java/com/coding/exercise/bankapp/model/CustomerAccountXRef.java +++ b/src/main/java/com/coding/exercise/bankapp/model/CustomerAccountXRef.java @@ -2,11 +2,11 @@ import java.util.UUID; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/coding/exercise/bankapp/model/Transaction.java b/src/main/java/com/coding/exercise/bankapp/model/Transaction.java index 7d7bcce..b4adda8 100644 --- a/src/main/java/com/coding/exercise/bankapp/model/Transaction.java +++ b/src/main/java/com/coding/exercise/bankapp/model/Transaction.java @@ -3,13 +3,13 @@ import java.util.Date; import java.util.UUID; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/test/java/com/coding/exercise/bankapp/BankingApplicationTests.java b/src/test/java/com/coding/exercise/bankapp/BankingApplicationTests.java index 803c91d..6b76be1 100644 --- a/src/test/java/com/coding/exercise/bankapp/BankingApplicationTests.java +++ b/src/test/java/com/coding/exercise/bankapp/BankingApplicationTests.java @@ -1,11 +1,8 @@ package com.coding.exercise.bankapp; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringRunner.class) @SpringBootTest public class BankingApplicationTests {