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}