From 52c50f41acbe7e711b82850243520c04d0a7f541 Mon Sep 17 00:00:00 2001 From: Eduardo Pinho Date: Sat, 30 Sep 2023 10:23:12 +0100 Subject: [PATCH 1/5] [dicoogle][sdk] Update maven plugins - maven-compiler-plugin 3.11.0 - maven-shade-plugin 3.5.1 - maven-resources-plugin 3.3.1 - frontend-maven-plugin 1.14.0 - update nodeVersion to 18.17.1 and npmVersion to 9.6.7 - license-maven-plugin 4.3 - formatter-maven-plugin 2.12.2 --- dicoogle/pom.xml | 38 ++++++++++++++++++-------------- pom.xml | 27 ++++++++++++++--------- sdk/pom.xml | 56 +++++++++++++++++++++++++++--------------------- 3 files changed, 70 insertions(+), 51 deletions(-) diff --git a/dicoogle/pom.xml b/dicoogle/pom.xml index b64140b9b..b3d63fd00 100644 --- a/dicoogle/pom.xml +++ b/dicoogle/pom.xml @@ -105,7 +105,7 @@ org.apache.maven.plugins maven-shade-plugin - 2.3 + 3.5.1 package @@ -146,7 +146,7 @@ org.apache.maven.plugins maven-compiler-plugin - 2.3.2 + 3.11.0 ${project.build.sourceEncoding} 1.8 @@ -158,7 +158,7 @@ org.apache.maven.plugins maven-resources-plugin - 3.2.0 + 3.3.1 ${project.build.sourceEncoding} @@ -209,16 +209,22 @@ com.mycila license-maven-plugin - 2.4 + 4.3 -
../short-license.txt
- - **/*.java - - - **/package-info.java - - + + JAVADOC_STYLE + + + +
../short-license.txt
+ + **/*.java + + + **/package-info.java + +
+
@@ -232,7 +238,7 @@ net.revelc.code.formatter formatter-maven-plugin - 2.11.0 + 2.12.2 UTF-8 @@ -257,7 +263,7 @@ com.github.eirslett frontend-maven-plugin - 1.12.0 + 1.14.0 @@ -296,8 +302,8 @@ - v14.17.3 - 6.14.13 + v18.17.1 + 9.6.7 target src/main/resources/webapp diff --git a/pom.xml b/pom.xml index f498ed62e..0cf71c26d 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ org.apache.maven.plugins maven-compiler-plugin - 2.3.2 + 3.11.0 1.8 1.8 @@ -28,15 +28,22 @@ com.mycila license-maven-plugin - 2.4 + 4.3 -
short-license.txt
- - **/*.java - - - **/package-info.java - + + JAVADOC_STYLE + + + +
short-license.txt
+ + **/*.java + + + **/package-info.java + +
+
@@ -51,7 +58,7 @@ net.revelc.code.formatter formatter-maven-plugin - 2.11.0 + 2.12.2 UTF-8 diff --git a/sdk/pom.xml b/sdk/pom.xml index 641f50951..2776ff2ef 100644 --- a/sdk/pom.xml +++ b/sdk/pom.xml @@ -56,25 +56,25 @@ org.apache.maven.plugins maven-shade-plugin - 2.3 + 3.5.1 + + + + *:* + + **/*.SF + **/*.DSA + **/*.RSA + + + + package shade - - - - *:* - - **/*.SF - **/*.DSA - **/*.RSA - - - - @@ -82,7 +82,7 @@ org.apache.maven.plugins maven-compiler-plugin - 2.3.2 + 3.11.0 ${project.build.sourceEncoding} 1.8 @@ -93,7 +93,7 @@ org.apache.maven.plugins maven-resources-plugin - 2.4.3 + 3.3.1 ${project.build.sourceEncoding} @@ -102,17 +102,23 @@ com.mycila license-maven-plugin - 2.4 + 4.3 -
../short-license.txt
- - **/*.java - - - **/package-info.java - + + JAVADOC_STYLE + + + +
../short-license.txt
+ + **/*.java + + + **/package-info.java + +
+
- @@ -125,7 +131,7 @@ net.revelc.code.formatter formatter-maven-plugin - 2.11.0 + 2.12.2 UTF-8 From 07bdea179a3c2e5f22cd2eaac67dfce670d9a21d Mon Sep 17 00:00:00 2001 From: Eduardo Pinho Date: Sat, 30 Sep 2023 11:06:50 +0100 Subject: [PATCH 2/5] Update formatter-maven-plugin - 2.16.0 - subsequent versions are not supported by Java 8 - Configure line endings to KEEP --- dicoogle/pom.xml | 3 ++- pom.xml | 3 ++- sdk/pom.xml | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/dicoogle/pom.xml b/dicoogle/pom.xml index b3d63fd00..f517363c9 100644 --- a/dicoogle/pom.xml +++ b/dicoogle/pom.xml @@ -238,9 +238,10 @@ net.revelc.code.formatter formatter-maven-plugin - 2.12.2 + 2.16.0 UTF-8 + KEEP **/*.java diff --git a/pom.xml b/pom.xml index 0cf71c26d..0b411c402 100644 --- a/pom.xml +++ b/pom.xml @@ -58,9 +58,10 @@ net.revelc.code.formatter formatter-maven-plugin - 2.12.2 + 2.16.0 UTF-8 + KEEP **/*.java diff --git a/sdk/pom.xml b/sdk/pom.xml index 2776ff2ef..2ff2d42b7 100644 --- a/sdk/pom.xml +++ b/sdk/pom.xml @@ -131,9 +131,10 @@ net.revelc.code.formatter formatter-maven-plugin - 2.12.2 + 2.16.0 UTF-8 + KEEP **/*.java From cdb0c077367aae873b4ea32ca496bf4e561265b0 Mon Sep 17 00:00:00 2001 From: Eduardo Pinho Date: Sat, 30 Sep 2023 11:09:57 +0100 Subject: [PATCH 3/5] Format Java code - dicoogle and sdk, some code was not formatted --- .../core/settings/LegacyServerSettings.java | 2 +- .../java/pt/ua/dicoogle/server/SOPList.java | 135 ++++++------------ .../ua/dicoogle/server/TransfersStorage.java | 2 +- .../server/queryretrieve/DicoogleDcmSend.java | 18 +-- .../dicoogle/server/users/UserFileHandle.java | 4 +- .../management/TransferOptionsServlet.java | 2 +- .../core/settings/ServerSettingsTest.java | 105 ++++---------- .../pt/ua/dicoogle/webui/WebUIPluginTest.java | 5 +- .../sdk/datastructs/dim/DIMGeneric.java | 2 +- 9 files changed, 87 insertions(+), 188 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/core/settings/LegacyServerSettings.java b/dicoogle/src/main/java/pt/ua/dicoogle/core/settings/LegacyServerSettings.java index e1fad5253..ba3a2c708 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/core/settings/LegacyServerSettings.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/core/settings/LegacyServerSettings.java @@ -1284,7 +1284,7 @@ public List getDefaultStorage() { public String getNodeName() { return LegacyServerSettings.this.getNodeName(); } - + @JsonGetter("encrypt-users-file") @Override public boolean isEncryptUsersFile() { diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/SOPList.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/SOPList.java index 519b93995..b383bf9a6 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/SOPList.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/SOPList.java @@ -48,91 +48,42 @@ public class SOPList { private Hashtable table; - private String[] SOP = { - UID.BasicStudyContentNotificationSOPClassRetired, - UID.StoredPrintStorageSOPClassRetired, - UID.HardcopyGrayscaleImageStorageSOPClassRetired, - UID.HardcopyColorImageStorageSOPClassRetired, - UID.ComputedRadiographyImageStorage, - UID.DigitalXRayImageStorageForPresentation, - UID.DigitalXRayImageStorageForProcessing, - UID.DigitalMammographyXRayImageStorageForPresentation, - UID.DigitalIntraOralXRayImageStorageForPresentation, - UID.DigitalIntraOralXRayImageStorageForProcessing, - UID.StandaloneModalityLUTStorageRetired, - UID.EncapsulatedPDFStorage, - UID.StandaloneVOILUTStorageRetired, - UID.GrayscaleSoftcopyPresentationStateStorageSOPClass, - UID.ColorSoftcopyPresentationStateStorageSOPClass, - UID.PseudoColorSoftcopyPresentationStateStorageSOPClass, - UID.BlendingSoftcopyPresentationStateStorageSOPClass, - UID.XRayAngiographicImageStorage, - UID.EnhancedXAImageStorage, - UID.XRayRadiofluoroscopicImageStorage, - UID.EnhancedXRFImageStorage, - UID.XRayAngiographicBiPlaneImageStorageRetired, - UID.PositronEmissionTomographyImageStorage, - UID.StandalonePETCurveStorageRetired, - UID.CTImageStorage, - UID.EnhancedCTImageStorage, - UID.NuclearMedicineImageStorage, - UID.UltrasoundMultiFrameImageStorageRetired, - UID.UltrasoundMultiFrameImageStorage, - UID.MRImageStorage, - UID.EnhancedMRImageStorage, - UID.MRSpectroscopyStorage, - UID.RTImageStorage, - UID.RTDoseStorage, - UID.RTStructureSetStorage, - UID.RTBeamsTreatmentRecordStorage, - UID.RTPlanStorage, - UID.RTBrachyTreatmentRecordStorage, - UID.RTTreatmentSummaryRecordStorage, - UID.NuclearMedicineImageStorageRetired, - UID.UltrasoundImageStorageRetired, - UID.UltrasoundImageStorage, - UID.RawDataStorage, - UID.SpatialRegistrationStorage, - UID.SpatialFiducialsStorage, - UID.RealWorldValueMappingStorage, - UID.SecondaryCaptureImageStorage, - UID.MultiFrameSingleBitSecondaryCaptureImageStorage, - UID.MultiFrameGrayscaleByteSecondaryCaptureImageStorage, - UID.MultiFrameGrayscaleWordSecondaryCaptureImageStorage, - UID.MultiFrameTrueColorSecondaryCaptureImageStorage, - UID.VLImageStorageTrialRetired, - UID.VLEndoscopicImageStorage, - UID.VideoEndoscopicImageStorage, - UID.VLMicroscopicImageStorage, - UID.VideoMicroscopicImageStorage, - UID.VLSlideCoordinatesMicroscopicImageStorage, - UID.VLPhotographicImageStorage, - UID.VideoPhotographicImageStorage, - UID.OphthalmicPhotography8BitImageStorage, - UID.OphthalmicPhotography16BitImageStorage, - UID.StereometricRelationshipStorage, - UID.VLMultiFrameImageStorageTrialRetired, - UID.StandaloneOverlayStorageRetired, - UID.BasicTextSRStorage, - UID.EnhancedSRStorage, - UID.ComprehensiveSRStorage, - UID.ProcedureLogStorage, - UID.MammographyCADSRStorage, - UID.KeyObjectSelectionDocumentStorage, - UID.ChestCADSRStorage, - UID.StandaloneCurveStorageRetired, - //UID._12leadECGWaveformStorage, - UID.GeneralECGWaveformStorage, - UID.AmbulatoryECGWaveformStorage, - UID.HemodynamicWaveformStorage, - UID.CardiacElectrophysiologyWaveformStorage, - UID.BasicVoiceAudioWaveformStorage, - UID.HangingProtocolStorage, - UID.SiemensCSANonImageStorage, - UID.VLWholeSlideMicroscopyImageStorage, - UID.BreastTomosynthesisImageStorage, - UID.XRayRadiationDoseSRStorage - }; + private String[] SOP = {UID.BasicStudyContentNotificationSOPClassRetired, UID.StoredPrintStorageSOPClassRetired, + UID.HardcopyGrayscaleImageStorageSOPClassRetired, UID.HardcopyColorImageStorageSOPClassRetired, + UID.ComputedRadiographyImageStorage, UID.DigitalXRayImageStorageForPresentation, + UID.DigitalXRayImageStorageForProcessing, UID.DigitalMammographyXRayImageStorageForPresentation, + UID.DigitalIntraOralXRayImageStorageForPresentation, UID.DigitalIntraOralXRayImageStorageForProcessing, + UID.StandaloneModalityLUTStorageRetired, UID.EncapsulatedPDFStorage, UID.StandaloneVOILUTStorageRetired, + UID.GrayscaleSoftcopyPresentationStateStorageSOPClass, UID.ColorSoftcopyPresentationStateStorageSOPClass, + UID.PseudoColorSoftcopyPresentationStateStorageSOPClass, + UID.BlendingSoftcopyPresentationStateStorageSOPClass, UID.XRayAngiographicImageStorage, + UID.EnhancedXAImageStorage, UID.XRayRadiofluoroscopicImageStorage, UID.EnhancedXRFImageStorage, + UID.XRayAngiographicBiPlaneImageStorageRetired, UID.PositronEmissionTomographyImageStorage, + UID.StandalonePETCurveStorageRetired, UID.CTImageStorage, UID.EnhancedCTImageStorage, + UID.NuclearMedicineImageStorage, UID.UltrasoundMultiFrameImageStorageRetired, + UID.UltrasoundMultiFrameImageStorage, UID.MRImageStorage, UID.EnhancedMRImageStorage, + UID.MRSpectroscopyStorage, UID.RTImageStorage, UID.RTDoseStorage, UID.RTStructureSetStorage, + UID.RTBeamsTreatmentRecordStorage, UID.RTPlanStorage, UID.RTBrachyTreatmentRecordStorage, + UID.RTTreatmentSummaryRecordStorage, UID.NuclearMedicineImageStorageRetired, + UID.UltrasoundImageStorageRetired, UID.UltrasoundImageStorage, UID.RawDataStorage, + UID.SpatialRegistrationStorage, UID.SpatialFiducialsStorage, UID.RealWorldValueMappingStorage, + UID.SecondaryCaptureImageStorage, UID.MultiFrameSingleBitSecondaryCaptureImageStorage, + UID.MultiFrameGrayscaleByteSecondaryCaptureImageStorage, + UID.MultiFrameGrayscaleWordSecondaryCaptureImageStorage, + UID.MultiFrameTrueColorSecondaryCaptureImageStorage, UID.VLImageStorageTrialRetired, + UID.VLEndoscopicImageStorage, UID.VideoEndoscopicImageStorage, UID.VLMicroscopicImageStorage, + UID.VideoMicroscopicImageStorage, UID.VLSlideCoordinatesMicroscopicImageStorage, + UID.VLPhotographicImageStorage, UID.VideoPhotographicImageStorage, + UID.OphthalmicPhotography8BitImageStorage, UID.OphthalmicPhotography16BitImageStorage, + UID.StereometricRelationshipStorage, UID.VLMultiFrameImageStorageTrialRetired, + UID.StandaloneOverlayStorageRetired, UID.BasicTextSRStorage, UID.EnhancedSRStorage, + UID.ComprehensiveSRStorage, UID.ProcedureLogStorage, UID.MammographyCADSRStorage, + UID.KeyObjectSelectionDocumentStorage, UID.ChestCADSRStorage, UID.StandaloneCurveStorageRetired, + // UID._12leadECGWaveformStorage, + UID.GeneralECGWaveformStorage, UID.AmbulatoryECGWaveformStorage, UID.HemodynamicWaveformStorage, + UID.CardiacElectrophysiologyWaveformStorage, UID.BasicVoiceAudioWaveformStorage, UID.HangingProtocolStorage, + UID.SiemensCSANonImageStorage, UID.VLWholeSlideMicroscopyImageStorage, UID.BreastTomosynthesisImageStorage, + UID.XRayRadiationDoseSRStorage}; public static synchronized SOPList getInstance() { if (instance == null) { @@ -383,10 +334,9 @@ public synchronized void updateList() { */ public synchronized void updateList(ServerSettings settings) { // Get all new SOP classes' UID (not existing in String[] SOP) - Collection newSOPs = settings.getDicomServicesSettings().getAdditionalSOPClasses().stream() - .map(AdditionalSOPClass::getUid) - .filter(newSOPUID -> !Arrays.asList(SOP).contains(newSOPUID)) - .collect(Collectors.toList()); + Collection newSOPs = + settings.getDicomServicesSettings().getAdditionalSOPClasses().stream().map(AdditionalSOPClass::getUid) + .filter(newSOPUID -> !Arrays.asList(SOP).contains(newSOPUID)).collect(Collectors.toList()); // Refresh hardcoded SOPs (outdated TransfersStorage) Arrays.asList(SOP).forEach(sop -> table.put(sop, new TransfersStorage())); // Add "Additional" SOPs to table w/ default transfer syntaxes @@ -417,11 +367,8 @@ public synchronized void readFromSettings() { * and update the archive's SOP list and storage transfer options accordingly. */ public synchronized void readFromSettings(ServerSettings settings) { - settings.getDicomServicesSettings() - .getSOPClasses() - .forEach(sopClass -> sopClass.getTransferSyntaxes() - .forEach(ts -> this.updateTSFieldByTsUID(sopClass.getUID(), ts, true)) - ); + settings.getDicomServicesSettings().getSOPClasses().forEach(sopClass -> sopClass.getTransferSyntaxes() + .forEach(ts -> this.updateTSFieldByTsUID(sopClass.getUID(), ts, true))); } /** Save any changes made to the SOP transfer options listings diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/TransfersStorage.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/TransfersStorage.java index fd48aa704..ee734212e 100755 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/TransfersStorage.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/TransfersStorage.java @@ -185,7 +185,7 @@ public String[] getVerboseTS() { } return return_value; } - + public static String convertTsNameToUID(String name) { return namesUidMapping.getKey(name).toString(); } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/queryretrieve/DicoogleDcmSend.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/queryretrieve/DicoogleDcmSend.java index a89d8a53a..4fa146923 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/queryretrieve/DicoogleDcmSend.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/queryretrieve/DicoogleDcmSend.java @@ -100,7 +100,8 @@ public class DicoogleDcmSend extends StorageCommitmentService { /** TransferSyntax: DCM4CHE URI Referenced */ private static final String DCM4CHEE_URI_REFERENCED_TS_UID = "1.2.40.0.13.1.1.2.4.94"; - private static final boolean FILE_READ_GUARD = System.getProperty("dicoogle.store.fileReadGuard", "").equalsIgnoreCase("true"); + private static final boolean FILE_READ_GUARD = + System.getProperty("dicoogle.store.fileReadGuard", "").equalsIgnoreCase("true"); private Executor executor = new NewThreadExecutor("DCMSND"); @@ -458,10 +459,8 @@ public void send() { FileInfo info = files.get(i); TransferCapability tc = assoc.getTransferCapabilityAsSCU(info.cuid); if (tc == null) { - LOGGER.warn("{} not supported by {}, skip file {}", - UIDDictionary.getDictionary().prompt(info.cuid), - remoteAE.getAETitle(), - info.item.getURI()); + LOGGER.warn("{} not supported by {}, skip file {}", UIDDictionary.getDictionary().prompt(info.cuid), + remoteAE.getAETitle(), info.item.getURI()); continue; } @@ -472,8 +471,7 @@ public void send() { LOGGER.warn("{} with {} not supported by {}, skip file {}", UIDDictionary.getDictionary().prompt(info.cuid), UIDDictionary.getDictionary().prompt(fileref ? DCM4CHEE_URI_REFERENCED_TS_UID : info.tsuid), - remoteAE.getAETitle(), - info.item.getURI()); + remoteAE.getAETitle(), info.item.getURI()); continue; } @@ -690,14 +688,12 @@ public void writeTo(PDVOutputStream out, String tsuid) throws IOException { } private void promptWarnRSP(String prefix, int status, FileInfo info, DicomObject cmd) { - LOGGER.warn("{} {}H for {}, cuid={}, tsuid={} (Command: {})", - prefix, StringUtils.shortToHex(status), + LOGGER.warn("{} {}H for {}, cuid={}, tsuid={} (Command: {})", prefix, StringUtils.shortToHex(status), info.item.getURI(), info.cuid, info.tsuid, cmd); } private void promptErrRSP(String prefix, int status, FileInfo info, DicomObject cmd) { - LOGGER.error("{} {}H for {}, cuid={}, tsuid={} (Command: {})", - prefix, StringUtils.shortToHex(status), + LOGGER.error("{} {}H for {}, cuid={}, tsuid={} (Command: {})", prefix, StringUtils.shortToHex(status), info.item.getURI(), info.cuid, info.tsuid, cmd); } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/UserFileHandle.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/UserFileHandle.java index 01003f8b5..b9283a93a 100755 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/UserFileHandle.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/UserFileHandle.java @@ -89,7 +89,7 @@ public UserFileHandle(Path baseConfDir) throws IOException { } else if (Files.exists(users)) { // (2) users, encrypted logger.warn("File `users` will be interpreted as an encrypted users file. " - + "If this is correct, please rename to `users.xml.enc`"); + + "If this is correct, please rename to `users.xml.enc`"); filename = users; shouldEncrypt = true; } else if (Files.exists(usersXml)) { @@ -115,7 +115,7 @@ public UserFileHandle(Path baseConfDir) throws IOException { if (Files.exists(users)) { // (4) users, no encryption logger.warn("File `users` will be interpreted as an plain XML users file. " - + "If this is correct, please rename to `users.xml`"); + + "If this is correct, please rename to `users.xml`"); filename = users; shouldEncrypt = false; } else if (encryptUsersFile) { diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/management/TransferOptionsServlet.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/management/TransferOptionsServlet.java index d347356a9..c4836a87e 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/management/TransferOptionsServlet.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/management/TransferOptionsServlet.java @@ -79,7 +79,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws Se ServerSettingsManager.saveSettings(); ResponseUtil.simpleResponse(resp, "success", true); } - + @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPut(req, resp); diff --git a/dicoogle/src/test/java/pt/ua/dicoogle/core/settings/ServerSettingsTest.java b/dicoogle/src/test/java/pt/ua/dicoogle/core/settings/ServerSettingsTest.java index 679ccacfd..aa7035064 100644 --- a/dicoogle/src/test/java/pt/ua/dicoogle/core/settings/ServerSettingsTest.java +++ b/dicoogle/src/test/java/pt/ua/dicoogle/core/settings/ServerSettingsTest.java @@ -85,19 +85,17 @@ public void testLoadConfig1() throws IOException { "1.2.840.10008.1.2.4.80", "1.2.840.10008.1.2.4.50"); assertSameContent(defaultTS, ((DicomServicesImpl) dcm).getDefaultTransferSyntaxes()); - Collection sopClasses = - Arrays.asList( - // CT Image Storage - new SOPClass("1.2.840.10008.5.1.4.1.1.2", Collections.emptyList()), - // Enhanced CT Image Storage - new SOPClass("1.2.840.10008.5.1.4.1.1.2.1", Collections.emptyList()), - // Enhanced CT Image Storage - new SOPClass("1.2.840.10008.5.1.4.1.1.12.1.1", - Arrays.asList("1.2.840.10008.1.2", "1.2.840.10008.1.2.1", "1.2.840.10008.1.2.5")), - // Ultrasound Multi-frame Image Storage - new SOPClass("1.2.840.10008.5.1.4.1.1.3.1", - Arrays.asList("1.2.840.10008.1.2", "1.2.840.10008.1.2.1", "1.2.840.10008.1.2.4.50", "1.2.840.10008.1.2.4.70")) - ); + Collection sopClasses = Arrays.asList( + // CT Image Storage + new SOPClass("1.2.840.10008.5.1.4.1.1.2", Collections.emptyList()), + // Enhanced CT Image Storage + new SOPClass("1.2.840.10008.5.1.4.1.1.2.1", Collections.emptyList()), + // Enhanced CT Image Storage + new SOPClass("1.2.840.10008.5.1.4.1.1.12.1.1", + Arrays.asList("1.2.840.10008.1.2", "1.2.840.10008.1.2.1", "1.2.840.10008.1.2.5")), + // Ultrasound Multi-frame Image Storage + new SOPClass("1.2.840.10008.5.1.4.1.1.3.1", Arrays.asList("1.2.840.10008.1.2", "1.2.840.10008.1.2.1", + "1.2.840.10008.1.2.4.50", "1.2.840.10008.1.2.4.70"))); Collection sopClassesFromSettings = ((DicomServicesImpl) dcm).getRawSOPClasses(); assertSameContent(sopClasses, sopClassesFromSettings); @@ -256,33 +254,21 @@ public void testLoadTransferOptions() throws IOException { ServerSettings.DicomServices dcm = settings.getDicomServicesSettings(); // should distinguish between an empty list and missing list - for (SOPClass sopClass: dcm.getSOPClasses()) { + for (SOPClass sopClass : dcm.getSOPClasses()) { switch (sopClass.getUID()) { case UID.CTImageStorage: - assertEquals( - Arrays.asList( - "1.2.840.10008.1.2", - "1.2.840.10008.1.2.1" - ), - sopClass.getTransferSyntaxes()); + assertEquals(Arrays.asList("1.2.840.10008.1.2", "1.2.840.10008.1.2.1"), + sopClass.getTransferSyntaxes()); break; case UID.UltrasoundMultiFrameImageStorage: - assertEquals( - Arrays.asList( - "1.2.840.10008.1.2", - "1.2.840.10008.1.2.1", - "1.2.840.10008.1.2.4.50", - "1.2.840.10008.1.2.4.70" - ), - sopClass.getTransferSyntaxes()); + assertEquals(Arrays.asList("1.2.840.10008.1.2", "1.2.840.10008.1.2.1", "1.2.840.10008.1.2.4.50", + "1.2.840.10008.1.2.4.70"), sopClass.getTransferSyntaxes()); break; case UID.UltrasoundMultiFrameImageStorageRetired: // no transfer syntaxes here, // and no default transfer syntaxes, // means no acceptable transfer syntax - assertEquals( - Collections.emptyList(), - sopClass.getTransferSyntaxes()); + assertEquals(Collections.emptyList(), sopClass.getTransferSyntaxes()); break; default: } @@ -294,31 +280,16 @@ public void testLoadTransferOptions() throws IOException { // see that the SOP list has been updated accordingly - assertEquals( - Arrays.asList("1.2.840.10008.1.2", "1.2.840.10008.1.2.1"), - list.getTS(UID.CTImageStorage).asList() - ); - assertEquals( - Arrays.asList( - "1.2.840.10008.1.2", - "1.2.840.10008.1.2.1", - "1.2.840.10008.1.2.4.70", - "1.2.840.10008.1.2.4.50" - ), - list.getTS(UID.UltrasoundMultiFrameImageStorage).asList() - ); - assertEquals( - Collections.emptyList(), - list.getTS(UID.UltrasoundMultiFrameImageStorageRetired).asList() - ); + assertEquals(Arrays.asList("1.2.840.10008.1.2", "1.2.840.10008.1.2.1"), + list.getTS(UID.CTImageStorage).asList()); + assertEquals(Arrays.asList("1.2.840.10008.1.2", "1.2.840.10008.1.2.1", "1.2.840.10008.1.2.4.70", + "1.2.840.10008.1.2.4.50"), list.getTS(UID.UltrasoundMultiFrameImageStorage).asList()); + assertEquals(Collections.emptyList(), list.getTS(UID.UltrasoundMultiFrameImageStorageRetired).asList()); // unmentioned SOP classes default to // accepting the default transfer syntaxes // (in this case, empty) - assertEquals( - Collections.emptyList(), - list.getTS(UID.BreastTomosynthesisImageStorage).asList() - ); + assertEquals(Collections.emptyList(), list.getTS(UID.BreastTomosynthesisImageStorage).asList()); } @Test @@ -348,32 +319,20 @@ public void testUpdateTransferOptions() throws IOException { Collection sopClasses = dcm.getSOPClasses(); for (SOPClass sopClass : sopClasses) { Collection tses = sopClass.getTransferSyntaxes(); - + switch (sopClass.getUID()) { case UID.CTImageStorage: assertEquals(Collections.emptyList(), tses); break; case UID.EnhancedXAImageStorage: - assertEquals( - Arrays.asList( - "1.2.840.10008.1.2", - "1.2.840.10008.1.2.1", - "1.2.840.10008.1.2.5" - ), - tses - ); + assertEquals(Arrays.asList("1.2.840.10008.1.2", "1.2.840.10008.1.2.1", "1.2.840.10008.1.2.5"), + tses); break; case UID.EnhancedCTImageStorage: - // fallthrough (same settings) + // fallthrough (same settings) case UID.UltrasoundMultiFrameImageStorage: - assertEquals( - Arrays.asList( - "1.2.840.10008.1.2", - "1.2.840.10008.1.2.1", - "1.2.840.10008.1.2.4.70", - "1.2.840.10008.1.2.4.50" - ), - tses); + assertEquals(Arrays.asList("1.2.840.10008.1.2", "1.2.840.10008.1.2.1", "1.2.840.10008.1.2.4.70", + "1.2.840.10008.1.2.4.50"), tses); break; default: break; @@ -419,11 +378,9 @@ public void testAdditionals() throws IOException { Logger logger = NOPLogger.NOP_LOGGER; // Filter (as in init) ds.setAdditionalTransferSyntaxes(ds.getAdditionalTransferSyntaxes().stream() - .filter(ats -> AdditionalTransferSyntax.isValid(ats, logger)) - .collect(Collectors.toList())); + .filter(ats -> AdditionalTransferSyntax.isValid(ats, logger)).collect(Collectors.toList())); ds.setAdditionalSOPClasses(ds.getAdditionalSOPClasses().stream() - .filter(asc -> AdditionalSOPClass.isValid(asc, logger)) - .collect(Collectors.toList())); + .filter(asc -> AdditionalSOPClass.isValid(asc, logger)).collect(Collectors.toList())); // assertions follow diff --git a/dicoogle/src/test/java/pt/ua/dicoogle/webui/WebUIPluginTest.java b/dicoogle/src/test/java/pt/ua/dicoogle/webui/WebUIPluginTest.java index 2a928e3a4..d53e3bd63 100644 --- a/dicoogle/src/test/java/pt/ua/dicoogle/webui/WebUIPluginTest.java +++ b/dicoogle/src/test/java/pt/ua/dicoogle/webui/WebUIPluginTest.java @@ -43,9 +43,8 @@ public class WebUIPluginTest { public void testLoadPlugin1() throws IOException, PluginFormatException { WebUIPluginManager webui = new WebUIPluginManager(); - String test1Path = WebUIPluginTest.class.getClassLoader() - .getResource("pt/ua/dicoogle/webui/WebPlugins/test1") - .getFile(); + String test1Path = + WebUIPluginTest.class.getClassLoader().getResource("pt/ua/dicoogle/webui/WebPlugins/test1").getFile(); webui.load(new File(test1Path)); WebUIPlugin plugin = webui.get("test1"); diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/dim/DIMGeneric.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/dim/DIMGeneric.java index 2a0fe2304..5544f82f0 100755 --- a/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/dim/DIMGeneric.java +++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/dim/DIMGeneric.java @@ -457,7 +457,7 @@ public JSONObject getJSONObject(int depth, int offset, int psize) { // not a number, do not include } } - + instances.add(image); } seriesObj.put("images", instances); From c846c09f829bde5d851369ce56c05f0c36057dd1 Mon Sep 17 00:00:00 2001 From: Eduardo Pinho Date: Sat, 30 Sep 2023 11:10:39 +0100 Subject: [PATCH 4/5] Reorganize .gitignore --- .gitignore | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index f6782eef4..9c9fee9ef 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,26 @@ +/target +/dicoogle/.classpath +/dicoogle/.settings/* +/sdk-ext/.classpath +/sdk-ext/.settings/* +/sdk/.classpath +/sdk/.project +/sdk/.settings/* +/webcore/lib/ node_modules/ -dist +**/webapp/dist .tmp .sass-cache/ -app/bower_components #eclipse .project .settings/* -dicoogle/.classpath -dicoogle/.settings/* -sdk-ext/.classpath -sdk-ext/.settings/* -sdk/.classpath -sdk/.project -sdk/.settings/* -webcore/lib/ +# IDEA .idea + +# Visual Studio Code .vscode/ + *.iml From 59f32bfb94e530a1464615f5971daed4e61f0c52 Mon Sep 17 00:00:00 2001 From: Eduardo Pinho Date: Sat, 30 Sep 2023 11:30:29 +0100 Subject: [PATCH 5/5] Update Jetty to 9.4 - from 9.0.3.v20130506 to 9.4.52.v20230823 - rearrange and reorganize servlets and handlers so that the server provides everything - remove server session attribute - we already handle user sessions separately at the moment - mark services known to be unused as deprecated - add plugin controller check to skip JettyPluginInterface resource if it is null --- .../ua/dicoogle/plugins/PluginController.java | 3 + .../ua/dicoogle/server/web/DicoogleWeb.java | 271 ++++++++++-------- .../ua/dicoogle/server/web/auth/Session.java | 3 - .../web/servlets/SearchHolderServlet.java | 2 + .../web/servlets/search/ExportServlet.java | 4 + .../web/servlets/search/WadoServlet.java | 2 + pom.xml | 2 +- 7 files changed, 159 insertions(+), 128 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/plugins/PluginController.java b/dicoogle/src/main/java/pt/ua/dicoogle/plugins/PluginController.java index 62b7acde7..a75b43c74 100755 --- a/dicoogle/src/main/java/pt/ua/dicoogle/plugins/PluginController.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/plugins/PluginController.java @@ -256,6 +256,9 @@ private void initJettyInterface(Collection plugins) { DicoogleWeb jettyServer = ControlServices.getInstance().getWebServicePlatform(); for (JettyPluginInterface resource : jettyInterfaces) { + if (resource == null) { + continue; + } jettyServer.addContextHandlers(resource.getJettyHandlers()); } } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/DicoogleWeb.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/DicoogleWeb.java index 87dff12a7..121a4bdd2 100755 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/DicoogleWeb.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/DicoogleWeb.java @@ -28,7 +28,6 @@ import pt.ua.dicoogle.server.web.servlets.SettingsServlet; import pt.ua.dicoogle.server.web.servlets.TagsServlet; import pt.ua.dicoogle.server.web.servlets.ExportCSVToFILEServlet; -import pt.ua.dicoogle.server.web.servlets.SearchHolderServlet; import pt.ua.dicoogle.server.web.servlets.IndexerServlet; import pt.ua.dicoogle.server.web.servlets.ImageServlet; import pt.ua.dicoogle.server.web.servlets.plugins.PluginsServlet; @@ -39,20 +38,6 @@ import pt.ua.dicoogle.server.web.servlets.accounts.LoginServlet; import pt.ua.dicoogle.server.web.servlets.accounts.UserServlet; -//import pt.ua.dicoogle.core.ServerSettings; - -import pt.ua.dicoogle.server.web.servlets.management.AETitleServlet; -import pt.ua.dicoogle.server.web.servlets.management.DicomQuerySettingsServlet; -import pt.ua.dicoogle.server.web.servlets.management.ForceIndexing; -import pt.ua.dicoogle.server.web.servlets.management.IndexerSettingsServlet; -import pt.ua.dicoogle.server.web.servlets.management.LoggerServlet; -import pt.ua.dicoogle.server.web.servlets.management.RemoveServlet; -import pt.ua.dicoogle.server.web.servlets.management.RunningTasksServlet; -import pt.ua.dicoogle.server.web.servlets.management.ServerStorageServlet; -import pt.ua.dicoogle.server.web.servlets.management.ServicesServlet; -import pt.ua.dicoogle.server.web.servlets.management.TransferOptionsServlet; - - import java.io.File; import java.net.URL; import java.nio.charset.StandardCharsets; @@ -64,18 +49,16 @@ import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.webapp.WebAppContext; +import org.restlet.Restlet; import javax.servlet.DispatcherType; -import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.server.handler.HandlerWrapper; - +import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.FilterHolder; -import org.eclipse.jetty.servlets.GzipFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -83,8 +66,6 @@ import pt.ua.dicoogle.server.LegacyRestletApplication; import pt.ua.dicoogle.server.web.servlets.accounts.LogoutServlet; -import pt.ua.dicoogle.server.web.servlets.search.DumpServlet; -import pt.ua.dicoogle.server.web.servlets.management.UnindexServlet; import pt.ua.dicoogle.server.web.servlets.webui.WebUIModuleServlet; import pt.ua.dicoogle.server.web.servlets.webui.WebUIServlet; import pt.ua.dicoogle.server.web.utils.LocalImageCache; @@ -115,9 +96,9 @@ public class DicoogleWeb { private final int port; private final ContextHandlerCollection contextHandlers; - private ServletContextHandler pluginHandler = null; + private Handler pluginHandler; private PluginRestletApplication pluginApp = null; - private ServletContextHandler legacyHandler = null; + private Handler legacyHandler = null; private LegacyRestletApplication legacyApp = null; /** @@ -128,123 +109,162 @@ public class DicoogleWeb { public DicoogleWeb(int port) throws Exception { logger.info("Starting Web Services in DicoogleWeb. Port: {}", port); System.setProperty("org.apache.jasper.compiler.disablejsr199", "true"); - // System.setProperty("org.mortbay.jetty.webapp.parentLoaderPriority", "true"); - // System.setProperty("production.mode", "true"); this.port = port; + this.contextHandlers = this.createHandlerCollection(); - // "build" the input location, based on the www directory/.war chosen - final URL warUrl = Thread.currentThread().getContextClassLoader().getResource(WEBAPPDIR); - final String warUrlString = warUrl.toExternalForm(); + // setup the server + server = new Server(port); + server.setHandler(this.contextHandlers); + // Increase maxFormContentSize to avoid issues with big forms + server.setAttribute("org.eclipse.jetty.server.Request.maxFormContentSize", 3325000); + + // and then start the server + server.start(); + } + + /** Root context handler, contains the full tree of services. */ + private ContextHandlerCollection createHandlerCollection() { // setup the DICOM to PNG image servlet, with a local cache cache = new LocalImageCache("dic2png", 300, 900, new SimpleImageRetriever()); // pooling rate of 12/hr and max un-used cache age of 15 minutes - final ServletContextHandler dic2png = createServletHandler(new ImageServlet(cache), "/dic2png"); cache.start(); // start the caching system - // setup the DICOM to PNG image servlet - final ServletContextHandler dictags = createServletHandler(new TagsServlet(), "/dictags"); - - // setup the Export to CSV Servlet - final ServletContextHandler csvServletHolder = createServletHandler(new ExportToCSVServlet(), "/export"); + // temporary folder for export CSV files File tempDir = Paths.get(System.getProperty("java.io.tmpdir")).toFile(); - csvServletHolder.addServlet(new ServletHolder(new ExportCSVToFILEServlet(tempDir)), "/exportFile"); - - // setup the search (DIMSE-service-user C-FIND ?!?) servlet - // final ServletContextHandler search = new ServletContextHandler(ServletContextHandler.SESSIONS); // servlet with session support enabled - // search.setContextPath(CONTEXTPATH); - // search.addServlet(new ServletHolder(new SearchServlet()), "/search"); - - /*hooks = getRegisteredHookActions(); - plugin.addServlet(new ServletHolder(new PluginsServlet(hooks)), "/plugin/*"); - */ - - // setup the web pages/scripts app - final WebAppContext webpages = new WebAppContext(warUrlString, CONTEXTPATH); - webpages.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false"); // disables directory listing - webpages.setInitParameter("useFileMappedBuffer", "false"); - webpages.setInitParameter("cacheControl", "public, max-age=2592000"); // cache for 30 days - webpages.setInitParameter("etags", "true"); // generate and handle weak entity validation tags - webpages.setDisplayName("webapp"); - webpages.setWelcomeFiles(new String[] {"index.html"}); - webpages.addServlet(new ServletHolder(new SearchHolderServlet()), "/search/holders"); - webpages.addFilter(GzipFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST)); + // set up plugin Restlet application for plugin services this.pluginApp = new PluginRestletApplication(); - this.pluginHandler = createServletHandler(new RestletHttpServlet(this.pluginApp), "/ext/*"); + this.pluginHandler = createRestletHandler("ext", this.pluginApp); + // set up plugin Restlet application for legacy services this.legacyApp = new LegacyRestletApplication(); - this.legacyHandler = createServletHandler(new RestletHttpServlet(this.legacyApp), "/legacy/*"); + this.legacyHandler = createRestletHandler("legacy", this.legacyApp); // Add Static RESTlet Plugins PluginRestletApplication.attachRestPlugin(new VersionResource()); - // list the all the handlers mounted above - Handler[] handlers = new Handler[] {pluginHandler, legacyHandler, dic2png, dictags, - createServletHandler(new IndexerServlet(), "/indexer"), // DEPRECATED - createServletHandler(new SettingsServlet(), "/settings"), csvServletHolder, - createServletHandler(new LoginServlet(), "/login"), - createServletHandler(new LogoutServlet(), "/logout"), - createServletHandler(new UserServlet(), "/user/*"), - createServletHandler(new SearchServlet(), "/search"), - createServletHandler(new SearchServlet(SearchType.PATIENT), "/searchDIM"), - createServletHandler(new DumpServlet(), "/dump"), - createServletHandler(new IndexerSettingsServlet(IndexerSettingsServlet.SettingsType.path), - "/management/settings/index/path"), - createServletHandler(new IndexerSettingsServlet(IndexerSettingsServlet.SettingsType.zip), - "/management/settings/index/zip"), - createServletHandler(new IndexerSettingsServlet(IndexerSettingsServlet.SettingsType.effort), - "/management/settings/index/effort"), - createServletHandler(new IndexerSettingsServlet(IndexerSettingsServlet.SettingsType.thumbnail), - "/management/settings/index/thumbnail"), - createServletHandler(new IndexerSettingsServlet(IndexerSettingsServlet.SettingsType.watcher), - "/management/settings/index/watcher"), - createServletHandler(new IndexerSettingsServlet(IndexerSettingsServlet.SettingsType.thumbnailSize), - "/management/settings/index/thumbnail/size"), - createServletHandler(new IndexerSettingsServlet(IndexerSettingsServlet.SettingsType.all), - "/management/settings/index"), - createServletHandler(new TransferOptionsServlet(), "/management/settings/transfer"), - createServletHandler(new WadoServlet(), "/wado"), - createServletHandler(new ProvidersServlet(), "/providers"), - createServletHandler(new DicomQuerySettingsServlet(), "/management/settings/dicom/query"), - createServletHandler(new DimTagsServlet(TagsStruct.getInstance()), "/management/settings/dicom/tags"), - createServletHandler(new ForceIndexing(), "/management/tasks/index"), - createServletHandler(new UnindexServlet(), "/management/tasks/unindex"), - createServletHandler(new RemoveServlet(), "/management/tasks/remove"), - createServletHandler(new ServicesServlet(ServicesServlet.STORAGE), "/management/dicom/storage"), - createServletHandler(new ServicesServlet(ServicesServlet.QUERY), "/management/dicom/query"), - createServletHandler(new ServicesServlet(ServicesServlet.PLUGIN), "/management/plugins/"), - createServletHandler(new AETitleServlet(), "/management/settings/dicom"), - createServletHandler(new PluginsServlet(), "/plugins/*"), - createServletHandler(new PresetsServlet(), "/presets/*"), - createServletHandler(new WebUIServlet(), "/webui"), createWebUIModuleServletHandler(), - createServletHandler(new LoggerServlet(), "/logger"), - createServletHandler(new RunningTasksServlet(), "/index/task"), - createServletHandler(new ExportServlet(ExportType.EXPORT_CVS), "/export/cvs"), - createServletHandler(new ExportServlet(ExportType.LIST), "/export/list"), - createServletHandler(new ServerStorageServlet(), "/management/settings/storage/dicom"), webpages}; + ServletContextHandler rootContextHandler = new ServletContextHandler(0); + rootContextHandler.setContextPath(CONTEXTPATH); + + // list handlers for services mounted in the root context directly + + // search + rootContextHandler.addServlet(new ServletHolder("search", new SearchServlet()), "/search"); + // DICOM to PNG image servlet + rootContextHandler.addServlet(new ServletHolder("dic2png", new ImageServlet(cache)), "/dic2png"); + // export to CSV servlets + rootContextHandler.addServlet(new ServletHolder("export", new ExportToCSVServlet()), "/export"); + rootContextHandler.addServlet(new ServletHolder(new ExportCSVToFILEServlet(tempDir)), "/exportFile"); + // dictags + rootContextHandler.addServlet(new ServletHolder(new TagsServlet()), "/dictags"); + // User servlets: logging in and out, and fetching user information. + rootContextHandler.addServlet(new ServletHolder(new LoginServlet()), "/login"); + rootContextHandler.addServlet(new ServletHolder(new LogoutServlet()), "/logout"); + rootContextHandler.addServlet(new ServletHolder(new UserServlet()), "/user/*"); + // DIM search servlet + rootContextHandler.addServlet(new ServletHolder(new SearchServlet(SearchType.PATIENT)), "/searchDIM"); + // metadata dump servlet + rootContextHandler.addServlet(new ServletHolder(new DumpServlet()), "/dump"); + // list query/index/storage providers + rootContextHandler.addServlet(new ServletHolder(new ProvidersServlet()), "/providers"); + // service to retrieve plugin information + rootContextHandler.addServlet(new ServletHolder(new PluginsServlet()), "/plugins/*"); + // service to retrieve export presets + rootContextHandler.addServlet(new ServletHolder(new PresetsServlet()), "/presets/*"); + // retrieve logs + rootContextHandler.addServlet(new ServletHolder(new LoggerServlet()), "/logger"); + // get running index tasks and do operations on them + rootContextHandler.addServlet(new ServletHolder(new RunningTasksServlet()), "/index/task"); + // deprecated stuff + rootContextHandler.addServlet(new ServletHolder(new IndexerServlet()), "/indexer"); + rootContextHandler.addServlet(new ServletHolder(new SettingsServlet()), "/settings"); + rootContextHandler.addServlet(new ServletHolder(new WadoServlet()), "/wado"); + rootContextHandler.addServlet(new ServletHolder(new ExportServlet(ExportType.EXPORT_CVS)), "/export/cvs"); + rootContextHandler.addServlet(new ServletHolder(new ExportServlet(ExportType.LIST)), "/export/list"); + // webapp + rootContextHandler.addServlet(createWebappServlet(), "/"); + + this.addCORSFilter(rootContextHandler); + + // list ALL of the handlers mounted above + Handler[] handlers = new Handler[] { + // /management + createManagementHandler(), + + // /webui + createWebUIServletHandler(), + + // /ext (handler for Restlet resources from Dicoogle plugins) + pluginHandler, + // /legacy (legacy Restlet service handling) + legacyHandler, + + // / + rootContextHandler}; + + ContextHandlerCollection col = new ContextHandlerCollection(); + col.setHandlers(handlers); + return col; + } - // setup the server - server = new Server(port); - // register the handlers on the server - this.contextHandlers = new ContextHandlerCollection(); - this.contextHandlers.setHandlers(handlers); - server.setHandler(this.contextHandlers); + private ServletHolder createWebappServlet() { + final URL warUrl = Thread.currentThread().getContextClassLoader().getResource(WEBAPPDIR); - // Increase maxFormContentSize to avoid issues with big forms - server.setAttribute("org.eclipse.jetty.server.Request.maxFormContentSize", 3325000); + // set up static serving of the webapp + ServletHolder webpages = new ServletHolder("webapp", DefaultServlet.class); + webpages.setInitParameter("resourceBase", warUrl.toExternalForm()); + webpages.setInitParameter("welcomeFile", "index.html"); + webpages.setInitParameter(AbstractCacheFilter.CACHE_CONTROL_PARAM, "public, max-age=2592000"); // cache for 30 days - // and then start the server - server.start(); + return webpages; + } + + /** Management services: create all servlets and respective handlers */ + private ServletContextHandler createManagementHandler() { + ServletContextHandler handler = new ServletContextHandler(0); + + handler.setContextPath(CONTEXTPATH + "management"); + + handler.addServlet(new ServletHolder(new IndexerSettingsServlet(IndexerSettingsServlet.SettingsType.path)), + "/settings/index/path"); + handler.addServlet(new ServletHolder(new IndexerSettingsServlet(IndexerSettingsServlet.SettingsType.zip)), + "/settings/index/zip"); + handler.addServlet(new ServletHolder(new IndexerSettingsServlet(IndexerSettingsServlet.SettingsType.effort)), + "/settings/index/effort"); + handler.addServlet(new ServletHolder(new IndexerSettingsServlet(IndexerSettingsServlet.SettingsType.thumbnail)), + "/settings/index/thumbnail"); + handler.addServlet(new ServletHolder(new IndexerSettingsServlet(IndexerSettingsServlet.SettingsType.watcher)), + "/settings/index/watcher"); + handler.addServlet( + new ServletHolder(new IndexerSettingsServlet(IndexerSettingsServlet.SettingsType.thumbnailSize)), + "/settings/index/thumbnail/size"); + handler.addServlet(new ServletHolder(new IndexerSettingsServlet(IndexerSettingsServlet.SettingsType.all)), + "/settings/index"); + handler.addServlet(new ServletHolder(new TransferOptionsServlet()), "/settings/transfer"); + handler.addServlet(new ServletHolder(new DicomQuerySettingsServlet()), "/settings/dicom/query"); + handler.addServlet(new ServletHolder(new DimTagsServlet(TagsStruct.getInstance())), "/settings/dicom/tags"); + handler.addServlet(new ServletHolder(new ForceIndexing()), "/tasks/index"); + handler.addServlet(new ServletHolder(new UnindexServlet()), "/tasks/unindex"); + handler.addServlet(new ServletHolder(new RemoveServlet()), "/tasks/remove"); + handler.addServlet(new ServletHolder(new ServicesServlet(ServicesServlet.STORAGE)), "/dicom/storage"); + handler.addServlet(new ServletHolder(new ServicesServlet(ServicesServlet.QUERY)), "/dicom/query"); + handler.addServlet(new ServletHolder(new AETitleServlet()), "/settings/dicom"); + handler.addServlet(new ServletHolder(new ServerStorageServlet()), "/settings/storage/dicom"); + + this.addCORSFilter(handler); + + return handler; } - private ServletContextHandler createWebUIModuleServletHandler() { - ServletContextHandler handler = new ServletContextHandler(ServletContextHandler.SESSIONS); // servlet with session support enabled - handler.setContextPath(CONTEXTPATH); + /** Web UI functionality: create all servlets and respective handlers */ + private ServletContextHandler createWebUIServletHandler() { + ServletContextHandler handler = new ServletContextHandler(0); + handler.setContextPath(CONTEXTPATH + "webui"); - HttpServlet servletModule = new WebUIModuleServlet(); // CORS support this.addCORSFilter(handler); + // Caching! FilterHolder cacheHolder = new FilterHolder(new AbstractCacheFilter() { @Override @@ -269,20 +289,24 @@ protected String etag(HttpServletRequest req) { } } }); + cacheHolder.setInitParameter(AbstractCacheFilter.CACHE_CONTROL_PARAM, "private, max-age=2592000"); // cache for 30 days - handler.addFilter(cacheHolder, "/*", EnumSet.of(DispatcherType.REQUEST)); - handler.addServlet(new ServletHolder(servletModule), "/webui/module/*"); + + // servlet for web UI extension info retrieval + handler.addServlet(new ServletHolder("webui", new WebUIServlet()), ""); + // servlet for web UI JavaScript retrieval (with Etag support) + handler.addFilter(cacheHolder, "/module/*", EnumSet.of(DispatcherType.REQUEST)); + handler.addServlet(new ServletHolder("webui/module", new WebUIModuleServlet()), "/module/*"); return handler; } - private ServletContextHandler createServletHandler(HttpServlet servlet, String path) { - ServletContextHandler handler = new ServletContextHandler(ServletContextHandler.SESSIONS); // servlet with session support enabled - handler.setContextPath(CONTEXTPATH); + private Handler createRestletHandler(String path, Restlet app) { - // CORS support - this.addCORSFilter(handler); + ServletContextHandler handler = new ServletContextHandler(0); + handler.setContextPath(CONTEXTPATH + path); + + handler.addServlet(new ServletHolder(path, new RestletHttpServlet(app)), "/*"); - handler.addServlet(new ServletHolder(servlet), path); return handler; } @@ -353,7 +377,6 @@ public void addContextHandlers(HandlerList handler) { this.contextHandlers.addHandler(handler); this.addCORSFilter(handler); - // this.server.setHandler(this.contextHandlers); } public void stopPluginWebServices() { diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Session.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Session.java index 07ba682b7..f8345b281 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Session.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Session.java @@ -235,9 +235,6 @@ public static LoggedInStatus webappLogin(HttpServletRequest request, HttpServlet return new LoggedInStatus(null, LoggedInStatus.S_UNAUTHORIZEDACCESS); } - // add the login information to the session - HttpSession session = request.getSession(true); // force the creation of a new session if there is none - session.setAttribute("login", login); return new LoggedInStatus(login, LoggedInStatus.S_VALIDLOGIN); } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/SearchHolderServlet.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/SearchHolderServlet.java index bd5eee724..2c862f060 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/SearchHolderServlet.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/SearchHolderServlet.java @@ -43,7 +43,9 @@ * * @author Tiago Godinho. * + * @deprecated See {@link pt.ua.dicoogle.server.web.servlets.search.SearchServlet} instead */ +@Deprecated public class SearchHolderServlet extends HttpServlet { private static final long serialVersionUID = 1L; diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/search/ExportServlet.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/search/ExportServlet.java index eedd97de7..638cd37d4 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/search/ExportServlet.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/search/ExportServlet.java @@ -35,6 +35,10 @@ import pt.ua.dicoogle.plugins.PluginController; import pt.ua.dicoogle.sdk.utils.DictionaryAccess; +/** + * @deprecated Use {@link pt.ua.dicoogle.server.web.servlets.ExportCSVToFILEServlet} instead. + */ +@Deprecated public class ExportServlet extends HttpServlet { private static final Logger logger = LoggerFactory.getLogger(ExportServlet.class); diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/search/WadoServlet.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/search/WadoServlet.java index 4af81c48c..985f9f3e8 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/search/WadoServlet.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/search/WadoServlet.java @@ -38,7 +38,9 @@ /** * @author Frederico Silva * @todo + * @deprecated Incomplete implementation, to be removed in Dicoogle 4 */ +@Deprecated public class WadoServlet extends HttpServlet { @Override diff --git a/pom.xml b/pom.xml index 0b411c402..2e01b41f5 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ dicoogle-all - 9.0.3.v20130506 + 9.4.52.v20230823 2.1.2 2.0.29 1.7.36