Appointment error handling check.
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
package net.gepafin.tendermanagement.dao;
|
package net.gepafin.tendermanagement.dao;
|
||||||
|
|
||||||
import com.amazonaws.services.s3.AmazonS3Client;
|
import com.amazonaws.services.s3.AmazonS3Client;
|
||||||
import com.amazonaws.services.s3.model.GetObjectRequest;
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
@@ -13,12 +12,14 @@ import net.gepafin.tendermanagement.config.Translator;
|
|||||||
import net.gepafin.tendermanagement.config.jwt.TokenProvider;
|
import net.gepafin.tendermanagement.config.jwt.TokenProvider;
|
||||||
import net.gepafin.tendermanagement.constants.AppointmentApiConstant;
|
import net.gepafin.tendermanagement.constants.AppointmentApiConstant;
|
||||||
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
||||||
|
import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity;
|
||||||
import net.gepafin.tendermanagement.entities.ApplicationEntity;
|
import net.gepafin.tendermanagement.entities.ApplicationEntity;
|
||||||
import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity;
|
import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity;
|
||||||
import net.gepafin.tendermanagement.entities.CompanyEntity;
|
import net.gepafin.tendermanagement.entities.CompanyEntity;
|
||||||
import net.gepafin.tendermanagement.entities.DocumentEntity;
|
import net.gepafin.tendermanagement.entities.DocumentEntity;
|
||||||
import net.gepafin.tendermanagement.entities.HubEntity;
|
import net.gepafin.tendermanagement.entities.HubEntity;
|
||||||
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
|
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
|
||||||
|
import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum;
|
||||||
import net.gepafin.tendermanagement.enums.NotificationTypeEnum;
|
import net.gepafin.tendermanagement.enums.NotificationTypeEnum;
|
||||||
import net.gepafin.tendermanagement.enums.VersionActionTypeEnum;
|
import net.gepafin.tendermanagement.enums.VersionActionTypeEnum;
|
||||||
import net.gepafin.tendermanagement.model.request.AppointmentCreationRequest;
|
import net.gepafin.tendermanagement.model.request.AppointmentCreationRequest;
|
||||||
@@ -63,7 +64,6 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -145,6 +145,15 @@ public class AppointmentDao {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private AmazonS3Service amazonS3Service;
|
private AmazonS3Service amazonS3Service;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationDao applicationDao;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationAmendmentRequestDao applicationAmendmentRequestDao;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationEvaluationDao applicationEvaluationDao;
|
||||||
|
|
||||||
private final Map<Long, ExecutorService> executorMap = new ConcurrentHashMap<>();
|
private final Map<Long, ExecutorService> executorMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final ConcurrentHashMap<Long, ExecutorService> threadForDocumentMap = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<Long, ExecutorService> threadForDocumentMap = new ConcurrentHashMap<>();
|
||||||
@@ -175,15 +184,182 @@ public class AppointmentDao {
|
|||||||
return ndgResponse;
|
return ndgResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HubEntity loginToOdessa(HubEntity hub, ApplicationEntity application) {
|
// private HubEntity loginToOdessa(HubEntity hub, ApplicationEntity application) {
|
||||||
|
//
|
||||||
|
// int maxRetries = 3;
|
||||||
|
// int attempt = 0;
|
||||||
|
// boolean success = false;
|
||||||
|
// while (attempt < maxRetries && !success) {
|
||||||
|
// attempt++;
|
||||||
|
// try {
|
||||||
|
// //code to generate token with payload having "iat" epoch timestamp and secret key with no expiry and send in below method call
|
||||||
|
// String authJwtToken = Utils.generateAuthTokenForLoginToOdessa();
|
||||||
|
// log.info("Got the auth for login to odessa {}", authJwtToken);
|
||||||
|
// hub.setAuthToken(authJwtToken);
|
||||||
|
// hubRepository.save(hub);
|
||||||
|
// Map<String, Object> body = Collections.emptyMap();
|
||||||
|
// ResponseEntity<Object> responseLogin = appointmentApiService.loginWithOdessa(authJwtToken, source, context, user, password, body);
|
||||||
|
// if (responseLogin.getStatusCode() == HttpStatus.OK) {
|
||||||
|
// log.info("Login successful to odessa. Parsing response.");
|
||||||
|
// String loginResponseJson = Utils.convertObjectToJson(responseLogin.getBody());
|
||||||
|
// AppointmentLoginResponse parsedResponse = parseLoginResponse(loginResponseJson);
|
||||||
|
//
|
||||||
|
// // Validate and save token
|
||||||
|
// if (parsedResponse.getTokenId() != null) {
|
||||||
|
// hub.setAppointmentAuthTokenId(parsedResponse.getTokenId());
|
||||||
|
// hub.setAreaCode(parsedResponse.getAreaCode());
|
||||||
|
// hubRepository.save(hub);
|
||||||
|
// log.info("Saved new authToken and areaCode for Hub.");
|
||||||
|
// success = true;
|
||||||
|
// return hub;
|
||||||
|
// } else {
|
||||||
|
// throw new RuntimeException("Login response is missing a valid tokenId for login to odessa system, please try again.");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.ERROR_IN_GENERATING_NDG_TRY_AGAIN));
|
||||||
|
// } catch (FeignException.Forbidden forbiddenException) {
|
||||||
|
// log.error("Failed to login to odessa due to some error");
|
||||||
|
//
|
||||||
|
// // Extract raw response body
|
||||||
|
// String responseBody = forbiddenException.contentUTF8(); // Extract raw JSON response
|
||||||
|
//
|
||||||
|
// // Parse JSON to check for "PasswordExpired"
|
||||||
|
// try {
|
||||||
|
// ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
// JsonNode rootNode = objectMapper.readTree(responseBody);
|
||||||
|
// JsonNode errorsNode = rootNode.path("errors");
|
||||||
|
//
|
||||||
|
// if (errorsNode.isArray()) {
|
||||||
|
// for (JsonNode error : errorsNode) {
|
||||||
|
// // Check the main errorCode
|
||||||
|
// if (GepafinConstant.PASSWORD_EXPIRED.equals(error.path("errorCode").asText())) {
|
||||||
|
// application.setNdgStatus(GepafinConstant.NDG_FAILED);
|
||||||
|
// applicationRepository.save(application);
|
||||||
|
// throw new CustomValidationException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PASSWORD_EXPIRED_LOGIN_TO_ODESSA));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Check inside "subErrors"
|
||||||
|
// JsonNode subErrorsNode = error.path("subErrors");
|
||||||
|
// if (subErrorsNode.isArray()) {
|
||||||
|
// for (JsonNode subError : subErrorsNode) {
|
||||||
|
// if (GepafinConstant.PASSWORD_EXPIRED.equals(subError.path("errorCode").asText())) {
|
||||||
|
// application.setNdgStatus(GepafinConstant.NDG_FAILED);
|
||||||
|
// applicationRepository.save(application);
|
||||||
|
// throw new CustomValidationException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PASSWORD_EXPIRED_LOGIN_TO_ODESSA));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// log.error("Error parsing JSON response: {}", e.getMessage());
|
||||||
|
// }
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// log.error("Failed to authenticate user on Odessa : {}", e.getMessage(), e);
|
||||||
|
// throw new RuntimeException("Authentication failed on Odessa. try again", e);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// private HubEntity authenticateAndSaveToken(HubEntity hub) {
|
||||||
|
//
|
||||||
|
// int maxRetries = 3;
|
||||||
|
// int attempt = 0;
|
||||||
|
// boolean success = false;
|
||||||
|
// while (attempt < maxRetries && !success) {
|
||||||
|
// attempt++;
|
||||||
|
// try {
|
||||||
|
// //code to generate token with payload having "iat" epoch timestamp and secret key with no expiry and send in below method call
|
||||||
|
// String authJwtToken = Utils.generateAuthTokenForLoginToOdessa();
|
||||||
|
// log.info("Got the auth for login to odessa {}", authJwtToken);
|
||||||
|
// hub.setAuthToken(authJwtToken);
|
||||||
|
// hubRepository.save(hub);
|
||||||
|
// // Prepare the request body (adjust if necessary for login API)
|
||||||
|
// Map<String, Object> body = Collections.emptyMap();
|
||||||
|
// // Perform login API call
|
||||||
|
// ResponseEntity<Object> responseLogin = appointmentApiService.loginWithOdessa(authJwtToken, source, context, user, password, body);
|
||||||
|
//
|
||||||
|
// // Handle successful login
|
||||||
|
// if (responseLogin.getStatusCode() == HttpStatus.OK) {
|
||||||
|
// log.info("Login successful to odessa. Parsing response.");
|
||||||
|
// String loginResponseJson = Utils.convertObjectToJson(responseLogin.getBody());
|
||||||
|
// AppointmentLoginResponse parsedResponse = parseLoginResponse(loginResponseJson);
|
||||||
|
//
|
||||||
|
// // Validate and save token
|
||||||
|
// if (parsedResponse.getTokenId() != null) {
|
||||||
|
// hub.setAppointmentAuthTokenId(parsedResponse.getTokenId());
|
||||||
|
// hub.setAreaCode(parsedResponse.getAreaCode());
|
||||||
|
// hubRepository.save(hub);
|
||||||
|
//
|
||||||
|
// log.info("Saved new authToken and areaCode for Hub.");
|
||||||
|
// success = true;
|
||||||
|
// return hub;
|
||||||
|
// } else {
|
||||||
|
// throw new RuntimeException("Login response is missing a valid tokenId for login to odessa system, please try again.");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // Handle non-OK response
|
||||||
|
// throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.ERROR_IN_GENERATING_NDG_TRY_AGAIN));
|
||||||
|
// } catch (FeignException.Forbidden forbiddenException) {
|
||||||
|
// log.error("Failed to login to odessa due to some error occurred.");
|
||||||
|
//
|
||||||
|
// // Extract raw response body
|
||||||
|
// String responseBody = forbiddenException.contentUTF8(); // Extract raw JSON response
|
||||||
|
//
|
||||||
|
// // Parse JSON to check for "PasswordExpired"
|
||||||
|
// try {
|
||||||
|
// ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
// JsonNode rootNode = objectMapper.readTree(responseBody);
|
||||||
|
// JsonNode errorsNode = rootNode.path("errors");
|
||||||
|
//
|
||||||
|
// if (errorsNode.isArray()) {
|
||||||
|
// for (JsonNode error : errorsNode) {
|
||||||
|
// // Check the main errorCode
|
||||||
|
// if (GepafinConstant.PASSWORD_EXPIRED.equals(error.path("errorCode").asText())) {
|
||||||
|
// throw new CustomValidationException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PASSWORD_EXPIRED_LOGIN_TO_ODESSA));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Check inside "subErrors"
|
||||||
|
// JsonNode subErrorsNode = error.path("subErrors");
|
||||||
|
// if (subErrorsNode.isArray()) {
|
||||||
|
// for (JsonNode subError : subErrorsNode) {
|
||||||
|
// if (GepafinConstant.PASSWORD_EXPIRED.equals(subError.path("errorCode").asText())) {
|
||||||
|
// throw new CustomValidationException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PASSWORD_EXPIRED_LOGIN_TO_ODESSA));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// log.error("Error parsing JSON response: {}", e.getMessage());
|
||||||
|
// }
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// log.error("Failed to authenticate user on Odessa : {}", e.getMessage(), e);
|
||||||
|
// throw new RuntimeException("Authentication failed on Odessa. try again", e);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
private void loginToOdessa(HubEntity hub, ApplicationEntity application) {
|
||||||
|
|
||||||
|
performOdessaLogin(hub, application);
|
||||||
|
}
|
||||||
|
|
||||||
|
private HubEntity authenticateAndSaveToken(HubEntity hub, ApplicationEntity application) {
|
||||||
|
|
||||||
|
return performOdessaLogin(hub, application);
|
||||||
|
}
|
||||||
|
|
||||||
|
private HubEntity performOdessaLogin(HubEntity hub, ApplicationEntity application) {
|
||||||
|
|
||||||
int maxRetries = 3;
|
int maxRetries = 3;
|
||||||
int attempt = 0;
|
int attempt = 0;
|
||||||
boolean success = false;
|
while (attempt < maxRetries) {
|
||||||
while (attempt < maxRetries && !success) {
|
|
||||||
attempt++;
|
attempt++;
|
||||||
try {
|
try {
|
||||||
//code to generate token with payload having "iat" epoch timestamp and secret key with no expiry and send in below method call
|
|
||||||
String authJwtToken = Utils.generateAuthTokenForLoginToOdessa();
|
String authJwtToken = Utils.generateAuthTokenForLoginToOdessa();
|
||||||
log.info("Got the auth for login to odessa {}", authJwtToken);
|
log.info("Got the auth for login to odessa {}", authJwtToken);
|
||||||
hub.setAuthToken(authJwtToken);
|
hub.setAuthToken(authJwtToken);
|
||||||
@@ -195,13 +371,11 @@ public class AppointmentDao {
|
|||||||
String loginResponseJson = Utils.convertObjectToJson(responseLogin.getBody());
|
String loginResponseJson = Utils.convertObjectToJson(responseLogin.getBody());
|
||||||
AppointmentLoginResponse parsedResponse = parseLoginResponse(loginResponseJson);
|
AppointmentLoginResponse parsedResponse = parseLoginResponse(loginResponseJson);
|
||||||
|
|
||||||
// Validate and save token
|
|
||||||
if (parsedResponse.getTokenId() != null) {
|
if (parsedResponse.getTokenId() != null) {
|
||||||
hub.setAppointmentAuthTokenId(parsedResponse.getTokenId());
|
hub.setAppointmentAuthTokenId(parsedResponse.getTokenId());
|
||||||
hub.setAreaCode(parsedResponse.getAreaCode());
|
hub.setAreaCode(parsedResponse.getAreaCode());
|
||||||
hubRepository.save(hub);
|
hubRepository.save(hub);
|
||||||
log.info("Saved new authToken and areaCode for Hub.");
|
log.info("Saved new authToken and areaCode for Hub.");
|
||||||
success = true;
|
|
||||||
return hub;
|
return hub;
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Login response is missing a valid tokenId for login to odessa system, please try again.");
|
throw new RuntimeException("Login response is missing a valid tokenId for login to odessa system, please try again.");
|
||||||
@@ -209,12 +383,19 @@ public class AppointmentDao {
|
|||||||
}
|
}
|
||||||
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.ERROR_IN_GENERATING_NDG_TRY_AGAIN));
|
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.ERROR_IN_GENERATING_NDG_TRY_AGAIN));
|
||||||
} catch (FeignException.Forbidden forbiddenException) {
|
} catch (FeignException.Forbidden forbiddenException) {
|
||||||
log.error("Failed to login to odessa due to some error");
|
log.error("Failed to login to odessa due to forbidden error.");
|
||||||
|
|
||||||
// Extract raw response body
|
CheckPasswordExpiredOrErrorInResponse(application, forbiddenException);
|
||||||
String responseBody = forbiddenException.contentUTF8(); // Extract raw JSON response
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to authenticate user on Odessa (Attempt {}): {}", attempt, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Max retries exceeded. Failed to login to Odessa.");
|
||||||
|
}
|
||||||
|
private void CheckPasswordExpiredOrErrorInResponse(ApplicationEntity application, FeignException.Forbidden forbiddenException) {
|
||||||
|
|
||||||
|
String responseBody = forbiddenException.contentUTF8();
|
||||||
|
|
||||||
// Parse JSON to check for "PasswordExpired"
|
|
||||||
try {
|
try {
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
JsonNode rootNode = objectMapper.readTree(responseBody);
|
JsonNode rootNode = objectMapper.readTree(responseBody);
|
||||||
@@ -222,20 +403,22 @@ public class AppointmentDao {
|
|||||||
|
|
||||||
if (errorsNode.isArray()) {
|
if (errorsNode.isArray()) {
|
||||||
for (JsonNode error : errorsNode) {
|
for (JsonNode error : errorsNode) {
|
||||||
// Check the main errorCode
|
|
||||||
if (GepafinConstant.PASSWORD_EXPIRED.equals(error.path("errorCode").asText())) {
|
if (GepafinConstant.PASSWORD_EXPIRED.equals(error.path("errorCode").asText())) {
|
||||||
|
if (application != null) {
|
||||||
application.setNdgStatus(GepafinConstant.NDG_FAILED);
|
application.setNdgStatus(GepafinConstant.NDG_FAILED);
|
||||||
applicationRepository.save(application);
|
applicationRepository.save(application);
|
||||||
|
}
|
||||||
throw new CustomValidationException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PASSWORD_EXPIRED_LOGIN_TO_ODESSA));
|
throw new CustomValidationException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PASSWORD_EXPIRED_LOGIN_TO_ODESSA));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check inside "subErrors"
|
|
||||||
JsonNode subErrorsNode = error.path("subErrors");
|
JsonNode subErrorsNode = error.path("subErrors");
|
||||||
if (subErrorsNode.isArray()) {
|
if (subErrorsNode.isArray()) {
|
||||||
for (JsonNode subError : subErrorsNode) {
|
for (JsonNode subError : subErrorsNode) {
|
||||||
if (GepafinConstant.PASSWORD_EXPIRED.equals(subError.path("errorCode").asText())) {
|
if (GepafinConstant.PASSWORD_EXPIRED.equals(subError.path("errorCode").asText())) {
|
||||||
|
if (application != null) {
|
||||||
application.setNdgStatus(GepafinConstant.NDG_FAILED);
|
application.setNdgStatus(GepafinConstant.NDG_FAILED);
|
||||||
applicationRepository.save(application);
|
applicationRepository.save(application);
|
||||||
|
}
|
||||||
throw new CustomValidationException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PASSWORD_EXPIRED_LOGIN_TO_ODESSA));
|
throw new CustomValidationException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PASSWORD_EXPIRED_LOGIN_TO_ODESSA));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -245,12 +428,6 @@ public class AppointmentDao {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Error parsing JSON response: {}", e.getMessage());
|
log.error("Error parsing JSON response: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Failed to authenticate user on Odessa : {}", e.getMessage(), e);
|
|
||||||
throw new RuntimeException("Authentication failed on Odessa. try again", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startAsyncNdgProcessing(Long applicationId) {
|
private void startAsyncNdgProcessing(Long applicationId) {
|
||||||
@@ -299,7 +476,7 @@ public class AppointmentDao {
|
|||||||
try {
|
try {
|
||||||
// Authenticate and fetch token if required
|
// Authenticate and fetch token if required
|
||||||
if (hub.getAppointmentAuthTokenId() == null || hub.getAreaCode() == null) {
|
if (hub.getAppointmentAuthTokenId() == null || hub.getAreaCode() == null) {
|
||||||
authenticateAndSaveToken(hub);
|
authenticateAndSaveToken(hub, application);
|
||||||
}
|
}
|
||||||
|
|
||||||
String authorizationToken = getBearerToken(hub);
|
String authorizationToken = getBearerToken(hub);
|
||||||
@@ -345,7 +522,8 @@ public class AppointmentDao {
|
|||||||
application.setStatus(ApplicationStatusTypeEnum.NDG.getValue());
|
application.setStatus(ApplicationStatusTypeEnum.NDG.getValue());
|
||||||
applicationRepository.save(application);
|
applicationRepository.save(application);
|
||||||
companyRepository.save(company);
|
companyRepository.save(company);
|
||||||
ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(application.getApplicationEvaluationId());
|
ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(
|
||||||
|
application.getApplicationEvaluationId());
|
||||||
Map<String, String> placeHolders = notificationDao.sendNotificationToBeneficiary(application, NotificationTypeEnum.NDG_GENERATION);
|
Map<String, String> placeHolders = notificationDao.sendNotificationToBeneficiary(application, NotificationTypeEnum.NDG_GENERATION);
|
||||||
notificationDao.sendNotificationToInstructor(placeHolders, applicationEvaluationEntity, NotificationTypeEnum.NDG_GENERATION);
|
notificationDao.sendNotificationToInstructor(placeHolders, applicationEvaluationEntity, NotificationTypeEnum.NDG_GENERATION);
|
||||||
notificationDao.sendNotificationToSuperUser(application, placeHolders, NotificationTypeEnum.NDG_GENERATION);
|
notificationDao.sendNotificationToSuperUser(application, placeHolders, NotificationTypeEnum.NDG_GENERATION);
|
||||||
@@ -416,7 +594,7 @@ public class AppointmentDao {
|
|||||||
} catch (FeignException.Forbidden forbiddenException) {
|
} catch (FeignException.Forbidden forbiddenException) {
|
||||||
log.error("403 Forbidden received while getting visuraList for Ndg code. Regenerating token...");
|
log.error("403 Forbidden received while getting visuraList for Ndg code. Regenerating token...");
|
||||||
// Regenerate the token and retry
|
// Regenerate the token and retry
|
||||||
String newAuthorizationToken = regenerateTokenAndSave(hub);
|
String newAuthorizationToken = regenerateTokenAndSave(hub, application);
|
||||||
return getVisuraList(idVisura, newAuthorizationToken, application, hub);
|
return getVisuraList(idVisura, newAuthorizationToken, application, hub);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Failed to fetch Ndg code: {}", e.getMessage(), e);
|
log.error("Failed to fetch Ndg code: {}", e.getMessage(), e);
|
||||||
@@ -424,86 +602,6 @@ public class AppointmentDao {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private HubEntity authenticateAndSaveToken(HubEntity hub) {
|
|
||||||
|
|
||||||
int maxRetries = 3;
|
|
||||||
int attempt = 0;
|
|
||||||
boolean success = false;
|
|
||||||
while (attempt < maxRetries && !success) {
|
|
||||||
attempt++;
|
|
||||||
try {
|
|
||||||
//code to generate token with payload having "iat" epoch timestamp and secret key with no expiry and send in below method call
|
|
||||||
String authJwtToken = Utils.generateAuthTokenForLoginToOdessa();
|
|
||||||
log.info("Got the auth for login to odessa {}", authJwtToken);
|
|
||||||
hub.setAuthToken(authJwtToken);
|
|
||||||
hubRepository.save(hub);
|
|
||||||
// Prepare the request body (adjust if necessary for login API)
|
|
||||||
Map<String, Object> body = Collections.emptyMap();
|
|
||||||
// Perform login API call
|
|
||||||
ResponseEntity<Object> responseLogin = appointmentApiService.loginWithOdessa(authJwtToken, source, context, user, password, body);
|
|
||||||
|
|
||||||
// Handle successful login
|
|
||||||
if (responseLogin.getStatusCode() == HttpStatus.OK) {
|
|
||||||
log.info("Login successful to odessa. Parsing response.");
|
|
||||||
String loginResponseJson = Utils.convertObjectToJson(responseLogin.getBody());
|
|
||||||
AppointmentLoginResponse parsedResponse = parseLoginResponse(loginResponseJson);
|
|
||||||
|
|
||||||
// Validate and save token
|
|
||||||
if (parsedResponse.getTokenId() != null) {
|
|
||||||
hub.setAppointmentAuthTokenId(parsedResponse.getTokenId());
|
|
||||||
hub.setAreaCode(parsedResponse.getAreaCode());
|
|
||||||
hubRepository.save(hub);
|
|
||||||
|
|
||||||
log.info("Saved new authToken and areaCode for Hub.");
|
|
||||||
success = true;
|
|
||||||
return hub;
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException("Login response is missing a valid tokenId for login to odessa system, please try again.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Handle non-OK response
|
|
||||||
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.ERROR_IN_GENERATING_NDG_TRY_AGAIN));
|
|
||||||
} catch (FeignException.Forbidden forbiddenException) {
|
|
||||||
log.error("Failed to login to odessa due to some error occurred.");
|
|
||||||
|
|
||||||
// Extract raw response body
|
|
||||||
String responseBody = forbiddenException.contentUTF8(); // Extract raw JSON response
|
|
||||||
|
|
||||||
// Parse JSON to check for "PasswordExpired"
|
|
||||||
try {
|
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
JsonNode rootNode = objectMapper.readTree(responseBody);
|
|
||||||
JsonNode errorsNode = rootNode.path("errors");
|
|
||||||
|
|
||||||
if (errorsNode.isArray()) {
|
|
||||||
for (JsonNode error : errorsNode) {
|
|
||||||
// Check the main errorCode
|
|
||||||
if (GepafinConstant.PASSWORD_EXPIRED.equals(error.path("errorCode").asText())) {
|
|
||||||
throw new CustomValidationException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PASSWORD_EXPIRED_LOGIN_TO_ODESSA));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check inside "subErrors"
|
|
||||||
JsonNode subErrorsNode = error.path("subErrors");
|
|
||||||
if (subErrorsNode.isArray()) {
|
|
||||||
for (JsonNode subError : subErrorsNode) {
|
|
||||||
if (GepafinConstant.PASSWORD_EXPIRED.equals(subError.path("errorCode").asText())) {
|
|
||||||
throw new CustomValidationException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PASSWORD_EXPIRED_LOGIN_TO_ODESSA));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("Error parsing JSON response: {}", e.getMessage());
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Failed to authenticate user on Odessa : {}", e.getMessage(), e);
|
|
||||||
throw new RuntimeException("Authentication failed on Odessa. try again", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private AppointmentLoginResponse retrieveNdgByVatNumber(String vatNumber, String authorizationToken, HubEntity hub, ApplicationEntity application) {
|
private AppointmentLoginResponse retrieveNdgByVatNumber(String vatNumber, String authorizationToken, HubEntity hub, ApplicationEntity application) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -517,7 +615,7 @@ public class AppointmentDao {
|
|||||||
} catch (FeignException.Forbidden forbiddenException) {
|
} catch (FeignException.Forbidden forbiddenException) {
|
||||||
logForbiddenError();
|
logForbiddenError();
|
||||||
// Regenerate the token and retry
|
// Regenerate the token and retry
|
||||||
String newAuthorizationToken = regenerateTokenAndSave(hub);
|
String newAuthorizationToken = regenerateTokenAndSave(hub, application);
|
||||||
return retrieveNdgByVatNumber(vatNumber, newAuthorizationToken, hub, application);
|
return retrieveNdgByVatNumber(vatNumber, newAuthorizationToken, hub, application);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Failed to retrieve NDG by VAT number: {}", e.getMessage(), e);
|
log.error("Failed to retrieve NDG by VAT number: {}", e.getMessage(), e);
|
||||||
@@ -525,8 +623,9 @@ public class AppointmentDao {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String regenerateTokenAndSave(HubEntity hub) {
|
private String regenerateTokenAndSave(HubEntity hub, ApplicationEntity application) {
|
||||||
hub = authenticateAndSaveToken(hub);
|
|
||||||
|
hub = authenticateAndSaveToken(hub, application);
|
||||||
return "Bearer " + hub.getAppointmentAuthTokenId();
|
return "Bearer " + hub.getAppointmentAuthTokenId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -540,7 +639,7 @@ public class AppointmentDao {
|
|||||||
} catch (FeignException.Forbidden forbiddenException) {
|
} catch (FeignException.Forbidden forbiddenException) {
|
||||||
logForbiddenError();
|
logForbiddenError();
|
||||||
// Regenerate the token and retry
|
// Regenerate the token and retry
|
||||||
String newAuthorizationToken = regenerateTokenAndSave(hub);
|
String newAuthorizationToken = regenerateTokenAndSave(hub, null);
|
||||||
return createVisura(company, newAuthorizationToken, hub);
|
return createVisura(company, newAuthorizationToken, hub);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Failed to create Visura for Ndg : {}", e.getMessage());
|
log.error("Failed to create Visura for Ndg : {}", e.getMessage());
|
||||||
@@ -710,9 +809,8 @@ public class AppointmentDao {
|
|||||||
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.NDG_NOT_FOUND_FOR_APPLICATION));
|
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.NDG_NOT_FOUND_FOR_APPLICATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
hub = authenticateAndSaveToken(hub);
|
|
||||||
// Generate authorization token and fetch template data
|
// Generate authorization token and fetch template data
|
||||||
String authorizationToken = getBearerToken(hub);
|
String authorizationToken = regenerateTokenAndSave(hub, application);
|
||||||
Long appointmentTemplateId = application.getCall().getAppointmentTemplateId();
|
Long appointmentTemplateId = application.getCall().getAppointmentTemplateId();
|
||||||
if (appointmentTemplateId == null) {
|
if (appointmentTemplateId == null) {
|
||||||
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPOINTMENT_CANNOT_BE_CREATED));
|
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPOINTMENT_CANNOT_BE_CREATED));
|
||||||
@@ -756,7 +854,7 @@ public class AppointmentDao {
|
|||||||
|
|
||||||
} catch (FeignException.Forbidden forbiddenException) {
|
} catch (FeignException.Forbidden forbiddenException) {
|
||||||
log.error("403 Forbidden received while retrieving template. Regenerating token...");
|
log.error("403 Forbidden received while retrieving template. Regenerating token...");
|
||||||
regenerateTokenAndSave(hub);
|
regenerateTokenAndSave(hub, application);
|
||||||
return createAppointment(applicationId, createAppointmentRequest);
|
return createAppointment(applicationId, createAppointmentRequest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -893,13 +991,40 @@ public class AppointmentDao {
|
|||||||
// Check if the document is already being processed
|
// Check if the document is already being processed
|
||||||
DocumentEntity systemDoc = documentDao.validateDocument(documentId);
|
DocumentEntity systemDoc = documentDao.validateDocument(documentId);
|
||||||
|
|
||||||
|
ApplicationEntity application = null;
|
||||||
|
|
||||||
|
if (systemDoc != null) {
|
||||||
|
DocumentSourceTypeEnum sourceType = DocumentSourceTypeEnum.valueOf(systemDoc.getSource());
|
||||||
|
|
||||||
|
switch (sourceType) {
|
||||||
|
case APPLICATION:
|
||||||
|
application = applicationDao.validateApplication(systemDoc.getSourceId());
|
||||||
|
break;
|
||||||
|
case AMENDMENT:
|
||||||
|
ApplicationAmendmentRequestEntity applicationAmendmentEntity = applicationAmendmentRequestDao.validateApplicationAmendmentRequest(systemDoc.getSourceId());
|
||||||
|
application = applicationDao.validateApplication(applicationAmendmentEntity.getApplicationId());
|
||||||
|
break;
|
||||||
|
case EVALUATION:
|
||||||
|
ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationDao.validateApplicationEvaluation(systemDoc.getSourceId());
|
||||||
|
application = applicationDao.validateApplication(applicationEvaluationEntity.getApplicationId());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CALL:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
log.warn("Unhandled document source type: {}", sourceType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Claims claims = tokenProvider.getClaimsFromToken(tokenProvider.extractTokenFromRequest(request));
|
Claims claims = tokenProvider.getClaimsFromToken(tokenProvider.extractTokenFromRequest(request));
|
||||||
Long hubId = Utils.extractHubIdFromPayload(claims.getSubject());
|
Long hubId = Utils.extractHubIdFromPayload(claims.getSubject());
|
||||||
|
|
||||||
// Authenticate the hub before proceeding
|
// Authenticate the hub before proceeding
|
||||||
HubEntity hub = hubRepository.findByHubId(hubId);
|
HubEntity hub = hubRepository.findByHubId(hubId);
|
||||||
authenticateAndSaveToken(hub);
|
authenticateAndSaveToken(hub, application);
|
||||||
if (systemDoc.getDocumentAttachmentId() != null) {
|
if (systemDoc != null && systemDoc.getDocumentAttachmentId() != null) {
|
||||||
// If the documentAttachmentId is already set, return the response
|
// If the documentAttachmentId is already set, return the response
|
||||||
log.info("Document already uploaded with documentAttachmentId: {}", systemDoc.getDocumentAttachmentId());
|
log.info("Document already uploaded with documentAttachmentId: {}", systemDoc.getDocumentAttachmentId());
|
||||||
DocumentUploadResponse response = new DocumentUploadResponse();
|
DocumentUploadResponse response = new DocumentUploadResponse();
|
||||||
@@ -919,11 +1044,12 @@ public class AppointmentDao {
|
|||||||
});
|
});
|
||||||
threadForDocumentMap.put(documentId, executor);
|
threadForDocumentMap.put(documentId, executor);
|
||||||
|
|
||||||
|
ApplicationEntity finalApplication = application;
|
||||||
executor.submit(() -> {
|
executor.submit(() -> {
|
||||||
threadLocalHubId.set(hubId);
|
threadLocalHubId.set(hubId);
|
||||||
try {
|
try {
|
||||||
log.info("Starting async document upload for documentId: {}", documentId);
|
log.info("Starting async document upload for documentId: {}", documentId);
|
||||||
uploadDocumentToExternalSystemSync(documentId, docToExternalSystemRequest);
|
uploadDocumentToExternalSystemSync(documentId, docToExternalSystemRequest, finalApplication);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Error in async document upload for documentId: {}", documentId, e);
|
log.error("Error in async document upload for documentId: {}", documentId, e);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -939,7 +1065,7 @@ public class AppointmentDao {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uploadDocumentToExternalSystemSync(Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest) {
|
private void uploadDocumentToExternalSystemSync(Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest, ApplicationEntity application) {
|
||||||
// Synchronous upload logic
|
// Synchronous upload logic
|
||||||
DocumentEntity systemDoc = documentDao.validateDocument(documentId);
|
DocumentEntity systemDoc = documentDao.validateDocument(documentId);
|
||||||
|
|
||||||
@@ -980,8 +1106,8 @@ public class AppointmentDao {
|
|||||||
log.info("Document uploaded successfully to external system: {}", parsedResponse);
|
log.info("Document uploaded successfully to external system: {}", parsedResponse);
|
||||||
} catch (FeignException.Forbidden forbiddenException) {
|
} catch (FeignException.Forbidden forbiddenException) {
|
||||||
log.error("403 Forbidden received while uploading document. Regenerating token...");
|
log.error("403 Forbidden received while uploading document. Regenerating token...");
|
||||||
regenerateTokenAndSave(hub);
|
regenerateTokenAndSave(hub, application);
|
||||||
uploadDocumentToExternalSystemSync(documentId, docToExternalSystemRequest);
|
uploadDocumentToExternalSystemSync(documentId, docToExternalSystemRequest, application);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Exception during document upload: {}", e.getMessage(), e);
|
log.error("Exception during document upload: {}", e.getMessage(), e);
|
||||||
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.EXTERNAL_DOCUMENT_UPLOAD_FAILURE_MSG));
|
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.EXTERNAL_DOCUMENT_UPLOAD_FAILURE_MSG));
|
||||||
|
|||||||
Reference in New Issue
Block a user