use of org.dcm4che3.data.IDWithIssuer in project dcm4chee-arc-light by dcm4che.
the class ApplyHL7RetentionPolicy method apply.
private void apply(HL7ConnectionEvent event, HL7StudyRetentionPolicy policy, HL7Fields hl7Fields) {
LOG.info("{}: Apply {}:", event.getSocket(), policy);
IDWithIssuer pid = new IDWithIssuer(hl7Fields.get("PID-3", null));
ArchiveDeviceExtension arcdev = device.getDeviceExtensionNotNull(ArchiveDeviceExtension.class);
ApplicationEntity ae = device.getApplicationEntity(policy.getAETitle(), true);
QueryParam queryParam = queryParam(policy, ae);
QueryContext queryCtx = queryService.newQueryContext(ae, queryParam);
queryCtx.setQueryRetrieveLevel(QueryRetrieveLevel2.STUDY);
queryCtx.setPatientIDs(pid);
queryCtx.setQueryKeys(new Attributes(0));
queryCtx.setReturnPrivate(true);
try (Query query = queryService.createStudyQuery(queryCtx)) {
query.executeQuery(arcdev.getQueryFetchSize());
while (query.hasMoreMatches()) {
Attributes match = query.nextMatch();
if (match != null)
updateExpirationDate(event, policy, match);
}
} catch (Exception e) {
LOG.warn("{}: Failed to apply {}:\n", event.getSocket(), policy, e);
}
}
use of org.dcm4che3.data.IDWithIssuer in project dcm4chee-arc-light by dcm4che.
the class PamRS method updatePatient.
@PUT
@Path("/patients/{priorPatientID}")
@Consumes("application/dicom+json,application/json")
public void updatePatient(@PathParam("priorPatientID") IDWithIssuer priorPatientID, @QueryParam("merge") @Pattern(regexp = "true|false") @DefaultValue("false") String merge, InputStream in) {
ArchiveAEExtension arcAE = getArchiveAE();
PatientMgtContext ctx = patientMgtCtx(in);
ctx.setArchiveAEExtension(arcAE);
IDWithIssuer targetPatientID = ctx.getPatientID();
if (targetPatientID == null)
throw new WebApplicationException(errResponse("missing Patient ID in message body", Response.Status.BAD_REQUEST));
boolean mergePatients = Boolean.parseBoolean(merge);
boolean patientMatch = priorPatientID.equals(targetPatientID);
if (patientMatch && mergePatients)
throw new WebApplicationException(errResponse("Circular Merge of Patients not allowed.", Response.Status.BAD_REQUEST));
RSOperation rsOp = RSOperation.CreatePatient;
String msgType = "ADT^A28^ADT_A05";
try {
if (patientMatch) {
patientService.updatePatient(ctx);
if (ctx.getEventActionCode().equals(AuditMessages.EventActionCode.Update)) {
rsOp = RSOperation.UpdatePatient;
msgType = "ADT^A31^ADT_A05";
}
} else {
ctx.setPreviousAttributes(priorPatientID.exportPatientIDWithIssuer(null));
if (mergePatients) {
msgType = "ADT^A40^ADT_A39";
rsOp = RSOperation.MergePatient2;
patientService.mergePatient(ctx);
} else {
msgType = "ADT^A47^ADT_A30";
rsOp = RSOperation.ChangePatientID2;
patientService.changePatientID(ctx);
}
}
if (ctx.getEventActionCode().equals(AuditMessages.EventActionCode.Read))
return;
rsForward.forward(rsOp, arcAE, ctx.getAttributes(), request);
notifyHL7Receivers(msgType, ctx);
} catch (PatientAlreadyExistsException | NonUniquePatientException | PatientTrackingNotAllowedException | CircularPatientMergeException e) {
throw new WebApplicationException(errResponse(e.getMessage(), Response.Status.CONFLICT));
} catch (PatientMergedException e) {
throw new WebApplicationException(errResponse(e.getMessage(), Response.Status.FORBIDDEN));
} catch (Exception e) {
throw new WebApplicationException(errResponseAsTextPlain(exceptionAsString(e), Response.Status.INTERNAL_SERVER_ERROR));
}
}
use of org.dcm4che3.data.IDWithIssuer in project dcm4chee-arc-light by dcm4che.
the class PamRS method supplementIssuer.
@POST
@Path("/patients/issuer/{issuer}")
public Response supplementIssuer(@PathParam("issuer") AttributesFormat issuer, @QueryParam("test") @Pattern(regexp = "true|false") @DefaultValue("false") String test) {
ArchiveAEExtension arcAE = getArchiveAE();
Set<IDWithIssuer> success = new HashSet<>();
Map<IDWithIssuer, Long> ambiguous = new HashMap<>();
Map<String, String> failures = new HashMap<>();
try {
QueryAttributes queryAttrs = new QueryAttributes(uriInfo, null);
Attributes queryKeys = queryAttrs.getQueryKeys();
if (queryKeys.getString(Tag.IssuerOfPatientID) != null || queryKeys.getNestedDataset(Tag.IssuerOfPatientIDQualifiersSequence) != null)
return errResponse("Issuer of Patient ID or Issuer of Patient ID Qualifiers Sequence not allowed in query filters", Response.Status.BAD_REQUEST);
CriteriaQuery<Patient> query = queryService.createPatientWithUnknownIssuerQuery(queryParam(arcAE.getApplicationEntity(), true), queryKeys);
String toManyDuplicates = null;
int supplementIssuerFetchSize = arcAE.getArchiveDeviceExtension().getSupplementIssuerFetchSize();
boolean testIssuer = Boolean.parseBoolean(test);
if (testIssuer) {
patientService.testSupplementIssuers(query, supplementIssuerFetchSize, success, ambiguous, issuer);
} else {
Set<Long> failedPks = new HashSet<>();
boolean remaining;
int carry = 0;
do {
int limit = supplementIssuerFetchSize + failedPks.size() + carry;
List<Patient> matches = patientService.queryWithOffsetAndLimit(query, 0, limit);
remaining = matches.size() == limit;
matches.removeIf(p -> failedPks.contains(p.getPk()));
if (matches.isEmpty())
break;
carry = 0;
if (remaining) {
try {
ListIterator<Patient> itr = matches.listIterator(matches.size());
toManyDuplicates = itr.previous().getPatientID().getID();
do {
itr.remove();
carry++;
} while (toManyDuplicates.equals(itr.previous().getPatientID().getID()));
toManyDuplicates = null;
} catch (NoSuchElementException e) {
break;
}
}
matches.stream().collect(Collectors.groupingBy(p -> new IDWithIssuer(p.getPatientID().getID(), issuer.format(p.getAttributes())))).forEach((idWithIssuer, patients) -> {
if (patients.size() > 1) {
ambiguous.put(idWithIssuer, Long.valueOf(patients.size()));
patients.stream().map(Patient::getPk).forEach(failedPks::add);
} else {
Patient patient = patients.get(0);
try {
if (patientService.supplementIssuer(patientMgtCtx(), patient, idWithIssuer, ambiguous)) {
success.add(idWithIssuer);
} else {
failedPks.add(patient.getPk());
}
} catch (Exception e) {
failures.put(idWithIssuer.toString(), e.getMessage());
failedPks.add(patient.getPk());
}
}
});
} while (remaining && failedPks.size() < supplementIssuerFetchSize);
if (!success.isEmpty())
rsForward.forward(RSOperation.SupplementIssuer, arcAE, null, request);
}
return supplementIssuerResponse(success, ambiguous, failures, toManyDuplicates).build();
} catch (Exception e) {
return errResponseAsTextPlain(exceptionAsString(e), Response.Status.INTERNAL_SERVER_ERROR);
}
}
use of org.dcm4che3.data.IDWithIssuer in project dcm4chee-arc-light by dcm4che.
the class PamRS method changePatientID.
@POST
@Path("/patients/{priorPatientID}/changeid/{patientID}")
public void changePatientID(@PathParam("priorPatientID") IDWithIssuer priorPatientID, @PathParam("patientID") IDWithIssuer patientID) {
ArchiveAEExtension arcAE = getArchiveAE();
try {
Patient prevPatient = patientService.findPatient(priorPatientID);
PatientMgtContext ctx = patientService.createPatientMgtContextWEB(HttpServletRequestInfo.valueOf(request));
ctx.setArchiveAEExtension(arcAE);
ctx.setAttributeUpdatePolicy(Attributes.UpdatePolicy.REPLACE);
ctx.setPreviousAttributes(priorPatientID.exportPatientIDWithIssuer(null));
ctx.setAttributes(patientID.exportPatientIDWithIssuer(prevPatient.getAttributes()));
patientService.changePatientID(ctx);
notifyHL7Receivers("ADT^A47^ADT_A30", ctx);
rsForward.forward(RSOperation.ChangePatientID, arcAE, null, request);
} catch (PatientAlreadyExistsException | NonUniquePatientException | PatientTrackingNotAllowedException | CircularPatientMergeException e) {
throw new WebApplicationException(errResponse(e.getMessage(), Response.Status.CONFLICT));
} catch (PatientMergedException e) {
throw new WebApplicationException(e.getMessage(), Response.Status.FORBIDDEN);
} catch (Exception e) {
throw new WebApplicationException(errResponseAsTextPlain(exceptionAsString(e), Response.Status.INTERNAL_SERVER_ERROR));
}
}
use of org.dcm4che3.data.IDWithIssuer in project dcm4chee-arc-light by dcm4che.
the class PamRS method mergePatient.
@POST
@Path("/patients/{priorPatientID}/merge/{patientID}")
public void mergePatient(@PathParam("priorPatientID") IDWithIssuer priorPatientID, @PathParam("patientID") IDWithIssuer patientID, @QueryParam("verify") String findSCP) {
ArchiveAEExtension arcAE = getArchiveAE();
try {
if (findSCP != null)
verifyMergePatient(priorPatientID, patientID, findSCP, cfindscu, arcAE.getApplicationEntity());
mergePatient(patientID, priorPatientID.exportPatientIDWithIssuer(null), arcAE);
rsForward.forward(RSOperation.MergePatient, arcAE, null, request);
} catch (NonUniquePatientException | PatientMergedException | CircularPatientMergeException | VerifyMergePatientException e) {
throw new WebApplicationException(errResponse(e.getMessage(), Response.Status.CONFLICT));
} catch (Exception e) {
throw new WebApplicationException(errResponseAsTextPlain(exceptionAsString(e), Response.Status.INTERNAL_SERVER_ERROR));
}
}
Aggregations