001/* 002 * *** BEGIN LICENSE BLOCK ***** 003 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 004 * 005 * The contents of this file are subject to the Mozilla Public License Version 006 * 1.1 (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * http://www.mozilla.org/MPL/ 009 * 010 * Software distributed under the License is distributed on an "AS IS" basis, 011 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 012 * for the specific language governing rights and limitations under the 013 * License. 014 * 015 * The Original Code is part of dcm4che, an implementation of DICOM(TM) in 016 * Java(TM), hosted at https://github.com/gunterze/dcm4che. 017 * 018 * The Initial Developer of the Original Code is 019 * Agfa Healthcare. 020 * Portions created by the Initial Developer are Copyright (C) 2015 021 * the Initial Developer. All Rights Reserved. 022 * 023 * Contributor(s): 024 * See @authors listed below 025 * 026 * Alternatively, the contents of this file may be used under the terms of 027 * either the GNU General Public License Version 2 or later (the "GPL"), or 028 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 029 * in which case the provisions of the GPL or the LGPL are applicable instead 030 * of those above. If you wish to allow use of your version of this file only 031 * under the terms of either the GPL or the LGPL, and not to allow others to 032 * use your version of this file under the terms of the MPL, indicate your 033 * decision by deleting the provisions above and replace them with the notice 034 * and other provisions required by the GPL or the LGPL. If you do not delete 035 * the provisions above, a recipient may use your version of this file under 036 * the terms of any one of the MPL, the GPL or the LGPL. 037 * 038 * ***** END LICENSE BLOCK ***** 039 */ 040 041package org.dcm4che3.tool.mppsscp.test; 042 043import java.util.ArrayList; 044import java.util.Collections; 045import java.util.List; 046import java.util.concurrent.ExecutorService; 047import java.util.concurrent.Executors; 048import java.util.concurrent.ScheduledExecutorService; 049 050import org.dcm4che3.data.Attributes; 051import org.dcm4che3.data.Tag; 052import org.dcm4che3.net.ApplicationEntity; 053import org.dcm4che3.net.Association; 054import org.dcm4che3.net.Device; 055import org.dcm4che3.net.Dimse; 056import org.dcm4che3.net.service.BasicCEchoSCP; 057import org.dcm4che3.net.service.BasicMPPSSCP; 058import org.dcm4che3.net.service.DicomServiceException; 059import org.dcm4che3.net.service.DicomServiceRegistry; 060import org.dcm4che3.tool.common.test.TestResult; 061import org.dcm4che3.tool.common.test.TestTool; 062 063 064/** 065 * @author Roman K 066 */ 067public class MPPSSCPTool implements TestTool { 068 069 Device d; 070 ApplicationEntity ae; 071 072 private List<ReceivedMPPS> received = Collections.synchronizedList(new ArrayList<ReceivedMPPS>()); 073 074 public class ReceivedMPPS { 075 public String iuid; 076 public Dimse dimse; 077 public Attributes attributes; 078 public Attributes request; 079 } 080 081 public MPPSSCPTool(Device d) { 082 this.d = d; 083 ae = d.getApplicationEntities().iterator().next(); 084 DicomServiceRegistry serviceRegistry = new DicomServiceRegistry(); 085 serviceRegistry.addDicomService(new BasicCEchoSCP()); 086 serviceRegistry.addDicomService(new ToolMPPSSCP()); 087 ae.setDimseRQHandler(serviceRegistry); 088 } 089 090 @Override 091 public void init(TestResult resultIn) { 092 093 094 } 095 096 public void start() { 097 ExecutorService executorService = Executors.newCachedThreadPool(); 098 ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); 099 d.setScheduledExecutor(scheduledExecutorService); 100 d.setExecutor(executorService); 101 try { 102 d.bindConnections(); 103 } catch (Exception e) { 104 throw new RuntimeException("Unable to start MPPSSCP tool", e); 105 } 106 } 107 108 public void stop() { 109 d.unbindConnections(); 110 ((ExecutorService) d.getExecutor()).shutdown(); 111 d.getScheduledExecutor().shutdown(); 112 113 //very quick fix to block for listening connection 114 while (d.getConnections().get(0).isListening()) { 115 try { 116 Thread.sleep(10); 117 } catch (InterruptedException e) { 118 // ignore 119 } 120 } 121 } 122 123 @Override 124 public MPPSResult getResult() { 125 return new MPPSResult(); 126 } 127 128 129 public void waitForIncoming(int howMany, int timeoutInSeconds) { 130 try { 131 long t = System.currentTimeMillis(); 132 while (timeoutInSeconds <= 0 || System.currentTimeMillis() < t + timeoutInSeconds * 1000.0) { 133 134 synchronized (this) { 135 try { 136 this.wait(100); 137 } catch (InterruptedException ignored) { 138 } 139 } 140 141 if (received.size() >= howMany) return; 142 143 } 144 throw new RuntimeException("Timeout - did not receive all the expected MPPS messages in "+timeoutInSeconds+" seconds:" + 145 "\n Expected "+howMany+" messages" + 146 "\n Received "+received.size()+" messages"); 147 } finally { 148 stop(); 149 } 150 } 151 152 public class MPPSResult implements TestResult { 153 public List<ReceivedMPPS> getReceivedMPPS() { 154 return received; 155 } 156 } 157 158 private class ToolMPPSSCP extends BasicMPPSSCP { 159 @Override 160 protected Attributes create(Association as, Attributes rq, Attributes rqAttrs, Attributes rsp) throws DicomServiceException { 161 162 ReceivedMPPS receivedMPPS = new ReceivedMPPS(); 163 receivedMPPS.iuid = rq.getString(Tag.AffectedSOPInstanceUID); 164 receivedMPPS.dimse = Dimse.N_CREATE_RQ; 165 receivedMPPS.attributes = rqAttrs; 166 received.add(receivedMPPS); 167 synchronized (MPPSSCPTool.this) { 168 MPPSSCPTool.this.notify(); 169 } 170 return null; 171 } 172 173 @Override 174 protected Attributes set(Association as, Attributes rq, Attributes rqAttrs, Attributes rsp) throws DicomServiceException { 175 176 ReceivedMPPS receivedMPPS = new ReceivedMPPS(); 177 receivedMPPS.iuid = rq.getString(Tag.AffectedSOPInstanceUID); 178 receivedMPPS.dimse = Dimse.N_SET_RQ; 179 receivedMPPS.attributes = rqAttrs; 180 received.add(receivedMPPS); 181 synchronized (MPPSSCPTool.this) { 182 MPPSSCPTool.this.notify(); 183 } 184 return null; 185 } 186 } 187 188}