diff --git a/pom.xml b/pom.xml index a0050bb0..9d4936f3 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ - 1.0.54 + 1.0.58 jar @@ -32,8 +32,8 @@ 3.0.0 1.6.2 21.0.9 - 5.27.0.1 - 4.5.5-dcm + 5.29.0.2 + 4.6.0-dcm 1.6.0 4.2.0 1.4.200 diff --git a/src/main/java/org/karnak/backend/service/ForwardService.java b/src/main/java/org/karnak/backend/service/ForwardService.java index 48d5fcee..18082f3e 100644 --- a/src/main/java/org/karnak/backend/service/ForwardService.java +++ b/src/main/java/org/karnak/backend/service/ForwardService.java @@ -18,7 +18,6 @@ import org.dcm4che3.data.Attributes; import org.dcm4che3.data.Tag; import org.dcm4che3.data.UID; -import org.dcm4che3.img.DicomOutputData; import org.dcm4che3.img.op.MaskArea; import org.dcm4che3.img.stream.BytesWithImageDescriptor; import org.dcm4che3.img.stream.ImageAdapter; @@ -62,11 +61,10 @@ @Service public class ForwardService { - private static final String ERROR_WHEN_FORWARDING = - "Error when forwarding to the final destination"; - private static final Logger LOGGER = LoggerFactory.getLogger(ForwardService.class); + private static final String ERROR_WHEN_FORWARDING = "Error when forwarding to the final destination"; + private final ApplicationEventPublisher applicationEventPublisher; @Autowired @@ -75,10 +73,11 @@ public ForwardService(final ApplicationEventPublisher applicationEventPublisher) } public void storeMultipleDestination( - ForwardDicomNode fwdNode, List destList, Params p) throws IOException { - if (destList == null || destList.isEmpty()) { + ForwardDicomNode forwardNode, List destinations, Params p) + throws IOException { + if (destinations == null || destinations.isEmpty()) { throw new IllegalStateException( - "Cannot find the DICOM destination from " + fwdNode.toString()); + "Cannot find destinations from " + forwardNode.toString()); } // Exclude DICOMDIR if ("1.2.840.10008.1.3.10".equals(p.getCuid())) { @@ -86,104 +85,73 @@ public void storeMultipleDestination( return; } - if (destList.size() == 1) { - storeOneDestination(fwdNode, destList.get(0), p); - } else { - List destConList = new ArrayList<>(); - for (ForwardDestination fwDest : destList) { - try { - if (fwDest instanceof DicomForwardDestination) { - prepareTransfer((DicomForwardDestination) fwDest, p); - } - destConList.add(fwDest); - } catch (Exception e) { - LOGGER.error("Cannot connect to the final destination", e); - } + // Prepare and transfer files + Attributes attributes = new Attributes(); + List files = new ArrayList<>(); + try { + int nbDestinations = destinations.size(); + for (int i = 0; i < nbDestinations; i++) { + prepareAndTransfer(forwardNode, p, i, destinations.get(i), attributes, + nbDestinations, files); } - - if (destConList.isEmpty()) { - return; - } else if (destConList.size() == 1) { - storeOneDestination(fwdNode, destConList.get(0), p); - } else { - List files = null; - try { - Attributes attributes = new Attributes(); - ForwardDestination fistDest = destConList.get(0); - if (fistDest instanceof DicomForwardDestination) { - files = transfer(fwdNode, (DicomForwardDestination) fistDest, attributes, p); - } else if (fistDest instanceof WebForwardDestination) { - files = transfer(fwdNode, (WebForwardDestination) fistDest, attributes, p); - } - if (!attributes.isEmpty()) { - for (int i = 1; i < destConList.size(); i++) { - ForwardDestination dest = destConList.get(i); - if (dest instanceof DicomForwardDestination) { - transferOther(fwdNode, (DicomForwardDestination) dest, attributes, p); - } else if (dest instanceof WebForwardDestination) { - transferOther(fwdNode, (WebForwardDestination) dest, attributes, p); - } - } - } - } finally { - if (files != null) { - // Force to clean if tmp bulk files - for (File file : files) { - FileUtil.delete(file); - } - } + } catch (IOException e) { + LOGGER.error("Cannot connect to the final destination", e); + throw e; + } finally { + if (!files.isEmpty()) { + // Force to clean if tmp bulk files + for (File file : files) { + FileUtil.delete(file); } } } } - public void storeOneDestination( - ForwardDicomNode fwdNode, ForwardDestination destination, Params p) throws IOException { + /** + * Prepare and transfer files + * + * @param fwdNode Forward node + * @param p Params + * @param index Current index + * @param destination Destination + * @param attributes Attributes + * @param nbDestinations Number of destinations to handle + * @param files Temp files to delete + */ + private void prepareAndTransfer(ForwardDicomNode fwdNode, Params p, int index, + ForwardDestination destination, Attributes attributes, int nbDestinations, List files) + throws IOException { if (destination instanceof DicomForwardDestination) { - DicomForwardDestination dest = (DicomForwardDestination) destination; - prepareTransfer(dest, p); - transfer(fwdNode, dest, null, p); - } else if (destination instanceof WebForwardDestination) { - transfer(fwdNode, (WebForwardDestination) destination, null, p); + // Prepare transfer only for dicom destination + prepareTransfer((DicomForwardDestination) destination, p); + } + if (index == 0) { + // Case first iteration: handle first destination of the forward node + Attributes attToApply = nbDestinations > 1 ? attributes : null; + if (destination instanceof DicomForwardDestination) { + files.addAll(transfer(fwdNode, (DicomForwardDestination) destination, attToApply, p)); + } else if (destination instanceof WebForwardDestination) { + files.addAll(transfer(fwdNode, (WebForwardDestination) destination, attToApply, p)); + } + } else { + // Case other iterations: handle other destinations of the forward node + if (!attributes.isEmpty()) { + if (destination instanceof DicomForwardDestination) { + transferOther(fwdNode, (DicomForwardDestination) destination, attributes, p); + } else if (destination instanceof WebForwardDestination) { + transferOther(fwdNode, (WebForwardDestination) destination, attributes, p); + } + } } } - public static synchronized StoreFromStreamSCU prepareTransfer( + public static StoreFromStreamSCU prepareTransfer( DicomForwardDestination destination, Params p) throws IOException { String cuid = p.getCuid(); String tsuid = p.getTsuid(); String dstTsuid = destination.getOutputTransferSyntax(tsuid); StoreFromStreamSCU streamSCU = destination.getStreamSCU(); - - if (streamSCU.hasAssociation()) { - // Handle dynamically new SOPClassUID - Set tss = streamSCU.getTransferSyntaxesFor(cuid); - if (!tss.contains(dstTsuid)) { - streamSCU.close(true); - } - - // Add Presentation Context for the association - streamSCU.addData(cuid, dstTsuid); - if (DicomOutputData.isAdaptableSyntax(dstTsuid)) { - streamSCU.addData(cuid, UID.JPEGLosslessSV1); - } - - if (!streamSCU.isReadyForDataTransfer()) { - // If connection has been closed just reopen - streamSCU.open(); - } - } else { - destination.getStreamSCUService().start(); - // Add Presentation Context for the association - streamSCU.addData(cuid, dstTsuid); - if (!dstTsuid.equals(UID.ExplicitVRLittleEndian)) { - streamSCU.addData(cuid, UID.ExplicitVRLittleEndian); - } - if (DicomOutputData.isAdaptableSyntax(dstTsuid)) { - streamSCU.addData(cuid, UID.JPEGLosslessSV1); - } - streamSCU.open(); - } + streamSCU.prepareTransfer(destination.getStreamSCUService(), p.getIuid(), cuid, dstTsuid); return streamSCU; } @@ -250,7 +218,7 @@ public List transfer( launchCStore(p, streamSCU, dataWriter, cuid, iuid, syntax, transformedPlanarImage); progressNotify( - destination, p.getIuid(), p.getCuid(), false, streamSCU.getNumberOfSuboperations()); + destination, p.getIuid(), p.getCuid(), false, streamSCU); monitor( sourceNode.getId(), destination.getId(), @@ -260,7 +228,7 @@ public List transfer( null); } catch (AbortException e) { progressNotify( - destination, p.getIuid(), p.getCuid(), true, streamSCU.getNumberOfSuboperations()); + destination, p.getIuid(), p.getCuid(), true, streamSCU); monitor( sourceNode.getId(), destination.getId(), @@ -273,7 +241,7 @@ public List transfer( } } catch (IOException e) { progressNotify( - destination, p.getIuid(), p.getCuid(), true, streamSCU.getNumberOfSuboperations()); + destination, p.getIuid(), p.getCuid(), true, streamSCU); monitor( sourceNode.getId(), destination.getId(), @@ -287,7 +255,7 @@ public List transfer( Thread.currentThread().interrupt(); } progressNotify( - destination, p.getIuid(), p.getCuid(), true, streamSCU.getNumberOfSuboperations()); + destination, p.getIuid(), p.getCuid(), true, streamSCU); monitor( sourceNode.getId(), destination.getId(), @@ -427,12 +395,12 @@ public void transferOther( launchCStore(p, streamSCU, dataWriter, cuid, iuid, syntax, transformedPlanarImage); progressNotify( - destination, p.getIuid(), p.getCuid(), false, streamSCU.getNumberOfSuboperations()); + destination, p.getIuid(), p.getCuid(), false, streamSCU); monitor( fwdNode.getId(), destination.getId(), attributesOriginal, attributesToSend, true, null); } catch (AbortException e) { progressNotify( - destination, p.getIuid(), p.getCuid(), true, streamSCU.getNumberOfSuboperations()); + destination, p.getIuid(), p.getCuid(), true, streamSCU); monitor( fwdNode.getId(), destination.getId(), @@ -445,7 +413,7 @@ public void transferOther( } } catch (IOException e) { progressNotify( - destination, p.getIuid(), p.getCuid(), true, streamSCU.getNumberOfSuboperations()); + destination, p.getIuid(), p.getCuid(), true, streamSCU); monitor( fwdNode.getId(), destination.getId(), @@ -459,7 +427,7 @@ public void transferOther( Thread.currentThread().interrupt(); } progressNotify( - destination, p.getIuid(), p.getCuid(), true, streamSCU.getNumberOfSuboperations()); + destination, p.getIuid(), p.getCuid(), true, streamSCU); monitor( fwdNode.getId(), destination.getId(), @@ -680,6 +648,20 @@ public void transferOther( } } + private static void progressNotify( + ForwardDestination destination, String iuid, String cuid, boolean failed, + StoreFromStreamSCU streamSCU) { + streamSCU.removeIUIDProcessed(iuid); + ServiceUtil.notifyProgession( + destination.getState(), + iuid, + cuid, + failed ? Status.ProcessingFailure : Status.Success, + failed ? ProgressStatus.FAILED : ProgressStatus.COMPLETED, + streamSCU.getNumberOfSuboperations()); + } + + private static void progressNotify( ForwardDestination destination, String iuid, String cuid, boolean failed, int subOperations) { ServiceUtil.notifyProgession(