1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.openr66.protocol.localhandler;
21
22 import org.waarp.common.logging.SysErrLogger;
23 import org.waarp.common.logging.WaarpLogger;
24 import org.waarp.common.logging.WaarpLoggerFactory;
25 import org.waarp.common.utility.WaarpShutdownHook;
26 import org.waarp.openr66.context.ErrorCode;
27 import org.waarp.openr66.context.R66FiniteDualStates;
28 import org.waarp.openr66.context.R66Result;
29 import org.waarp.openr66.context.R66Session;
30 import org.waarp.openr66.context.task.exception.OpenR66RunnerErrorException;
31 import org.waarp.openr66.database.data.DbTaskRunner;
32 import org.waarp.openr66.protocol.configuration.Configuration;
33 import org.waarp.openr66.protocol.exception.OpenR66ProtocolNoConnectionException;
34 import org.waarp.openr66.protocol.exception.OpenR66ProtocolNotAuthenticatedException;
35 import org.waarp.openr66.protocol.exception.OpenR66ProtocolPacketException;
36 import org.waarp.openr66.protocol.exception.OpenR66ProtocolRemoteShutdownException;
37 import org.waarp.openr66.protocol.exception.OpenR66ProtocolShutdownException;
38 import org.waarp.openr66.protocol.exception.OpenR66ProtocolSystemException;
39 import org.waarp.openr66.protocol.localhandler.packet.LocalPacketFactory;
40 import org.waarp.openr66.protocol.localhandler.packet.StartupPacket;
41 import org.waarp.openr66.protocol.localhandler.packet.ValidPacket;
42 import org.waarp.openr66.protocol.networkhandler.NetworkChannelReference;
43 import org.waarp.openr66.protocol.networkhandler.packet.NetworkPacket;
44 import org.waarp.openr66.protocol.utils.R66Future;
45
46 import java.util.Collection;
47 import java.util.Iterator;
48 import java.util.concurrent.ConcurrentHashMap;
49
50
51
52
53 public class LocalTransaction {
54
55
56
57 private static final WaarpLogger logger =
58 WaarpLoggerFactory.getLogger(LocalTransaction.class);
59
60
61
62
63 private final ConcurrentHashMap<Integer, LocalChannelReference>
64 localChannelHashMap =
65 new ConcurrentHashMap<Integer, LocalChannelReference>();
66
67
68
69
70 private final ConcurrentHashMap<String, LocalChannelReference>
71 localChannelHashMapIdBased =
72 new ConcurrentHashMap<String, LocalChannelReference>();
73
74
75
76
77 public LocalTransaction() {
78
79 }
80
81 public final String hashStatus() {
82 return "LocalTransaction: [localChannelHashMap: " +
83 localChannelHashMap.size() + " localChannelHashMapIdBased: " +
84 localChannelHashMapIdBased.size() + "] ";
85 }
86
87
88
89
90
91
92
93
94
95
96
97
98 public final LocalChannelReference getClient(final Integer remoteId,
99 final Integer localId)
100 throws OpenR66ProtocolSystemException {
101 final LocalChannelReference localChannelReference = getFromId(localId);
102 if (localChannelReference != null) {
103 if (localChannelReference.getRemoteId().compareTo(remoteId) != 0) {
104 localChannelReference.setRemoteId(remoteId);
105 }
106 return localChannelReference;
107 }
108 throw new OpenR66ProtocolSystemException(
109 "Cannot find LocalChannelReference");
110 }
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 public final LocalChannelReference createNewClient(
126 final NetworkChannelReference networkChannelReference,
127 final Integer remoteId, final R66Future futureRequest,
128 final boolean fromSsl) throws OpenR66ProtocolRemoteShutdownException,
129 OpenR66ProtocolNoConnectionException {
130 if (WaarpShutdownHook.isShutdownStarting()) {
131
132 throw new OpenR66ProtocolNoConnectionException(
133 "Cannot create client since the server is in shutdown.");
134 }
135 final LocalChannelReference localChannelReference =
136 new LocalChannelReference(networkChannelReference, remoteId,
137 futureRequest);
138 localChannelHashMap.put(localChannelReference.getLocalId(),
139 localChannelReference);
140 logger.debug("Db connection done and Create LocalChannel entry: {}",
141 localChannelReference);
142
143 final StartupPacket startup =
144 new StartupPacket(localChannelReference.getLocalId(), fromSsl);
145 try {
146 localChannelReference.getServerHandler().startup(startup);
147
148 localChannelReference.getServerHandler().validateAuthenticationReuse();
149 } catch (final OpenR66ProtocolPacketException e) {
150 throw new OpenR66ProtocolNoConnectionException(e);
151 } catch (final OpenR66ProtocolNotAuthenticatedException e) {
152 throw new OpenR66ProtocolNoConnectionException(e);
153 }
154 return localChannelReference;
155 }
156
157
158
159
160
161
162 public final LocalChannelReference getFromId(final Integer id) {
163 return localChannelHashMap.get(id);
164 }
165
166
167
168
169
170
171 protected final void remove(
172 final LocalChannelReference localChannelReference) {
173 logger.debug("DEBUG remove: {}", localChannelReference.getLocalId());
174 localChannelHashMap.remove(localChannelReference.getLocalId());
175 if (localChannelReference.getRequestId() != null) {
176 localChannelHashMapIdBased.remove(localChannelReference.getRequestId());
177 }
178 if (localChannelReference.getNetworkChannelObject() != null) {
179 localChannelReference.getNetworkChannelObject()
180 .remove(localChannelReference);
181 }
182 }
183
184
185
186
187
188 public final void setFromId(final DbTaskRunner runner,
189 final LocalChannelReference lcr) {
190 final String key = runner.getKey();
191 lcr.setRequestId(key);
192 localChannelHashMapIdBased.put(key, lcr);
193 }
194
195
196
197
198
199
200 public final LocalChannelReference getFromRequest(final String key) {
201 return localChannelHashMapIdBased.get(key);
202 }
203
204
205
206
207
208
209 public final boolean contained(final String key) {
210 return localChannelHashMapIdBased.containsKey(key);
211 }
212
213
214
215
216
217
218 public final boolean contained(final int id) {
219 return localChannelHashMap.containsKey(id);
220 }
221
222
223
224
225 public final int getNumberLocalChannel() {
226 return localChannelHashMap.size();
227 }
228
229
230
231
232 public final void debugPrintActiveLocalChannels() {
233 final Collection<LocalChannelReference> collection =
234 localChannelHashMap.values();
235 for (final LocalChannelReference localChannelReference : collection) {
236 logger.debug("Will close local channel: {}", localChannelReference);
237 logger.debug(" Containing: {}",
238 localChannelReference.getSession() != null?
239 localChannelReference.getSession() : "no session");
240 }
241 }
242
243
244
245
246 public final void shutdownLocalChannels() {
247 logger.warn(
248 "Will inform LocalChannels of Shutdown: " + localChannelHashMap.size());
249 final Collection<LocalChannelReference> collection =
250 localChannelHashMap.values();
251 final Iterator<LocalChannelReference> iterator = collection.iterator();
252 final ValidPacket packet = new ValidPacket("Shutdown forced", null,
253 LocalPacketFactory.SHUTDOWNPACKET);
254 while (iterator.hasNext()) {
255 final LocalChannelReference localChannelReference = iterator.next();
256 logger.info("Inform Shutdown {}", localChannelReference);
257 packet.setSmiddle(null);
258 packet.retain();
259
260
261 if (localChannelReference.getSession() != null) {
262 final R66Session session = localChannelReference.getSession();
263 final DbTaskRunner runner = session.getRunner();
264 if (runner != null && runner.isInTransfer()) {
265 if (!session.isSender()) {
266 final int newrank = runner.getRank();
267 packet.setSmiddle(Integer.toString(newrank));
268 }
269
270 try {
271 runner.saveStatus();
272 } catch (final OpenR66RunnerErrorException ignored) {
273
274 }
275 }
276 if (runner != null && !runner.isFinished()) {
277 final R66Result result =
278 new R66Result(new OpenR66ProtocolShutdownException(), session,
279 true, ErrorCode.Shutdown, runner);
280 result.setOther(packet);
281 try {
282 final NetworkPacket message =
283 new NetworkPacket(localChannelReference.getLocalId(),
284 localChannelReference.getRemoteId(), packet,
285 localChannelReference);
286 localChannelReference.sessionNewState(R66FiniteDualStates.SHUTDOWN);
287 try {
288 localChannelReference.getNetworkChannel().writeAndFlush(message)
289 .await(Configuration.WAITFORNETOP);
290 } catch (final InterruptedException e1) {
291 SysErrLogger.FAKE_LOGGER.ignoreLog(e1);
292 }
293 } catch (final OpenR66ProtocolPacketException ignored) {
294
295 }
296 try {
297 session.setFinalizeTransfer(false, result);
298 } catch (final OpenR66RunnerErrorException ignored) {
299
300 } catch (final OpenR66ProtocolSystemException ignored) {
301
302 }
303 }
304 localChannelReference.close();
305 continue;
306 }
307 try {
308 final NetworkPacket message =
309 new NetworkPacket(localChannelReference.getLocalId(),
310 localChannelReference.getRemoteId(), packet,
311 localChannelReference);
312 localChannelReference.getNetworkChannel().writeAndFlush(message);
313 } catch (final OpenR66ProtocolPacketException ignored) {
314
315 }
316 localChannelReference.close();
317 }
318 }
319
320
321
322
323 public final void closeAll() {
324 logger.debug("close All Local Channels");
325 final Collection<LocalChannelReference> collection =
326 localChannelHashMap.values();
327 for (final LocalChannelReference localChannelReference : collection) {
328 logger.info("Inform Shutdown {}", localChannelReference);
329 localChannelReference.close();
330 }
331 }
332
333 }