Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
286583e
#3 | Hendi Santika | Upgraded into Spring Boot 3.2.0 version πŸ«ΈπŸŒ€βœοΈπŸ“—πŸ§πŸ³β¬†
hendisantika May 7, 2024
477dfc4
#3 | Hendi Santika | Upgraded into Spring Boot 3.2.1 version πŸ«ΈπŸŒ€βœοΈπŸ“—πŸ§πŸ³β¬†
hendisantika May 7, 2024
a86b768
#3 | Hendi Santika | Upgraded into Spring Boot 3.2.2 version πŸ«ΈπŸŒ€βœοΈπŸ“—πŸ§πŸ³β¬†
hendisantika May 7, 2024
451c485
#3 | Hendi Santika | Upgraded into Spring Boot 3.2.3 version πŸ«ΈπŸŒ€βœοΈπŸ“—πŸ§πŸ³β¬†
hendisantika May 7, 2024
73f19c2
#3 | Hendi Santika | Upgraded into Spring Boot 3.2.4 version πŸ«ΈπŸŒ€βœοΈπŸ“—πŸ§πŸ³β¬†
hendisantika May 7, 2024
4d64c68
#3 | Hendi Santika | Add Spring Doc 2.5.0 version πŸ«ΈπŸŒ€βœοΈπŸ“—πŸ§πŸ³β¬†
hendisantika May 7, 2024
25f13cc
#3 | Hendi Santika | Adjust with new Spring Doc config πŸ«ΈπŸŒ€βœοΈπŸ“—πŸ§πŸ³β¬†
hendisantika May 7, 2024
acebd68
#3 | Hendi Santika | Adjust Spring security config πŸ«ΈπŸŒ€βœοΈπŸ“—πŸ§πŸ³β¬†
hendisantika May 7, 2024
d624596
#3 | Hendi Santika | Adjust Hibernate 6 πŸ«ΈπŸŒ€βœοΈπŸ“—πŸ§πŸ³β¬†
hendisantika May 7, 2024
ffdcca5
#3 | Hendi Santika | Set Spring Doc API πŸ«ΈπŸŒ€βœοΈπŸ“—πŸ§πŸ³β¬†
hendisantika May 7, 2024
f5641a5
#3 | Hendi Santika | Adjust with new Spring Doc annotation πŸ«ΈπŸŒ€βœοΈπŸ“—πŸ§πŸ³β¬†
hendisantika May 7, 2024
dabd7ad
#3 | Hendi Santika | Adjust with JUnit 5 πŸ«ΈπŸŒ€βœοΈπŸ“—πŸ§πŸ³β¬†
hendisantika May 7, 2024
f380631
#3 | Hendi Santika | Adjust Security Config πŸ«ΈπŸŒ€βœοΈπŸ“—πŸ§πŸ³β¬†
hendisantika May 7, 2024
1f0dce8
#3 | Hendi Santika | Add Swagger UI Screen shot πŸ«ΈπŸŒ€βœοΈπŸ“—πŸ§πŸ³β¬†
hendisantika May 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Compiled class file
*.class

/.idea
*.iml
# Log file
*.log

Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ spring-security-test
Please find the Rest API documentation in the below url

```
http://localhost:8989/bank-api/swagger-ui.html
http://localhost:8989/bank-api/swagger-ui/index.html

```

Expand All @@ -84,8 +84,14 @@ http://localhost:8989/bank-api/h2-console/

2. Browse to <project-root>/src/test/resources to find sample requests to add customer and accounts.

### Image Screen shot

Swagger UI Page

![Swagger UI Page](img/Swagger-UI.png "Swagger UI Page")

## Authors

* **Shyam Bathina**


Binary file added img/Swagger-UI.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 17 additions & 10 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<version>3.2.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.coding.exercise</groupId>
<artifactId>bank-app</artifactId>
<version>1.0.0</version>
<name>BankApp</name>
<description>Bank App Spring Boot Project</description>
<description>API for Banking Application.</description>

<properties>
<java.version>1.8</java.version>
<java.version>21</java.version>
</properties>

<dependencies>
Expand Down Expand Up @@ -52,15 +52,22 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-security -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-security</artifactId>
<version>1.8.0</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,43 @@
package com.coding.exercise.bankapp.config;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.beans.factory.annotation.Value;
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;

@Configuration
@EnableSwagger2
public class ApplicationConfig {

@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.paths(PathSelectors.any())
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("bank-service")
.pathsToMatch("/**")
.build();
}

private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("BANKING APPLICATION REST API")
.description("API for Banking Application.")
.version("1.0.0").build();

@Bean
public OpenAPI customOpenAPI(@Value("${application-description}") String appDescription, @Value("${application" +
"-version}") String appVersion) {
Contact contact = new Contact();
contact.setEmail("hendisantika@yahoo.co.id");
contact.setName("HENDI SANTIKA");
contact.setUrl("https://www.s.id/hendisantika");
return new OpenAPI()
.info(new Info()
.title("BANKING APPLICATION REST API")
.version(appVersion)
.description(appDescription)
.termsOfService("http://swagger.io/terms/")
.license(new License().name("Apache 2.0").url("http://springdoc.org"))
.contact(contact)
);

}


}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;

/**
*
Expand All @@ -13,14 +15,20 @@
*
*/
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
public class SecurityConfig {

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests().antMatchers("/").permitAll().and()
.authorizeRequests().antMatchers("/h2-console/**").permitAll();
@Bean
public SecurityFilterChain configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(authz -> authz
.requestMatchers("/swagger-ui", "/swagger-ui/**").permitAll()
.requestMatchers("/v3/api-docs", "/v3/api-docs/**").permitAll()
.requestMatchers("/").permitAll()
.requestMatchers("/h2-console/**").permitAll()
)
.headers().frameOptions().disable();
return httpSecurity.build();

httpSecurity.csrf().disable();
httpSecurity.headers().frameOptions().disable();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package com.coding.exercise.bankapp.controller;

import java.util.List;

import com.coding.exercise.bankapp.domain.AccountInformation;
import com.coding.exercise.bankapp.domain.TransactionDetails;
import com.coding.exercise.bankapp.domain.TransferDetails;
import com.coding.exercise.bankapp.service.BankingServiceImpl;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -12,40 +18,32 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.coding.exercise.bankapp.domain.AccountInformation;
import com.coding.exercise.bankapp.domain.TransactionDetails;
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;
import java.util.List;

@RestController
@RequestMapping("accounts")
@Api(tags = { "Accounts and Transactions REST endpoints" })
@Tag(name = "Account", description = "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") })
@Operation(summary = "Get account details", description = "Find account details by account number")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")})

public ResponseEntity<Object> 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") })
@Operation(summary = "Add a new account", description = "Create an new account for existing customer.")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")})

public ResponseEntity<Object> addNewAccount(@RequestBody AccountInformation accountInformation,
@PathVariable Long customerNumber) {
Expand All @@ -54,10 +52,10 @@ public ResponseEntity<Object> 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") })
@Operation(summary = "Transfer funds between accounts", description = "Transfer funds between accounts.")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")})

public ResponseEntity<Object> transferDetails(@RequestBody TransferDetails transferDetails,
@PathVariable Long customerNumber) {
Expand All @@ -66,10 +64,10 @@ public ResponseEntity<Object> 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") })
@Operation(summary = "Get all transactions", description = "Get all Transactions by account number")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")})

public List<TransactionDetails> getTransactionByAccountNumber(@PathVariable Long accountNumber) {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package com.coding.exercise.bankapp.controller;

import java.util.List;

import com.coding.exercise.bankapp.domain.CustomerDetails;
import com.coding.exercise.bankapp.service.BankingServiceImpl;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
Expand All @@ -13,61 +17,55 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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;
import java.util.List;

@RestController
@RequestMapping("customers")
@Api(tags = { "Customer REST endpoints" })
@Tag(name = "Customer", description = "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") })
@Operation(summary = "Find all customers", description = "Gets details of all the customers")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")})

public List<CustomerDetails> 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") })
@Operation(summary = "Add a Customer", description = "Add customer and create an account")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")})

public ResponseEntity<Object> addCustomer(@RequestBody CustomerDetails customer) {

return bankingService.addCustomer(customer);
}

@GetMapping(path = "/{customerNumber}")
@ApiOperation(value = "Get customer details", notes = "Get Customer details by customer number.")
@Operation(summary = "Get customer details", description = "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") })
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "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") })
@Operation(summary = "Update customer", description = "Update customer and any other account information associated with him.")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")})

public ResponseEntity<Object> updateCustomer(@RequestBody CustomerDetails customerDetails,
@PathVariable Long customerNumber) {
Expand All @@ -76,10 +74,10 @@ public ResponseEntity<Object> 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") })
@Operation(summary = "Delete customer and related accounts", description = "Delete customer and all accounts associated with him.")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "400", description = "Bad Request"),
@ApiResponse(responseCode = "500", description = "Internal Server Error")})

public ResponseEntity<Object> deleteCustomer(@PathVariable Long customerNumber) {

Expand Down
Loading