Skip to content

Commit

Permalink
Restore LoggingExceptionResolver to capture/monitor/alter exceptions …
Browse files Browse the repository at this point in the history
…return to Client
  • Loading branch information
RustyHMCTS committed Jul 31, 2024
1 parent 36bee12 commit 93fcad3
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import static uk.gov.hmcts.opal.authorisation.aspect.AuthorizationAspectService.AUTHORIZATION;

@Component
@Slf4j
@Slf4j(topic = "UserStateAspectService")
@RequiredArgsConstructor
public class UserStateAspectService {

Expand All @@ -29,12 +29,14 @@ public class UserStateAspectService {
* @return UserState object for the user
*/
public UserState getUserState(ProceedingJoinPoint joinPoint) {
log.info(":getUserState:");
return authorizationAspectService.getUserState(joinPoint.getArgs())
.orElseGet(getUserStateSupplier(joinPoint));
}

public Supplier<UserState> getUserStateSupplier(ProceedingJoinPoint joinPoint) {
return () -> {
log.info(":getUserStateSupplier:");
String authHeaderValue = authorizationAspectService.getAccessTokenParam(joinPoint).orElse(null);
String bearerToken = authorizationAspectService.getAuthorization(authHeaderValue)
.orElseThrow(() -> new MissingRequestHeaderException(AUTHORIZATION));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package uk.gov.hmcts.opal.authentication.client;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
Expand All @@ -12,6 +13,7 @@
import uk.gov.hmcts.opal.authentication.model.AccessTokenRequest;


@Slf4j(topic = "AzureTokenClient")
@Service
@RequiredArgsConstructor
public class AzureTokenClient {
Expand All @@ -29,6 +31,8 @@ public AccessTokenResponse getAccessToken(AccessTokenRequest request) {
body.add("username", request.getUsername());
body.add("password", request.getPassword());

log.info(":getAccessToken:");

ResponseEntity<AccessTokenResponse> response = restClient
.post()
.uri(this.provider.getTokenUri())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.nimbusds.oauth2.sdk.http.HTTPResponse;
import com.nimbusds.oauth2.sdk.id.ClientID;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import uk.gov.hmcts.opal.authentication.config.AuthProviderConfigurationProperties;

Expand All @@ -20,13 +21,15 @@


@Component
@Slf4j(topic = "OAuthClient")
public class OAuthClient {
@SneakyThrows({URISyntaxException.class, IOException.class})
public HTTPResponse fetchAccessToken(AuthProviderConfigurationProperties providerConfigurationProperties,
String redirectType, String authCode,
String clientId,
String authClientSecret,
String scope) {
log.info(":fetchAccessToken:");
AuthorizationCode code = new AuthorizationCode(authCode);
URI callback = new URI(redirectType);
AuthorizationGrant codeGrant = new AuthorizationCodeGrant(code, callback);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public CourtController(@Qualifier("courtServiceProxy") CourtServiceInterface cou
@GetMapping(value = "/{courtId}")
@Operation(summary = "Returns the court for the given courtId.")
public ResponseEntity<CourtEntity> getCourtById(@PathVariable Long courtId,
@RequestHeader("Authorization") String authHeaderValue) {
@RequestHeader(value = "Authorization", required = false) String authHeaderValue) {

log.info(":GET:getCourtById: courtId: {}", courtId);

Expand All @@ -64,7 +64,7 @@ public ResponseEntity<CourtEntity> getCourtById(@PathVariable Long courtId,
@PostMapping(value = "/search", consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Searches courts based upon criteria in request body")
public ResponseEntity<List<CourtEntity>> postCourtsSearch(@RequestBody CourtSearchDto criteria,
@RequestHeader("Authorization") String authHeaderValue) {
@RequestHeader(value = "Authorization", required = false) String authHeaderValue) {
log.info(":POST:postCourtsSearch: query: \n{}", criteria);

userStateService.checkForAuthorisedUser(authHeaderValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public DefendantAccountController(
public ResponseEntity<DefendantAccountEntity> getDefendantAccount(
@RequestParam(name = "businessUnitId") Short businessUnitId,
@RequestParam(name = "accountNumber") String accountNumber,
@RequestHeader("Authorization") String authHeaderValue) {
@RequestHeader(value = "Authorization", required = false) String authHeaderValue) {

AccountEnquiryDto enquiryDto = AccountEnquiryDto.builder()
.businessUnitId(businessUnitId)
Expand All @@ -80,7 +80,7 @@ public ResponseEntity<DefendantAccountEntity> getDefendantAccount(
@Operation(summary = "Updates defendant account information")
public ResponseEntity<DefendantAccountEntity> putDefendantAccount(
@RequestBody DefendantAccountEntity defendantAccountEntity,
@RequestHeader("Authorization") String authHeaderValue) {
@RequestHeader(value = "Authorization", required = false) String authHeaderValue) {

DefendantAccountEntity response = defendantAccountService.putDefendantAccount(defendantAccountEntity);

Expand All @@ -90,7 +90,7 @@ public ResponseEntity<DefendantAccountEntity> putDefendantAccount(
@GetMapping(value = "/{defendantAccountId}")
@Operation(summary = "Get defendant account details by providing the defendant account summary")
public ResponseEntity<AccountDetailsDto> getAccountDetails(@PathVariable Long defendantAccountId,
@RequestHeader("Authorization") String authHeaderValue) {
@RequestHeader(value = "Authorization", required = false) String authHeaderValue) {

AccountDetailsDto response = defendantAccountService.getAccountDetailsByDefendantAccountId(defendantAccountId);

Expand All @@ -101,7 +101,7 @@ public ResponseEntity<AccountDetailsDto> getAccountDetails(@PathVariable Long de
@Operation(summary = "Searches defendant accounts based upon criteria in request body")
public ResponseEntity<AccountSearchResultsDto> postDefendantAccountSearch(
@RequestBody AccountSearchDto accountSearchDto,
@RequestHeader("Authorization") String authHeaderValue) {
@RequestHeader(value = "Authorization", required = false) String authHeaderValue) {
log.info(":POST:postDefendantAccountSearch: query: \n{}", accountSearchDto.toPrettyJson());

AccountSearchResultsDto response = defendantAccountService.searchDefendantAccounts(accountSearchDto);
Expand All @@ -113,7 +113,7 @@ public ResponseEntity<AccountSearchResultsDto> postDefendantAccountSearch(
@Operation(summary = "Adds a single note associated with the defendant account")
public ResponseEntity<NoteDto> addNote(
@RequestBody AddNoteDto addNote,
@RequestHeader("Authorization") String authHeaderValue) {
@RequestHeader(value = "Authorization", required = false) String authHeaderValue) {
log.info(":POST:addNote: {}", addNote.toPrettyJson());

UserState userState = userStateService.getUserStateUsingAuthToken(authHeaderValue);
Expand Down Expand Up @@ -142,7 +142,7 @@ public ResponseEntity<NoteDto> addNote(
@Operation(summary = "Returns all notes for an associated defendant account id.")
public ResponseEntity<List<NoteDto>> getNotesForDefendantAccount(
@PathVariable String defendantId,
@RequestHeader("Authorization") String authHeaderValue) {
@RequestHeader(value = "Authorization", required = false) String authHeaderValue) {

log.info(":GET:getNotesForDefendantAccount: defendant account id: {}", defendantId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public DraftAccountController(UserStateService userStateService, DraftAccountSer
@GetMapping(value = "/{draftAccountId}")
@Operation(summary = "Returns the Draft Account for the given draftAccountId.")
public ResponseEntity<DraftAccountEntity> getDraftAccountById(@PathVariable Long draftAccountId,
@RequestHeader("Authorization") String authHeaderValue) {
@RequestHeader(value = "Authorization", required = false) String authHeaderValue) {

log.info(":GET:getDraftAccountById: draftAccountId: {}", draftAccountId);

Expand All @@ -54,7 +54,7 @@ public ResponseEntity<DraftAccountEntity> getDraftAccountById(@PathVariable Long
@PostMapping(value = "/search", consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Searches Draft Accounts based upon criteria in request body")
public ResponseEntity<List<DraftAccountEntity>> postDraftAccountsSearch(@RequestBody DraftAccountSearchDto criteria,
@RequestHeader("Authorization") String authHeaderValue) {
@RequestHeader(value = "Authorization", required = false) String authHeaderValue) {
log.info(":POST:postDraftAccountsSearch: query: \n{}", criteria);

userStateService.checkForAuthorisedUser(authHeaderValue);
Expand All @@ -67,7 +67,7 @@ public ResponseEntity<List<DraftAccountEntity>> postDraftAccountsSearch(@Request
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Creates a Draft Account entity in the DB based upon data in request body")
public ResponseEntity<DraftAccountEntity> postDraftAccount(@RequestBody DraftAccountEntity entity,
@RequestHeader("Authorization") String authHeaderValue) {
@RequestHeader(value = "Authorization", required = false) String authHeaderValue) {
log.info(":POST:postDraftAccount: creating a new draft account entity.");

userStateService.checkForAuthorisedUser(authHeaderValue);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package uk.gov.hmcts.opal.controllers;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.PropertyValueException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import uk.gov.hmcts.opal.authentication.service.AccessTokenService;

@Component
@RequiredArgsConstructor
@Slf4j(topic = "LoggingExceptionResolver")
public class LoggingExceptionResolver implements HandlerExceptionResolver {

private final AccessTokenService tokenService;

@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
if (ex instanceof DataIntegrityViolationException dive) {
log.warn(":resolveException: DataIntegrityViolationException: ", dive.getCause());
} else if (ex instanceof PropertyValueException pve) {
log.warn(":resolveException: for Entity '{}', value '{}': {}",
pve.getEntityName(), pve.getPropertyName(), pve.getMessage());
} else {
log.warn(":resolveException: {}: '{}'", ex.getClass().getSimpleName(), ex.getMessage());
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public NoteController(@Qualifier("noteServiceProxy") NoteServiceInterface noteSe
@Operation(summary = "Creates a new note in the Opal Fines Notes table assigning an ID.")
public ResponseEntity<NoteDto> createNote(
@RequestBody NoteDto noteDto,
@RequestHeader("Authorization") String authHeaderValue) {
@RequestHeader(value = "Authorization", required = false) String authHeaderValue) {
log.info(":POST:createNote: {}", noteDto.toPrettyJson());

UserState userState = userStateService.getUserStateUsingAuthToken(authHeaderValue);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package uk.gov.hmcts.opal.controllers;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.hibernate.PropertyValueException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.dao.DataIntegrityViolationException;

@ExtendWith(MockitoExtension.class)
class LoggingExceptionResolverTest {

@InjectMocks
private LoggingExceptionResolver loggingExceptionResolver;

@Test
void codeCoverage() {
// Arrange
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
Object object = "null";

// Act
loggingExceptionResolver.resolveException(request, response, object, new DataIntegrityViolationException(""));
loggingExceptionResolver.resolveException(request, response, object, new PropertyValueException("", "", ""));
loggingExceptionResolver.resolveException(request, response, object, new Exception());
}

}

0 comments on commit 93fcad3

Please sign in to comment.