Skip to content

Commit

Permalink
Pyic 6966 lambda catch all logging (#2691)
Browse files Browse the repository at this point in the history
  • Loading branch information
DanCorderIPV authored Nov 15, 2024
2 parents 1869035 + 907a3c8 commit 82ebfaa
Show file tree
Hide file tree
Showing 92 changed files with 871 additions and 138 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ dev
production
uuid_results

libs/pact-test-helpers/bin
libs/test-helpers/bin
local-running/bin/

# User-specific secrets
Expand Down
4 changes: 3 additions & 1 deletion lambdas/build-client-oauth-response/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ dependencies {
libs.aspectj

testImplementation libs.junitJupiter,
libs.mockitoJunit
libs.mockitoJunit,
libs.hamcrest,
project(path: ':libs:test-helpers')

testRuntimeOnly libs.junitPlatform
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ public Map<String, Object> handleRequest(JourneyRequest input, Context context)
} catch (IpvSessionNotFoundException e) {
return buildJourneyErrorResponse(
HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorResponse.IPV_SESSION_NOT_FOUND);
} catch (Exception e) {
LOGGER.error(LogHelper.buildErrorMessage("Unhandled lambda exception", e));
throw e;
} finally {
auditService.awaitAuditEvents();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import uk.gov.di.ipv.core.library.service.ClientOAuthSessionDetailsService;
import uk.gov.di.ipv.core.library.service.ConfigService;
import uk.gov.di.ipv.core.library.service.IpvSessionService;
import uk.gov.di.ipv.core.library.testhelpers.unit.LogCollector;
import uk.gov.di.ipv.core.library.validation.ValidationResult;

import java.net.URI;
Expand All @@ -47,8 +48,11 @@
import java.util.Map;
import java.util.stream.Stream;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.StringContains.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.anyString;
Expand Down Expand Up @@ -414,6 +418,34 @@ void shouldReturn200OnSuccessfulOauthRequestForJsonRequest() throws Exception {
assertEquals("test-state", params.get(1).getValue());
}

@Test
void shouldLogRuntimeExceptionsAndRethrow() throws Exception {
// Arrange
when(mockSessionService.getIpvSession(anyString()))
.thenThrow(new RuntimeException("Test error"));
JourneyRequest event =
JourneyRequest.builder()
.ipvSessionId(TEST_SESSION_ID)
.ipAddress(TEST_IP_ADDRESS)
.clientOAuthSessionId(TEST_CLIENT_OAUTH_SESSION_ID)
.build();

var logCollector = LogCollector.getLogCollectorFor(BuildClientOauthResponseHandler.class);

// Act
var thrown =
assertThrows(
Exception.class,
() -> handler.handleRequest(event, context),
"Expected handleRequest() to throw, but it didn't");

// Assert
assertEquals("Test error", thrown.getMessage());
var logMessage = logCollector.getLogMessages().get(0);
assertThat(logMessage, containsString("Unhandled lambda exception"));
assertThat(logMessage, containsString("Test error"));
}

private IpvSessionItem generateIpvSessionItem() {
IpvSessionItem item = new IpvSessionItem();
item.setIpvSessionId(SecureTokenHelper.getInstance().generate());
Expand Down
7 changes: 5 additions & 2 deletions lambdas/build-cri-oauth-request/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ dependencies {
compileOnly libs.lombok
annotationProcessor libs.lombok

testImplementation libs.junitJupiter,
testImplementation libs.hamcrest,
libs.junitJupiter,
libs.mockitoJunit,
project(path: ':libs:common-services', configuration: 'tests')
project(path: ':libs:common-services', configuration: 'tests'),
project(path: ':libs:test-helpers')

testRuntimeOnly libs.junitPlatform
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ public Map<String, Object> handleRequest(CriJourneyRequest input, Context contex
e,
HttpStatus.SC_INTERNAL_SERVER_ERROR,
IPV_SESSION_NOT_FOUND);
} catch (Exception e) {
LOGGER.error(LogHelper.buildErrorMessage("Unhandled lambda exception", e));
throw e;
} finally {
auditService.awaitAuditEvents();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import uk.gov.di.ipv.core.library.service.UserIdentityService;
import uk.gov.di.ipv.core.library.signing.LocalECDSASigner;
import uk.gov.di.ipv.core.library.signing.SignerFactory;
import uk.gov.di.ipv.core.library.testhelpers.unit.LogCollector;
import uk.gov.di.ipv.core.library.verifiablecredential.helpers.VcHelper;
import uk.gov.di.ipv.core.library.verifiablecredential.service.SessionCredentialsService;

Expand All @@ -73,8 +74,11 @@
import java.util.Optional;
import java.util.stream.Stream;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.StringContains.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
Expand Down Expand Up @@ -1094,6 +1098,35 @@ void shouldIncludeGivenParametersIntoCriResponseIfInJourneyUri(
}
}

@Test
void shouldLogRuntimeExceptionsAndRethrow() throws Exception {
// Arrange
when(mockIpvSessionService.getIpvSession(SESSION_ID))
.thenThrow(new RuntimeException("Test error"));
CriJourneyRequest input =
CriJourneyRequest.builder()
.ipvSessionId(SESSION_ID)
.ipAddress(TEST_IP_ADDRESS)
.language(TEST_LANGUAGE)
.journey(String.format(JOURNEY_BASE_URL, HMRC_KBV.getId()))
.build();

var logCollector = LogCollector.getLogCollectorFor(BuildCriOauthRequestHandler.class);

// Act
var thrown =
assertThrows(
Exception.class,
() -> handleRequest(input, context),
"Expected handleRequest() to throw, but it didn't");

// Assert
assertEquals("Test error", thrown.getMessage());
var logMessage = logCollector.getLogMessages().get(0);
assertThat(logMessage, containsString("Unhandled lambda exception"));
assertThat(logMessage, containsString("Test error"));
}

private static Stream<Arguments> journeyUriParameters() {
return Stream.of(
Arguments.of(CRI_WITH_CONTEXT, Map.of(CONTEXT, TEST_CONTEXT)),
Expand Down
7 changes: 5 additions & 2 deletions lambdas/build-proven-user-identity-details/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ dependencies {
compileOnly libs.lombok
annotationProcessor libs.lombok

testImplementation libs.junitJupiter,
testImplementation libs.hamcrest,
libs.junitJupiter,
libs.mockitoJunit,
project(path: ':libs:common-services', configuration: 'tests')
project(path: ':libs:common-services', configuration: 'tests'),
project(path: ':libs:test-helpers')

testRuntimeOnly(libs.junitPlatform)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ public APIGatewayProxyResponseEvent handleRequest(
ErrorResponse.FAILED_TO_GENERATE_PROVEN_USER_IDENTITY_DETAILS);
} catch (IpvSessionNotFoundException e) {
return buildJourneyErrorResponse(ErrorResponse.IPV_SESSION_NOT_FOUND);
} catch (Exception e) {
LOGGER.error(LogHelper.buildErrorMessage("Unhandled lambda exception", e));
throw e;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,20 @@
import uk.gov.di.ipv.core.library.service.ConfigService;
import uk.gov.di.ipv.core.library.service.IpvSessionService;
import uk.gov.di.ipv.core.library.service.UserIdentityService;
import uk.gov.di.ipv.core.library.testhelpers.unit.LogCollector;
import uk.gov.di.ipv.core.library.verifiablecredential.helpers.VcHelper;
import uk.gov.di.ipv.core.library.verifiablecredential.service.SessionCredentialsService;

import java.util.List;
import java.util.Map;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.StringContains.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
Expand Down Expand Up @@ -89,7 +94,9 @@ void setUp() {
.userId(TEST_USER_ID)
.build();

when(mockIpvSessionItem.getClientOAuthSessionId()).thenReturn(TEST_CLIENT_OAUTH_SESSION_ID);
Mockito.lenient()
.when(mockIpvSessionItem.getClientOAuthSessionId())
.thenReturn(TEST_CLIENT_OAUTH_SESSION_ID);
Mockito.lenient().when(mockIpvSessionItem.getVot()).thenReturn(Vot.P2);
}

Expand Down Expand Up @@ -428,6 +435,30 @@ private APIGatewayProxyRequestEvent createRequestEvent() {
Map.of(IPV_SESSION_ID_HEADER, SESSION_ID, IP_ADDRESS_HEADER, "10.10.10.1"));
}

@Test
void shouldLogRuntimeExceptionsAndRethrow() throws Exception {
// Arrange
when(mockIpvSessionService.getIpvSession(anyString()))
.thenThrow(new RuntimeException("Test error"));
var input = createRequestEvent();

var logCollector =
LogCollector.getLogCollectorFor(BuildProvenUserIdentityDetailsHandler.class);

// Act
var thrown =
assertThrows(
Exception.class,
() -> handler.handleRequest(input, context),
"Expected handleRequest() to throw, but it didn't");

// Assert
assertEquals("Test error", thrown.getMessage());
var logMessage = logCollector.getLogMessages().get(0);
assertThat(logMessage, containsString("Unhandled lambda exception"));
assertThat(logMessage, containsString("Test error"));
}

private <T> T toResponseClass(
APIGatewayProxyResponseEvent handlerOutput, Class<T> responseClass)
throws JsonProcessingException {
Expand Down
5 changes: 3 additions & 2 deletions lambdas/build-user-identity/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ dependencies {
libs.powertoolsTracing,
libs.aspectj

testImplementation libs.junitJupiter,
testImplementation libs.hamcrest,
libs.junitJupiter,
libs.mockitoJunit,
libs.pactProviderJunit,
project(path: ':libs:common-services', configuration: 'tests'),
project(path: ':libs:pact-test-helpers')
project(path: ':libs:test-helpers')

testRuntimeOnly libs.junitPlatform
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ public APIGatewayProxyResponseEvent handleRequest(
return getAccessDeniedApiGatewayProxyResponseEvent();
} catch (IpvSessionNotFoundException e) {
return getUnknownAccessTokenApiGatewayProxyResponseEvent();
} catch (Exception e) {
LOGGER.error(LogHelper.buildErrorMessage("Unhandled lambda exception", e));
throw e;
} finally {
auditService.awaitAuditEvents();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import uk.gov.di.ipv.core.library.service.ConfigService;
import uk.gov.di.ipv.core.library.service.IpvSessionService;
import uk.gov.di.ipv.core.library.service.UserIdentityService;
import uk.gov.di.ipv.core.library.testhelpers.unit.LogCollector;
import uk.gov.di.ipv.core.library.verifiablecredential.service.SessionCredentialsService;
import uk.gov.di.model.BirthDate;
import uk.gov.di.model.ContraIndicator;
Expand All @@ -70,10 +71,14 @@
import java.util.Map;

import static java.lang.String.valueOf;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.StringContains.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
Expand Down Expand Up @@ -986,6 +991,28 @@ void shouldReturnErrorResponseWhenIpvSessionIsNull() throws Exception {
verify(mockSessionCredentialsService, never()).deleteSessionCredentials(any());
}

@Test
void shouldLogRuntimeExceptionsAndRethrow() throws Exception {
// Arrange
when(mockIpvSessionService.getIpvSessionByAccessToken(anyString()))
.thenThrow(new RuntimeException("Test error"));

var logCollector = LogCollector.getLogCollectorFor(BuildUserIdentityHandler.class);

// Act
var thrown =
assertThrows(
Exception.class,
() -> buildUserIdentityHandler.handleRequest(testEvent, mockContext),
"Expected handleRequest() to throw, but it didn't");

// Assert
assertEquals("Test error", thrown.getMessage());
var logMessage = logCollector.getLogMessages().get(0);
assertThat(logMessage, containsString("Unhandled lambda exception"));
assertThat(logMessage, containsString("Test error"));
}

private static APIGatewayProxyRequestEvent getEventWithAuthAndIpHeaders() {
APIGatewayProxyRequestEvent event = new APIGatewayProxyRequestEvent();
AccessToken accessToken = new BearerAccessToken(TEST_ACCESS_TOKEN);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
import uk.gov.di.ipv.core.library.dto.AccessTokenMetadata;
import uk.gov.di.ipv.core.library.enums.Vot;
import uk.gov.di.ipv.core.library.exceptions.CredentialParseException;
import uk.gov.di.ipv.core.library.pacttesthelpers.LambdaHttpServer;
import uk.gov.di.ipv.core.library.pacttesthelpers.PactJwtBuilder;
import uk.gov.di.ipv.core.library.persistence.DataStore;
import uk.gov.di.ipv.core.library.persistence.item.ClientOAuthSessionItem;
import uk.gov.di.ipv.core.library.persistence.item.IpvSessionItem;
Expand All @@ -39,6 +37,8 @@
import uk.gov.di.ipv.core.library.service.ConfigService;
import uk.gov.di.ipv.core.library.service.IpvSessionService;
import uk.gov.di.ipv.core.library.service.UserIdentityService;
import uk.gov.di.ipv.core.library.testhelpers.pact.LambdaHttpServer;
import uk.gov.di.ipv.core.library.testhelpers.pact.PactJwtBuilder;
import uk.gov.di.ipv.core.library.verifiablecredential.service.SessionCredentialsService;

import java.io.IOException;
Expand Down
5 changes: 3 additions & 2 deletions lambdas/call-dcmaw-async-cri/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ dependencies {
libs.powertoolsTracing,
libs.aspectj

testImplementation libs.junitJupiter,
testImplementation libs.hamcrest,
libs.junitJupiter,
libs.mockitoJunit,
libs.pactConsumerJunit,
project(path: ':libs:common-services', configuration: 'tests'),
project(path: ':libs:pact-test-helpers')
project(path: ':libs:test-helpers')

testRuntimeOnly libs.junitPlatform
}
Expand Down
Loading

0 comments on commit 82ebfaa

Please sign in to comment.