Skip to content

Commit

Permalink
Merge pull request #1092 from Shreeja-dev/main
Browse files Browse the repository at this point in the history
feat : remove redundant issues to align with FHIR OperationOutcome#1071
  • Loading branch information
ratheesh-kr authored Jan 23, 2025
2 parents e0eb1f1 + 6d7743c commit 10ec99c
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 296 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,12 @@ public ResponseEntity<Object> handleCsvUploadAndConversion(
@Parameter(description = "Parameter to specify the Tenant ID. This is a <b>mandatory</b> parameter.", required = true) @RequestHeader(value = Configuration.Servlet.HeaderName.Request.TENANT_ID, required = true) String tenantId,
@Parameter(description = "Parameter to specify origin of the request.", required = false) @RequestParam(value = "origin", required = false,defaultValue = "HTTP") String origin,
@Parameter(description = "Parameter to specify sftp session id.", required = false) @RequestParam(value = "sftp-session-id", required = false) String sftpSessionId,
@Parameter(description = "Optional parameter to specify if transformed validation issue needs to be appended.", required = false) @RequestParam(value = "append-validation-issue", required = false, defaultValue = "true") boolean appendValidationIssue,
HttpServletRequest request,
HttpServletResponse response) throws Exception {

validateFile(file);
validateTenantId(tenantId);
List<Object> processedFiles = csvService.processZipFile(file, request, response, tenantId, origin, sftpSessionId,appendValidationIssue);
List<Object> processedFiles = csvService.processZipFile(file, request, response, tenantId, origin, sftpSessionId);
return ResponseEntity.ok(processedFiles);

}
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public List<Object> processPayload(final String masterInteractionId,
final List<String> filesNotProcessed,
final HttpServletRequest request,
final HttpServletResponse response,
final String tenantId, final String originalFileName,boolean appendValidationIssue) {
final String tenantId, final String originalFileName) {
final List<Object> resultBundles = new ArrayList<>();
final List<Object> miscErrors = new ArrayList<>();
boolean isAllCsvConvertedToFhir = true;
Expand Down Expand Up @@ -103,7 +103,7 @@ public List<Object> processPayload(final String masterInteractionId,
resultBundles.addAll(processScreening(groupKey, demographicData, screeningProfileData,
qeAdminData, screeningObservationData, request, response, groupInteractionId,
masterInteractionId,
tenantId, outcome.isValid(), outcome, isAllCsvConvertedToFhir,appendValidationIssue));
tenantId, outcome.isValid(), outcome, isAllCsvConvertedToFhir));
}
} else {
isAllCsvConvertedToFhir = false;
Expand Down Expand Up @@ -295,7 +295,7 @@ private List<Object> processScreening(final String groupKey,
final String groupInteractionId,
final String masterInteractionId,
final String tenantId, final boolean isValid, final PayloadAndValidationOutcome payloadAndValidationOutcome,
boolean isAllCsvConvertedToFhir,boolean appendValidationIssue)
boolean isAllCsvConvertedToFhir)
throws IOException {

final List<Object> results = new ArrayList<>();
Expand Down Expand Up @@ -342,7 +342,7 @@ private List<Object> processScreening(final String groupKey,
request, response,
updatedProvenance,
true, null, interactionId, groupInteractionId,
masterInteractionId, SourceType.CSV.name(), null,appendValidationIssue));
masterInteractionId, SourceType.CSV.name(), null));
} else {
LOG.error("Bundle not generated for patient MrId: {}, interactionId: {}, masterInteractionId: {}, groupInteractionId :{}",
profile.getPatientMrIdValue(), interactionId, masterInteractionId,groupInteractionId);
Expand Down
4 changes: 2 additions & 2 deletions hub-prime/src/main/java/org/techbd/service/CsvService.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ private void saveArchiveInteraction(final org.jooq.Configuration jooqCfg, final
* @throws Exception If an error occurs during processing the zip file or CSV
* parsing.
*/
public List<Object> processZipFile(final MultipartFile file,final HttpServletRequest request ,HttpServletResponse response ,final String tenantId,String origin,String sftpSessionId,boolean appendValidationIssue) throws Exception {
public List<Object> processZipFile(final MultipartFile file,final HttpServletRequest request ,HttpServletResponse response ,final String tenantId,String origin,String sftpSessionId) throws Exception {
CsvOrchestrationEngine.OrchestrationSession session = null;
try {
final var dslContext = udiPrimeJpaConfig.dsl();
Expand All @@ -149,7 +149,7 @@ public List<Object> processZipFile(final MultipartFile file,final HttpServletReq
engine.orchestrate(session);
return csvBundleProcessorService.processPayload(masterInteractionId,
session.getPayloadAndValidationOutcomes(), session.getFilesNotProcessed(),request,
response,tenantId,file.getOriginalFilename(),appendValidationIssue);
response,tenantId,file.getOriginalFilename());
} finally {
if (null == session) {
engine.clear(session);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public Object processBundle(final @RequestBody @Nonnull String payload,
HttpServletRequest request, HttpServletResponse response, String provenance,
boolean includeOperationOutcome, String mtlsStrategy, String interactionId,
String groupInteractionId, String masterInteractionId, String sourceType,
String requestUriToBeOverriden, boolean appendValidationIssue)
String requestUriToBeOverriden)
throws IOException {
Span span = tracer.spanBuilder("FHIRService.processBundle").startSpan();
try {
Expand Down Expand Up @@ -151,8 +151,7 @@ public Object processBundle(final @RequestBody @Nonnull String payload,
try {
immediateResult = validate(request, payload, fhirProfileUrl,
uaValidationStrategyJson,
includeRequestInOutcome, interactionId, provenance, sourceType,
appendValidationIssue);
includeRequestInOutcome, interactionId, provenance, sourceType);
} finally {
validateSpan.end();
}
Expand All @@ -178,7 +177,7 @@ public Object processBundle(final @RequestBody @Nonnull String payload,
includeIncomingPayloadInDB, tenantId, payload,
provenance, null, includeOperationOutcome, mtlsStrategy,
interactionId, groupInteractionId, masterInteractionId,
sourceType, requestUriToBeOverriden, appendValidationIssue);
sourceType, requestUriToBeOverriden);
Instant end = Instant.now();
Duration timeElapsed = Duration.between(start, end);
LOG.info("Bundle processing end for interaction id: {} Time Taken : {} milliseconds",
Expand All @@ -191,8 +190,7 @@ public Object processBundle(final @RequestBody @Nonnull String payload,
includeIncomingPayloadInDB, tenantId, payload,
provenance, payloadWithDisposition, includeOperationOutcome,
mtlsStrategy, interactionId, groupInteractionId,
masterInteractionId, sourceType, requestUriToBeOverriden,
appendValidationIssue);
masterInteractionId, sourceType, requestUriToBeOverriden);
Instant end = Instant.now();
Duration timeElapsed = Duration.between(start, end);
LOG.info("Bundle processing end for interaction id: {} Time Taken : {} milliseconds",
Expand Down Expand Up @@ -423,8 +421,7 @@ private void setActiveInteraction(final @NonNull HttpServletRequest request,

private Map<String, Object> validate(HttpServletRequest request, String payload, String fhirProfileUrl,
String uaValidationStrategyJson,
boolean includeRequestInOutcome, String interactionId, String provenance, String sourceType,
boolean appendValidationIssue) {
boolean includeRequestInOutcome, String interactionId, String provenance, String sourceType) {
Span span = tracer.spanBuilder("FhirService.validate").startSpan();
try {
final var start = Instant.now();
Expand All @@ -434,7 +431,6 @@ private Map<String, Object> validate(HttpServletRequest request, String payload,
final var sessionBuilder = engine.session()
.withSessionId(UUID.randomUUID().toString())
.onDevice(Device.createDefault())
.withAppendValidationIssue(appendValidationIssue)
.withInteractionId(interactionId)
.withPayloads(List.of(payload))
.withFhirProfileUrl(fhirProfileUrl)
Expand Down Expand Up @@ -508,8 +504,7 @@ private void sendToScoringEngine(org.jooq.Configuration jooqCfg, HttpServletRequ
String provenance,
Map<String, Object> validationPayloadWithDisposition, boolean includeOperationOutcome,
String mtlsStrategy, String interactionId, String groupInteractionId,
String masterInteractionId, String sourceType, String requestUriToBeOverriden,
boolean appendValidationIssue) {
String masterInteractionId, String sourceType, String requestUriToBeOverriden) {
Span span = tracer.spanBuilder("FhirService.sentToScoringEngine").startSpan();
try {
interactionId = null != interactionId ? interactionId : getBundleInteractionId(request);
Expand All @@ -525,7 +520,7 @@ private void sendToScoringEngine(org.jooq.Configuration jooqCfg, HttpServletRequ
interactionId);
bundlePayloadWithDisposition = preparePayload(request,
payload,
validationPayloadWithDisposition, appendValidationIssue);
validationPayloadWithDisposition);
} else {
LOG.debug("FHIRService:: sendToScoringEngine Send payload without operation outcome interaction id: {}",
interactionId);
Expand Down Expand Up @@ -1202,16 +1197,15 @@ private void handleError(Map<String, Object> validationPayloadWithDisposition,
}

private Map<String, Object> preparePayload(HttpServletRequest request, String bundlePayload,
Map<String, Object> payloadWithDisposition, boolean appendValidationIssue) {
Map<String, Object> payloadWithDisposition) {
final var interactionId = getBundleInteractionId(request);
LOG.debug("FHIRService:: addValidationResultToPayload BEGIN for interaction id : {}", interactionId);

Map<String, Object> resultMap = null;

try {
Map<String, Object> extractedOutcome = Optional
.ofNullable(extractIssueAndDisposition(interactionId, payloadWithDisposition,
appendValidationIssue))
.ofNullable(extractIssueAndDisposition(interactionId, payloadWithDisposition))
.filter(outcome -> !outcome.isEmpty())
.orElseGet(() -> {
LOG.warn("FHIRService:: resource type operation outcome or issues or techByDisposition is missing or empty for interaction id : {}",
Expand Down Expand Up @@ -1254,7 +1248,7 @@ private Map<String, Object> preparePayload(HttpServletRequest request, String bu

@SuppressWarnings("unchecked")
public Map<String, Object> extractIssueAndDisposition(String interactionId,
Map<String, Object> operationOutcomePayload, boolean appendValidationIssue) {
Map<String, Object> operationOutcomePayload) {
LOG.debug("FHIRService:: extractResourceTypeAndDisposition BEGIN for interaction id : {}",
interactionId);

Expand All @@ -1280,74 +1274,14 @@ public Map<String, Object> extractIssueAndDisposition(String interactionId,
Map<String, Object> result = new HashMap<>();
result.put("resourceType", operationOutcomeMap.get("resourceType"));

// Get issues based on appendValidationIssue flag
if (appendValidationIssue) {
result.put("issue", validationResult.get("issues"));
} else {
Map<String, Object> operationOutcome = (Map<String, Object>) validationResult
.get("operationOutcome");
if (operationOutcome != null) {
result.put("issue", operationOutcome.get("issue"));
} else {
LOG.warn("FHIRService:: operationOutcome is missing in validationResult for interaction id : {}",
interactionId);
}
}

List<?> techByDesignDisposition = (List<?>) operationOutcomeMap
.get("techByDesignDisposition");
if (techByDesignDisposition != null && !techByDesignDisposition.isEmpty()) {
result.put("techByDesignDisposition", techByDesignDisposition);
}

return Optional.of(result);
})
.orElseGet(() -> {
LOG.warn("FHIRService:: Missing required fields in operationOutcome for interaction id : {}",
interactionId);
return null;
});
}

@SuppressWarnings("unchecked")
public Map<String, Object> extractIssueAndDisposition(String interactionId,
Map<String, Object> operationOutcomePayload) {
LOG.debug("FHIRService:: extractResourceTypeAndDisposition BEGIN for interaction id : {}",
interactionId);

if (operationOutcomePayload == null) {
LOG.warn("FHIRService:: operationOutcomePayload is null for interaction id : {}",
interactionId);
return null;
}

return Optional.ofNullable(operationOutcomePayload.get("OperationOutcome"))
.filter(Map.class::isInstance)
.map(Map.class::cast)
.flatMap(operationOutcomeMap -> {
List<?> validationResults = (List<?>) operationOutcomeMap
.get("validationResults");
if (validationResults == null || validationResults.isEmpty()) {
return Optional.empty();
}

// Extract the first validationResult
Map<String, Object> validationResult = (Map<String, Object>) validationResults
.get(0);

// Navigate to operationOutcome.issue
Map<String, Object> operationOutcome = (Map<String, Object>) validationResult
.get("operationOutcome");
List<?> issues = operationOutcome != null
? (List<?>) operationOutcome.get("issue")
: null;

// Prepare the result
Map<String, Object> result = new HashMap<>();
result.put("resourceType", operationOutcomeMap.get("resourceType"));
result.put("issue", issues);

// Add techByDesignDisposition if available
if (operationOutcome != null) {
result.put("issue", operationOutcome.get("issue"));
} else {
LOG.warn("FHIRService:: operationOutcome is missing in validationResult for interaction id : {}",
interactionId);
}
List<?> techByDesignDisposition = (List<?>) operationOutcomeMap
.get("techByDesignDisposition");
if (techByDesignDisposition != null && !techByDesignDisposition.isEmpty()) {
Expand Down
Loading

0 comments on commit 10ec99c

Please sign in to comment.