in import/src/main/java/com/google/cloud/healthcare/imaging/dicomadapter/CMoveService.java [85:193]
public void run() {
List<String> failedInstanceUids = new ArrayList<>();
ISender sender = null;
try {
if (canceled) {
throw new CancellationException();
}
runThread = Thread.currentThread();
AetDictionary.Aet cstoreTarget = aets.getAet(cmd.getString(Tag.MoveDestination));
if (cstoreTarget == null) {
sendErrorResponse(Status.MoveDestinationUnknown,
"Unknown AET: " + cmd.getString(Tag.MoveDestination));
return;
}
// need to get instances belonging to series/study
Attributes keysCopy = new Attributes(keys);
keysCopy.setString(Tag.QueryRetrieveLevel, VR.CS, "IMAGE");
String qidoPath;
try {
qidoPath = AttributesUtil.attributesToQidoPath(keysCopy);
log.info("CMove QidoPath: " + qidoPath);
} catch (DicomServiceException e) {
log.error("CMove QidoPath error");
sendErrorResponse(e.getStatus(), e.getMessage(), null);
return;
}
JSONArray qidoResult;
try {
MonitoringService.addEvent(Event.CMOVE_QIDORS_REQUEST);
qidoResult = dicomWebClient.qidoRs(qidoPath);
if (qidoResult == null || qidoResult.length() == 0) {
throw new IDicomWebClient.DicomWebException("No instances to move",
Status.UnableToCalculateNumberOfMatches);
}
} catch (IDicomWebClient.DicomWebException e) {
MonitoringService.addEvent(Event.CMOVE_QIDORS_ERROR);
log.error("CMove Qido-rs error", e);
sendErrorResponse(e.getStatus(), e.getMessage());
return;
}
sender = senderFactory.create();
int successfullInstances = 0;
int remainingInstances = qidoResult.length();
for (Object instance : qidoResult) {
sendPendingResponse(remainingInstances, successfullInstances, failedInstanceUids.size());
if (canceled) {
throw new CancellationException();
}
JSONObject instanceJson = (JSONObject) instance;
String studyUid = AttributesUtil.getTagValue(instanceJson,
TagUtils.toHexString(Tag.StudyInstanceUID));
String seriesUid = AttributesUtil.getTagValue(instanceJson,
TagUtils.toHexString(Tag.SeriesInstanceUID));
String instanceUid = AttributesUtil.getTagValue(instanceJson,
TagUtils.toHexString(Tag.SOPInstanceUID));
String classUid = AttributesUtil.getTagValue(instanceJson,
TagUtils.toHexString(Tag.SOPClassUID));
try {
MonitoringService.addEvent(Event.CMOVE_CSTORE_REQUEST);
long bytesSent = sender.cmove(cstoreTarget, studyUid, seriesUid,
instanceUid, classUid);
successfullInstances++;
MonitoringService.addEvent(Event.CMOVE_CSTORE_BYTES, bytesSent);
} catch (IDicomWebClient.DicomWebException | IOException e) {
MonitoringService.addEvent(Event.CMOVE_CSTORE_ERROR);
log.error("Failed CStore within CMove", e);
failedInstanceUids.add(instanceUid);
}
remainingInstances--;
}
if (failedInstanceUids.isEmpty()) {
as.tryWriteDimseRSP(pc, Commands.mkCMoveRSP(cmd, Status.Success));
} else {
int status = successfullInstances > 0 ?
Status.OneOrMoreFailures : Status.UnableToPerformSubOperations;
sendErrorResponse(status, failedInstanceUids);
}
} catch (CancellationException | InterruptedException e) {
log.info("Canceled CMove", e);
sendErrorResponse(Status.Cancel, failedInstanceUids);
} catch (Throwable e) {
log.error("Failure processing CMove", e);
sendErrorResponse(Status.ProcessingFailure, e.getMessage());
} finally {
synchronized (this) {
runThread = null;
}
int msgId = cmd.getInt(Tag.MessageID, -1);
as.removeCancelRQHandler(msgId);
if (sender != null) {
try {
sender.close();
} catch (IOException e) {
log.error("Failure closing cstoreSender: ", e);
}
}
}
}