Done Ticket GEPAFINBE-171

This commit is contained in:
Piyush
2025-05-28 11:56:17 +05:30
parent 9699964b09
commit f9b9c5f2e0
10 changed files with 361 additions and 64 deletions

View File

@@ -148,10 +148,11 @@ public class AppointmentDao {
private static final ThreadLocal<Long> threadLocalHubId = new ThreadLocal<>();
public NdgResponse checkNdgForAppointment(Long applicationId) {
log.info("Starting NDG check for appointment. applicationId: {}", applicationId);
ApplicationEntity application = applicationService.validateApplication(applicationId);
NdgResponse ndgResponse = new NdgResponse();
if (application.getNdgStatus() != null && application.getNdgStatus().equalsIgnoreCase(GepafinConstant.NDG_IN_PROGRESS)) {
log.warn("NDG generation already in progress. applicationId: {}", applicationId);
throw new CustomValidationException(Status.SUCCESS, Translator.toLocale(GepafinConstant.NDG_GENERATION_IS_IN_PROGRESS));
}
@@ -161,6 +162,7 @@ public class AppointmentDao {
}
// Update application status
log.info("Updating NDG status to IN_PROGRESS. applicationId: {}", applicationId);
application.setNdgStatus(GepafinConstant.NDG_IN_PROGRESS);
applicationRepository.save(application);
@@ -168,10 +170,12 @@ public class AppointmentDao {
HubEntity hub = hubRepository.findByHubId(application.getHubId());
loginToOdessa(hub, application);
startAsyncNdgProcessing(applicationId);
log.info("NDG check initiation completed. applicationId: {}", applicationId);
return ndgResponse;
}
private HubEntity loginToOdessa(HubEntity hub, ApplicationEntity application) {
log.info("Starting login to Odessa. HubId: {}, ApplicationId: {}", hub.getId(), application.getId());
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();
@@ -181,7 +185,7 @@ public class AppointmentDao {
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.");
log.info("Login to Odessa successful. Parsing response. HubId: {}", hub.getId());
String loginResponseJson = Utils.convertObjectToJson(responseLogin.getBody());
AppointmentLoginResponse parsedResponse = parseLoginResponse(loginResponseJson);
@@ -193,12 +197,14 @@ public class AppointmentDao {
log.info("Saved new authToken and areaCode for Hub.");
return hub;
} else {
log.error("Login response from Odessa missing tokenId. HubId: {}", hub.getId());
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.warn("Received 403 Forbidden from Odessa. Attempting to parse error response.");
logForbiddenError();
// Extract raw response body
@@ -216,6 +222,7 @@ public class AppointmentDao {
if (GepafinConstant.PASSWORD_EXPIRED.equals(error.path("errorCode").asText())) {
application.setNdgStatus(GepafinConstant.NDG_FAILED);
applicationRepository.save(application);
log.warn("Detected PASSWORD_EXPIRED error during Odessa login. ApplicationId: {}", application.getId());
throw new CustomValidationException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PASSWORD_EXPIRED_LOGIN_TO_ODESSA));
}
@@ -240,7 +247,7 @@ public class AppointmentDao {
loginToOdessa(hub, application);
}
catch (Exception e) {
log.error("Failed to authenticate user on Odessa : {}", e.getMessage(), e);
log.error("Unexpected exception during Odessa login. HubId: {}, Error: {}", hub.getId(), e.getMessage(), e);
throw new RuntimeException("Authentication failed on Odessa. try again", e);
}
return null;
@@ -280,6 +287,7 @@ public class AppointmentDao {
private void processNdgGeneration(Long applicationId) {
// Validate application, company, and hub
log.info("Starting NDG generation process for applicationId: {}", applicationId);
ApplicationEntity application = applicationService.validateApplication(applicationId);
CompanyEntity company = companyService.validateCompany(application.getCompanyId());
HubEntity hub = hubRepository.findByHubId(application.getHubId());
@@ -307,14 +315,15 @@ public class AppointmentDao {
handleNdgPolling(application, company, hub, authorizationToken);
}
} catch (Exception e) {
log.error("Error during NDG generation for applicationId: {}", applicationId, e);
log.error("Exception occurred during NDG generation. ApplicationId: {}, CompanyId: {}, HubId: {}, Error: {}",
applicationId, company.getId(), hub.getId(), e.getMessage(), e);
}
}
private void handleNdgPolling(ApplicationEntity application, CompanyEntity company, HubEntity hub, String authorizationToken) {
try {
log.info("Starting NDG polling for applicationId: {}", application.getId());
log.info("Starting NDG polling for applicationId: {}, CompanyId: {}, HubId: {}", application.getId(),company.getId(), hub.getId());
long startTime = System.currentTimeMillis();
while (true) {
@@ -326,12 +335,13 @@ public class AppointmentDao {
try {
// Fetch Visura list and attempt to parse NDG
String visuraListJson = getVisuraList(application.getIdVisura(), authorizationToken, application, hub);
log.debug("Parsing NDG from visura list response | ApplicationId: {}", application.getId());
String ndg = parseNdgFromVisuraListResponse(visuraListJson);
if (isNdgValid(ndg)) {
// CompanyEntity oldCompanyData = Utils.getClonedEntityForData(company);
// ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(application);
log.info("Valid NDG retrieved: {} | ApplicationId: {}", ndg, application.getId());
company.setNdg(ndg);
application.setNdg(ndg);
application.setNdgStatus(GepafinConstant.NDG_GENERATED);
@@ -397,6 +407,7 @@ public class AppointmentDao {
private String getVisuraList(String idVisura, String authorizationToken, ApplicationEntity application, HubEntity hub) {
log.info("Initiating Visura list retrieval | ApplicationId: {}, HubId: {}, IdVisura: {}", application.getId(), hub.getId(), idVisura);
AppointmentVisuraListRequest visuraListRequest = new AppointmentVisuraListRequest();
AppointmentVisuraListRequest.VisuraFilter filter = new AppointmentVisuraListRequest.VisuraFilter();
filter.setIdVisura(idVisura);
@@ -407,12 +418,12 @@ public class AppointmentDao {
ResponseEntity<Object> response = appointmentApiService.getVisuraList(requestJson, authorizationToken);
return Utils.convertObjectToJson(response.getBody());
} catch (FeignException.Forbidden forbiddenException) {
log.error("403 Forbidden received while getting visuraList for Ndg code. Regenerating token...");
log.warn("403 Forbidden while fetching Visura list. Attempting token regeneration | ApplicationId: {}, HubId: {}", application.getId(), hub.getId());
// Regenerate the token and retry
String newAuthorizationToken = regenerateTokenAndSave(hub);
return getVisuraList(idVisura, newAuthorizationToken, application, hub);
} catch (Exception e) {
log.error("Failed to fetch Ndg code: {}", e.getMessage(), e);
log.error("Error while fetching Visura list | ApplicationId: {}, HubId: {}, Error: {}", application.getId(), hub.getId(), e.getMessage(), e);
throw new RuntimeException("Error fetching Ndg List", e);
}
}
@@ -420,6 +431,7 @@ public class AppointmentDao {
private HubEntity authenticateAndSaveToken(HubEntity hub) {
try {
log.info("Starting authentication to Odessa | HubId: {}", hub.getId());
//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);
@@ -445,12 +457,14 @@ public class AppointmentDao {
log.info("Saved new authToken and areaCode for Hub.");
return hub;
} else {
log.error("Login response missing tokenId | HubId: {}", hub.getId());
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("403 Forbidden during Odessa login | HubId: {}", hub.getId());
logForbiddenError();
// Extract raw response body
@@ -466,6 +480,7 @@ public class AppointmentDao {
for (JsonNode error : errorsNode) {
// Check the main errorCode
if (GepafinConstant.PASSWORD_EXPIRED.equals(error.path("errorCode").asText())) {
log.warn("Odessa password expired detected in login response | HubId: {}", hub.getId());
throw new CustomValidationException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PASSWORD_EXPIRED_LOGIN_TO_ODESSA));
}
@@ -481,13 +496,13 @@ public class AppointmentDao {
}
}
} catch (IOException e) {
log.error("Error parsing JSON response: {}", e.getMessage());
log.error("Error parsing forbidden JSON response | HubId: {}, Error: {}", hub.getId(), e.getMessage(), e);
}
// Regenerate the token and retry
regenerateTokenAndSave(hub);
} catch (Exception e) {
log.error("Failed to authenticate user on Odessa : {}", e.getMessage(), e);
log.error("Unexpected error during Odessa authentication | HubId: {}, Error: {}", hub.getId(), e.getMessage(), e);
throw new RuntimeException("Authentication failed on Odessa. try again", e);
}
return null;
@@ -496,6 +511,7 @@ public class AppointmentDao {
private AppointmentLoginResponse retrieveNdgByVatNumber(String vatNumber, String authorizationToken, HubEntity hub, ApplicationEntity application) {
try {
log.info("Initiating NDG retrieval by VAT number | ApplicationId: {}, HubId: {}, VAT: {}", application.getId(), hub.getId(), vatNumber);
// Prepare the NDG request
AppointmentNdgRequest ndgRequest = getAppointmentNdgRequest(vatNumber);
// Call the API to retrieve NDG
@@ -504,12 +520,13 @@ public class AppointmentDao {
// Parse and return the NDG response
return parseNdgResponse(responseJson);
} catch (FeignException.Forbidden forbiddenException) {
log.error("403 Forbidden during NDG retrieval | ApplicationId: {}, HubId: {}", application.getId(), hub.getId());
logForbiddenError();
// Regenerate the token and retry
String newAuthorizationToken = regenerateTokenAndSave(hub);
return retrieveNdgByVatNumber(vatNumber, newAuthorizationToken, hub, application);
} catch (Exception e) {
log.error("Failed to retrieve NDG by VAT number: {}", e.getMessage(), e);
log.error("Error during NDG retrieval | ApplicationId: {}, HubId: {}, Message: {}", application.getId(), hub.getId(), e.getMessage(), e);
throw new RuntimeException("NDG retrieval failed.", e);
}
}
@@ -544,6 +561,7 @@ public class AppointmentDao {
private static AppointmentNdgRequest getAppointmentNdgRequest(String vatNumber) {
log.info("Creating Appointment NDG Request | VAT Number: {}", vatNumber);
AppointmentNdgRequest request = new AppointmentNdgRequest();
AppointmentNdgRequest.Filter filter = new AppointmentNdgRequest.Filter();
filter.setPartitaIva(vatNumber);
@@ -674,6 +692,7 @@ public class AppointmentDao {
public AppointmentCreationResponse createAppointment(Long applicationId, CreateAppointmentRequest createAppointmentRequest) {
// Validate the application
log.info("Starting appointment creation for applicationId: {}", applicationId);
ApplicationEntity application = applicationService.validateApplication(applicationId);
AppointmentCreationResponse appointmentCreationResponse = new AppointmentCreationResponse();
@@ -696,6 +715,7 @@ public class AppointmentDao {
}
if (application.getNdg() == null && Objects.equals(application.getNdgStatus(), GepafinConstant.NDG_IN_PROGRESS)) {
log.warn("NDG in progress but not available for applicationId: {}", applicationId);
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.NDG_NOT_FOUND_FOR_APPLICATION));
}
@@ -704,6 +724,7 @@ public class AppointmentDao {
String authorizationToken = getBearerToken(hub);
Long appointmentTemplateId = application.getCall().getAppointmentTemplateId();
if (appointmentTemplateId == null) {
log.error("Missing appointment template ID for applicationId: {}", applicationId);
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPOINTMENT_CANNOT_BE_CREATED));
}
ResponseEntity<Object> response = appointmentApiService.getAppointmentTemplateForTemplateCreation(authorizationToken, appointmentTemplateId);
@@ -727,6 +748,7 @@ public class AppointmentDao {
String appointmentId = extractAppointmentIdFromResponse(appointmentResponse);
if (appointmentId == null) {
log.error("Failed to extract appointment ID from response for applicationId: {}", applicationId);
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPOINTMENT_NOT_CREATED));
}
// Update application with the appointment ID
@@ -742,7 +764,7 @@ public class AppointmentDao {
return appointmentCreationResponse;
} catch (FeignException.Forbidden forbiddenException) {
log.error("403 Forbidden received while retrieving template. Regenerating token...");
log.error("403 Forbidden received while retrieving template. Attempting to regenerate token and retry. Application ID: {}", applicationId);
regenerateTokenAndSave(hub);
return createAppointment(applicationId, createAppointmentRequest);
}
@@ -857,6 +879,7 @@ public class AppointmentDao {
}
public DocumentUploadResponse uploadDocumentToExternalSystem(Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest) {
log.info("Initiating upload to external system for documentId: {}", documentId);
// Check if the document is already being processed
DocumentEntity systemDoc = documentDao.validateDocument(documentId);
@@ -907,6 +930,7 @@ public class AppointmentDao {
}
private void uploadDocumentToExternalSystemSync(Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest) {
log.info("Starting sync document upload for documentId: {}", documentId);
// Synchronous upload logic
DocumentEntity systemDoc = documentDao.validateDocument(documentId);
@@ -937,6 +961,7 @@ public class AppointmentDao {
DocumentUploadResponse parsedResponse = parseDocumentUploadResponse(responseData);
if (parsedResponse == null) {
log.error("Upload failed: parsed response is null for documentId: {}", documentId);
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.ERROR_UPLOADING_DOCUMENT));
}
@@ -946,7 +971,7 @@ public class AppointmentDao {
log.info("Document uploaded successfully to external system: {}", parsedResponse);
} catch (FeignException.Forbidden forbiddenException) {
log.error("403 Forbidden received while uploading document. Regenerating token...");
log.error("403 Forbidden from external system during upload for documentId: {}. Retrying with new token...", documentId);
regenerateTokenAndSave(hub);
uploadDocumentToExternalSystemSync(documentId, docToExternalSystemRequest);
} catch (Exception e) {