diff --git a/signup-service/src/main/java/io/mosip/signup/controllers/RegistrationController.java b/signup-service/src/main/java/io/mosip/signup/controllers/RegistrationController.java index e744188f..3a9475e3 100644 --- a/signup-service/src/main/java/io/mosip/signup/controllers/RegistrationController.java +++ b/signup-service/src/main/java/io/mosip/signup/controllers/RegistrationController.java @@ -1,5 +1,7 @@ package io.mosip.signup.controllers; +import io.micrometer.core.annotation.Counted; +import io.micrometer.core.annotation.Timed; import io.mosip.esignet.core.dto.RequestWrapper; import io.mosip.esignet.core.dto.ResponseWrapper; import io.mosip.esignet.core.util.IdentityProviderUtil; @@ -70,6 +72,8 @@ public ResponseWrapper verifyChallenge(@Valid @RequestB return responseWrapper; } + + @Timed(value = "register.timer", percentiles = {0.95, 0.99}) @PostMapping("/register") public ResponseWrapper register(@Valid @RequestBody RequestWrapper requestWrapper, @Valid @NotBlank(message = ErrorConstants.INVALID_TRANSACTION) diff --git a/signup-service/src/main/java/io/mosip/signup/controllers/SignUpController.java b/signup-service/src/main/java/io/mosip/signup/controllers/SignUpController.java index 8af399ea..ee177671 100644 --- a/signup-service/src/main/java/io/mosip/signup/controllers/SignUpController.java +++ b/signup-service/src/main/java/io/mosip/signup/controllers/SignUpController.java @@ -1,6 +1,7 @@ package io.mosip.signup.controllers; +import io.micrometer.core.annotation.Timed; import io.mosip.esignet.core.dto.RequestWrapper; import io.mosip.esignet.core.dto.ResponseWrapper; import io.mosip.esignet.core.util.IdentityProviderUtil; @@ -43,6 +44,7 @@ public ResponseWrapper getSignUpDetails() { return responseWrapper; } + @Timed(value = "resetpwd.timer", percentiles = {0.95, 0.99}) @PostMapping("/reset-password") public ResponseWrapper resetPassword(@Valid @RequestBody RequestWrapper requestWrapper, @Valid @NotBlank(message = ErrorConstants.INVALID_TRANSACTION) diff --git a/signup-service/src/main/java/io/mosip/signup/services/CacheUtilService.java b/signup-service/src/main/java/io/mosip/signup/services/CacheUtilService.java index 75a0b9da..8cb2810e 100644 --- a/signup-service/src/main/java/io/mosip/signup/services/CacheUtilService.java +++ b/signup-service/src/main/java/io/mosip/signup/services/CacheUtilService.java @@ -22,11 +22,6 @@ public class CacheUtilService { CacheManager cacheManager; //---Setter--- - @Cacheable(value = SignUpConstants.CHALLENGE_GENERATED, key = "#transactionId") - public RegistrationTransaction setChallengeGeneratedTransaction(String transactionId, - RegistrationTransaction registrationTransaction) { - return registrationTransaction; - } @CacheEvict(value = SignUpConstants.CHALLENGE_GENERATED, key = "#transactionId") @Cacheable(value = SignUpConstants.CHALLENGE_VERIFIED, key = "#verifiedTransactionId") @@ -36,14 +31,15 @@ public RegistrationTransaction setChallengeVerifiedTransaction(String transactio } @CacheEvict(value = SignUpConstants.CHALLENGE_VERIFIED, key = "#transactionId") - @CachePut(value = SignUpConstants.STATUS_CHECK, key = "#transactionId") + @Cacheable(value = SignUpConstants.STATUS_CHECK, key = "#transactionId") public RegistrationTransaction setStatusCheckTransaction(String transactionId, RegistrationTransaction registrationTransaction) { return registrationTransaction; } + @CacheEvict(value = SignUpConstants.CHALLENGE_GENERATED, key = "#transactionId") @Cacheable(value = SignUpConstants.BLOCKED_IDENTIFIER, key = "#key") - public String blockIdentifier(String key, String value) { + public String blockIdentifier(String transactionId, String key, String value) { return value; } @@ -52,11 +48,26 @@ public String setSecretKey(String key, String secretKey) { return secretKey; } - @Cacheable(value = SignUpConstants.KEY_ALIAS, key = "#key") + @CachePut(value = SignUpConstants.KEY_ALIAS, key = "#key") public String setActiveKeyAlias(String key, String alias) { return alias; } + + //----- cache update is separated + //----- we are not using @cacheput as @cacheput extends the TTL on cache entry + + public RegistrationTransaction createUpdateChallengeGeneratedTransaction(String transactionId, + RegistrationTransaction registrationTransaction) { + cacheManager.getCache(SignUpConstants.CHALLENGE_GENERATED).put(transactionId, registrationTransaction); + return registrationTransaction; + } + + public void updateStatusCheckTransaction(String transactionId, + RegistrationTransaction registrationTransaction) { + cacheManager.getCache(SignUpConstants.STATUS_CHECK).put(transactionId, registrationTransaction); + } + //---Getter--- public RegistrationTransaction getChallengeGeneratedTransaction(String transactionId) { return cacheManager.getCache(SignUpConstants.CHALLENGE_GENERATED).get(transactionId, RegistrationTransaction.class); diff --git a/signup-service/src/main/java/io/mosip/signup/services/ChallengeManagerService.java b/signup-service/src/main/java/io/mosip/signup/services/ChallengeManagerService.java index a2c8bd85..0d98e698 100644 --- a/signup-service/src/main/java/io/mosip/signup/services/ChallengeManagerService.java +++ b/signup-service/src/main/java/io/mosip/signup/services/ChallengeManagerService.java @@ -1,5 +1,6 @@ package io.mosip.signup.services; +import io.micrometer.core.annotation.Timed; import io.mosip.esignet.core.util.IdentityProviderUtil; import io.mosip.signup.dto.*; import io.mosip.signup.exception.SignUpException; @@ -39,6 +40,7 @@ public String generateChallenge(RegistrationTransaction transaction) throws Sign throw new SignUpException(ErrorConstants.UNSUPPORTED_CHALLENGE_TYPE); } + @Timed(value = "generateotp.api.timer", percentiles = {0.95, 0.99}) private String generateOTPChallenge(String challengeTransactionId) { OtpRequest otpRequest = new OtpRequest(); otpRequest.setKey(challengeTransactionId); diff --git a/signup-service/src/main/java/io/mosip/signup/services/GoogleRecaptchaValidatorService.java b/signup-service/src/main/java/io/mosip/signup/services/GoogleRecaptchaValidatorService.java index 281c4f71..fdbb9474 100644 --- a/signup-service/src/main/java/io/mosip/signup/services/GoogleRecaptchaValidatorService.java +++ b/signup-service/src/main/java/io/mosip/signup/services/GoogleRecaptchaValidatorService.java @@ -1,5 +1,6 @@ package io.mosip.signup.services; +import io.micrometer.core.annotation.Timed; import io.mosip.esignet.api.spi.CaptchaValidator; import io.mosip.signup.dto.ReCaptchaResponse; import lombok.extern.slf4j.Slf4j; @@ -30,6 +31,7 @@ public class GoogleRecaptchaValidatorService implements CaptchaValidator { @Autowired private RestTemplate restTemplate; + @Timed(value = "validatecaptcha.api.timer", percentiles = {0.95, 0.99}) @Override public boolean validateCaptcha(String captchaToken) { diff --git a/signup-service/src/main/java/io/mosip/signup/services/RegistrationService.java b/signup-service/src/main/java/io/mosip/signup/services/RegistrationService.java index d888751e..c7979b66 100644 --- a/signup-service/src/main/java/io/mosip/signup/services/RegistrationService.java +++ b/signup-service/src/main/java/io/mosip/signup/services/RegistrationService.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import io.micrometer.core.annotation.Timed; import io.mosip.esignet.core.util.IdentityProviderUtil; import io.mosip.kernel.core.util.HMACUtils2; import io.mosip.signup.dto.*; @@ -146,7 +147,7 @@ public GenerateChallengeResponse generateChallenge(GenerateChallengeRequest gene } else { transaction = cacheUtilService.getChallengeGeneratedTransaction(transactionId); - validateTransaction(transaction, identifier); + validateTransaction(transaction, identifier, generateChallengeRequest); } // generate Challenge @@ -155,11 +156,11 @@ public GenerateChallengeResponse generateChallenge(GenerateChallengeRequest gene transaction.setChallengeHash(challengeHash); transaction.increaseAttempt(); transaction.setLocale(generateChallengeRequest.getLocale()); - cacheUtilService.setChallengeGeneratedTransaction(transactionId, transaction); + cacheUtilService.createUpdateChallengeGeneratedTransaction(transactionId, transaction); //Resend attempts exhausted, block the identifier for configured time. if(transaction.getChallengeRetryAttempts() > resendAttempts) - cacheUtilService.blockIdentifier(transaction.getIdentifier(), "blocked"); + cacheUtilService.blockIdentifier(transactionId, transaction.getIdentifier(), "blocked"); notificationHelper.sendSMSNotificationAsync(generateChallengeRequest.getIdentifier(), transaction.getLocale(), SEND_OTP_SMS_NOTIFICATION_TEMPLATE_KEY, new HashMap<>(){{put("{challenge}", challenge);}}) @@ -265,10 +266,15 @@ public RegistrationStatusResponse updatePassword(ResetPasswordRequest resetPassw } if(!transaction.isValidIdentifier(resetPasswordRequest.getIdentifier().toLowerCase(Locale.ROOT))) { - log.error("generate-challenge failed: invalid identifier"); + log.error("reset password failed: invalid identifier"); throw new SignUpException(ErrorConstants.IDENTIFIER_MISMATCH); } + if(!transaction.getPurpose().equals(Purpose.RESET_PASSWORD)) { + log.error("reset password failed: purpose mismatch in transaction"); + throw new SignUpException(ErrorConstants.UNSUPPORTED_PURPOSE); + } + Identity identity = new Identity(); identity.setUIN(cryptoHelper.symmetricDecrypt(transaction.getUin())); identity.setIDSchemaVersion(idSchemaVersion); @@ -339,7 +345,7 @@ public RegistrationStatusResponse getRegistrationStatus(String transactionId) registrationTransaction.getHandlesStatus().put(handleRequestId, registrationStatus); //TODO This is temporary fix, we need to remove this field later from registrationTransaction DTO. registrationTransaction.setRegistrationStatus(registrationStatus); - cacheUtilService.setStatusCheckTransaction(transactionId, registrationTransaction); + cacheUtilService.updateStatusCheckTransaction(transactionId, registrationTransaction); } } registrationTransaction = cacheUtilService.getStatusCheckTransaction(transactionId); @@ -450,6 +456,7 @@ private void saveIdentityData(RegisterRequest registerRequest, String transactio addIdentity(identityRequest, transactionId); } + @Timed(value = "addidentity.api.timer", percentiles = {0.95, 0.99}) private void addIdentity(IdentityRequest identityRequest, String transactionId) throws SignUpException{ RestRequestWrapper restRequest = new RestRequestWrapper<>(); @@ -475,6 +482,7 @@ private void addIdentity(IdentityRequest identityRequest, String transactionId) restResponseWrapper.getErrors().get(0).getErrorCode() : ErrorConstants.ADD_IDENTITY_FAILED); } + @Timed(value = "generatehash.api.timer", percentiles = {0.95, 0.99}) private Password generateSaltedHash(String password, String transactionId) throws SignUpException{ RestRequestWrapper restRequestWrapper = new RestRequestWrapper<>(); @@ -497,6 +505,7 @@ private Password generateSaltedHash(String password, String transactionId) throw restResponseWrapper.getErrors().get(0).getErrorCode() : ErrorConstants.HASH_GENERATE_FAILED); } + @Timed(value = "getuin.api.timer", percentiles = {0.95, 0.99}) private String getUniqueIdentifier(String transactionId) throws SignUpException { RestResponseWrapper restResponseWrapper = selfTokenRestTemplate.exchange(getUinEndpoint, @@ -513,7 +522,8 @@ private String getUniqueIdentifier(String transactionId) throws SignUpException restResponseWrapper.getErrors().get(0).getErrorCode() : ErrorConstants.GET_UIN_FAILED); } - private void validateTransaction(RegistrationTransaction transaction, String identifier) { + private void validateTransaction(RegistrationTransaction transaction, String identifier, + GenerateChallengeRequest generateChallengeRequest) { if(transaction == null) { log.error("generate-challenge failed: validate transaction null"); throw new InvalidTransactionException(); @@ -533,8 +543,14 @@ private void validateTransaction(RegistrationTransaction transaction, String ide log.error("generate-challenge failed: too early attempts"); throw new GenerateChallengeException(ErrorConstants.TOO_EARLY_ATTEMPT); } + + if(!transaction.getPurpose().equals(generateChallengeRequest.getPurpose())) { + log.error("generate-challenge failed: purpose mismatch"); + throw new GenerateChallengeException(ErrorConstants.INVALID_PURPOSE); + } } + @Timed(value = "getstatus.api.timer", percentiles = {0.95, 0.99}) private RegistrationStatus getRegistrationStatusFromServer(String applicationId) { RestResponseWrapper> restResponseWrapper = selfTokenRestTemplate.exchange(getRegistrationStatusEndpoint, HttpMethod.GET, null, diff --git a/signup-service/src/test/java/io/mosip/signup/services/CacheUtilServiceTest.java b/signup-service/src/test/java/io/mosip/signup/services/CacheUtilServiceTest.java index ca32be57..3fc66470 100644 --- a/signup-service/src/test/java/io/mosip/signup/services/CacheUtilServiceTest.java +++ b/signup-service/src/test/java/io/mosip/signup/services/CacheUtilServiceTest.java @@ -31,7 +31,7 @@ public void test_RegistrationTransaction_cache() { Mockito.when(cache.get("mock", RegistrationTransaction.class)).thenReturn(registrationTransaction); Mockito.when(cacheManager.getCache(Mockito.anyString())).thenReturn(cache); - Assert.assertEquals(cacheUtilService.setChallengeGeneratedTransaction("mock", + Assert.assertEquals(cacheUtilService.createUpdateChallengeGeneratedTransaction("mock", registrationTransaction), registrationTransaction); Assert.assertEquals(cacheUtilService.setChallengeVerifiedTransaction("mock", "vmock", registrationTransaction), registrationTransaction); @@ -45,8 +45,9 @@ public void test_RegistrationTransaction_cache() { @Test public void setChallengeTransaction_thenPass() { + Mockito.when(cacheManager.getCache(Mockito.anyString())).thenReturn(cache); RegistrationTransaction registrationTransaction = new RegistrationTransaction("+85512123123", Purpose.REGISTRATION); - Assert.assertEquals(cacheUtilService.setChallengeGeneratedTransaction("mock-transaction", registrationTransaction), registrationTransaction); - Assert.assertNotNull(cacheUtilService.setChallengeGeneratedTransaction("mock-transaction", registrationTransaction)); + Assert.assertEquals(cacheUtilService.createUpdateChallengeGeneratedTransaction("mock-transaction", registrationTransaction), registrationTransaction); + Assert.assertNotNull(cacheUtilService.createUpdateChallengeGeneratedTransaction("mock-transaction", registrationTransaction)); } } diff --git a/signup-service/src/test/java/io/mosip/signup/services/RegistrationServiceTest.java b/signup-service/src/test/java/io/mosip/signup/services/RegistrationServiceTest.java index 0fca5cfb..c937e56f 100644 --- a/signup-service/src/test/java/io/mosip/signup/services/RegistrationServiceTest.java +++ b/signup-service/src/test/java/io/mosip/signup/services/RegistrationServiceTest.java @@ -1639,6 +1639,7 @@ public void doGenerateChallenge_withRetryAttemptsOver3time_thenFail() throws Sig generateChallengeRequest.setIdentifier(identifier); generateChallengeRequest.setCaptchaToken("mock-captcha"); generateChallengeRequest.setRegenerate(true); + generateChallengeRequest.setPurpose(Purpose.REGISTRATION); String transactionId = "TRAN-1234"; RegistrationTransaction transaction = new RegistrationTransaction(identifier, Purpose.REGISTRATION); transaction.setLastRetryAt(LocalDateTime.now(ZoneOffset.UTC).minusSeconds(40)); @@ -1665,6 +1666,7 @@ public void doGenerateChallenge_withTransactionId_thenPass() throws SignUpExcept generateChallengeRequest.setIdentifier(identifier); generateChallengeRequest.setCaptchaToken("mock-captcha"); generateChallengeRequest.setRegenerate(true); + generateChallengeRequest.setPurpose(Purpose.REGISTRATION); String transactionId = "TRAN-1234"; RegistrationTransaction transaction = new RegistrationTransaction(identifier, Purpose.REGISTRATION); transaction.setLastRetryAt(LocalDateTime.now(ZoneOffset.UTC).minusSeconds(40));