diff --git a/src/main/java/com/iemr/mmu/service/dataSyncActivity/DownloadDataFromServerImpl.java b/src/main/java/com/iemr/mmu/service/dataSyncActivity/DownloadDataFromServerImpl.java index 6e7b1c91..b483517e 100644 --- a/src/main/java/com/iemr/mmu/service/dataSyncActivity/DownloadDataFromServerImpl.java +++ b/src/main/java/com/iemr/mmu/service/dataSyncActivity/DownloadDataFromServerImpl.java @@ -23,12 +23,12 @@ import java.text.DecimalFormat; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.HashMap; import org.json.JSONObject; import org.slf4j.Logger; @@ -40,11 +40,7 @@ import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; import com.google.gson.Gson; import com.iemr.mmu.data.syncActivity_syncLayer.MasterDownloadDataDigester; @@ -56,8 +52,6 @@ import com.iemr.mmu.utils.RestTemplateUtil; import com.iemr.mmu.utils.mapper.InputMapper; -import jakarta.servlet.http.HttpServletRequest; - @Service @PropertySource("classpath:application.properties") public class DownloadDataFromServerImpl implements DownloadDataFromServer { @@ -335,11 +329,13 @@ public int callCentralAPIToGenerateBenIDAndimportToLocal(String requestOBJ, Stri // Rest template RestTemplate restTemplate = new RestTemplate(); HttpEntity request = RestTemplateUtil.createRequestEntity(requestOBJ, ServerAuthorization,"datasync"); + logger.info("request obj check="+requestOBJ); // Call rest-template to call central API to generate UNIQUE ID at central ResponseEntity response = restTemplate.exchange(benGenUrlCentral, HttpMethod.POST, request, String.class); logger.info("Authorization before calling local api="+Authorization); logger.info("Import url="+benImportUrlLocal); + logger.info("Response from benGenUrlCentral: " + response.getBody()); if (response != null && response.hasBody()) { JSONObject obj = new JSONObject(response.getBody()); if (obj != null && obj.has("data") && obj.has("statusCode") && obj.getInt("statusCode") == 200) { diff --git a/src/main/java/com/iemr/mmu/service/dataSyncActivity/DownloadDataFromServerTransactionalImpl.java b/src/main/java/com/iemr/mmu/service/dataSyncActivity/DownloadDataFromServerTransactionalImpl.java index 5cd8d26d..ee3c39a5 100644 --- a/src/main/java/com/iemr/mmu/service/dataSyncActivity/DownloadDataFromServerTransactionalImpl.java +++ b/src/main/java/com/iemr/mmu/service/dataSyncActivity/DownloadDataFromServerTransactionalImpl.java @@ -109,7 +109,7 @@ public int downloadTransactionalData(int vanID, String ServerAuthorization, Stri } indentRepo.saveAll(indentList); - int updateFlag = updateProcessedFlagToCentral("db_iemr_sync", "t_indent", ids, ServerAuthorization, token); + int updateFlag = updateProcessedFlagToCentral("db_iemr", "t_indent", ids, ServerAuthorization, token); } break; @@ -136,7 +136,7 @@ public int downloadTransactionalData(int vanID, String ServerAuthorization, Stri indentOrder.setProcessed("P"); } indentOrderRepo.saveAll(indentOrderList); - int updateFlag = updateProcessedFlagToCentral("db_iemr_sync", "t_indentorder", ids, ServerAuthorization, token); + int updateFlag = updateProcessedFlagToCentral("db_iemr", "t_indentorder", ids, ServerAuthorization, token); } break; } @@ -164,7 +164,7 @@ public int downloadTransactionalData(int vanID, String ServerAuthorization, Stri } indentIssueRepo.saveAll(indentIssueList); - int updateFlag = updateProcessedFlagToCentral("db_iemr_sync", "t_indentissue", ids, ServerAuthorization, token); + int updateFlag = updateProcessedFlagToCentral("db_iemr", "t_indentissue", ids, ServerAuthorization, token); } break; } @@ -191,7 +191,7 @@ public int downloadTransactionalData(int vanID, String ServerAuthorization, Stri } stockTransferRepo.saveAll(stockTransferList); - int updateFlag = updateProcessedFlagToCentral("db_iemr_sync", "t_stocktransfer", ids, + int updateFlag = updateProcessedFlagToCentral("db_iemr", "t_stocktransfer", ids, ServerAuthorization, token); } break; @@ -219,7 +219,7 @@ public int downloadTransactionalData(int vanID, String ServerAuthorization, Stri } itemStockEntryRepo.saveAll(itemStockEntryList); - int updateFlag = updateProcessedFlagToCentral("db_iemr_sync", "t_itemstockentry", ids, + int updateFlag = updateProcessedFlagToCentral("db_iemr", "t_itemstockentry", ids, ServerAuthorization, token); } break; diff --git a/src/main/java/com/iemr/mmu/service/dataSyncActivity/UploadDataToServerImpl.java b/src/main/java/com/iemr/mmu/service/dataSyncActivity/UploadDataToServerImpl.java index 266d3d28..f0764baa 100644 --- a/src/main/java/com/iemr/mmu/service/dataSyncActivity/UploadDataToServerImpl.java +++ b/src/main/java/com/iemr/mmu/service/dataSyncActivity/UploadDataToServerImpl.java @@ -88,6 +88,7 @@ public class UploadDataToServerImpl implements UploadDataToServer { private SyncUtilityClassRepo syncutilityClassRepo; @Autowired private CookieUtil cookieUtil; +boolean criticalTableFailure = false; // Add this flag /** * @@ -242,19 +243,22 @@ private String startDataSync(int vanID, String user, String Authorization, Strin } } - // Determine table status based on success/failure counts - String tableStatus; - if (successfulRecords == totalRecords && failedRecords == 0) { - tableStatus = "success"; - } else if (failedRecords == totalRecords && successfulRecords == 0) { - tableStatus = "failed"; - groupHasFailures = true; - } else if (successfulRecords > 0 && failedRecords > 0) { - tableStatus = "partial"; - } else { - tableStatus = "failed"; // Default to failed if unclear - groupHasFailures = true; - } + String tableStatus; + +if (successfulRecords == totalRecords && failedRecords == 0) { + tableStatus = "success"; +} else if (failedRecords == totalRecords && successfulRecords == 0) { + tableStatus = "failed"; + criticalTableFailure = true; // Only critical failures stop sync + groupHasFailures = true; +} else if (successfulRecords > 0 && failedRecords > 0) { + tableStatus = "partial"; + groupHasFailures = true; // Group has issues but don't stop sync +} else { + tableStatus = "failed"; + criticalTableFailure = true; // Complete failure is critical + groupHasFailures = true; +} // Create detailed table info with failure reasons Map tableDetails = new HashMap<>(); @@ -289,11 +293,10 @@ private String startDataSync(int vanID, String user, String Authorization, Strin tableDetailsList.add(tableDetails); } - // If this table had critical failures, stop processing this group - if (tableHasError) { - hasSyncFailed = true; - break; - } + if (criticalTableFailure) { + hasSyncFailed = true; + break; +} } // Determine overall group status String groupStatus; @@ -438,6 +441,7 @@ public Map syncDataToServer(int vanID, String schemaName, String String requestOBJ = gson.toJson(dataMap); HttpEntity request = RestTemplateUtil.createRequestEntity(requestOBJ, Authorization, "datasync"); + logger.info("Request to sync data: " + requestOBJ); ResponseEntity response = restTemplate.exchange(dataSyncUploadUrl, HttpMethod.POST, request, String.class); diff --git a/src/main/java/com/iemr/mmu/service/dataSyncLayerCentral/DataSyncRepositoryCentral.java b/src/main/java/com/iemr/mmu/service/dataSyncLayerCentral/DataSyncRepositoryCentral.java index 6dba4611..3cb869e1 100644 --- a/src/main/java/com/iemr/mmu/service/dataSyncLayerCentral/DataSyncRepositoryCentral.java +++ b/src/main/java/com/iemr/mmu/service/dataSyncLayerCentral/DataSyncRepositoryCentral.java @@ -62,7 +62,7 @@ private JdbcTemplate getJdbcTemplate() { "t_ncdscreening", "t_ncdcare", "i_ben_flow_outreach", "t_covid19", "t_idrsdetails", "t_physicalactivity", "t_phy_generalexam", "t_phy_headtotoe", "t_sys_obstetric", "t_sys_gastrointestinal", "t_sys_cardiovascular", "t_sys_respiratory", "t_sys_centralnervous", "t_sys_musculoskeletalsystem", "t_sys_genitourinarysystem", - "t_ancdiagnosis", "t_ncddiagnosis", "t_pncdiagnosis", "t_benchefcomplaint", "t_benclinicalobservation", + "t_ancdiagnosis", "t_ncddiagnosis", "t_pncdiagnosis", "t_benchiefcomplaint", "t_benclinicalobservation", "t_prescription", "t_prescribeddrug", "t_lab_testorder", "t_benreferdetails", "t_lab_testresult", "t_physicalstockentry", "t_patientissue", "t_facilityconsumption", "t_itemstockentry", "t_itemstockexit", "t_benmedhistory", "t_femaleobstetrichistory", "t_benmenstrualdetails", diff --git a/src/main/java/com/iemr/mmu/service/dataSyncLayerCentral/GetDataFromVanAndSyncToDBImpl.java b/src/main/java/com/iemr/mmu/service/dataSyncLayerCentral/GetDataFromVanAndSyncToDBImpl.java index e338ba17..1f648198 100644 --- a/src/main/java/com/iemr/mmu/service/dataSyncLayerCentral/GetDataFromVanAndSyncToDBImpl.java +++ b/src/main/java/com/iemr/mmu/service/dataSyncLayerCentral/GetDataFromVanAndSyncToDBImpl.java @@ -21,7 +21,6 @@ */ package com.iemr.mmu.service.dataSyncLayerCentral; -import java.sql.SQLException; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Arrays; @@ -177,6 +176,23 @@ public String syncDataToServer(String requestOBJ, String Authorization) throws E private boolean syncTablesInGroup(String schemaName, String currentTableName, SyncUploadDataDigester originalDigester, List syncResults) { + + // Filter syncData for this specific table + List> filteredData = new ArrayList<>(); + for (Map map : originalDigester.getSyncData()) { + if (map.get("tableName") != null && + map.get("tableName").toString().equalsIgnoreCase(currentTableName)) { + filteredData.add(map); + } + } + + logger.info("Filtered {} records for table {}", filteredData.size(), currentTableName); + + if (filteredData.isEmpty()) { + logger.info("No data found for table: {}", currentTableName); + return true; // No data to sync is considered success + } + SyncUploadDataDigester tableSpecificDigester = new SyncUploadDataDigester(); tableSpecificDigester.setSchemaName(schemaName); tableSpecificDigester.setTableName(currentTableName); @@ -184,7 +200,8 @@ private boolean syncTablesInGroup(String schemaName, String currentTableName, tableSpecificDigester.setFacilityID(originalDigester.getFacilityID()); tableSpecificDigester.setVanAutoIncColumnName(originalDigester.getVanAutoIncColumnName()); tableSpecificDigester.setServerColumns(originalDigester.getServerColumns()); - tableSpecificDigester.setSyncData(originalDigester.getSyncData()); + tableSpecificDigester.setSyncData(filteredData); // Use filtered data + return performGenericTableSync(tableSpecificDigester, syncResults); } @@ -441,7 +458,7 @@ private boolean performGenericTableSync(SyncUploadDataDigester syncUploadDataDig // Add to syncResults first, then track the index int currentSyncResultIndex = syncResults.size(); syncResults.add(new SyncResult(schemaName, syncTableName, vanSerialNo, - syncUploadDataDigester.getSyncedBy(), true, null)); // Initially set as success + syncUploadDataDigester.getSyncedBy(), false, "Pending")); // Initially set as success if (recordCheck == 0) { // Record doesn't exist - INSERT @@ -466,8 +483,8 @@ private boolean performGenericTableSync(SyncUploadDataDigester syncUploadDataDig } } - boolean insertSuccess = true; - boolean updateSuccess = true; + boolean insertSuccess = false; + boolean updateSuccess = false; // Process INSERT operations if (!syncDataListInsert.isEmpty()) { @@ -477,47 +494,77 @@ private boolean performGenericTableSync(SyncUploadDataDigester syncUploadDataDig int[] insertResults = dataSyncRepositoryCentral.syncDataToCentralDB(schemaName, syncTableName, serverColumns, queryInsert, syncDataListInsert); - // Update syncResults based on insert results for (Map.Entry entry : insertIndexMap.entrySet()) { int syncResultIndex = entry.getKey(); int insertListIndex = entry.getValue(); - if (insertListIndex < insertResults.length && insertResults[insertListIndex] > 0) { - // Success - keep the existing success entry - logger.info("Successfully inserted record at index {}", insertListIndex); - } else { - // Failed - update the syncResults entry with concise reason - String vanSerialNo = String.valueOf(syncDataListInsert.get(insertListIndex)[vanSerialIndex]); - String conciseReason = "Insert failed (code: " + - (insertListIndex < insertResults.length ? insertResults[insertListIndex] : "unknown") - + ")"; + boolean success = insertListIndex < insertResults.length && insertResults[insertListIndex] > 0; - syncResults.set(syncResultIndex, new SyncResult(schemaName, syncTableName, vanSerialNo, + if (!success) { + String failedVanSerialNo = getVanSerialNo(syncDataListInsert.get(insertListIndex), + vanSerialIndex, + syncResults.get(syncResultIndex)); + String conciseReason = "Insert failed (code: " + + (insertListIndex < insertResults.length ? insertResults[insertListIndex] : "unknown") + + ")"; + syncResults.set(syncResultIndex, new SyncResult(schemaName, syncTableName, failedVanSerialNo, syncUploadDataDigester.getSyncedBy(), false, conciseReason)); insertSuccess = false; } + else { + // ADD THIS ELSE BLOCK + syncResults.set(syncResultIndex, new SyncResult(schemaName, syncTableName, + syncResults.get(syncResultIndex).getVanSerialNo(), + syncUploadDataDigester.getSyncedBy(), true, null)); +} } } catch (Exception e) { - insertSuccess = false; - logger.error("Exception during insert for table {}: {}", syncTableName, e.getMessage(), e); - - // Store the main error reason instead of complete exception message - String mainErrorReason = extractMainErrorReason(e); - - // Update all insert-related syncResults to failed with concise error message - for (Map.Entry entry : insertIndexMap.entrySet()) { - int syncResultIndex = entry.getKey(); - int insertListIndex = entry.getValue(); - String vanSerialNo = String.valueOf(syncDataListInsert.get(insertListIndex)[vanSerialIndex]); - - syncResults.set(syncResultIndex, new SyncResult(schemaName, syncTableName, vanSerialNo, - syncUploadDataDigester.getSyncedBy(), false, "INSERT: " + mainErrorReason)); - } + String mainErrorReason = extractMainErrorReason(e); + + // Check if we can get partial results even with an exception + try { + // Try to check which records actually made it to the database + for (Map.Entry entry : insertIndexMap.entrySet()) { + int syncResultIndex = entry.getKey(); + int insertListIndex = entry.getValue(); + + String vanSerialNo = getVanSerialNo(syncDataListInsert.get(insertListIndex), vanSerialIndex, + syncResults.get(syncResultIndex)); + int vanIDIndex = serverColumnsList.indexOf("VanID"); + String vanID = vanIDIndex >= 0 && vanIDIndex < syncDataListInsert.get(insertListIndex).length + ? String.valueOf(syncDataListInsert.get(insertListIndex)[vanIDIndex]) + : null; + + // Check if this specific record exists in DB now (it might have succeeded before the exception) + int recordExists = dataSyncRepositoryCentral.checkRecordIsAlreadyPresentOrNot( + schemaName, syncTableName, vanSerialNo, vanID, vanAutoIncColumnName, 0); + + if (recordExists > 0) { + // Record exists - it was actually inserted successfully + syncResults.set(syncResultIndex, new SyncResult(schemaName, syncTableName, vanSerialNo, + syncUploadDataDigester.getSyncedBy(), true, null)); + } else { + // Record doesn't exist - it failed + syncResults.set(syncResultIndex, new SyncResult(schemaName, syncTableName, vanSerialNo, + syncUploadDataDigester.getSyncedBy(), false, "INSERT: " + mainErrorReason)); } } + } catch (Exception checkException) { + // If we can't check, mark all as failed + for (Map.Entry entry : insertIndexMap.entrySet()) { + int syncResultIndex = entry.getKey(); + int insertListIndex = entry.getValue(); + String vanSerialNo = getVanSerialNo(syncDataListInsert.get(insertListIndex), vanSerialIndex, + syncResults.get(syncResultIndex)); + syncResults.set(syncResultIndex, new SyncResult(schemaName, syncTableName, vanSerialNo, + syncUploadDataDigester.getSyncedBy(), false, "INSERT: " + mainErrorReason)); + } + } + insertSuccess = false; +} + } - // Process UPDATE operations if (!syncDataListUpdate.isEmpty()) { String queryUpdate = getQueryToUpdateDataToServerDB(schemaName, serverColumns, syncTableName); @@ -525,50 +572,88 @@ private boolean performGenericTableSync(SyncUploadDataDigester syncUploadDataDig int[] updateResults = dataSyncRepositoryCentral.syncDataToCentralDB(schemaName, syncTableName, serverColumns, queryUpdate, syncDataListUpdate); - // Update syncResults based on update results for (Map.Entry entry : updateIndexMap.entrySet()) { int syncResultIndex = entry.getKey(); int updateListIndex = entry.getValue(); - if (updateListIndex < updateResults.length && updateResults[updateListIndex] > 0) { - // Success - keep the existing success entry - logger.info("Successfully updated record at index {}", updateListIndex); - } else { - // Failed - update the syncResults entry with concise reason - String vanSerialNo = String.valueOf(syncDataListUpdate.get(updateListIndex)[vanSerialIndex]); - String conciseReason = "Update failed (code: " + - (updateListIndex < updateResults.length ? updateResults[updateListIndex] : "unknown") - + ")"; + boolean success = updateListIndex < updateResults.length && updateResults[updateListIndex] > 0; - syncResults.set(syncResultIndex, new SyncResult(schemaName, syncTableName, vanSerialNo, + if (!success) { + String failedVanSerialNo = getVanSerialNo(syncDataListUpdate.get(updateListIndex), + vanSerialIndex, + syncResults.get(syncResultIndex)); + String conciseReason = "Update failed (code: " + + (updateListIndex < updateResults.length ? updateResults[updateListIndex] : "unknown") + + ")"; + syncResults.set(syncResultIndex, new SyncResult(schemaName, syncTableName, failedVanSerialNo, syncUploadDataDigester.getSyncedBy(), false, conciseReason)); updateSuccess = false; } + else { + // ADD THIS ELSE BLOCK + syncResults.set(syncResultIndex, new SyncResult(schemaName, syncTableName, + syncResults.get(syncResultIndex).getVanSerialNo(), + syncUploadDataDigester.getSyncedBy(), true, null)); +} } } catch (Exception e) { - updateSuccess = false; - logger.error("Exception during update for table {}: {}", syncTableName, e.getMessage(), e); - - // Store the main error reason instead of complete exception message - String mainErrorReason = extractMainErrorReason(e); - - // Update all update-related syncResults to failed with concise error message - for (Map.Entry entry : updateIndexMap.entrySet()) { - int syncResultIndex = entry.getKey(); - int updateListIndex = entry.getValue(); - String vanSerialNo = String.valueOf(syncDataListUpdate.get(updateListIndex)[vanSerialIndex]); - - syncResults.set(syncResultIndex, new SyncResult(schemaName, syncTableName, vanSerialNo, - syncUploadDataDigester.getSyncedBy(), false, "UPDATE: " + mainErrorReason)); - } + String mainErrorReason = extractMainErrorReason(e); + + // Check if we can get partial results even with an exception + try { + // Try to check which records actually made it to the database + for (Map.Entry entry : updateIndexMap.entrySet()) { + int syncResultIndex = entry.getKey(); + int updateListIndex = entry.getValue(); + + String vanSerialNo = getVanSerialNo(syncDataListUpdate.get(updateListIndex), vanSerialIndex, + syncResults.get(syncResultIndex)); + int vanIDIndex = serverColumnsList.indexOf("VanID"); + String vanID = vanIDIndex >= 0 && vanIDIndex < syncDataListUpdate.get(updateListIndex).length + ? String.valueOf(syncDataListUpdate.get(updateListIndex)[vanIDIndex]) + : null; + + // Check if this specific record was actually updated in DB + int recordExists = dataSyncRepositoryCentral.checkRecordIsAlreadyPresentOrNot( + schemaName, syncTableName, vanSerialNo, vanID, vanAutoIncColumnName, 0); + + if (recordExists > 0) { + // Record exists and was likely updated successfully + syncResults.set(syncResultIndex, new SyncResult(schemaName, syncTableName, vanSerialNo, + syncUploadDataDigester.getSyncedBy(), true, null)); + } else { + // Record doesn't exist or update failed + syncResults.set(syncResultIndex, new SyncResult(schemaName, syncTableName, vanSerialNo, + syncUploadDataDigester.getSyncedBy(), false, "UPDATE: " + mainErrorReason)); } } + } catch (Exception checkException) { + // If we can't check, mark all as failed + for (Map.Entry entry : updateIndexMap.entrySet()) { + int syncResultIndex = entry.getKey(); + int updateListIndex = entry.getValue(); + String vanSerialNo = getVanSerialNo(syncDataListUpdate.get(updateListIndex), vanSerialIndex, + syncResults.get(syncResultIndex)); + syncResults.set(syncResultIndex, new SyncResult(schemaName, syncTableName, vanSerialNo, + syncUploadDataDigester.getSyncedBy(), false, "UPDATE: " + mainErrorReason)); + } + } + updateSuccess = false; +} + } logger.info("Sync results for table {}: {}", syncTableName, syncResults); return insertSuccess && updateSuccess; } + private String getVanSerialNo(Object[] record, int vanSerialIndex, SyncResult originalResult) { + if (vanSerialIndex >= 0 && vanSerialIndex < record.length) { + return String.valueOf(record[vanSerialIndex]); + } + return originalResult.getVanSerialNo() != null ? originalResult.getVanSerialNo() : "UNKNOWN"; + } + // Helper method to extract concise but meaningful error message private String extractMainErrorReason(Exception e) { if (e == null) { @@ -682,7 +767,6 @@ private String getQueryToInsertDataToServerDB(String schemaName, String tableNam queryBuilder.append(") VALUES ("); queryBuilder.append(preparedStatementSetter); queryBuilder.append(")"); - logger.info("Test Query Builder: {}", queryBuilder.toString()); return queryBuilder.toString(); }