Skip to content

Commit

Permalink
feature: add specific exception in the number module (#8)
Browse files Browse the repository at this point in the history
* feature: add specific exception in the number module

* chore: upgrade spring authorization server to 0.4.0

* doc: update spring authorization server version

Co-authored-by: Alexandre Touret <alexandre-touret@users.noreply.github.com>
  • Loading branch information
alexandre-touret and alexandre-touret authored Nov 23, 2022
1 parent c890292 commit 8ec0b33
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 34 deletions.
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ C4Context
#### Explanations

Here we have two main kind of users:

* Customer : He can browse and create books
* Administrator: He can create books and activate/deactivate the maintenance mode

Expand Down Expand Up @@ -100,7 +99,7 @@ Here is a summary of the stack used in this workshop for this architecture:
| ISBN API | JAVA 17,Spring Boot 2.7.X | |
| Configuration Server | Spring Cloud Config 2021.0.4 | |
| Database | PostgreSQL | |
| Authorization Server | JAVA 17,Spring Boot 2.7.X, Spring Authorization Server 0.3.1 | |
| Authorization Server | JAVA 17,Spring Boot 2.7.X, Spring Authorization Server 0.4.0 | |


### Customers
Expand Down Expand Up @@ -183,4 +182,4 @@ or you can directly browse this URL (think to change the ``%%MY_NAMESPACE%%`` pr

``https://gitpod.io/#github.com/%%MY_NAMESPACE%%/rest-apis-versioning-workshop.git``

Now, you can start [the workshop](./docs/index.md).
Now, you can start [the workshop](./docs/index.md).
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,20 @@
import com.nimbusds.jose.proc.SecurityContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
import org.springframework.security.web.SecurityFilterChain;

import java.security.KeyPair;
Expand Down Expand Up @@ -105,9 +104,7 @@ private static KeyPair generateRsaKey() {
}

@Bean
public ProviderSettings providerSettings(@Value("${authorization.url}") String issuerUrl) {
return ProviderSettings.builder()
.issuer(issuerUrl)
.build();
public AuthorizationServerSettings authorizationServerSettings() {
return AuthorizationServerSettings.builder().build();
}
}
10 changes: 3 additions & 7 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,12 @@ subprojects {
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

sourceCompatibility = '17'

dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}


dependencies {
developmentOnly 'org.springframework.boot:spring-boot-devtools'
implementation 'io.opentracing.contrib:opentracing-spring-jaeger-cloud-starter:3.3.1'
Expand Down Expand Up @@ -118,8 +115,8 @@ project(':rest-number') {
implementation 'org.springframework.boot:spring-boot-starter-aop'
implementation "org.springdoc:springdoc-openapi-ui:${springdocVersion}"
implementation 'com.fasterxml.jackson.core:jackson-annotations'
implementation 'com.github.javafaker:javafaker:1.0.2'
implementation 'org.yaml:snakeyaml:1.33'
implementation "com.github.javafaker:javafaker:${javaFakerVersion}"
implementation "org.yaml:snakeyaml:${snakeYamlVersion}"
implementation "org.mapstruct:mapstruct:${mapstructVersion}"
annotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}"

Expand Down Expand Up @@ -183,10 +180,9 @@ project(':authorization-server') {
dependencies {
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.security:spring-security-oauth2-authorization-server:0.2.3'
implementation "org.springframework.security:spring-security-oauth2-authorization-server:${springAuthServerVersion}"
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'

}
}
5 changes: 4 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ springDependencyManagementVersion=1.0.15.RELEASE
#org.gradle.daemon=false
openApiGeneratorVersion=6.2.1
mapstructVersion=1.5.3.Final
springdocVersion=1.6.12
springdocVersion=1.6.12
springAuthServerVersion=0.4.0
javaFakerVersion=1.0.2
snakeYamlVersion=1.33
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package info.touret.bookstore.spring.number;

import info.touret.bookstore.spring.number.exception.ISBNExecutionException;
import info.touret.bookstore.spring.number.generated.dto.APIErrorDto;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.concurrent.TimeoutException;

/**
* Handles all the exceptions thrown by the application
*/
@RestControllerAdvice
public class GlobalExceptionHandler {

/**
* Indicates that the application is on maintenance
*/
@ResponseStatus(HttpStatus.GATEWAY_TIMEOUT)
@ExceptionHandler({ TimeoutException.class, ISBNExecutionException.class})
public APIErrorDto timeout() {
APIErrorDto apiErrorDto = new APIErrorDto();
apiErrorDto.setCode(HttpStatus.GATEWAY_TIMEOUT.value());
apiErrorDto.setReason("Timeout");
return apiErrorDto;
}

/**
* Any other exception
*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler({RuntimeException.class, Exception.class})
public APIErrorDto anyException() {
APIErrorDto apiErrorDto = new APIErrorDto();
apiErrorDto.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
apiErrorDto.setReason("An unexpected server error occured");
return apiErrorDto;
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
package info.touret.bookstore.spring.number.controller;

import info.touret.bookstore.spring.number.exception.ISBNExecutionException;
import info.touret.bookstore.spring.number.generated.controller.IsbnsApi;
import info.touret.bookstore.spring.number.generated.dto.BookNumbersDto;
import info.touret.bookstore.spring.number.service.BookNumbersService;
import io.micrometer.core.annotation.Timed;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

import static org.springframework.http.HttpStatus.GATEWAY_TIMEOUT;

/**
* Numbers API spring controller
* the time to respond is monitored using <code>@Timed</code> annotation
Expand All @@ -22,16 +19,14 @@
@RestController
public class BookNumbersController implements IsbnsApi {

private static final Logger LOGGER = LoggerFactory.getLogger(BookNumbersController.class);

private final BookNumbersService bookNumbersService;

public BookNumbersController(BookNumbersService bookNumbersService) {
this.bookNumbersService = bookNumbersService;
}

/**
* Gets the ISBN numbers for a given book. If there is a timeout calling {@link #bookNumbersService}, the method {@link BookSer#generateBookNumbersFallBack(TimeoutException)} is called
* Gets the ISBN numbers for a given book. If there is a timeout calling {@link #bookNumbersService}, the method {@link BookNumbersService#generateBookNumbersFallBack(TimeoutException)} is called
* The timeout mechanism is specified in the <code>application.yml</code> . You can check the <code>book-numbers</code> timeout instance out.
*
* @return The ISBN numbers
Expand All @@ -45,8 +40,7 @@ public ResponseEntity<BookNumbersDto> generateBookNumbers() {
try {
return ResponseEntity.ok(bookNumbersService.createBookNumbersAsync().get());
} catch (InterruptedException | ExecutionException e) {
LOGGER.warn("Timeout issue: Cause: {} / Error: {}", e.getCause(), e.getMessage());
return ResponseEntity.status(GATEWAY_TIMEOUT).build();
throw new ISBNExecutionException(e);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package info.touret.bookstore.spring.number.exception;

public class ISBNExecutionException extends RuntimeException{
public ISBNExecutionException() {
}

public ISBNExecutionException(String message) {
super(message);
}

public ISBNExecutionException(String message, Throwable cause) {
super(message, cause);
}

public ISBNExecutionException(Throwable cause) {
super(cause);
}

public ISBNExecutionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package info.touret.bookstore.spring.number.service;

import com.github.javafaker.Faker;
import info.touret.bookstore.spring.number.exception.ISBNExecutionException;
import info.touret.bookstore.spring.number.generated.dto.BookNumbersDto;
import io.github.resilience4j.timelimiter.annotation.TimeLimiter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.annotation.PostConstruct;
import java.util.concurrent.CompletableFuture;
Expand Down Expand Up @@ -53,7 +51,7 @@ public BookNumbersDto createBookNumbers() {
if (timeToSleep != 0)
TimeUnit.MILLISECONDS.sleep(timeToSleep);
} catch (InterruptedException e) {
throw new RuntimeException(e);
throw new ISBNExecutionException(e);
}

Faker faker = new Faker();
Expand All @@ -72,8 +70,6 @@ public BookNumbersDto createBookNumbers() {
* @param e The handled exception
* @return failedFuture
*/
@ResponseStatus(HttpStatus.GATEWAY_TIMEOUT)
@ExceptionHandler({TimeoutException.class})
public CompletableFuture<BookNumbersDto> generateBookNumbersFallBack(TimeoutException e) {
LOGGER.error(e.getMessage(), e);
return CompletableFuture.failedFuture(e);
Expand Down
16 changes: 15 additions & 1 deletion rest-number/src/main/resources/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,23 @@ paths:
content:
application/json:
schema:
"$ref": "#/components/schemas/BookNumbers"
"$ref": "#/components/schemas/APIError"
'500':
description: Internal Server Error
content:
"*/*":
schema:
"$ref": "#/components/schemas/APIError"
components:
schemas:
APIError:
type: object
properties:
code:
type: integer
format: int32
reason:
type: string
BookNumbers:
type: object
properties:
Expand Down

0 comments on commit 8ec0b33

Please sign in to comment.