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 }