From ef07cd86cc2e21f3125b548850a5b36c0b724e4d Mon Sep 17 00:00:00 2001 From: Rick Herrick <jrherrick@wustl.edu> Date: Mon, 21 Mar 2016 18:32:29 -0500 Subject: [PATCH] Fixed handling of DicomSCP instances with preferences. --- .../java/org/nrg/dcm/DicomSCPManager.java | 190 ++++++------------ .../dcm/preferences/DicomSCPPreference.java | 87 +++++++- .../xnat/configuration/DicomImportConfig.java | 4 +- .../restlet/extensions/DicomSCPRestlet.java | 16 +- 4 files changed, 147 insertions(+), 150 deletions(-) diff --git a/src/main/java/org/nrg/dcm/DicomSCPManager.java b/src/main/java/org/nrg/dcm/DicomSCPManager.java index 1503473b..a1df4e5a 100644 --- a/src/main/java/org/nrg/dcm/DicomSCPManager.java +++ b/src/main/java/org/nrg/dcm/DicomSCPManager.java @@ -10,22 +10,14 @@ */ package org.nrg.dcm; -import com.google.common.base.Joiner; -import org.apache.commons.lang3.StringUtils; import org.nrg.config.services.SiteConfigurationService; import org.nrg.dcm.preferences.DicomSCPInstance; import org.nrg.dcm.preferences.DicomSCPPreference; import org.nrg.framework.exceptions.NrgServiceError; import org.nrg.framework.exceptions.NrgServiceException; import org.nrg.framework.exceptions.NrgServiceRuntimeException; -import org.nrg.xdat.om.XnatProjectdata; -import org.nrg.xnat.DicomObjectIdentifier; -import org.nrg.xnat.utils.XnatUserProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; import javax.annotation.PreDestroy; import javax.inject.Inject; @@ -34,18 +26,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.Executors; -public class DicomSCPManager implements ApplicationContextAware { - - public DicomSCPManager(final XnatUserProvider provider) throws IOException { - _provider = provider; - } - - @Override - public void setApplicationContext(final ApplicationContext context) throws BeansException { - _context = context; - } +public class DicomSCPManager { @PreDestroy public void shutdown() { @@ -53,41 +35,26 @@ public class DicomSCPManager implements ApplicationContextAware { stopDicomSCPs(); } - /** - * Sets the preferences for the DICOM SCP manager. - * - * @param preferences The preferences to set. - */ - @SuppressWarnings("unused") - public void setPreferences(final DicomSCPPreference preferences) { - _preferences = preferences; - for (final DicomSCPInstance instance : preferences.getDicomSCPInstances().values()) { - try { - createDicomScpFromInstance(instance); - } catch (IOException e) { - _log.error("An error occurred trying to create the DICOM SCP instance " + instance.toString()); - } - } - } - - public void create(final DicomSCPInstance instance) throws IOException, NrgServiceException { + public DicomSCP create(final DicomSCPInstance instance) throws IOException, NrgServiceException { final String scpId = instance.getScpId(); if (_preferences.hasDicomSCPInstance(scpId)) { throw new NrgServiceException(NrgServiceError.ConfigurationError, "There is already a DICOM SCP instance with the ID " + scpId); } _preferences.setDicomSCPInstance(instance); - createDicomScpFromInstance(instance); + return _preferences.getDicomSCP(scpId); } public void delete(final String scpId) throws NrgServiceException { if (!_preferences.hasDicomSCPInstance(scpId)) { throw new NrgServiceException(NrgServiceError.UnknownEntity, "There is no DICOM SCP instance with the ID " + scpId); } - stopDicomSCP(scpId); - _dicomSCPs.remove(scpId); _preferences.deleteDicomSCPInstance(scpId); } + public List<DicomSCPInstance> getDicomSCPInstances() { + return new ArrayList<>(_preferences.getDicomSCPInstances().values()); + } + public void startOrStopDicomSCPAsDictatedByConfiguration() { final boolean enableDicomReceiver = _siteConfigurationService.getBoolSiteConfigurationProperty("enableDicomReceiver", true); if (enableDicomReceiver) { @@ -98,128 +65,95 @@ public class DicomSCPManager implements ApplicationContextAware { } public void startDicomSCPs() { - for (final String scpId : _dicomSCPs.keySet()) { - final DicomSCPInstance instance = _preferences.getDicomSCPInstance(scpId); + for (final DicomSCPInstance instance : _preferences.getDicomSCPInstances().values()) { if (instance.isEnabled()) { - startDicomSCP(scpId); + startDicomSCP(instance); } } } public void startDicomSCP(final String scpId) { - final DicomSCP dicomSCP = getDicomSCP(scpId); - try { - dicomSCP.start(); - final DicomSCPInstance instance = _preferences.getDicomSCPInstance(scpId); - if (!instance.isEnabled()) { - enableDicomSCP(scpId); - } - } catch (IOException e) { - throw new NrgServiceRuntimeException(NrgServiceError.Unknown, "Unable to start DICOM SCP: " + Joiner.on("/").join(dicomSCP.getAEs()) + ":" + dicomSCP.getPort(), e); - } + startDicomSCP(_preferences.getDicomSCPInstance(scpId)); } - public void enableDicomSCP(final String scpId) throws IOException { - final DicomSCPInstance instance = _preferences.getDicomSCPInstance(scpId); - if (!instance.isEnabled()) { - instance.setEnabled(true); - _preferences.setDicomSCPInstance(instance); - } - final DicomSCP dicomSCP = _dicomSCPs.get(scpId); - if (!dicomSCP.isStarted()) { - dicomSCP.start(); + public void stopDicomSCPs() { + for (final DicomSCP dicomSCP : _preferences.getDicomSCPs()) { + dicomSCP.stop(); } } - public void disableDicomSCP(final String scpId) throws IOException { + public void stopDicomSCP(final String scpId) { final DicomSCPInstance instance = _preferences.getDicomSCPInstance(scpId); - if (instance.isEnabled()) { - instance.setEnabled(false); - _preferences.setDicomSCPInstance(instance); + if (instance == null) { + throw new NrgServiceRuntimeException(NrgServiceError.UnknownEntity, "Couldn't find the DICOM SCP instance identified by " + scpId); } - final DicomSCP dicomSCP = _dicomSCPs.get(scpId); - if (dicomSCP.isStarted()) { - dicomSCP.stop(); + try { + final DicomSCP dicomSCP = _preferences.getDicomSCP(scpId); + if (dicomSCP != null) { + if (dicomSCP.isStarted()) { + dicomSCP.stop(); + } + } + } catch (IOException e) { + throw new NrgServiceRuntimeException(NrgServiceError.Unknown, "Unable to stop DICOM SCP: " + instance.getAeTitle() + ":" + instance.getPort(), e); } } - public void stopDicomSCPs() { - for (final String scpId : _dicomSCPs.keySet()) { - stopDicomSCP(scpId); + public void enableDicomSCP(final String scpId) { + final DicomSCPInstance instance = _preferences.getDicomSCPInstance(scpId); + try { + if (!instance.isEnabled()) { + instance.setEnabled(true); + _preferences.setDicomSCPInstance(instance); + } + final DicomSCP dicomSCP = _preferences.getDicomSCP(scpId); + if (!dicomSCP.isStarted()) { + dicomSCP.start(); + } + } catch (IOException e) { + throw new NrgServiceRuntimeException(NrgServiceError.Unknown, "Unable to enable DICOM SCP: " + instance.getAeTitle() + ":" + instance.getPort(), e); } } - public void stopDicomSCP(final String scpId) { - final DicomSCP dicomSCP = _dicomSCPs.get(scpId); - if (dicomSCP == null) { - throw new NrgServiceRuntimeException(NrgServiceError.UnknownEntity, "Couldn't find the DICOM SCP instance identified by " + scpId); - } - if (dicomSCP.isStarted()) { - dicomSCP.stop(); + public void disableDicomSCP(final String scpId) { + final DicomSCPInstance instance = _preferences.getDicomSCPInstance(scpId); + try { + if (instance.isEnabled()) { + instance.setEnabled(false); + _preferences.setDicomSCPInstance(instance); + } + final DicomSCP dicomSCP = _preferences.getDicomSCP(scpId); + if (dicomSCP.isStarted()) { + dicomSCP.stop(); + } + } catch (IOException e) { + throw new NrgServiceRuntimeException(NrgServiceError.Unknown, "Unable to disable DICOM SCP: " + instance.getAeTitle() + ":" + instance.getPort(), e); } } public Map<String, Boolean> areDicomSCPsStarted() { final Map<String, Boolean> statuses = new HashMap<>(); - for (final String scpId : _dicomSCPs.keySet()) { - statuses.put(scpId, isDicomSCPStarted(scpId)); + for (final DicomSCP dicomSCP : _preferences.getDicomSCPs()) { + statuses.put(dicomSCP.getScpId(), dicomSCP.isStarted()); } return statuses; } - public boolean isDicomSCPStarted(final String scpId) { - final DicomSCP dicomSCP = _dicomSCPs.get(scpId); - if (dicomSCP == null) { - throw new NrgServiceRuntimeException(NrgServiceError.UnknownEntity, "Couldn't find the DICOM SCP instance identified by " + scpId); - } - return dicomSCP.isStarted(); - } - public boolean hasDicomSCP(final String scpId) { - return _dicomSCPs.containsKey(scpId); - } - - public List<DicomSCPInstance> getDicomSCPInstances() { - return new ArrayList<>(_preferences.getDicomSCPInstances().values()); + return _preferences.hasDicomSCPInstance(scpId); } public DicomSCPInstance getDicomSCPInstance(final String scpId) { return _preferences.getDicomSCPInstance(scpId); } - private DicomSCP getDicomSCP(final String scpId) { - final DicomSCP dicomSCP = _dicomSCPs.get(scpId); - if (dicomSCP == null) { - throw new NrgServiceRuntimeException(NrgServiceError.UnknownEntity, "Couldn't find the DICOM SCP instance identified by " + scpId); - } - return dicomSCP; - } - - private void createDicomScpFromInstance(final DicomSCPInstance instance) throws IOException { - final String scpId = instance.getScpId(); - final DicomSCP dicomScp = DicomSCP.create(scpId, Executors.newCachedThreadPool(), instance.getPort(), _provider, instance.getAeTitle(), getIdentifier(instance.getIdentifier()), getDicomFileNamer(instance.getFileNamer())); - _dicomSCPs.put(scpId, dicomScp); - if (instance.isEnabled()) { - dicomScp.start(); - } - } - - private DicomObjectIdentifier<XnatProjectdata> getIdentifier(final String identifier) { - final DicomObjectIdentifier bean = StringUtils.isBlank(identifier) ? _context.getBean(DicomObjectIdentifier.class) : _context.getBean(identifier, DicomObjectIdentifier.class); - if (bean == null) { - throw new NrgServiceRuntimeException(NrgServiceError.Unknown, "Could not find a DICOM object identifier with the ID " + identifier); - } - //noinspection unchecked - return (DicomObjectIdentifier<XnatProjectdata>) bean; - } - - private DicomFileNamer getDicomFileNamer(final String identifier) { - //noinspection unchecked - final DicomFileNamer bean = StringUtils.isBlank(identifier) ? _context.getBean(DicomFileNamer.class) : _context.getBean(identifier, DicomFileNamer.class); - if (bean == null) { - throw new NrgServiceRuntimeException(NrgServiceError.Unknown, "Could not find a DICOM object identifier with the ID " + identifier); + private void startDicomSCP(final DicomSCPInstance instance) { + try { + final DicomSCP dicomSCP = _preferences.getDicomSCP(instance.getScpId()); + dicomSCP.start(); + } catch (IOException e) { + throw new NrgServiceRuntimeException(NrgServiceError.Unknown, "Unable to start DICOM SCP: " + instance.getAeTitle() + ":" + instance.getPort(), e); } - return bean; } private static final Logger _log = LoggerFactory.getLogger(DicomSCPManager.class); @@ -229,8 +163,4 @@ public class DicomSCPManager implements ApplicationContextAware { @Inject private DicomSCPPreference _preferences; - - private final Map<String, DicomSCP> _dicomSCPs = new HashMap<>(); - private ApplicationContext _context; - private final XnatUserProvider _provider; } diff --git a/src/main/java/org/nrg/dcm/preferences/DicomSCPPreference.java b/src/main/java/org/nrg/dcm/preferences/DicomSCPPreference.java index 78ab6aaf..a184ae50 100644 --- a/src/main/java/org/nrg/dcm/preferences/DicomSCPPreference.java +++ b/src/main/java/org/nrg/dcm/preferences/DicomSCPPreference.java @@ -1,17 +1,42 @@ package org.nrg.dcm.preferences; +import org.apache.commons.lang3.StringUtils; +import org.nrg.dcm.DicomFileNamer; +import org.nrg.dcm.DicomSCP; +import org.nrg.framework.exceptions.NrgServiceError; +import org.nrg.framework.exceptions.NrgServiceRuntimeException; import org.nrg.prefs.annotations.NrgPreference; import org.nrg.prefs.annotations.NrgPreferenceBean; import org.nrg.prefs.beans.AbstractPreferenceBean; import org.nrg.prefs.exceptions.InvalidPreferenceName; +import org.nrg.xdat.om.XnatProjectdata; +import org.nrg.xnat.DicomObjectIdentifier; +import org.nrg.xnat.utils.XnatUserProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import javax.inject.Inject; import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.concurrent.Executors; @NrgPreferenceBean(toolId = "dicomScpManager", toolName = "DICOM SCP Manager", description = "Manages configuration of the various DICOM SCP endpoints on the XNAT system.") -public class DicomSCPPreference extends AbstractPreferenceBean { +public class DicomSCPPreference extends AbstractPreferenceBean implements ApplicationContextAware { + + /** + * {@inheritDoc} + */ + @Override + public void setApplicationContext(final ApplicationContext context) throws BeansException { + _context = context; + } + public boolean hasDicomSCPInstance(final String scpId) { return getDicomSCPInstances().containsKey(scpId); } @@ -26,21 +51,71 @@ public class DicomSCPPreference extends AbstractPreferenceBean { } public void setDicomSCPInstance(final DicomSCPInstance instance) throws IOException { + final String scpId = instance.getScpId(); + deleteDicomSCP(scpId); try { - set(serialize(instance), PREF_ID, instance.getScpId()); + set(serialize(instance), PREF_ID, scpId); } catch (InvalidPreferenceName invalidPreferenceName) { - _log.info("Got an invalidate preference name error for " + instance.getScpId()); + _log.info("Got an invalidate preference name error for " + scpId); } + _dicomSCPs.put(scpId, getDicomSCP(scpId)); } public void deleteDicomSCPInstance(final String scpId) { - final String instanceId = getNamespacedPropertyId(PREF_ID, scpId); + deleteDicomSCP(scpId); try { - delete(instanceId); + delete(PREF_ID, scpId); } catch (InvalidPreferenceName invalidPreferenceName) { _log.info("Got an invalidate preference name error trying to delete DICOM SCP instance " + scpId); } } - private static final Logger _log = LoggerFactory.getLogger(DicomSCPInstance.class); + + public List<DicomSCP> getDicomSCPs() { + return new ArrayList<>(_dicomSCPs.values()); + } + + public DicomSCP getDicomSCP(final String scpId) throws IOException { + if (!hasDicomSCPInstance(scpId)) { + throw new NrgServiceRuntimeException(NrgServiceError.UnknownEntity, "There is no definition for the DICOM SCP with ID " + scpId); + } + if (!_dicomSCPs.containsKey(scpId)) { + final DicomSCPInstance instance = getDicomSCPInstance(scpId); + _dicomSCPs.put(scpId, DicomSCP.create(scpId, Executors.newCachedThreadPool(), instance.getPort(), _provider, instance.getAeTitle(), getIdentifier(instance.getIdentifier()), getDicomFileNamer(instance.getFileNamer()))); + } + return _dicomSCPs.get(scpId); + } + + private void deleteDicomSCP(final String scpId) { + if (_dicomSCPs.containsKey(scpId)) { + final DicomSCP deleted = _dicomSCPs.remove(scpId); + deleted.stop(); + } + } + + private DicomObjectIdentifier<XnatProjectdata> getIdentifier(final String identifier) { + final DicomObjectIdentifier bean = StringUtils.isBlank(identifier) ? _context.getBean(DicomObjectIdentifier.class) : _context.getBean(identifier, DicomObjectIdentifier.class); + if (bean == null) { + throw new NrgServiceRuntimeException(NrgServiceError.Unknown, "Could not find a DICOM object identifier with the ID " + identifier); + } + //noinspection unchecked + return (DicomObjectIdentifier<XnatProjectdata>) bean; + } + + private DicomFileNamer getDicomFileNamer(final String identifier) { + //noinspection unchecked + final DicomFileNamer bean = StringUtils.isBlank(identifier) ? _context.getBean(DicomFileNamer.class) : _context.getBean(identifier, DicomFileNamer.class); + if (bean == null) { + throw new NrgServiceRuntimeException(NrgServiceError.Unknown, "Could not find a DICOM object identifier with the ID " + identifier); + } + return bean; + } + + private static final Logger _log = LoggerFactory.getLogger(DicomSCPInstance.class); private static final String PREF_ID = "dicomSCPInstances"; + + @Inject + private XnatUserProvider _provider; + + private ApplicationContext _context; + private final Map<String, DicomSCP> _dicomSCPs = new HashMap<>(); } diff --git a/src/main/java/org/nrg/xnat/configuration/DicomImportConfig.java b/src/main/java/org/nrg/xnat/configuration/DicomImportConfig.java index 35164494..62cda997 100644 --- a/src/main/java/org/nrg/xnat/configuration/DicomImportConfig.java +++ b/src/main/java/org/nrg/xnat/configuration/DicomImportConfig.java @@ -31,8 +31,8 @@ public class DicomImportConfig { } @Bean - public DicomSCPManager dicomSCPManager(final XnatUserProvider provider) throws Exception { - return new DicomSCPManager(provider); + public DicomSCPManager dicomSCPManager() throws Exception { + return new DicomSCPManager(); } @Bean diff --git a/src/main/java/org/nrg/xnat/restlet/extensions/DicomSCPRestlet.java b/src/main/java/org/nrg/xnat/restlet/extensions/DicomSCPRestlet.java index cb3c3035..56617d32 100644 --- a/src/main/java/org/nrg/xnat/restlet/extensions/DicomSCPRestlet.java +++ b/src/main/java/org/nrg/xnat/restlet/extensions/DicomSCPRestlet.java @@ -151,23 +151,15 @@ public class DicomSCPRestlet extends SecureResource { if (StringUtils.isBlank(_scpId)) { getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST, "You must specify a specific DICOM SCP instance to enable."); } else { - try { - _dicomSCPManager.enableDicomSCP(_scpId); - returnDefaultRepresentation(); - } catch (IOException e) { - getResponse().setStatus(Status.SERVER_ERROR_INTERNAL, e, "An error occurred trying to enable the DICOM SCP instance for ID: " + _scpId); - } + _dicomSCPManager.enableDicomSCP(_scpId); + returnDefaultRepresentation(); } } else if (_action.equalsIgnoreCase("disable")) { if (StringUtils.isBlank(_scpId)) { getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST, "You must specify a specific DICOM SCP instance to disable."); } else { - try { - _dicomSCPManager.disableDicomSCP(_scpId); - returnDefaultRepresentation(); - } catch (IOException e) { - getResponse().setStatus(Status.SERVER_ERROR_INTERNAL, e, "An error occurred while disabling the DICOM receiver " + _scpId); - } + _dicomSCPManager.disableDicomSCP(_scpId); + returnDefaultRepresentation(); } } else { _dicomSCPManager.startDicomSCPs(); -- GitLab