1 | |
package ca.uhn.hl7v2.hoh.relay.listener; |
2 | |
|
3 | |
import java.util.ArrayList; |
4 | |
import java.util.List; |
5 | |
import java.util.concurrent.Executors; |
6 | |
import java.util.concurrent.ThreadFactory; |
7 | |
import java.util.concurrent.atomic.AtomicInteger; |
8 | |
|
9 | |
import ca.uhn.hl7v2.model.Message; |
10 | |
import org.springframework.beans.factory.BeanNameAware; |
11 | |
import org.springframework.beans.factory.DisposableBean; |
12 | |
import org.springframework.beans.factory.InitializingBean; |
13 | |
|
14 | |
import ca.uhn.hl7v2.DefaultHapiContext; |
15 | |
import ca.uhn.hl7v2.app.SimpleServer; |
16 | |
import ca.uhn.hl7v2.hoh.util.Validate; |
17 | |
import ca.uhn.hl7v2.llp.MinLowerLayerProtocol; |
18 | |
import ca.uhn.hl7v2.parser.GenericModelClassFactory; |
19 | |
import ca.uhn.hl7v2.protocol.ApplicationRouter.AppRoutingData; |
20 | |
import ca.uhn.hl7v2.protocol.ReceivingApplication; |
21 | |
import ca.uhn.hl7v2.util.StandardSocketFactory; |
22 | |
|
23 | 220 | public class RelayMllpListener implements InitializingBean, DisposableBean, IRelayListener, BeanNameAware { |
24 | |
|
25 | 5 | private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RelayMllpListener.class); |
26 | 20 | private List<ReceivingApplication<? extends Message>> myApplications = new ArrayList<ReceivingApplication<? extends Message>>(); |
27 | 20 | private List<AppRoutingData> myAppRoutingData = new ArrayList<AppRoutingData>(); |
28 | |
private String myBeanName; |
29 | |
private int myPort; |
30 | |
private SimpleServer myServer; |
31 | 20 | private AtomicInteger threadNum = new AtomicInteger(1); |
32 | |
private DefaultHapiContext myContext; |
33 | |
|
34 | |
|
35 | |
|
36 | |
|
37 | |
|
38 | |
public void afterPropertiesSet() throws Exception { |
39 | 20 | if (myPort <= 0) { |
40 | 0 | throw new IllegalStateException("Port not set"); |
41 | |
} |
42 | |
|
43 | 20 | myContext = new DefaultHapiContext(); |
44 | 20 | StandardSocketFactory socketFactory = new StandardSocketFactory(); |
45 | 20 | socketFactory.setAcceptedSocketTimeout(2000); |
46 | 20 | myContext.setSocketFactory(socketFactory); |
47 | 20 | myContext.setExecutorService(Executors.newCachedThreadPool(new MyThreadFactory())); |
48 | 20 | myContext.setLowerLayerProtocol(new MinLowerLayerProtocol(true)); |
49 | 20 | myContext.setModelClassFactory(new GenericModelClassFactory()); |
50 | 20 | myServer = myContext.newServer(myPort, false); |
51 | |
|
52 | 20 | for (int i = 0; i < myAppRoutingData.size(); i++) { |
53 | 0 | myServer.registerApplication(myAppRoutingData.get(i), myApplications.get(i)); |
54 | |
} |
55 | |
|
56 | 20 | ourLog.info("Starting listener on port {}", myPort); |
57 | 20 | myServer.startAndWait(); |
58 | 20 | ourLog.info("Listener on port {} has started, and is ready for processing", myPort); |
59 | |
|
60 | 20 | if (myServer.getServiceExitedWithException() != null) { |
61 | 0 | Throwable ex = myServer.getServiceExitedWithException(); |
62 | 0 | ourLog.error("Server failed to start", ex); |
63 | 0 | if (ex instanceof Exception) { |
64 | 0 | throw (Exception) ex; |
65 | |
} else { |
66 | 0 | throw new Error(ex); |
67 | |
} |
68 | |
} |
69 | |
|
70 | 20 | } |
71 | |
|
72 | |
|
73 | |
|
74 | |
|
75 | |
|
76 | |
|
77 | |
public void destroy() throws Exception { |
78 | 20 | ourLog.info("Stopping listener on port {}", myPort); |
79 | 20 | myServer.stopAndWait(); |
80 | 20 | ourLog.info("Listener on port {} has stopped", myPort); |
81 | |
|
82 | 20 | ourLog.info("Closing HAPI Context Object"); |
83 | 20 | myContext.close(); |
84 | 20 | ourLog.info("Done closing HAPI Context object"); |
85 | 20 | } |
86 | |
|
87 | |
public String getBeanName() { |
88 | 20 | return myBeanName; |
89 | |
} |
90 | |
|
91 | |
|
92 | |
public void registerApplication(AppRoutingData theAppRouting, ReceivingApplication<? extends Message> theReceivingApplication) { |
93 | 20 | Validate.notNull(theAppRouting, "appRouting"); |
94 | 20 | Validate.notNull(theReceivingApplication, "receivingApplication"); |
95 | |
|
96 | 20 | if (myServer != null) { |
97 | 20 | myServer.registerApplication(theAppRouting, theReceivingApplication); |
98 | |
} else { |
99 | 0 | myAppRoutingData.add(theAppRouting); |
100 | 0 | myApplications.add(theReceivingApplication); |
101 | |
} |
102 | 20 | } |
103 | |
|
104 | |
|
105 | |
public void setBeanName(String theBeanName) { |
106 | 20 | myBeanName = theBeanName; |
107 | 20 | } |
108 | |
|
109 | |
public void setPort(int thePort) { |
110 | 20 | myPort = thePort; |
111 | 20 | } |
112 | |
|
113 | 20 | private class MyThreadFactory implements ThreadFactory { |
114 | |
|
115 | |
private ThreadGroup group; |
116 | |
|
117 | 20 | private MyThreadFactory() { |
118 | 20 | group = Thread.currentThread().getThreadGroup(); |
119 | 20 | } |
120 | |
|
121 | |
public Thread newThread(Runnable theR) { |
122 | 100 | String name = "hoh-port-" + myPort + "-worker-" + threadNum.getAndIncrement(); |
123 | 100 | Thread t = new Thread(group, theR, name, 0); |
124 | 100 | if (t.isDaemon()) { |
125 | 0 | t.setDaemon(false); |
126 | |
} |
127 | 100 | if (t.getPriority() != Thread.NORM_PRIORITY) { |
128 | 0 | t.setPriority(Thread.NORM_PRIORITY); |
129 | |
} |
130 | 100 | return t; |
131 | |
} |
132 | |
|
133 | |
} |
134 | |
|
135 | |
|
136 | |
} |