Repository: govuk-one-login/authentication-api
Pull request #6214: ATO-1514: get processing identity attempts orch session
Author: login: Ryan-Andrews99
Created: 2025-03-25T16:56:08Z | Merged: 2025-04-14T09:17:32Z

Wider context of change:

We're now migrating the processing identity attempts field to the orch session from the redis one. We have previously setup the new field on the Orch session and have been incrementing and resetting in the same places. We also added consistency logging to ensure the values were the same. 

What’s changed:
- Swaps to using the orch session for this value instead of the shared session
- Removes setting as this is only done in one handler

### Manual testing: 
- Added logging in a previous PR and can see the values are now in sync
- Deployed to dev and ran through an identity journey

### Checklist

<!-- If any lambdas are accessing a resource for the first time, they must have additional permissions to do so.
This should be done in a separate PR.
-->

- [x] Lambdas have correct permissions for the resources they're accessing.

<!-- Be careful when making changes to code in 'shared' components where each team has a copy.
Check with counterparts to see if changes need to be made in the other team's code.
In particular pay attention to classes representing Session data where changes need to be applied on both sides to avoid deserialization errors.
-->

- [x] Impact on orch and auth mutual dependencies has been checked.

<!-- Changes required to contract tests?
If there are changes to the API interaction between Orchestration and other services, the contract tests may need updating
-->

- [x] Changes have been made to contract tests or not required.

<!-- Changes required to the simulator?
If there are RP facing changes then this may need to be reflected in updates to [simulator](https://github.com/govuk-one-login/simulator).
-->

- [x] Changes have been made to the simulator or not required.

<!-- Changes required to the stubs?
eg. RP / IPV / SPOT / Auth stub
-->

- [x] Changes have been made to stubs or not required.

<!-- Deployed to authdev?
If this is a session split change, please check that it can be deployed to either authdev1 or authdev2. See [slack](https://gds.slack.com/archives/C060UE8NSP4/p1733137845652609).
-->

- [x] Successfully deployed to authdev or not required.

<!-- Run Authentication acceptance tests against sandpit?
As Orch code reaches production faster than Auth code, if this change could affect Auth, please run [Authentication acceptance tests](https://github.com/govuk-one-login/authentication-acceptance-tests) against sandpit.
-->

- [x] Successfully run Authentication acceptance tests against sandpit or not required.

### Related PRs

<!-- Links to PRs in other repositories that are relevant to this PR.

This could be:
  - PRs that depend on this one
  - PRs this one depends on
  - If this work is being duplicated in other repos, other PRs
  - PRs which just provide context to this one.

Delete this section if not needed! -->



Diff:
diff --git a/integration-tests/src/test/java/uk/gov/di/authentication/api/ProcessingIdentityIntegrationTest.java b/integration-tests/src/test/java/uk/gov/di/authentication/api/ProcessingIdentityIntegrationTest.java
index 040b3c28e6b..ec6afc2b911 100644
--- a/integration-tests/src/test/java/uk/gov/di/authentication/api/ProcessingIdentityIntegrationTest.java
+++ b/integration-tests/src/test/java/uk/gov/di/authentication/api/ProcessingIdentityIntegrationTest.java
@@ -228,7 +228,9 @@ private void setupSession(boolean incrementProcessIdentityAttempts) throws Json.
         orchClientSessionExtension.storeClientSession(orchClientSession);
         redis.addStateToRedis(STATE, SESSION_ID);
         if (incrementProcessIdentityAttempts) {
-            redis.incrementInitialProcessingIdentityAttemptsInSession(SESSION_ID);
+            var session = orchSessionExtension.getSession(SESSION_ID).orElseThrow();
+            session.incrementProcessingIdentityAttempts();
+            orchSessionExtension.updateSession(session);
         }
     }
 
diff --git a/ipv-api/src/main/java/uk/gov/di/authentication/ipv/lambda/IdentityProgressFrontendHandler.java b/ipv-api/src/main/java/uk/gov/di/authentication/ipv/lambda/IdentityProgressFrontendHandler.java
index 1a980b19ef9..8282a11141b 100644
--- a/ipv-api/src/main/java/uk/gov/di/authentication/ipv/lambda/IdentityProgressFrontendHandler.java
+++ b/ipv-api/src/main/java/uk/gov/di/authentication/ipv/lambda/IdentityProgressFrontendHandler.java
@@ -124,23 +124,18 @@ public APIGatewayProxyResponseEvent handleRequestWithUserSession(
                 return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1000);
             }
 
-            var pairwiseSubjectId = (String) userInfo.getClaim("rp_pairwise_id");
-
-            int processingAttempts = userSession.getSession().incrementProcessingIdentityAttempts();
-            // ATO-1514: Introducing this unused var, we will swap usages over to it in a future PR
-            int orchSessionProcessingIdentityAttempts =
+            int processingIdentityAttempts =
                     userSession.getOrchSession().incrementProcessingIdentityAttempts();
             LOG.info(
                     "Attempting to find identity credentials in dynamo. Attempt: {}",
-                    processingAttempts);
+                    processingIdentityAttempts);
             var identityCredentials =
                     dynamoIdentityService.getIdentityCredentials(userSession.getClientSessionId());
 
             var processingStatus = IdentityProgressStatus.PROCESSING;
             if (identityCredentials.isEmpty()
-                    && userSession.getSession().getProcessingIdentityAttempts() == 1) {
+                    && userSession.getOrchSession().getProcessingIdentityAttempts() == 1) {
                 processingStatus = IdentityProgressStatus.NO_ENTRY;
-                userSession.getSession().resetProcessingIdentityAttempts();
                 userSession.getOrchSession().resetProcessingIdentityAttempts();
             } else if (identityCredentials.isEmpty()) {
                 processingStatus = IdentityProgressStatus.ERROR;
@@ -171,9 +166,6 @@ public APIGatewayProxyResponseEvent handleRequestWithUserSession(
                             .orElse(AuditService.UNKNOWN),
                     user);
 
-            sessionService.storeOrUpdateSession(
-                    userSession.getSession(), userSession.getSessionId());
-
             orchSessionService.updateSession(userSession.getOrchSession());
 
             LOG.info(
diff --git a/ipv-api/src/main/java/uk/gov/di/authentication/ipv/lambda/ProcessingIdentityHandler.java b/ipv-api/src/main/java/uk/gov/di/authentication/ipv/lambda/ProcessingIdentityHandler.java
index 558e41010dc..fd56e3edcff 100644
--- a/ipv-api/src/main/java/uk/gov/di/authentication/ipv/lambda/ProcessingIdentityHandler.java
+++ b/ipv-api/src/main/java/uk/gov/di/authentication/ipv/lambda/ProcessingIdentityHandler.java
@@ -14,9 +14,7 @@
 import uk.gov.di.orchestration.shared.entity.AccountIntervention;
 import uk.gov.di.orchestration.shared.entity.ClientRegistry;
 import uk.gov.di.orchestration.shared.entity.DestroySessionsRequest;
-import uk.gov.di.orchestration.shared.entity.OrchSessionItem;
 import uk.gov.di.orchestration.shared.entity.ResponseHeaders;
-import uk.gov.di.orchestration.shared.entity.Session;
 import uk.gov.di.orchestration.shared.entity.UserProfile;
 import uk.gov.di.orchestration.shared.helpers.ClientSubjectHelper;
 import uk.gov.di.orchestration.shared.helpers.IpAddressHelper;
@@ -138,12 +136,8 @@ public APIGatewayProxyResponseEvent handleRequestWithUserContext(
                             userProfile.getSubjectID(),
                             URI.create(configurationService.getInternalSectorURI()),
                             authenticationService.getOrGenerateSalt(userProfile));
-            int processingAttempts = userContext.getSession().incrementProcessingIdentityAttempts();
-            // ATO-1514: Introducing this unused var, we will swap usages over to it in a future PR
-            int orchSessionProcessingIdentityAttempts =
+            int processingAttempts =
                     userContext.getOrchSession().incrementProcessingIdentityAttempts();
-            // ATO-1514: Temporary logging to check the values are in sync.
-            logProcessingIdentityAttempts(userContext.getSession(), userContext.getOrchSession());
             LOG.info(
                     "Attempting to find identity credentials in dynamo. Attempt: {}",
                     processingAttempts);
@@ -152,9 +146,8 @@ public APIGatewayProxyResponseEvent handleRequestWithUserContext(
                     dynamoIdentityService.getIdentityCredentials(userContext.getClientSessionId());
             var processingStatus = ProcessingIdentityStatus.PROCESSING;
             if (identityCredentials.isEmpty()
-                    && userContext.getSession().getProcessingIdentityAttempts() == 1) {
+                    && userContext.getOrchSession().getProcessingIdentityAttempts() == 1) {
                 processingStatus = ProcessingIdentityStatus.NO_ENTRY;
-                userContext.getSession().resetProcessingIdentityAttempts();
                 userContext.getOrchSession().resetProcessingIdentityAttempts();
             } else if (identityCredentials.isEmpty()) {
                 processingStatus = ProcessingIdentityStatus.ERROR;
@@ -186,8 +179,6 @@ public APIGatewayProxyResponseEvent handleRequestWithUserContext(
             auditService.submitAuditEvent(
                     IPVAuditableEvent.PROCESSING_IDENTITY_REQUEST, auditContext);
             orchSessionService.updateSession(userContext.getOrchSession());
-            sessionService.storeOrUpdateSession(
-                    userContext.getSession(), userContext.getSessionId());
             LOG.info(
                     "Generating ProcessingIdentityResponse with ProcessingIdentityStatus: {}",
                     processingStatus);
@@ -239,27 +230,4 @@ private APIGatewayProxyResponseEvent performIntervention(
                 new ProcessingIdentityInterventionResponse(
                         ProcessingIdentityStatus.INTERVENTION, redirectUrl));
     }
-
-    private void logProcessingIdentityAttempts(Session session, OrchSessionItem orchSession) {
-        try {
-
-            LOG.info(
-                    "Are processing identity attempts equal in both session stores: {}",
-                    Objects.equals(
-                            session.getProcessingIdentityAttempts(),
-                            orchSession.getProcessingIdentityAttempts()));
-
-            LOG.info(
-                    "Shared session processing identity attempts: {}",
-                    session.getProcessingIdentityAttempts());
-            LOG.info(
-                    "Orch session processing identity attempts: {}",
-                    orchSession.getProcessingIdentityAttempts());
-
-        } catch (Exception e) {
-            LOG.warn(
-                    "Exception when logging processing identity attempts: {}. Continuing as normal",
-                    e.getMessage());
-        }
-    }
 }
diff --git a/ipv-api/src/test/java/uk/gov/di/authentication/ipv/lambda/IdentityProgressFrontendHandlerTest.java b/ipv-api/src/test/java/uk/gov/di/authentication/ipv/lambda/IdentityProgressFrontendHandlerTest.java
index c88a96e9fbf..260b2157501 100644
--- a/ipv-api/src/test/java/uk/gov/di/authentication/ipv/lambda/IdentityProgressFrontendHandlerTest.java
+++ b/ipv-api/src/test/java/uk/gov/di/authentication/ipv/lambda/IdentityProgressFrontendHandlerTest.java
@@ -195,7 +195,6 @@ void shouldReturnCOMPLETEDStatusWhenIdentityCredentialIsPresent() throws Json.Js
 
         verify(auditService)
                 .submitAuditEvent(IPVAuditableEvent.PROCESSING_IDENTITY_REQUEST, CLIENT_ID, USER);
-        assertThat(session.getProcessingIdentityAttempts(), equalTo(1));
         assertThat(orchSession.getProcessingIdentityAttempts(), equalTo(1));
     }
 
@@ -240,7 +239,7 @@ void shouldReturnPROCESSINGStatusWhenEntryIsInDynamoButNoIdentityCredentialIsPre
     @Test
     void shouldReturnERRORStatusWhenNoEntryIsFoundInDynamoAfterSecondAttempt()
             throws Json.JsonException {
-        session.incrementProcessingIdentityAttempts();
+        orchSession.incrementProcessingIdentityAttempts();
         usingValidSession();
         when(dynamoIdentityService.getIdentityCredentials(CLIENT_SESSION_ID))
                 .thenReturn(Optional.empty());
diff --git a/ipv-api/src/test/java/uk/gov/di/authentication/ipv/lambda/ProcessingIdentityHandlerTest.java b/ipv-api/src/test/java/uk/gov/di/authentication/ipv/lambda/ProcessingIdentityHandlerTest.java
index 372c43441bd..2590ea88d16 100644
--- a/ipv-api/src/test/java/uk/gov/di/authentication/ipv/lambda/ProcessingIdentityHandlerTest.java
+++ b/ipv-api/src/test/java/uk/gov/di/authentication/ipv/lambda/ProcessingIdentityHandlerTest.java
@@ -197,7 +197,6 @@ void shouldReturnCOMPLETEDStatusWhenIdentityCredentialIsPresent() throws Json.Js
                                 ENVIRONMENT,
                                 "Status",
                                 ProcessingIdentityStatus.COMPLETED.toString()));
-        assertThat(session.getProcessingIdentityAttempts(), equalTo(1));
         assertThat(orchSession.getProcessingIdentityAttempts(), equalTo(1));
     }
 
@@ -315,7 +314,7 @@ void shouldReturnPROCESSINGStatusWhenEntryIsInDynamoButNoIdentityCredentialIsPre
     @Test
     void shouldReturnERRORStatusWhenNoEntryIsFoundInDynamoAfterSecondAttempt()
             throws Json.JsonException {
-        session.incrementProcessingIdentityAttempts();
+        orchSession.incrementProcessingIdentityAttempts();
         usingValidSession();
         when(dynamoIdentityService.getIdentityCredentials(CLIENT_SESSION_ID))
                 .thenReturn(Optional.empty());


Reviews:
user: login: cearl1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T14:11:45Z
user: login: Ryan-Andrews99
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T14:43:10Z
user: login: Ryan-Andrews99
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T15:12:26Z
user: login: cearl1
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T15:19:19Z
user: login: cearl1
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-14T08:48:48Z

Review comments:
diff_hunk: @@ -241,6 +241,7 @@ void shouldReturnPROCESSINGStatusWhenEntryIsInDynamoButNoIdentityCredentialIsPre
     void shouldReturnERRORStatusWhenNoEntryIsFoundInDynamoAfterSecondAttempt()
             throws Json.JsonException {
         session.incrementProcessingIdentityAttempts();
path: ipv-api/src/test/java/uk/gov/di/authentication/ipv/lambda/IdentityProgressFrontendHandlerTest.java
user: login: cearl1
body: Did you want to remove the use of this shared session method in this test too? I noticed you removed the use in the other unit test.
created_at: 2025-04-10T14:11:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -241,6 +241,7 @@ void shouldReturnPROCESSINGStatusWhenEntryIsInDynamoButNoIdentityCredentialIsPre
     void shouldReturnERRORStatusWhenNoEntryIsFoundInDynamoAfterSecondAttempt()
             throws Json.JsonException {
         session.incrementProcessingIdentityAttempts();
path: ipv-api/src/test/java/uk/gov/di/authentication/ipv/lambda/IdentityProgressFrontendHandlerTest.java
user: login: Ryan-Andrews99
body: Ooh good spot!
created_at: 2025-04-10T14:43:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -241,6 +241,7 @@ void shouldReturnPROCESSINGStatusWhenEntryIsInDynamoButNoIdentityCredentialIsPre
     void shouldReturnERRORStatusWhenNoEntryIsFoundInDynamoAfterSecondAttempt()
             throws Json.JsonException {
         session.incrementProcessingIdentityAttempts();
path: ipv-api/src/test/java/uk/gov/di/authentication/ipv/lambda/IdentityProgressFrontendHandlerTest.java
user: login: Ryan-Andrews99
body: Have removed this now
created_at: 2025-04-10T15:12:26Z
author_association: CONTRIBUTOR

PR comments:
user: login: sonarqubecloud[bot]
created_at: 2025-04-14T08:49:51Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=govuk-one-login_authentication-api&pullRequest=6214) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [2 New issues](https://sonarcloud.io/project/issues?id=govuk-one-login_authentication-api&pullRequest=6214&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=govuk-one-login_authentication-api&pullRequest=6214&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=govuk-one-login_authentication-api&pullRequest=6214&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [100.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=govuk-one-login_authentication-api&pullRequest=6214&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=govuk-one-login_authentication-api&pullRequest=6214&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=govuk-one-login_authentication-api&pullRequest=6214)


author_association: NONE