View Javadoc

1   /**
2      This file is part of GoldenGate Project (named also GoldenGate or GG).
3   
4      Copyright 2009, Frederic Bregier, and individual contributors by the @author
5      tags. See the COPYRIGHT.txt in the distribution for a full listing of
6      individual contributors.
7   
8      All GoldenGate Project is free software: you can redistribute it and/or 
9      modify it under the terms of the GNU General Public License as published 
10     by the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12  
13     GoldenGate is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17  
18     You should have received a copy of the GNU General Public License
19     along with GoldenGate .  If not, see <http://www.gnu.org/licenses/>.
20   */
21  package openr66.protocol.localhandler;
22  
23  import goldengate.common.command.exception.CommandAbstractException;
24  import goldengate.common.command.exception.Reply421Exception;
25  import goldengate.common.command.exception.Reply530Exception;
26  import goldengate.common.database.DbPreparedStatement;
27  import goldengate.common.database.exception.GoldenGateDatabaseException;
28  import goldengate.common.database.exception.GoldenGateDatabaseNoConnectionException;
29  import goldengate.common.database.exception.GoldenGateDatabaseNoDataException;
30  import goldengate.common.database.exception.GoldenGateDatabaseSqlException;
31  import goldengate.common.exception.FileTransferException;
32  import goldengate.common.file.DataBlock;
33  import goldengate.common.logging.GgInternalLogger;
34  import goldengate.common.logging.GgInternalLoggerFactory;
35  
36  import java.io.File;
37  import java.net.InetAddress;
38  import java.net.InetSocketAddress;
39  import java.net.UnknownHostException;
40  import java.sql.Timestamp;
41  import java.util.List;
42  
43  import openr66.client.AbstractBusinessRequest;
44  import openr66.commander.ClientRunner;
45  import openr66.configuration.AuthenticationFileBasedConfiguration;
46  import openr66.configuration.RuleFileBasedConfiguration;
47  import openr66.context.ErrorCode;
48  import static openr66.context.R66FiniteDualStates.*;
49  import openr66.context.R66Result;
50  import openr66.context.R66Session;
51  import openr66.context.authentication.R66Auth;
52  import openr66.context.filesystem.R66Dir;
53  import openr66.context.filesystem.R66File;
54  import openr66.context.task.ExecJavaTask;
55  import openr66.context.task.exception.OpenR66RunnerErrorException;
56  import openr66.context.task.exception.OpenR66RunnerException;
57  import openr66.database.DbConstant;
58  import openr66.database.data.DbHostAuth;
59  import openr66.database.data.DbRule;
60  import openr66.database.data.DbTaskRunner;
61  import openr66.protocol.configuration.Configuration;
62  import openr66.protocol.exception.OpenR66DatabaseGlobalException;
63  import openr66.protocol.exception.OpenR66Exception;
64  import openr66.protocol.exception.OpenR66ExceptionTrappedFactory;
65  import openr66.protocol.exception.OpenR66ProtocolBusinessCancelException;
66  import openr66.protocol.exception.OpenR66ProtocolBusinessException;
67  import openr66.protocol.exception.OpenR66ProtocolBusinessNoWriteBackException;
68  import openr66.protocol.exception.OpenR66ProtocolBusinessQueryAlreadyFinishedException;
69  import openr66.protocol.exception.OpenR66ProtocolBusinessQueryStillRunningException;
70  import openr66.protocol.exception.OpenR66ProtocolBusinessRemoteFileNotFoundException;
71  import openr66.protocol.exception.OpenR66ProtocolBusinessStopException;
72  import openr66.protocol.exception.OpenR66ProtocolNetworkException;
73  import openr66.protocol.exception.OpenR66ProtocolNoConnectionException;
74  import openr66.protocol.exception.OpenR66ProtocolNoDataException;
75  import openr66.protocol.exception.OpenR66ProtocolNoSslException;
76  import openr66.protocol.exception.OpenR66ProtocolNotAuthenticatedException;
77  import openr66.protocol.exception.OpenR66ProtocolNotYetConnectionException;
78  import openr66.protocol.exception.OpenR66ProtocolPacketException;
79  import openr66.protocol.exception.OpenR66ProtocolRemoteShutdownException;
80  import openr66.protocol.exception.OpenR66ProtocolShutdownException;
81  import openr66.protocol.exception.OpenR66ProtocolSystemException;
82  import openr66.protocol.localhandler.packet.AbstractLocalPacket;
83  import openr66.protocol.localhandler.packet.AuthentPacket;
84  import openr66.protocol.localhandler.packet.BusinessRequestPacket;
85  import openr66.protocol.localhandler.packet.ConnectionErrorPacket;
86  import openr66.protocol.localhandler.packet.DataPacket;
87  import openr66.protocol.localhandler.packet.EndRequestPacket;
88  import openr66.protocol.localhandler.packet.EndTransferPacket;
89  import openr66.protocol.localhandler.packet.ErrorPacket;
90  import openr66.protocol.localhandler.packet.InformationPacket;
91  import openr66.protocol.localhandler.packet.LocalPacketFactory;
92  import openr66.protocol.localhandler.packet.RequestPacket;
93  import openr66.protocol.localhandler.packet.ShutdownPacket;
94  import openr66.protocol.localhandler.packet.StartupPacket;
95  import openr66.protocol.localhandler.packet.TestPacket;
96  import openr66.protocol.localhandler.packet.ValidPacket;
97  import openr66.protocol.networkhandler.NetworkChannel;
98  import openr66.protocol.networkhandler.NetworkTransaction;
99  import openr66.protocol.utils.ChannelCloseTimer;
100 import openr66.protocol.utils.ChannelUtils;
101 import openr66.protocol.utils.R66Future;
102 import openr66.protocol.utils.TransferUtils;
103 
104 import org.jboss.netty.channel.Channel;
105 import org.jboss.netty.channel.ChannelFuture;
106 import org.jboss.netty.channel.ChannelFutureListener;
107 import org.jboss.netty.channel.ChannelHandlerContext;
108 import org.jboss.netty.channel.ChannelStateEvent;
109 import org.jboss.netty.channel.Channels;
110 import org.jboss.netty.channel.ExceptionEvent;
111 import org.jboss.netty.channel.MessageEvent;
112 import org.jboss.netty.channel.SimpleChannelHandler;
113 
114 /**
115  * The local server handler handles real end file operations.
116  *
117  * @author frederic bregier
118  */
119 public class LocalServerHandler extends SimpleChannelHandler {
120     /**
121      * Internal Logger
122      */
123     private static final GgInternalLogger logger = GgInternalLoggerFactory
124             .getLogger(LocalServerHandler.class);
125 
126     /**
127      * Session
128      */
129     private volatile R66Session session;
130     /**
131      * Local Channel Reference
132      */
133     private volatile LocalChannelReference localChannelReference;
134 
135     /*
136      * (non-Javadoc)
137      *
138      * @see
139      * org.jboss.netty.channel.SimpleChannelHandler#channelClosed(org.jboss.
140      * netty.channel.ChannelHandlerContext,
141      * org.jboss.netty.channel.ChannelStateEvent)
142      */
143     @Override
144     public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) {
145         logger.debug("Local Server Channel Closed: {} {}",
146                 (localChannelReference != null? localChannelReference
147                         : "no LocalChannelReference"), (session.getRunner() != null ?
148                             session.getRunner().toShortString() : "no runner"));
149         // clean session objects like files
150         DbTaskRunner runner = session.getRunner();
151         boolean mustFinalize = true;
152         if (localChannelReference != null &&
153                 localChannelReference.getFutureRequest().isDone()) {
154             // already done
155         } else {
156             if (localChannelReference != null) {
157                 R66Future fvr = localChannelReference.getFutureValidRequest();
158                 try {
159                     fvr.await();
160                 } catch (InterruptedException e1) {
161                 }
162                 if (fvr.isDone()) {
163                     if (!fvr.isSuccess()) {
164                         // test if remote server was Overloaded
165                         if (fvr.getResult().code == ErrorCode.ServerOverloaded) {
166                             // ignore
167                             mustFinalize = false;
168                         }
169                     }
170                 }
171                 logger.debug("Must Finalize: "+mustFinalize);
172                 if (mustFinalize) {
173                     session.newState(ERROR);
174                     R66Result finalValue = new R66Result(
175                             new OpenR66ProtocolSystemException("Finalize too early at close time But Must Finalize"),
176                             session, true, ErrorCode.FinalOp, runner); // True since closed
177                     try {
178                         tryFinalizeRequest(finalValue);
179                     } catch (OpenR66Exception e2) {
180                     }
181                 }
182             }
183         }
184         if (mustFinalize && runner != null) {
185             if (runner.isSelfRequested()) {
186                 R66Future transfer = localChannelReference.getFutureRequest();
187                 // Since requested : log
188                 R66Result result = transfer.getResult();
189                 if (transfer.isDone() && transfer.isSuccess()){
190                     logger.info("TRANSFER REQUESTED RESULT:\n    SUCCESS\n    "+
191                             (result != null ? result.toString() : "no result"));
192                 } else {
193                     logger.error("TRANSFER REQUESTED RESULT:\n    FAILURE\n    "+
194                             (result != null ? result.toString() : "no result"));
195                 }
196             }
197         }
198         session.setStatus(50);
199         session.newState(CLOSEDCHANNEL);
200         session.clear();
201         session.setStatus(51);
202         if (localChannelReference != null) {
203             if (localChannelReference.getDbSession() != null) {
204                 localChannelReference.getDbSession().endUseConnection();
205                 logger.debug("End Use Connection");
206             }
207             String requester = 
208                 (runner != null && runner.isSelfRequested() &&
209                         localChannelReference.getNetworkChannelObject() != null) ?
210                                 runner.getRequester() : null;
211             NetworkTransaction.removeNetworkChannel(localChannelReference
212                     .getNetworkChannel(), e.getChannel(), requester);
213             /*
214             // Only requested can has a remote client
215             if (runner != null && runner.isSelfRequested() &&
216                     localChannelReference.getNetworkChannelObject() != null
217                     && localChannelReference.getNetworkChannelObject().count <= 0) {
218                 NetworkTransaction.removeClient(runner.getRequester(),
219                         localChannelReference.getNetworkChannelObject());
220             }
221             */
222             session.setStatus(52);
223             Configuration.configuration.getLocalTransaction().remove(e.getChannel());
224         } else {
225             logger
226                     .error("Local Server Channel Closed but no LocalChannelReference: " +
227                             e.getChannel().getId());
228         }
229         // Now if runner is not yet finished, finish it by force
230         if (mustFinalize && localChannelReference != null && (!localChannelReference.getFutureRequest().isDone())) {
231             R66Result finalValue = new R66Result(
232                     new OpenR66ProtocolSystemException("Finalize too early at close time while Request not yet finished"),
233                     session, true, ErrorCode.FinalOp, runner);
234             localChannelReference.invalidateRequest(finalValue);
235             // In case stop the attached thread if any
236             ClientRunner clientRunner = localChannelReference.getClientRunner();
237             if (clientRunner != null) {
238                 try {
239                     Thread.sleep(Configuration.WAITFORNETOP);
240                 } catch (InterruptedException e1) {
241                 }
242                 clientRunner.interrupt();
243             }
244         }
245     }
246 
247     /*
248      * (non-Javadoc)
249      *
250      * @see
251      * org.jboss.netty.channel.SimpleChannelHandler#channelConnected(org.jboss
252      * .netty.channel.ChannelHandlerContext,
253      * org.jboss.netty.channel.ChannelStateEvent)
254      */
255     @Override
256     public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
257         session = new R66Session();
258         session.setStatus(60);
259     }
260 
261     /*
262      * (non-Javadoc)
263      *
264      * @see
265      * org.jboss.netty.channel.SimpleChannelHandler#messageReceived(org.jboss
266      * .netty.channel.ChannelHandlerContext,
267      * org.jboss.netty.channel.MessageEvent)
268      */
269     @Override
270     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
271             throws OpenR66Exception {
272         // action as requested and answer if necessary
273         final AbstractLocalPacket packet = (AbstractLocalPacket) e.getMessage();
274         if (packet.getType() == LocalPacketFactory.STARTUPPACKET) {
275             startup(e.getChannel(), (StartupPacket) packet);
276         } else {
277             if (localChannelReference == null) {
278                 logger.error("No LocalChannelReference at " +
279                         packet.getClass().getName());
280                 session.newState(ERROR);
281                 final ErrorPacket errorPacket = new ErrorPacket(
282                         "No LocalChannelReference at " +
283                                 packet.getClass().getName(),
284                                 ErrorCode.ConnectionImpossible.getCode(),
285                         ErrorPacket.FORWARDCLOSECODE);
286                 try {
287                     Channels.write(e.getChannel(), errorPacket).await();
288                 } catch (InterruptedException e1) {
289                 }
290                 localChannelReference.invalidateRequest(new R66Result(
291                         new OpenR66ProtocolSystemException(
292                                 "No LocalChannelReference"), session, true,
293                         ErrorCode.ConnectionImpossible, null));
294                 ChannelUtils.close(e.getChannel());
295                 if (Configuration.configuration.r66Mib != null) {
296                     Configuration.configuration.r66Mib.notifyWarning(
297                             "No LocalChannelReference", packet.getClass().getSimpleName());
298                 }
299                 return;
300             }
301             switch (packet.getType()) {
302                 case LocalPacketFactory.AUTHENTPACKET: {
303                     authent(e.getChannel(), (AuthentPacket) packet);
304                     break;
305                 }
306                     // Already done case LocalPacketFactory.STARTUPPACKET:
307                 case LocalPacketFactory.DATAPACKET: {
308                     session.newState(DATAR);
309                     data(e.getChannel(), (DataPacket) packet);
310                     break;
311                 }
312                 case LocalPacketFactory.VALIDPACKET: {
313                     valid(e.getChannel(), (ValidPacket) packet);
314                     break;
315                 }
316                 case LocalPacketFactory.ERRORPACKET: {
317                     session.newState(ERROR);
318                     errorMesg(e.getChannel(), (ErrorPacket) packet);
319                     break;
320                 }
321                 case LocalPacketFactory.CONNECTERRORPACKET: {
322                     connectionError(e.getChannel(),
323                             (ConnectionErrorPacket) packet);
324                     break;
325                 }
326                 case LocalPacketFactory.REQUESTPACKET: {
327                     request(e.getChannel(), (RequestPacket) packet);
328                     break;
329                 }
330                 case LocalPacketFactory.SHUTDOWNPACKET: {
331                     session.newState(SHUTDOWN);
332                     shutdown(e.getChannel(), (ShutdownPacket) packet);
333                     break;
334                 }
335                 case LocalPacketFactory.STOPPACKET:
336                 case LocalPacketFactory.CANCELPACKET:
337                 case LocalPacketFactory.CONFIMPORTPACKET:
338                 case LocalPacketFactory.CONFEXPORTPACKET:
339                 case LocalPacketFactory.BANDWIDTHPACKET: {
340                     logger.error("Unimplemented Mesg: " +
341                             packet.getClass().getName());
342                     session.newState(ERROR);
343                     localChannelReference.invalidateRequest(new R66Result(
344                             new OpenR66ProtocolSystemException(
345                                     "Not implemented"), session, true,
346                             ErrorCode.Unimplemented, null));
347                     final ErrorPacket errorPacket = new ErrorPacket(
348                             "Unimplemented Mesg: " +
349                                     packet.getClass().getName(),
350                                     ErrorCode.Unimplemented.getCode(),
351                             ErrorPacket.FORWARDCLOSECODE);
352                     ChannelUtils.writeAbstractLocalPacket(localChannelReference, errorPacket, true);
353                     ChannelUtils.close(e.getChannel());
354                     break;
355                 }
356                 case LocalPacketFactory.TESTPACKET: {
357                     session.newState(TEST);
358                     test(e.getChannel(), (TestPacket) packet);
359                     break;
360                 }
361                 case LocalPacketFactory.ENDTRANSFERPACKET: {
362                     endTransfer(e.getChannel(), (EndTransferPacket) packet);
363                     break;
364                 }
365                 case LocalPacketFactory.INFORMATIONPACKET: {
366                     session.newState(INFORMATION);
367                     information(e.getChannel(), (InformationPacket) packet);
368                     break;
369                 }
370                 case LocalPacketFactory.ENDREQUESTPACKET: {
371                     endRequest(e.getChannel(), (EndRequestPacket) packet);
372                     break;
373                 }
374                 case LocalPacketFactory.BUSINESSREQUESTPACKET: {
375                     businessRequest(e.getChannel(), (BusinessRequestPacket) packet);
376                     break;
377                 }
378                 default: {
379                     logger
380                             .error("Unknown Mesg: " +
381                                     packet.getClass().getName());
382                     session.newState(ERROR);
383                     localChannelReference.invalidateRequest(new R66Result(
384                             new OpenR66ProtocolSystemException(
385                                     "Unknown Message"), session, true,
386                             ErrorCode.Unimplemented, null));
387                     final ErrorPacket errorPacket = new ErrorPacket(
388                             "Unkown Mesg: " + packet.getClass().getName(),
389                             ErrorCode.Unimplemented.getCode(), ErrorPacket.FORWARDCLOSECODE);
390                     ChannelUtils.writeAbstractLocalPacket(localChannelReference, errorPacket, true);
391                     ChannelUtils.close(e.getChannel());
392                 }
393             }
394         }
395     }
396 
397     /*
398      * (non-Javadoc)
399      *
400      * @see
401      * org.jboss.netty.channel.SimpleChannelHandler#exceptionCaught(org.jboss
402      * .netty.channel.ChannelHandlerContext,
403      * org.jboss.netty.channel.ExceptionEvent)
404      */
405     @Override
406     public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
407         // inform clients
408         if (localChannelReference != null && localChannelReference.getFutureRequest().isDone()) {
409             return;
410         }
411         OpenR66Exception exception = OpenR66ExceptionTrappedFactory
412                 .getExceptionFromTrappedException(e.getChannel(), e);
413         ErrorCode code = null;
414         if (exception != null) {
415             session.newState(ERROR);
416             boolean isAnswered = false;
417             if (exception instanceof OpenR66ProtocolShutdownException) {
418                 logger.warn("Shutdown order received and going from: " +
419                         session.getAuth().getUser());
420                 if (localChannelReference != null) {
421                     R66Result finalValue = new R66Result(exception, session, true,
422                             ErrorCode.Shutdown, session.getRunner());
423                     try {
424                         tryFinalizeRequest(finalValue);
425                     } catch (OpenR66RunnerErrorException e2) {
426                     } catch (OpenR66ProtocolSystemException e2) {
427                     }
428                     if (!localChannelReference.getFutureRequest().isDone()) {
429                         try {
430                             session.setFinalizeTransfer(false, finalValue);
431                         } catch (OpenR66RunnerErrorException e1) {
432                             localChannelReference.invalidateRequest(finalValue);
433                         } catch (OpenR66ProtocolSystemException e1) {
434                             localChannelReference.invalidateRequest(finalValue);
435                         }
436                     }
437                 }
438                 // dont'close, thread will do
439                 Thread thread = new Thread(new ChannelUtils(), "R66 Shutdown Thread");
440                 thread.setDaemon(true);
441                 thread.start();
442                 // set global shutdown info and before close, send a valid
443                 // shutdown to all
444                 session.setStatus(54);
445                 return;
446             } else {
447                 if (localChannelReference != null && localChannelReference.getFutureRequest() != null) {
448                     if (localChannelReference.getFutureRequest().isDone()) {
449                         R66Result result = localChannelReference.getFutureRequest()
450                             .getResult();
451                         if (result != null) {
452                             isAnswered = result.isAnswered;
453                         }
454                     }
455                 }
456                 if (exception instanceof OpenR66ProtocolNoConnectionException) {
457                     code = ErrorCode.ConnectionImpossible;
458                     DbTaskRunner runner = session.getRunner();
459                     if (runner != null) {
460                         runner.stopOrCancelRunner(code);
461                     }
462                 } else if (exception instanceof OpenR66ProtocolBusinessCancelException) {
463                     code = ErrorCode.CanceledTransfer;
464                     DbTaskRunner runner = session.getRunner();
465                     if (runner != null) {
466                         runner.stopOrCancelRunner(code);
467                     }
468                 } else if (exception instanceof OpenR66ProtocolBusinessStopException) {
469                     code = ErrorCode.StoppedTransfer;
470                     DbTaskRunner runner = session.getRunner();
471                     if (runner != null) {
472                         runner.stopOrCancelRunner(code);
473                     }
474                 } else if (exception instanceof OpenR66ProtocolBusinessQueryAlreadyFinishedException) {
475                     code = ErrorCode.QueryAlreadyFinished;
476                     try {
477                         tryFinalizeRequest(new R66Result(session, true, code, session.getRunner()));
478                         return;
479                     } catch (OpenR66RunnerErrorException e1) {
480                     } catch (OpenR66ProtocolSystemException e1) {
481                     }
482                 } else if (exception instanceof OpenR66ProtocolBusinessQueryStillRunningException) {
483                     code = ErrorCode.QueryStillRunning;
484                     // nothing is to be done
485                     logger.error("Will close channel since ", exception);
486                     Channels.close(e.getChannel());
487                     session.setStatus(56);
488                     return;
489                 } else if (exception instanceof OpenR66ProtocolBusinessRemoteFileNotFoundException) {
490                     code = ErrorCode.FileNotFound;
491                 } else if (exception instanceof OpenR66RunnerException) {
492                     code = ErrorCode.ExternalOp;
493                 } else if (exception instanceof OpenR66ProtocolNotAuthenticatedException) {
494                     code = ErrorCode.BadAuthent;
495                 } else if (exception instanceof OpenR66ProtocolNetworkException) {
496                     code = ErrorCode.Disconnection;
497                     DbTaskRunner runner = session.getRunner();
498                     if (runner != null) {
499                         R66Result finalValue = new R66Result(
500                                 new OpenR66ProtocolSystemException("Finalize too early at close time with Network Exception"),
501                                 session, true, code, session.getRunner());
502                         try {
503                             tryFinalizeRequest(finalValue);
504                         } catch (OpenR66Exception e2) {
505                         }
506                     }
507                 } else if (exception instanceof OpenR66ProtocolRemoteShutdownException) {
508                     code = ErrorCode.RemoteShutdown;
509                     DbTaskRunner runner = session.getRunner();
510                     if (runner != null) {
511                         runner.stopOrCancelRunner(code);
512                     }
513                 } else {
514                     DbTaskRunner runner = session.getRunner();
515                     if (runner != null) {
516                         switch (runner.getErrorInfo()) {
517                             case InitOk:
518                             case PostProcessingOk:
519                             case PreProcessingOk:
520                             case Running:
521                             case TransferOk:
522                                 code = ErrorCode.Internal;
523                             default:
524                                 code = runner.getErrorInfo();
525                         }
526                     } else {
527                         code = ErrorCode.Internal;
528                     }
529                 }
530                 if ((!isAnswered) &&
531                         (!(exception instanceof OpenR66ProtocolBusinessNoWriteBackException)) &&
532                         (!(exception instanceof OpenR66ProtocolNoConnectionException))) {
533                     if (code == null || code == ErrorCode.Internal) {
534                         code = ErrorCode.RemoteError;
535                     }
536                     final ErrorPacket errorPacket = new ErrorPacket(exception
537                             .getMessage(),
538                             code.getCode(), ErrorPacket.FORWARDCLOSECODE);
539                     try {
540                         ChannelUtils.writeAbstractLocalPacket(localChannelReference,
541                                 errorPacket, true);
542                     } catch (OpenR66ProtocolPacketException e1) {
543                         // should not be
544                     }
545                 }
546                 R66Result finalValue =
547                     new R66Result(
548                             exception, session, true, code, session.getRunner());
549                 try {
550                     session.setFinalizeTransfer(false, finalValue);
551                     if (localChannelReference != null)
552                         localChannelReference.invalidateRequest(finalValue);
553                 } catch (OpenR66RunnerErrorException e1) {
554                     if (localChannelReference != null)
555                         localChannelReference.invalidateRequest(finalValue);
556                 } catch (OpenR66ProtocolSystemException e1) {
557                     if (localChannelReference != null)
558                         localChannelReference.invalidateRequest(finalValue);
559                 }
560             }
561             if (exception instanceof OpenR66ProtocolBusinessNoWriteBackException) {
562                 logger.error("Will close channel {}", exception.getMessage());
563                 Channels.close(e.getChannel());
564                 session.setStatus(56);
565                 return;
566             } else if (exception instanceof OpenR66ProtocolNoConnectionException) {
567                 logger.error("Will close channel {}", exception.getMessage());
568                 Channels.close(e.getChannel());
569                 session.setStatus(57);
570                 return;
571             }
572             session.setStatus(58);
573             ChannelCloseTimer.closeFutureChannel(e.getChannel());
574         } else {
575             // Nothing to do
576             session.setStatus(59);
577             return;
578         }
579     }
580     /**
581      * Startup of the session and the local channel reference
582      * @param channel
583      * @param packet
584      * @throws OpenR66ProtocolPacketException
585      */
586     private void startup(Channel channel, StartupPacket packet)
587             throws OpenR66ProtocolPacketException {
588         localChannelReference = Configuration.configuration
589                 .getLocalTransaction().getFromId(packet.getLocalId());
590         if (localChannelReference == null) {
591             session.newState(ERROR);
592             logger.error("Cannot startup");
593             ErrorPacket error = new ErrorPacket("Cannot startup connection",
594                     ErrorCode.ConnectionImpossible.getCode(), ErrorPacket.FORWARDCLOSECODE);
595             try {
596                 Channels.write(channel, error).await();
597             } catch (InterruptedException e) {
598             }
599             // Cannot do writeBack(error, true);
600             session.setStatus(40);
601             ChannelCloseTimer.closeFutureChannel(channel);
602             return;
603         }
604         NetworkChannel networkChannel =
605             NetworkTransaction.getNetworkChannel(localChannelReference.getNetworkChannel());
606         if (networkChannel != null) {
607             localChannelReference.setNetworkChannelObject(networkChannel);
608         } else {
609             logger.error("No NetworkChannek found!");
610         }
611         session.newState(STARTUP);
612         localChannelReference.validateStartup(true);
613         session.setLocalChannelReference(localChannelReference);
614         Channels.write(channel, packet);
615         session.setStatus(41);
616     }
617     /**
618      * Refuse a connection
619      * @param channel
620      * @param packet
621      * @param e1
622      * @throws OpenR66ProtocolPacketException
623      */
624     private void refusedConnection(Channel channel, AuthentPacket packet, Exception e1) throws OpenR66ProtocolPacketException {
625         logger.error("Cannot connect: " + packet.getHostId(), e1);
626         if (Configuration.configuration.r66Mib != null) {
627             Configuration.configuration.r66Mib.notifyError(
628                     "Connection not allowed since "+e1.getMessage(), packet.getHostId());
629         }
630         R66Result result = new R66Result(
631                 new OpenR66ProtocolSystemException(
632                         "Connection not allowed", e1), session, true,
633                 ErrorCode.BadAuthent, null);
634         localChannelReference.invalidateRequest(result);
635         session.newState(ERROR);
636         ErrorPacket error = new ErrorPacket("Connection not allowed",
637                 ErrorCode.BadAuthent.getCode(),
638                 ErrorPacket.FORWARDCLOSECODE);
639         ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
640         localChannelReference.validateConnection(false, result);
641         ChannelCloseTimer.closeFutureChannel(channel);
642     }
643     /**
644      * Authentication
645      * @param channel
646      * @param packet
647      * @throws OpenR66ProtocolPacketException
648      */
649     private void authent(Channel channel, AuthentPacket packet)
650             throws OpenR66ProtocolPacketException {
651         if (packet.isToValidate()) {
652            session.newState(AUTHENTR);
653         }
654 
655         if (localChannelReference.getDbSession() != null) {
656             localChannelReference.getDbSession().useConnection();
657         }
658         try {
659             session.getAuth().connection(localChannelReference.getDbSession(),
660                     packet.getHostId(), packet.getKey());
661         } catch (Reply530Exception e1) {
662             refusedConnection(channel, packet, e1);
663             session.setStatus(42);
664             return;
665         } catch (Reply421Exception e1) {
666             session.newState(ERROR);
667             logger.error("Service unavailable: " + packet.getHostId(), e1);
668             R66Result result = new R66Result(
669                     new OpenR66ProtocolSystemException("Service unavailable",
670                             e1), session, true,
671                     ErrorCode.ConnectionImpossible, null);
672             localChannelReference.invalidateRequest(result);
673             ErrorPacket error = new ErrorPacket("Service unavailable",
674                     ErrorCode.ConnectionImpossible.getCode(),
675                     ErrorPacket.FORWARDCLOSECODE);
676             ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
677             localChannelReference.validateConnection(false, result);
678             ChannelCloseTimer.closeFutureChannel(channel);
679             session.setStatus(43);
680             return;
681         }
682         // Now if configuration say to do so: check remote ip address
683         if (Configuration.configuration.checkRemoteAddress) {
684             DbHostAuth host = R66Auth.getServerAuth(DbConstant.admin.session,
685                     packet.getHostId());
686             boolean toTest = false;
687             if (host.isClient()) {
688                 if (Configuration.configuration.checkClientAddress) {
689                     if (host.isNoAddress()) {
690                         // 0.0.0.0 so nothing
691                         toTest = false;
692                     } else {
693                         toTest = true;
694                     }
695                 }
696             } else {
697                 toTest = true;
698             }
699             if (toTest) {
700                 // Real address so compare
701                 String address = host.getAddress();
702                 InetAddress []inetAddress = null;
703                 try {
704                     inetAddress = InetAddress.getAllByName(address);
705                 } catch (UnknownHostException e) {
706                     inetAddress = null;
707                 }
708                 if (inetAddress != null) {
709                     InetSocketAddress socketAddress = (InetSocketAddress) session.getRemoteAddress();
710                     boolean found = false;
711                     for (int i = 0; i < inetAddress.length; i++) {
712                         if (socketAddress.getAddress().equals(inetAddress[i])) {
713                             found = true;
714                             break;
715                         }
716                     }
717                     if (! found) {
718                         // error
719                         refusedConnection(channel, packet, 
720                                 new OpenR66ProtocolNotAuthenticatedException("Server IP not authenticated: "+
721                                         inetAddress[0].toString()+" compare to "+socketAddress.getAddress().toString()));
722                         session.setStatus(104);
723                         return;
724                     }
725                 }
726             }
727         }
728         R66Result result = new R66Result(session, true, ErrorCode.InitOk, null);
729         session.newState(AUTHENTD);
730         localChannelReference.validateConnection(true, result);
731         logger.debug("Local Server Channel Validated: {} ",
732                 (localChannelReference != null? localChannelReference
733                         : "no LocalChannelReference"));
734         session.setStatus(44);
735         if (packet.isToValidate()) {
736             // only requested
737             NetworkTransaction.addClient(localChannelReference.getNetworkChannel(),
738                     packet.getHostId());
739             packet.validate(session.getAuth().isSsl());
740             ChannelUtils.writeAbstractLocalPacket(localChannelReference, packet, false);
741             session.setStatus(98);
742         }
743     }
744     /**
745      * Receive a connection error
746      * @param channel
747      * @param packet
748      */
749     private void connectionError(Channel channel, ConnectionErrorPacket packet) {
750         // do something according to the error
751         logger.error(channel.getId() + ": " + packet.toString());
752         localChannelReference.invalidateRequest(new R66Result(
753                 new OpenR66ProtocolSystemException(packet.getSheader()),
754                 session, true, ErrorCode.ConnectionImpossible, null));
755         // True since closing
756         session.newState(ERROR);
757         session.setStatus(45);
758         Channels.close(channel);
759     }
760     /**
761      * Class to finalize a runner when the future is over
762      * @author Frederic Bregier
763      *
764      */
765     private class RunnerChannelFutureListener implements ChannelFutureListener {
766         private LocalChannelReference localChannelReference;
767         private R66Result result;
768         public RunnerChannelFutureListener(LocalChannelReference localChannelReference,
769                 R66Result result) {
770             this.localChannelReference = localChannelReference;
771             this.result = result;
772         }
773         /* (non-Javadoc)
774          * @see org.jboss.netty.channel.ChannelFutureListener#operationComplete(org.jboss.netty.channel.ChannelFuture)
775          */
776         @Override
777         public void operationComplete(ChannelFuture future) throws Exception {
778             localChannelReference.invalidateRequest(
779                     result);
780             ChannelCloseTimer.closeFutureChannel(localChannelReference.getLocalChannel());
781         }
782 
783     }
784     /**
785      * Receive a remote error
786      * @param channel
787      * @param packet
788      * @throws OpenR66RunnerErrorException
789      * @throws OpenR66ProtocolSystemException
790      * @throws OpenR66ProtocolBusinessException
791      */
792     private void errorMesg(Channel channel, ErrorPacket packet)
793             throws OpenR66RunnerErrorException, OpenR66ProtocolSystemException, OpenR66ProtocolBusinessException {
794         // do something according to the error
795         if (session.getLocalChannelReference().getFutureRequest().isDone()) {
796             // already canceled or successful
797             return;
798         }
799         logger.error(channel.getId() + ": " + packet.toString());
800         session.setStatus(46);
801         ErrorCode code = ErrorCode.getFromCode(packet.getSmiddle());
802         session.getLocalChannelReference().setErrorMessage(packet.getSheader(),code);
803         OpenR66ProtocolBusinessException exception;
804         if (code.code == ErrorCode.CanceledTransfer.code) {
805             exception =
806                 new OpenR66ProtocolBusinessCancelException(packet.getSheader());
807             int rank = 0;
808             DbTaskRunner runner = this.session.getRunner();
809             if (runner != null) {
810                 runner.setRankAtStartup(rank);
811                 runner.stopOrCancelRunner(code);
812             }
813             R66Result result = new R66Result(exception, session,
814                     true, code, runner);
815             // now try to inform other
816             try {
817                 ChannelUtils.writeAbstractLocalPacket(localChannelReference, packet, false).
818                     addListener(new RunnerChannelFutureListener(localChannelReference, result));
819             } catch (OpenR66ProtocolPacketException e) {
820             }
821             session.setFinalizeTransfer(false, result);
822             return;
823         } else if (code.code == ErrorCode.StoppedTransfer.code) {
824             exception =
825                 new OpenR66ProtocolBusinessStopException(packet.getSheader());
826             String []vars = packet.getSheader().split(" ");
827             String var = vars[vars.length-1];
828             int rank = Integer.parseInt(var);
829             DbTaskRunner runner = this.session.getRunner();
830             if (runner != null) {
831                 if (rank < runner.getRank()) {
832                     runner.setRankAtStartup(rank);
833                 }
834                 runner.stopOrCancelRunner(code);
835             }
836             R66Result result = new R66Result(exception, session,
837                     true, code, runner);
838             // now try to inform other
839             try {
840                 ChannelUtils.writeAbstractLocalPacket(localChannelReference, packet, false).
841                     addListener(new RunnerChannelFutureListener(localChannelReference, result));
842             } catch (OpenR66ProtocolPacketException e) {
843             }
844             session.setFinalizeTransfer(false, result);
845             return;
846         } else if (code.code == ErrorCode.QueryAlreadyFinished.code) {
847             DbTaskRunner runner = session.getRunner();
848             if (runner == null) {
849                 exception =
850                     new OpenR66ProtocolBusinessCancelException(packet.toString());
851             } else {
852                 if (runner.isSender()) {
853                     exception =
854                         new OpenR66ProtocolBusinessQueryAlreadyFinishedException(packet.getSheader());
855                     runner.finishTransferTask(code);
856                     tryFinalizeRequest(new R66Result(exception, session, true, code, runner));
857                 } else {
858                     exception =
859                         new OpenR66ProtocolBusinessCancelException(packet.toString());
860                 }
861             }
862             throw exception;
863         } else if (code.code == ErrorCode.QueryStillRunning.code) {
864             exception =
865                 new OpenR66ProtocolBusinessQueryStillRunningException(packet.getSheader());
866             throw exception;
867         } else if (code.code == ErrorCode.BadAuthent.code) {
868             exception =
869                 new OpenR66ProtocolNotAuthenticatedException(packet.toString());
870         } else if (code.code == ErrorCode.QueryRemotelyUnknown.code) {
871             exception =
872                 new OpenR66ProtocolBusinessCancelException(packet.toString());
873         } else if (code.code == ErrorCode.FileNotFound.code) {
874             exception =
875                 new OpenR66ProtocolBusinessRemoteFileNotFoundException(packet.toString());
876         } else {
877             exception =
878                 new OpenR66ProtocolBusinessNoWriteBackException(packet.toString());
879         }
880         session.setFinalizeTransfer(false, new R66Result(exception, session,
881                 true, code, session.getRunner()));
882         throw exception;
883     }
884 
885     /**
886      * Finalize a request initialization in error
887      * @param channel
888      * @param code
889      * @param runner
890      * @param e1
891      * @param packet
892      * @throws OpenR66ProtocolPacketException
893      */
894     private void endInitRequestInError(Channel channel, ErrorCode code, DbTaskRunner runner,
895             OpenR66Exception e1, RequestPacket packet) throws OpenR66ProtocolPacketException {
896         logger.error("TaskRunner initialisation in error: "+ code.mesg+" "+session+" {} runner {}",
897                 e1 != null ? e1.getMessage():"no exception", (runner != null ? runner.toShortString() : "no runner"));
898         localChannelReference.invalidateRequest(new R66Result(
899                 e1, session, true, code, null));
900 
901         if (packet.isToValidate()) {
902             /// answer with a wrong request since runner is not set on remote host
903             if (runner != null) {
904                 if (runner.isSender()) {
905                     // In case Wildcard was used
906                     logger.debug("New FILENAME: {}", runner.getOriginalFilename());
907                     packet.setFilename(runner.getOriginalFilename());
908                     logger.debug("Rank set: "+runner.getRank());
909                     packet.setRank(runner.getRank());
910                 } else {
911                     logger.debug("Rank set: "+runner.getRank());
912                     packet.setRank(runner.getRank());
913                 }
914             }
915             packet.validate();
916             packet.setCode(code.code);
917             session.newState(ERROR);
918             ChannelUtils.writeAbstractLocalPacket(localChannelReference, packet, true);
919         } else {
920             session.newState(ERROR);
921             ErrorPacket error = new ErrorPacket(
922                 "TaskRunner initialisation in error: "+e1
923                         .getMessage()+" for "+packet.toString()+" since "+code.mesg,
924                         code.getCode(), ErrorPacket.FORWARDCLOSECODE);
925             ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
926         }
927         session.setStatus(47);
928         ChannelCloseTimer.closeFutureChannel(channel);
929     }
930 
931     /**
932      * Receive a request
933      * @param channel
934      * @param packet
935      * @throws OpenR66ProtocolNoDataException
936      * @throws OpenR66ProtocolPacketException
937      * @throws OpenR66ProtocolBusinessException
938      * @throws OpenR66ProtocolSystemException
939      * @throws OpenR66RunnerErrorException
940      */
941     private void request(Channel channel, RequestPacket packet)
942             throws OpenR66ProtocolNoDataException, OpenR66ProtocolPacketException,
943             OpenR66RunnerErrorException, OpenR66ProtocolSystemException,
944             OpenR66ProtocolBusinessException {
945         session.setStatus(99);
946         if (!session.isAuthenticated()) {
947             session.setStatus(48);
948             throw new OpenR66ProtocolNotAuthenticatedException(
949                     "Not authenticated while Request received");
950         }
951         // XXX validLimit only on requested side
952         if (packet.isToValidate()) {
953             if (Configuration.configuration.constraintLimitHandler.checkConstraints()) {
954                 if (Configuration.configuration.r66Mib != null) {
955                     Configuration.configuration.r66Mib.
956                         notifyOverloaded("Rule: " + packet.getRulename()+" from "+session.getAuth().toString(), 
957                                 Configuration.configuration.constraintLimitHandler.lastAlert);
958                 }
959                 logger.info("Limit exceeded when receive request with Rule: " + packet.getRulename()+" from "+session.getAuth().toString());
960                 session.setStatus(100);
961                 endInitRequestInError(channel,
962                         ErrorCode.ServerOverloaded, null,
963                     new OpenR66ProtocolNotYetConnectionException(
964                        "Limit exceeded"), packet);
965                 session.setStatus(100);
966                 return;
967             }
968         } else if (packet.getCode() == ErrorCode.ServerOverloaded.code) {
969             // XXX unvalid limit on requested host received
970             logger.info("TaskRunner initialisation in error: "+ ErrorCode.ServerOverloaded.mesg);
971             localChannelReference.invalidateRequest(new R66Result(
972                     null, session, true, ErrorCode.ServerOverloaded, null));
973             session.setStatus(101);
974             ChannelCloseTimer.closeFutureChannel(channel);
975             return;
976         }
977         DbRule rule;
978         try {
979             rule = new DbRule(localChannelReference.getDbSession(), packet.getRulename());
980         } catch (GoldenGateDatabaseException e) {
981             logger.info("Rule is unknown: " + packet.getRulename()+" {}", e.getMessage());
982             session.setStatus(49);
983             endInitRequestInError(channel,
984                     ErrorCode.QueryRemotelyUnknown, null,
985                 new OpenR66ProtocolBusinessException(
986                    "The Transfer is associated with an Unknown Rule: "+
987                    packet.getRulename()), packet);
988             return;
989         }
990         int blocksize = packet.getBlocksize();
991         if (packet.isToValidate()) {
992             if (!rule.checkHostAllow(session.getAuth().getUser())) {
993                 session.setStatus(30);
994                 throw new OpenR66ProtocolNotAuthenticatedException(
995                         "Rule is not allowed for the remote host");
996             }
997             // Check if the blocksize is greater than local value
998             if (Configuration.configuration.BLOCKSIZE < blocksize) {
999                 blocksize = Configuration.configuration.BLOCKSIZE;
1000                 packet = new RequestPacket(packet.getRulename(),packet.getMode(),
1001                         packet.getFilename(),blocksize,packet.getRank(), 
1002                         packet.getSpecialId(), packet.getFileInformation());
1003             }
1004         }
1005         if (! RequestPacket.isCompatibleMode(rule.mode, packet.getMode())) {
1006             // not compatible Rule and mode in request
1007             throw new OpenR66ProtocolNotAuthenticatedException(
1008                     "Rule has not the same mode of transmission: "+rule.mode+" vs "+packet.getMode());
1009         }
1010         session.setBlockSize(blocksize);
1011         DbTaskRunner runner;
1012         if (packet.getSpecialId() != DbConstant.ILLEGALVALUE) {
1013             // Reload or create
1014             String requested = DbTaskRunner.getRequested(session, packet);
1015             String requester = DbTaskRunner.getRequester(session, packet);
1016             if (packet.isToValidate()) {
1017                 // Id could be a creation or a reload
1018                 // Try reload
1019                 try {
1020                     runner = new DbTaskRunner(localChannelReference.getDbSession(),
1021                             session, rule, packet.getSpecialId(),
1022                             requester, requested);
1023                     if (runner.isAllDone()) {
1024                         // truly an error since done
1025                         session.setStatus(31);
1026                         endInitRequestInError(channel,
1027                                 ErrorCode.QueryAlreadyFinished, runner,
1028                             new OpenR66ProtocolBusinessQueryAlreadyFinishedException(
1029                                "The TransferId is associated with a Transfer already finished: "+
1030                                packet.getSpecialId()), packet);
1031                         return;
1032                     }
1033                     LocalChannelReference lcr =
1034                         Configuration.configuration.getLocalTransaction().
1035                         getFromRequest(requested+" "+requester+" "+packet.getSpecialId());
1036                     if (lcr != null) {
1037                         // truly an error since still running
1038                         session.setStatus(32);
1039                         endInitRequestInError(channel,
1040                                 ErrorCode.QueryStillRunning, runner,
1041                             new OpenR66ProtocolBusinessQueryStillRunningException(
1042                                "The TransferId is associated with a Transfer still running: "+
1043                                packet.getSpecialId()), packet);
1044                         return;
1045                     }
1046                     // ok to restart
1047                     try {
1048                         runner.restart(false);
1049                     } catch (OpenR66RunnerErrorException e) {
1050                     }
1051                 } catch (GoldenGateDatabaseNoDataException e) {
1052                     // Reception of request from requester host
1053                     boolean isRetrieve = RequestPacket.isRecvMode(packet.getMode());
1054                     try {
1055                         runner = new DbTaskRunner(localChannelReference.getDbSession(),
1056                                 session, rule, isRetrieve, packet);
1057                     } catch (GoldenGateDatabaseException e1) {
1058                         session.setStatus(33);
1059                         endInitRequestInError(channel, ErrorCode.QueryRemotelyUnknown, 
1060                                 null, new OpenR66DatabaseGlobalException(e), packet);
1061                         return;
1062                     }
1063                 } catch (GoldenGateDatabaseException e) {
1064                     session.setStatus(34);
1065                     endInitRequestInError(channel, ErrorCode.QueryRemotelyUnknown, null, 
1066                             new OpenR66DatabaseGlobalException(e), packet);
1067                     return;
1068                 }
1069                 // Change the SpecialID! => could generate an error ? 
1070                 packet.setSpecialId(runner.getSpecialId());
1071             } else {
1072                 // Id should be a reload
1073                 try {
1074                     runner = new DbTaskRunner(localChannelReference.getDbSession(),
1075                             session, rule, packet.getSpecialId(),
1076                             requester, requested);
1077                     try {
1078                         runner.restart(false);
1079                     } catch (OpenR66RunnerErrorException e) {
1080                     }
1081                 } catch (GoldenGateDatabaseException e) {
1082                     if (localChannelReference.getDbSession() == null) {
1083                         //Special case of no database client
1084                         boolean isRetrieve = (!RequestPacket.isRecvMode(packet.getMode()));
1085                         try {
1086                             runner = new DbTaskRunner(localChannelReference.getDbSession(),
1087                                     session, rule, isRetrieve, packet);
1088                         } catch (GoldenGateDatabaseException e1) {
1089                             session.setStatus(35);
1090                             endInitRequestInError(channel, ErrorCode.QueryRemotelyUnknown, null,
1091                                     new OpenR66DatabaseGlobalException(e1), packet);
1092                             return;
1093                         }
1094                     } else {
1095                         endInitRequestInError(channel, ErrorCode.QueryRemotelyUnknown, null,
1096                                 new OpenR66DatabaseGlobalException(e), packet);
1097                         session.setStatus(36);
1098                         return;
1099                     }
1100                 }
1101             }
1102         } else {
1103             // Very new request
1104             // should not be the case (the requester should always set the id)
1105             logger.error("NO TransferID specified: SHOULD NOT BE THE CASE");
1106             boolean isRetrieve = packet.isRetrieve();
1107             if (!packet.isToValidate()) {
1108                 isRetrieve = !isRetrieve;
1109             }
1110             try {
1111                 runner = new DbTaskRunner(localChannelReference.getDbSession(),
1112                         session, rule, isRetrieve, packet);
1113             } catch (GoldenGateDatabaseException e) {
1114                 session.setStatus(37);
1115                 endInitRequestInError(channel, ErrorCode.QueryRemotelyUnknown, null,
1116                         new OpenR66DatabaseGlobalException(e), packet);
1117                 return;
1118             }
1119             packet.setSpecialId(runner.getSpecialId());
1120         }
1121         // Check now if request is a valid one
1122         if (packet.getCode() != ErrorCode.InitOk.code) {
1123             //not valid so create an error from there
1124             ErrorCode code = ErrorCode.getFromCode(""+packet.getCode());
1125             session.setBadRunner(runner, code);
1126             session.newState(ERROR);
1127             logger.error("Bad runner at startup {} {}", packet, session);
1128             ErrorPacket errorPacket = new ErrorPacket(code.mesg,
1129                     code.getCode(), ErrorPacket.FORWARDCLOSECODE);
1130             errorMesg(channel, errorPacket);
1131             return;
1132         }
1133         // Receiver can specify a rank different from database
1134         if (runner.isSender()) {
1135             logger.debug("Rank was: "+runner.getRank()+" -> "+packet.getRank());
1136             runner.setRankAtStartup(packet.getRank());
1137         } else if (runner.getRank() > packet.getRank()) {
1138             logger.debug("Recv Rank was: "+runner.getRank()+" -> "+packet.getRank());
1139             // if receiver, change only if current rank is upper proposed rank
1140             runner.setRankAtStartup(packet.getRank());
1141         }
1142         try {
1143             session.setRunner(runner);
1144         } catch (OpenR66RunnerErrorException e) {
1145             try {
1146                 runner.saveStatus();
1147             } catch (OpenR66RunnerErrorException e1) {
1148                 logger.error("Cannot save Status: " + runner, e1);
1149             }
1150             if (runner.getErrorInfo() == ErrorCode.InitOk ||
1151                     runner.getErrorInfo() == ErrorCode.PreProcessingOk ||
1152                     runner.getErrorInfo() == ErrorCode.TransferOk) {
1153                 runner.setErrorExecutionStatus(ErrorCode.ExternalOp);
1154             }
1155             logger.error("PreTask in error {}", e.getMessage());
1156             session.newState(ERROR);
1157             ErrorPacket error = new ErrorPacket("PreTask in error: "+e
1158                     .getMessage(), runner.getErrorInfo().getCode(), ErrorPacket.FORWARDCLOSECODE);
1159             ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
1160             localChannelReference.invalidateRequest(new R66Result(e, session,
1161                     true, runner.getErrorInfo(), runner));
1162             try {
1163                 session.setFinalizeTransfer(false, new R66Result(e, session,
1164                         true, runner.getErrorInfo(), runner));
1165             } catch (OpenR66RunnerErrorException e1) {
1166             } catch (OpenR66ProtocolSystemException e1) {
1167             }
1168             session.setStatus(38);
1169             ChannelCloseTimer.closeFutureChannel(channel);
1170             return;
1171         }
1172         if (packet.isToValidate()) {
1173             session.newState(REQUESTR);
1174         }
1175         if (runner.isFileMoved() && runner.isSender() && runner.isInTransfer()
1176                 && runner.getRank() == 0 && (!packet.isToValidate())) {
1177             // File was moved during PreTask and very beginning of the transfer
1178             // and the remote host has already received the request packet
1179             // => Informs the receiver of the new name
1180             logger.debug("Will send a modification of filename due to pretask: "+
1181                     runner.getFilename());
1182             session.newState(VALID);
1183             ValidPacket validPacket = new ValidPacket("Change Filename by Pre action on sender",
1184                     runner.getFilename(), LocalPacketFactory.REQUESTPACKET);
1185             ChannelUtils.writeAbstractLocalPacket(localChannelReference,
1186                     validPacket, true);
1187         }
1188         session.setReady(true);
1189         Configuration.configuration.getLocalTransaction().setFromId(runner, localChannelReference);
1190         // inform back
1191         if (packet.isToValidate()) {
1192             if (Configuration.configuration.monitoring != null) {
1193                 Configuration.configuration.monitoring.lastInActiveTransfer =
1194                     System.currentTimeMillis();
1195             }
1196             if (runner.isSender()) {
1197                 // In case Wildcard was used
1198                 logger.debug("New FILENAME: {}", runner.getOriginalFilename());
1199                 packet.setFilename(runner.getOriginalFilename());
1200                 logger.debug("Rank set: "+runner.getRank());
1201                 packet.setRank(runner.getRank());
1202             } else {
1203                 logger.debug("Rank set: "+runner.getRank());
1204                 packet.setRank(runner.getRank());
1205             }
1206             packet.validate();
1207             session.newState(REQUESTD);
1208             ChannelUtils.writeAbstractLocalPacket(localChannelReference, packet, true);
1209         } else {
1210             session.newState(REQUESTD);
1211             // requester => might be a client
1212             // Save the runner into the session and validate the request so begin transfer 
1213             session.getLocalChannelReference().getFutureRequest().runner = runner;
1214             localChannelReference.getFutureValidRequest().setSuccess();
1215             if (Configuration.configuration.monitoring != null) {
1216                 Configuration.configuration.monitoring.lastOutActiveTransfer =
1217                     System.currentTimeMillis();
1218             }
1219         }
1220         // if retrieve => START the retrieve operation except if in Send Through mode
1221         if (runner.isSender()) {
1222             if (runner.isSendThrough()) {
1223                 // it is legal to send data from now
1224                 logger.debug("Now ready to continue with send through");
1225                 localChannelReference.validateEndTransfer(
1226                         new R66Result(session, false, ErrorCode.PreProcessingOk, runner));
1227             } else {
1228                 // Automatically send data now
1229                 NetworkTransaction.runRetrieve(session, channel);
1230             }
1231         }
1232         session.setStatus(39);
1233     }
1234     /**
1235      * Receive a data
1236      * @param channel
1237      * @param packet
1238      * @throws OpenR66ProtocolNotAuthenticatedException
1239      * @throws OpenR66ProtocolBusinessException
1240      * @throws OpenR66ProtocolPacketException
1241      */
1242     private void data(Channel channel, DataPacket packet)
1243             throws OpenR66ProtocolNotAuthenticatedException,
1244             OpenR66ProtocolBusinessException, OpenR66ProtocolPacketException {
1245         if (!session.isAuthenticated()) {
1246             throw new OpenR66ProtocolNotAuthenticatedException(
1247                     "Not authenticated while Data received");
1248         }
1249         if (!session.isReady()) {
1250             throw new OpenR66ProtocolBusinessException("No request prepared");
1251         }
1252         if (session.getRunner().isSender()) {
1253             throw new OpenR66ProtocolBusinessException(
1254                     "Not in receive MODE but receive a packet");
1255         }
1256         if (! session.getRunner().continueTransfer()) {
1257             if (localChannelReference.getFutureEndTransfer().isFailed()) {
1258                 // nothing to do since already done
1259                 session.setStatus(94);
1260                 return;
1261             }
1262             session.newState(ERROR);
1263             ErrorPacket error = new ErrorPacket("Transfer in error due previously aborted transmission",
1264                     ErrorCode.TransferError.getCode(), ErrorPacket.FORWARDCLOSECODE);
1265             ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
1266             try {
1267                 session.setFinalizeTransfer(false, new R66Result(
1268                         new OpenR66ProtocolPacketException(
1269                                 "Transfer was aborted previously"), session, true,
1270                         ErrorCode.TransferError, session.getRunner()));
1271             } catch (OpenR66RunnerErrorException e1) {
1272             } catch (OpenR66ProtocolSystemException e1) {
1273             }
1274             session.setStatus(95);
1275             ChannelCloseTimer.closeFutureChannel(channel);
1276             return;
1277         }
1278         if (packet.getPacketRank() != session.getRunner().getRank()) {
1279             // Fix the rank if possible
1280             if (packet.getPacketRank() < session.getRunner().getRank()) {
1281                 logger.debug("Bad RANK: " + packet.getPacketRank() + " : " +
1282                         session.getRunner().getRank());
1283                 session.getRunner().setRankAtStartup(packet.getPacketRank());
1284                 session.getRestart().restartMarker(
1285                         session.getRunner().getBlocksize() *
1286                         session.getRunner().getRank());
1287                 try {
1288                     session.getFile().restartMarker(session.getRestart());
1289                 } catch (CommandAbstractException e) {
1290                     logger.error("Bad RANK: " + packet.getPacketRank() + " : " +
1291                             session.getRunner().getRank());
1292                     session.newState(ERROR);
1293                     try {
1294                         session.setFinalizeTransfer(false, new R66Result(
1295                                 new OpenR66ProtocolPacketException(
1296                                         "Bad Rank in transmission even after retry: "+
1297                                         packet.getPacketRank()), session, true,
1298                                 ErrorCode.TransferError, session.getRunner()));
1299                     } catch (OpenR66RunnerErrorException e1) {
1300                     } catch (OpenR66ProtocolSystemException e1) {
1301                     }
1302                     ErrorPacket error = new ErrorPacket("Transfer in error due to bad rank transmission",
1303                             ErrorCode.TransferError.getCode(), ErrorPacket.FORWARDCLOSECODE);
1304                     ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
1305                     session.setStatus(96);
1306                     ChannelCloseTimer.closeFutureChannel(channel);
1307                     return;
1308                 }
1309             } else {
1310                 // really bad
1311                 logger.error("Bad RANK: " + packet.getPacketRank() + " : " +
1312                         session.getRunner().getRank());
1313                 session.newState(ERROR);
1314                 try {
1315                     session.setFinalizeTransfer(false, new R66Result(
1316                             new OpenR66ProtocolPacketException(
1317                                     "Bad Rank in transmission: "+
1318                                     packet.getPacketRank()+" > "+
1319                                     session.getRunner().getRank()), session, true,
1320                             ErrorCode.TransferError, session.getRunner()));
1321                 } catch (OpenR66RunnerErrorException e1) {
1322                 } catch (OpenR66ProtocolSystemException e1) {
1323                 }
1324                 ErrorPacket error = new ErrorPacket("Transfer in error due to bad rank transmission",
1325                         ErrorCode.TransferError.getCode(), ErrorPacket.FORWARDCLOSECODE);
1326                 ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
1327                 session.setStatus(20);
1328                 ChannelCloseTimer.closeFutureChannel(channel);
1329                 return;
1330             }
1331         }
1332         DataBlock dataBlock = new DataBlock();
1333         // if MD5 check MD5
1334         if (RequestPacket.isMD5Mode(session.getRunner().getMode())) {
1335             if (!packet.isKeyValid()) {
1336                 // Wrong packet
1337                 logger.error("Wrong MD5 Packet: {}", packet);
1338                 session.newState(ERROR);
1339                 try {
1340                     session.setFinalizeTransfer(false, new R66Result(
1341                             new OpenR66ProtocolPacketException(
1342                                     "Wrong Packet MD5"), session, true,
1343                             ErrorCode.MD5Error, session.getRunner()));
1344                 } catch (OpenR66RunnerErrorException e1) {
1345                 } catch (OpenR66ProtocolSystemException e1) {
1346                 }
1347                 ErrorPacket error = new ErrorPacket(
1348                         "Transfer in error due to bad MD5",
1349                         ErrorCode.MD5Error.getCode(), ErrorPacket.FORWARDCLOSECODE);
1350                 ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
1351                 session.setStatus(21);
1352                 ChannelCloseTimer.closeFutureChannel(channel);
1353                 return;
1354             }
1355         }
1356         if (session.getRunner().isRecvThrough() && localChannelReference.isRecvThroughMode()) {
1357             localChannelReference.getRecvThroughHandler().writeChannelBuffer(packet.getData());
1358             session.getRunner().incrementRank();
1359         } else {
1360             dataBlock.setBlock(packet.getData());
1361             try {
1362                 session.getFile().writeDataBlock(dataBlock);
1363                 session.getRunner().incrementRank();
1364             } catch (FileTransferException e) {
1365                 session.newState(ERROR);
1366                 try {
1367                     session.setFinalizeTransfer(false, new R66Result(
1368                             new OpenR66ProtocolSystemException(e), session, true,
1369                             ErrorCode.TransferError, session.getRunner()));
1370                 } catch (OpenR66RunnerErrorException e1) {
1371                 } catch (OpenR66ProtocolSystemException e1) {
1372                 }
1373                 ErrorPacket error = new ErrorPacket("Transfer in error",
1374                         ErrorCode.TransferError.getCode(), ErrorPacket.FORWARDCLOSECODE);
1375                 ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
1376                 session.setStatus(22);
1377                 ChannelCloseTimer.closeFutureChannel(channel);
1378                 return;
1379             }
1380         }
1381     }
1382     /**
1383      * Test reception
1384      * @param channel
1385      * @param packet
1386      * @throws OpenR66ProtocolNotAuthenticatedException
1387      * @throws OpenR66ProtocolPacketException
1388      */
1389     private void test(Channel channel, TestPacket packet)
1390             throws OpenR66ProtocolNotAuthenticatedException,
1391             OpenR66ProtocolPacketException {
1392         if (!session.isAuthenticated()) {
1393             throw new OpenR66ProtocolNotAuthenticatedException(
1394                     "Not authenticated while Test received");
1395         }
1396         // simply write back after+1
1397         packet.update();
1398         if (packet.getType() == LocalPacketFactory.VALIDPACKET) {
1399             ValidPacket validPacket = new ValidPacket(packet.toString(), null,
1400                     LocalPacketFactory.TESTPACKET);
1401             R66Result result = new R66Result(session, true,
1402                     ErrorCode.CompleteOk, null);
1403             result.other = validPacket;
1404             session.newState(VALIDOTHER);
1405             localChannelReference.validateRequest(result);
1406             ChannelUtils.writeAbstractLocalPacket(localChannelReference, validPacket, true);
1407             logger.warn("Valid TEST MESSAGE: " +packet.toString());
1408             ChannelCloseTimer.closeFutureChannel(channel);
1409         } else {
1410             ChannelUtils.writeAbstractLocalPacket(localChannelReference, packet, false);
1411         }
1412     }
1413     /**
1414      * Receive an End of Transfer
1415      * @param channel
1416      * @param packet
1417      * @throws OpenR66RunnerErrorException
1418      * @throws OpenR66ProtocolSystemException
1419      * @throws OpenR66ProtocolNotAuthenticatedException
1420      */
1421     private void endTransfer(Channel channel, EndTransferPacket packet)
1422             throws OpenR66RunnerErrorException, OpenR66ProtocolSystemException,
1423             OpenR66ProtocolNotAuthenticatedException {
1424         if (!session.isAuthenticated()) {
1425             throw new OpenR66ProtocolNotAuthenticatedException(
1426                     "Not authenticated while EndTransfer received");
1427         }
1428         // Check end of transfer
1429         if (packet.isToValidate()) {
1430             session.newState(ENDTRANSFERS);
1431             if (!localChannelReference.getFutureRequest().isDone()) {
1432                 // Finish with post Operation
1433                 R66Result result = new R66Result(session, false,
1434                         ErrorCode.TransferOk, session.getRunner());
1435                 session.newState(ENDTRANSFERR);
1436                 session.setFinalizeTransfer(true, result);
1437                 // Now can send validation
1438                 packet.validate();
1439                 try {
1440                     ChannelUtils.writeAbstractLocalPacket(localChannelReference,
1441                             packet, false);
1442                 } catch (OpenR66ProtocolPacketException e) {
1443                     // ignore
1444                 }
1445             } else {
1446                 // in error due to a previous status (like bad MD5)
1447                 logger
1448                         .error("Error since end of transfer signaled but already done");
1449                 session.setStatus(23);
1450                 Channels.close(channel);
1451                 return;
1452             }
1453         } else {
1454             session.newState(ENDTRANSFERR);
1455             if (!localChannelReference.getFutureRequest().isDone()) {
1456                 // Validation of end of transfer
1457                 R66Result result = new R66Result(session, false,
1458                         ErrorCode.TransferOk, session.getRunner());
1459                 session.setFinalizeTransfer(true, result);
1460             }
1461         }
1462     }
1463     /**
1464      * Receive a request of information
1465      * @param channel
1466      * @param packet
1467      * @throws CommandAbstractException
1468      * @throws OpenR66ProtocolNotAuthenticatedException
1469      * @throws OpenR66ProtocolNoDataException
1470      * @throws OpenR66ProtocolPacketException
1471      */
1472     private void information(Channel channel, InformationPacket packet)
1473             throws OpenR66ProtocolNotAuthenticatedException,
1474             OpenR66ProtocolNoDataException, OpenR66ProtocolPacketException {
1475         if (!session.isAuthenticated()) {
1476             throw new OpenR66ProtocolNotAuthenticatedException(
1477                     "Not authenticated while Information received");
1478         }
1479         byte request = packet.getRequest();
1480         DbRule rule;
1481         try {
1482             rule = new DbRule(localChannelReference.getDbSession(), packet.getRulename());
1483         } catch (GoldenGateDatabaseException e) {
1484             logger.error("Rule is unknown: " + packet.getRulename(), e);
1485             throw new OpenR66ProtocolNoDataException(e);
1486         }
1487         try {
1488             if (RequestPacket.isRecvMode(rule.mode)) {
1489                 session.getDir().changeDirectory(rule.workPath);
1490             } else {
1491                 session.getDir().changeDirectory(rule.sendPath);
1492             }
1493 
1494             if (request == InformationPacket.ASKENUM.ASKLIST.ordinal() ||
1495                     request == InformationPacket.ASKENUM.ASKMLSLIST.ordinal()) {
1496                 // ls or mls from current directory
1497                 List<String> list;
1498                 if (request == InformationPacket.ASKENUM.ASKLIST.ordinal()) {
1499                     list = session.getDir().list(packet.getFilename());
1500                 } else{
1501                     list = session.getDir().listFull(packet.getFilename(), false);
1502                 }
1503 
1504                 StringBuilder builder = new StringBuilder();
1505                 for (String elt: list) {
1506                     builder.append(elt);
1507                     builder.append('\n');
1508                 }
1509                 session.newState(VALIDOTHER);
1510                 ValidPacket validPacket = new ValidPacket(builder.toString(), ""+list.size(),
1511                         LocalPacketFactory.INFORMATIONPACKET);
1512                 R66Result result = new R66Result(session, true,
1513                         ErrorCode.CompleteOk, null);
1514                 result.other = validPacket;
1515                 localChannelReference.validateEndTransfer(result);
1516                 localChannelReference.validateRequest(result);
1517                 ChannelUtils.writeAbstractLocalPacket(localChannelReference,
1518                         validPacket, true);
1519                 Channels.close(channel);
1520             } else {
1521                 // ls pr mls from current directory and filename
1522                 R66File file = (R66File) session.getDir().setFile(packet.getFilename(), false);
1523                 String sresult = null;
1524                 if (request == InformationPacket.ASKENUM.ASKEXIST.ordinal()) {
1525                     sresult = ""+file.exists();
1526                 } else if (request == InformationPacket.ASKENUM.ASKMLSDETAIL.ordinal()) {
1527                     sresult = session.getDir().fileFull(packet.getFilename(), false);
1528                     String [] list = sresult.split("\n");
1529                     sresult = list[1];
1530                 } else {
1531                     session.newState(ERROR);
1532                     ErrorPacket error = new ErrorPacket("Unknown Request "+request,
1533                             ErrorCode.Warning.getCode(), ErrorPacket.FORWARDCLOSECODE);
1534                     ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
1535                     ChannelCloseTimer.closeFutureChannel(channel);
1536                     return;
1537                 }
1538                 session.newState(VALIDOTHER);
1539                 ValidPacket validPacket = new ValidPacket(sresult, "1",
1540                         LocalPacketFactory.INFORMATIONPACKET);
1541                 R66Result result = new R66Result(session, true,
1542                         ErrorCode.CompleteOk, null);
1543                 result.other = validPacket;
1544                 localChannelReference.validateEndTransfer(result);
1545                 localChannelReference.validateRequest(result);
1546                 ChannelUtils.writeAbstractLocalPacket(localChannelReference,
1547                         validPacket, true);
1548                 ChannelCloseTimer.closeFutureChannel(channel);
1549             }
1550         } catch (CommandAbstractException e) {
1551             session.newState(ERROR);
1552             ErrorPacket error = new ErrorPacket("Error while Request "+request+" "+e.getMessage(),
1553                     ErrorCode.Internal.getCode(), ErrorPacket.FORWARDCLOSECODE);
1554             ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
1555             ChannelCloseTimer.closeFutureChannel(channel);
1556         }
1557     }
1558     /**
1559      * Stop or Cancel a Runner
1560      * @param id
1561      * @param reqd
1562      * @param reqr
1563      * @param code
1564      * @return True if correctly stopped or canceled
1565      */
1566     private boolean stopOrCancelRunner(long id, String reqd, String reqr, ErrorCode code) {
1567         try {
1568             DbTaskRunner taskRunner =
1569                 new DbTaskRunner(localChannelReference.getDbSession(), session,
1570                         null, id, reqr, reqd);
1571             return taskRunner.stopOrCancelRunner(code);
1572         } catch (GoldenGateDatabaseException e) {
1573         }
1574         return false;
1575     }
1576     /**
1577      * Receive a validation or a special request
1578      * @param channel
1579      * @param packet
1580      * @throws OpenR66ProtocolNotAuthenticatedException
1581      * @throws OpenR66RunnerErrorException
1582      * @throws OpenR66ProtocolSystemException
1583      * @throws OpenR66ProtocolBusinessException
1584      */
1585     private void valid(Channel channel, ValidPacket packet)
1586             throws OpenR66ProtocolNotAuthenticatedException,
1587             OpenR66RunnerErrorException, OpenR66ProtocolSystemException, OpenR66ProtocolBusinessException {
1588         if (packet.getTypeValid() != LocalPacketFactory.SHUTDOWNPACKET &&
1589                 (!session.isAuthenticated())) {
1590             logger.warn("Valid packet received while not authenticated: {} {}",packet, session);
1591             session.newState(ERROR);
1592             throw new OpenR66ProtocolNotAuthenticatedException(
1593                     "Not authenticated while Valid received");
1594         }
1595         switch (packet.getTypeValid()) {
1596             case LocalPacketFactory.SHUTDOWNPACKET: {
1597                 session.newState(SHUTDOWN);
1598                 logger.warn("Shutdown received so Will close channel" +
1599                         localChannelReference.toString());
1600                 R66Result result = new R66Result(
1601                         new OpenR66ProtocolShutdownException(), session, true,
1602                         ErrorCode.Shutdown, session.getRunner());
1603                 result.other = packet;
1604                 if (session.getRunner() != null &&
1605                         session.getRunner().isInTransfer()) {
1606                     String srank = packet.getSmiddle();
1607                     DbTaskRunner runner = session.getRunner();
1608                     if (srank != null && srank.length() > 0) {
1609                         // Save last rank from remote point of view
1610                         try {
1611                             int rank = Integer.parseInt(srank);
1612                             runner.setRankAtStartup(rank);
1613                         } catch (NumberFormatException e) {
1614                             // ignore
1615                         }
1616                         session.setFinalizeTransfer(false, result);
1617                     } else if (! runner.isSender()) {
1618                         // is receiver so informs back for the rank to use next time
1619                         int newrank = runner.getRank();
1620                         packet.setSmiddle(Integer.toString(newrank));
1621                         try {
1622                             runner.saveStatus();
1623                         } catch (OpenR66RunnerErrorException e) {
1624                         }
1625                         session.setFinalizeTransfer(false, result);
1626                         try {
1627                             ChannelUtils.writeAbstractLocalPacket(localChannelReference, packet, true);
1628                         } catch (OpenR66ProtocolPacketException e) {
1629                         }
1630                     } else {
1631                         session.setFinalizeTransfer(false, result);
1632                     }
1633                 } else {
1634                     session.setFinalizeTransfer(false, result);
1635                 }
1636                 session.setStatus(26);
1637                 try {
1638                     Thread.sleep(Configuration.WAITFORNETOP*2);
1639                 } catch (InterruptedException e) {
1640                     Thread.currentThread().interrupt();
1641                 }
1642                 logger.warn("Will Close Local from Network Channel");
1643                 Configuration.configuration.getLocalTransaction()
1644                     .closeLocalChannelsFromNetworkChannel(localChannelReference
1645                             .getNetworkChannel());
1646                 NetworkTransaction
1647                     .shuttingdownNetworkChannel(localChannelReference
1648                         .getNetworkChannel());
1649                 ChannelCloseTimer.closeFutureChannel(channel);
1650                 break;
1651             }
1652             case LocalPacketFactory.STOPPACKET:
1653             case LocalPacketFactory.CANCELPACKET: {
1654                 session.newState(VALIDOTHER);
1655                 // Authentication must be the local server
1656                 try {
1657                     if (!session.getAuth().getUser().equals(
1658                             Configuration.configuration.getHostId(session.getAuth().isSsl()))) {
1659                         throw new OpenR66ProtocolNotAuthenticatedException(
1660                                 "Not correctly authenticated");
1661                     }
1662                 } catch (OpenR66ProtocolNoSslException e1) {
1663                     throw new OpenR66ProtocolNotAuthenticatedException(
1664                             "Not correctly authenticated since SSL is not supported", e1);
1665                 }
1666                 // header = ?; middle = requested+blank+requester+blank+specialId
1667                 LocalChannelReference lcr =
1668                     Configuration.configuration.getLocalTransaction().
1669                     getFromRequest(packet.getSmiddle());
1670                 // stop the current transfer
1671                 R66Result resulttest;
1672                 ErrorCode code = (packet.getTypeValid() == LocalPacketFactory.STOPPACKET) ?
1673                         ErrorCode.StoppedTransfer : ErrorCode.CanceledTransfer;
1674                 if (lcr != null) {
1675                     int rank = 0;
1676                     if (code == ErrorCode.StoppedTransfer && lcr.getSession() != null) {
1677                         DbTaskRunner taskRunner = lcr.getSession().getRunner();
1678                         if (taskRunner != null) {
1679                             rank = taskRunner.getRank();
1680                         }
1681                     }
1682                     session.newState(ERROR);
1683                     ErrorPacket error = new ErrorPacket(code.name()+" "+rank,
1684                             code.getCode(), ErrorPacket.FORWARDCLOSECODE);
1685                     try {
1686                         //XXX ChannelUtils.writeAbstractLocalPacket(lcr, error);
1687                         // inform local instead of remote
1688                         ChannelUtils.writeAbstractLocalPacketToLocal(lcr, error);
1689                     } catch (Exception e) {
1690                     }
1691                     resulttest = new R66Result(session, true,
1692                             ErrorCode.CompleteOk, session.getRunner());
1693                 } else {
1694                     // Transfer is not running
1695                     // but maybe need action on database
1696                     String [] keys = packet.getSmiddle().split(" ");
1697                     long id = Long.parseLong(keys[2]);
1698                     if (stopOrCancelRunner(id, keys[0], keys[1], code)) {
1699                         resulttest = new R66Result(session, true,
1700                                 ErrorCode.CompleteOk, session.getRunner());
1701                     } else {
1702                         resulttest = new R66Result(session, true,
1703                             ErrorCode.TransferOk, session.getRunner());
1704                     }
1705                 }
1706                 // inform back the requester
1707                 ValidPacket valid = new ValidPacket(packet.getSmiddle(), resulttest.code.getCode(),
1708                         LocalPacketFactory.REQUESTUSERPACKET);
1709                 resulttest.other = packet;
1710                 localChannelReference.validateRequest(resulttest);
1711                 try {
1712                     ChannelUtils.writeAbstractLocalPacket(localChannelReference,
1713                             valid, true);
1714                 } catch (OpenR66ProtocolPacketException e) {
1715                 }
1716                 session.setStatus(27);
1717                 Channels.close(channel);
1718                 break;
1719             }
1720             case LocalPacketFactory.REQUESTUSERPACKET: {
1721                 session.newState(VALIDOTHER);
1722                 // Validate user request
1723                 R66Result resulttest = new R66Result(session, true,
1724                         ErrorCode.getFromCode(packet.getSmiddle()), null);
1725                 resulttest.other = packet;
1726                 switch (resulttest.code) {
1727                     case CompleteOk:
1728                     case InitOk:
1729                     case PostProcessingOk:
1730                     case PreProcessingOk:
1731                     case QueryAlreadyFinished:
1732                     case QueryStillRunning:
1733                     case Running:
1734                     case TransferOk:
1735                         break;
1736                     default:
1737                         localChannelReference.invalidateRequest(resulttest);
1738                         session.setStatus(102);
1739                         Channels.close(channel);
1740                         return;
1741                 }
1742                 localChannelReference.validateRequest(resulttest);
1743                 session.setStatus(28);
1744                 Channels.close(channel);
1745                 break;
1746             }
1747             case LocalPacketFactory.LOGPACKET:
1748             case LocalPacketFactory.LOGPURGEPACKET: {
1749                 session.newState(VALIDOTHER);
1750                 // should be from the local server or from an authorized hosts: isAdmin
1751                 if (!session.getAuth().isAdmin()) {
1752                     throw new OpenR66ProtocolNotAuthenticatedException(
1753                             "Not correctly authenticated");
1754                 }
1755                 String sstart = packet.getSheader();
1756                 String sstop = packet.getSmiddle();
1757                 boolean isPurge = (packet.getTypeValid() == LocalPacketFactory.LOGPURGEPACKET) ?
1758                         true : false;
1759                 Timestamp start = (sstart == null || sstart.length() == 0) ? null :
1760                     Timestamp.valueOf(sstart);
1761                 Timestamp stop = (sstop == null || sstop.length() == 0) ? null :
1762                     Timestamp.valueOf(sstop);
1763                 // create export of log and optionally purge them from database
1764                 DbPreparedStatement getValid = null;
1765                 String filename = Configuration.configuration.baseDirectory+
1766                     Configuration.configuration.archivePath+R66Dir.SEPARATOR+
1767                     Configuration.configuration.HOST_ID+"_"+System.currentTimeMillis()+
1768                     "_runners.xml";
1769                 try {
1770                     getValid =
1771                         DbTaskRunner.getLogPrepareStatement(localChannelReference.getDbSession(),
1772                                 start, stop);
1773                     DbTaskRunner.writeXMLWriter(getValid, filename);
1774                 } catch (GoldenGateDatabaseNoConnectionException e1) {
1775                     throw new OpenR66ProtocolBusinessException(e1);
1776                 } catch (GoldenGateDatabaseSqlException e1) {
1777                     throw new OpenR66ProtocolBusinessException(e1);
1778                 } finally {
1779                     if (getValid != null) {
1780                         getValid.realClose();
1781                     }
1782                 }
1783                 // in case of purge
1784                 int nb = 0;
1785                 if (isPurge) {
1786                     // purge in same interval all runners with globallaststep
1787                     // as ALLDONETASK or ERRORTASK
1788                     if (Configuration.configuration.r66Mib != null) {
1789                         Configuration.configuration.r66Mib.notifyWarning(
1790                                 "Purge Log Order received", session.getAuth().getUser());
1791                     }
1792                     try {
1793                         nb = DbTaskRunner.purgeLogPrepareStatement(
1794                                 localChannelReference.getDbSession(),
1795                                 start, stop);
1796                     } catch (GoldenGateDatabaseNoConnectionException e) {
1797                         throw new OpenR66ProtocolBusinessException(e);
1798                     } catch (GoldenGateDatabaseSqlException e) {
1799                         throw new OpenR66ProtocolBusinessException(e);
1800                     }
1801                 }
1802                 R66Result result = new R66Result(session, true, ErrorCode.CompleteOk, null);
1803                 // Now answer
1804                 ValidPacket valid = new ValidPacket(filename+" "+nb, result.code.getCode(),
1805                         LocalPacketFactory.REQUESTUSERPACKET);
1806                 localChannelReference.validateRequest(result);
1807                 try {
1808                     ChannelUtils.writeAbstractLocalPacket(localChannelReference,
1809                             valid, true);
1810                 } catch (OpenR66ProtocolPacketException e) {
1811                 }
1812                 Channels.close(channel);
1813                 break;
1814             }
1815             case LocalPacketFactory.CONFEXPORTPACKET: {
1816                 session.newState(VALIDOTHER);
1817                 if (Configuration.configuration.r66Mib != null) {
1818                     Configuration.configuration.r66Mib.notifyWarning(
1819                             "Export Configuration Order received", session.getAuth().getUser());
1820                 }
1821                 String shost = packet.getSheader();
1822                 String srule = packet.getSmiddle();
1823                 boolean bhost = Boolean.parseBoolean(shost);
1824                 boolean brule = Boolean.parseBoolean(srule);
1825                 String dir = Configuration.configuration.baseDirectory+
1826                     Configuration.configuration.archivePath;
1827                 String hostname = Configuration.configuration.HOST_ID;
1828                 if (bhost) {
1829                     String filename = dir+File.separator+hostname+"_Authentications.xml";
1830                     try {
1831                         AuthenticationFileBasedConfiguration.writeXML(Configuration.configuration, 
1832                                 filename);
1833                         shost = filename;
1834                     } catch (GoldenGateDatabaseNoConnectionException e) {
1835                         logger.error("Error",e);
1836                         shost = "#";
1837                         bhost = false;
1838                     } catch (GoldenGateDatabaseSqlException e) {
1839                         logger.error("Error",e);
1840                         shost = "#";
1841                         bhost = false;
1842                     } catch (OpenR66ProtocolSystemException e) {
1843                         logger.error("Error",e);
1844                         shost = "#";
1845                         bhost = false;
1846                     }
1847                 }
1848                 if (brule) {
1849                     try {
1850                         srule = RuleFileBasedConfiguration.writeOneXml(dir, hostname);
1851                     } catch (GoldenGateDatabaseNoConnectionException e1) {
1852                         logger.error("Error",e1);
1853                         srule = "#";
1854                         brule = false;
1855                     } catch (GoldenGateDatabaseSqlException e1) {
1856                         logger.error("Error",e1);
1857                         srule = "#";
1858                         brule = false;
1859                     } catch (OpenR66ProtocolSystemException e1) {
1860                         logger.error("Error",e1);
1861                         srule = "#";
1862                         brule = false;
1863                     }
1864                 }
1865                 R66Result result = null;
1866                 if (brule || bhost) {
1867                     result = new R66Result(session, true, ErrorCode.CompleteOk, null);
1868                 } else {
1869                     result = new R66Result(session, true, ErrorCode.TransferError, null);
1870                 }
1871                 // Now answer
1872                 ValidPacket valid = new ValidPacket(shost+" "+srule, result.code.getCode(),
1873                         LocalPacketFactory.REQUESTUSERPACKET);
1874                 localChannelReference.validateRequest(result);
1875                 try {
1876                     ChannelUtils.writeAbstractLocalPacket(localChannelReference,
1877                             valid, true);
1878                 } catch (OpenR66ProtocolPacketException e) {
1879                 }
1880                 Channels.close(channel);
1881                 break;
1882             }
1883             case LocalPacketFactory.CONFIMPORTPACKET: {
1884                 session.newState(VALIDOTHER);
1885                 if (Configuration.configuration.r66Mib != null) {
1886                     Configuration.configuration.r66Mib.notifyWarning(
1887                             "Import Configuration Order received", session.getAuth().getUser());
1888                 }
1889                 String shost = packet.getSheader();
1890                 String srule = packet.getSmiddle();
1891                 boolean bhostPurge = shost.startsWith("1 ");
1892                 shost = shost.substring(2);
1893                 boolean brulePurge = srule.startsWith("1 ");
1894                 srule = srule.substring(2);
1895                 boolean bhost = shost.length()>0;
1896                 boolean brule = srule.length()>0;
1897                 if (bhost) {
1898                     DbHostAuth [] oldHosts = null;
1899                     if (bhostPurge) {
1900                         // Need to first delete all entries
1901                         try {
1902                             oldHosts = DbHostAuth.deleteAll(DbConstant.admin.session);
1903                         } catch (GoldenGateDatabaseException e) {
1904                             // ignore
1905                         }
1906                     }
1907                     String filename = shost;
1908                     if (AuthenticationFileBasedConfiguration.loadAuthentication(Configuration.configuration, 
1909                             filename)) {
1910                         shost = "Host:OK";
1911                     } else {
1912                         logger.error("Error in Load Hosts");
1913                         shost = "Host:KO";
1914                         bhost = false;
1915                     }
1916                     if (!bhost) {
1917                         if (oldHosts != null) {
1918                             for (DbHostAuth dbHost: oldHosts) {
1919                                 try {
1920                                     if (!dbHost.exist()) {
1921                                         dbHost.insert();
1922                                     }
1923                                 } catch (GoldenGateDatabaseException e1) {
1924                                     // ignore
1925                                 }
1926                             }
1927                         }
1928                     }
1929                 }
1930                 if (brule) {
1931                     DbRule[] oldRules = null;
1932                     if (brulePurge) {
1933                         // Need to first delete all entries
1934                         try {
1935                             oldRules = DbRule.deleteAll(DbConstant.admin.session);
1936                         } catch (GoldenGateDatabaseException e) {
1937                             // ignore
1938                         }
1939                     }
1940                     File file = new File(srule);
1941                     try {
1942                         RuleFileBasedConfiguration.getMultipleFromFile(file);
1943                         srule = "Rule:OK";
1944                         brule = true;
1945                     } catch (GoldenGateDatabaseNoConnectionException e) {
1946                         logger.error("Error",e);
1947                         srule = "Rule:KO";
1948                         brule = false;
1949                     } catch (GoldenGateDatabaseSqlException e) {
1950                         logger.error("Error",e);
1951                         srule = "Rule:KO";
1952                         brule = false;
1953                     } catch (GoldenGateDatabaseNoDataException e) {
1954                         logger.error("Error",e);
1955                         srule = "Rule:KO";
1956                         brule = false;
1957                     } catch (GoldenGateDatabaseException e) {
1958                         logger.error("Error",e);
1959                         srule = "Rule:KO";
1960                         brule = false;
1961                     }
1962                     if (!brule) {
1963                         if (oldRules != null) {
1964                             for (DbRule dbRule: oldRules) {
1965                                 try {
1966                                     if (!dbRule.exist()) {
1967                                         dbRule.insert();
1968                                     }
1969                                 } catch (GoldenGateDatabaseException e1) {
1970                                     // ignore
1971                                 }
1972                             }
1973                         }
1974                     }
1975                 }
1976                 R66Result result = null;
1977                 if (brule || bhost) {
1978                     result = new R66Result(session, true, ErrorCode.CompleteOk, null);
1979                 } else {
1980                     result = new R66Result(session, true, ErrorCode.TransferError, null);
1981                 }
1982                 // Now answer
1983                 ValidPacket valid = new ValidPacket(shost+" "+srule, result.code.getCode(),
1984                         LocalPacketFactory.REQUESTUSERPACKET);
1985                 localChannelReference.validateRequest(result);
1986                 try {
1987                     ChannelUtils.writeAbstractLocalPacket(localChannelReference,
1988                             valid, true);
1989                 } catch (OpenR66ProtocolPacketException e) {
1990                 }
1991                 Channels.close(channel);
1992                 break;
1993             }
1994             case LocalPacketFactory.INFORMATIONPACKET: {
1995                 session.newState(VALIDOTHER);
1996                 // Validate user request
1997                 R66Result resulttest = new R66Result(session, true,
1998                         ErrorCode.CompleteOk, null);
1999                 resulttest.other = packet;
2000                 localChannelReference.validateRequest(resulttest);
2001                 Channels.close(channel);
2002                 break;
2003             }
2004             case LocalPacketFactory.VALIDPACKET: {
2005                 session.newState(VALIDOTHER);
2006                 // Try to validate a restarting transfer
2007                 // XXX validLimit on requested side
2008                 if (Configuration.configuration.constraintLimitHandler.checkConstraints()) {
2009                     logger.error("Limit exceeded while asking to relaunch a task" + packet.getSmiddle());
2010                     session.setStatus(100);
2011                     ValidPacket valid;
2012                     valid = new ValidPacket(packet.getSmiddle(),
2013                             ErrorCode.ServerOverloaded.getCode(),
2014                             LocalPacketFactory.REQUESTUSERPACKET);
2015                     R66Result resulttest = new R66Result(null, session, true,
2016                             ErrorCode.Internal, null);
2017                     resulttest.other = packet;
2018                     localChannelReference.invalidateRequest(resulttest);
2019                     // inform back the requester
2020                     try {
2021                         ChannelUtils.writeAbstractLocalPacket(localChannelReference,
2022                                 valid, true);
2023                     } catch (OpenR66ProtocolPacketException e) {
2024                     }
2025                     Channels.close(channel);
2026                     return;
2027                 }
2028                 // Try to validate a restarting transfer
2029                 // header = ?; middle = requested+blank+requester+blank+specialId
2030                 String [] keys = packet.getSmiddle().split(" ");
2031                 long id = Long.parseLong(keys[2]);
2032                 DbTaskRunner taskRunner = null;
2033                 ValidPacket valid;
2034                 try {
2035                     taskRunner = new DbTaskRunner(localChannelReference.getDbSession(), session,
2036                             null, id, keys[1], keys[0]);
2037                     LocalChannelReference lcr =
2038                         Configuration.configuration.getLocalTransaction().
2039                         getFromRequest(packet.getSmiddle());
2040                     R66Result resulttest = TransferUtils.restartTransfer(taskRunner, lcr);
2041                     valid = new ValidPacket(packet.getSmiddle(), resulttest.code.getCode(),
2042                             LocalPacketFactory.REQUESTUSERPACKET);
2043                     resulttest.other = packet;
2044                     localChannelReference.validateRequest(resulttest);
2045                 } catch (GoldenGateDatabaseException e1) {
2046                     valid = new ValidPacket(packet.getSmiddle(),
2047                             ErrorCode.Internal.getCode(),
2048                             LocalPacketFactory.REQUESTUSERPACKET);
2049                     R66Result resulttest = new R66Result(new OpenR66DatabaseGlobalException(e1), session, true,
2050                             ErrorCode.Internal, taskRunner);
2051                     resulttest.other = packet;
2052                     localChannelReference.invalidateRequest(resulttest);
2053                 }
2054                 // inform back the requester
2055                 try {
2056                     ChannelUtils.writeAbstractLocalPacket(localChannelReference,
2057                             valid, true);
2058                 } catch (OpenR66ProtocolPacketException e) {
2059                 }
2060                 Channels.close(channel);
2061                 break;
2062             }
2063             case LocalPacketFactory.REQUESTPACKET: {
2064                 session.newState(VALID);
2065                 // The filename from sender is changed due to PreTask so change it too in receiver
2066                 String newfilename = packet.getSmiddle();
2067                 // Pre execution was already done since this packet is only received once
2068                 // the request is already validated by the receiver
2069                 try {
2070                     session.renameReceiverFile(newfilename);
2071                 } catch (OpenR66RunnerErrorException e) {
2072                     DbTaskRunner runner = session.getRunner();
2073                     runner.saveStatus();
2074                     runner.setErrorExecutionStatus(ErrorCode.FileNotFound);
2075                     session.newState(ERROR);
2076                     logger.error("File renaming in error {}", e.getMessage());
2077                     ErrorPacket error = new ErrorPacket("File renaming in error: "+e
2078                             .getMessage(), runner.getErrorInfo().getCode(),
2079                             ErrorPacket.FORWARDCLOSECODE);
2080                     try {
2081                         ChannelUtils.writeAbstractLocalPacket(localChannelReference,
2082                                 error, true);
2083                     } catch (OpenR66ProtocolPacketException e2) {
2084                     }
2085                     localChannelReference.invalidateRequest(new R66Result(e, session,
2086                             true, runner.getErrorInfo(), runner));
2087                     try {
2088                         session.setFinalizeTransfer(false, new R66Result(e, session,
2089                                 true, runner.getErrorInfo(), runner));
2090                     } catch (OpenR66RunnerErrorException e1) {
2091                     } catch (OpenR66ProtocolSystemException e1) {
2092                     }
2093                     session.setStatus(97);
2094                     ChannelCloseTimer.closeFutureChannel(channel);
2095                     return;
2096                 }
2097                 // Success: No write back at all
2098                 break;
2099             }
2100             case LocalPacketFactory.BANDWIDTHPACKET: {
2101                 session.newState(VALIDOTHER);
2102                 // should be from the local server or from an authorized hosts: isAdmin
2103                 if (!session.getAuth().isAdmin()) {
2104                     throw new OpenR66ProtocolNotAuthenticatedException(
2105                             "Not correctly authenticated");
2106                 }
2107                 String []splitglobal  = packet.getSheader().split(" ");
2108                 String []splitsession = packet.getSmiddle().split(" ");
2109                 long wgl  = (Long.parseLong(splitglobal[0])/10)*10;
2110                 long rgl  = (Long.parseLong(splitglobal[1])/10)*10;
2111                 long wsl  = (Long.parseLong(splitsession[0])/10)*10;
2112                 long rsl  = (Long.parseLong(splitsession[1])/10)*10;
2113                 if (wgl < 0) {
2114                     wgl = Configuration.configuration.serverGlobalWriteLimit;
2115                 }
2116                 if (rgl < 0) {
2117                     rgl = Configuration.configuration.serverGlobalReadLimit;
2118                 }
2119                 if (wsl < 0) {
2120                     wsl = Configuration.configuration.serverChannelWriteLimit;
2121                 }
2122                 if (rsl < 0) {
2123                     rsl = Configuration.configuration.serverChannelReadLimit;
2124                 }
2125                 if (Configuration.configuration.r66Mib != null) {
2126                     Configuration.configuration.r66Mib.notifyWarning(
2127                             "Change Bandwidth Limit Order received: Global "+
2128                             wgl+":"+rgl+" (W:R) Local "+wsl+":"+rsl+" (W:R)", 
2129                             session.getAuth().getUser());
2130                 }
2131                 Configuration.configuration.changeNetworkLimit(wgl, rgl, wsl, rsl,
2132                         Configuration.configuration.delayLimit);
2133                 R66Result result = new R66Result(session, true, ErrorCode.CompleteOk, null);
2134                 // Now answer
2135                 ValidPacket valid = new ValidPacket("Bandwidth changed", result.code.getCode(),
2136                         LocalPacketFactory.REQUESTUSERPACKET);
2137                 localChannelReference.validateRequest(result);
2138                 try {
2139                     ChannelUtils.writeAbstractLocalPacket(localChannelReference,
2140                             valid, true);
2141                 } catch (OpenR66ProtocolPacketException e) {
2142                 }
2143                 Channels.close(channel);
2144                 break;
2145             }
2146             case LocalPacketFactory.TESTPACKET: {
2147                 session.newState(VALIDOTHER);
2148                 logger.warn("Valid TEST MESSAGE: " +packet.toString());
2149                 R66Result resulttest = new R66Result(session, true,
2150                         ErrorCode.CompleteOk, null);
2151                 resulttest.other = packet;
2152                 localChannelReference.validateRequest(resulttest);
2153                 Channels.close(channel);
2154                 break;
2155             }
2156             default:
2157                 logger.info("Validation is ignored: " + packet.getTypeValid());
2158         }
2159     }
2160     /**
2161      * Receive an End of Request
2162      * @param channel
2163      * @param packet
2164      * @throws OpenR66RunnerErrorException
2165      * @throws OpenR66ProtocolSystemException
2166      * @throws OpenR66ProtocolNotAuthenticatedException
2167      */
2168     private void endRequest(Channel channel, EndRequestPacket packet) {
2169      // Validate the last post action on a transfer from receiver remote host
2170         logger.info("Valid Request {}\nPacket {}",
2171                 localChannelReference,
2172                 packet);
2173         DbTaskRunner runner = session.getRunner();
2174         if (runner != null) {
2175             runner.setAllDone();
2176             try {
2177                 runner.saveStatus();
2178             } catch (OpenR66RunnerErrorException e) {
2179                 // ignore
2180             }
2181         }
2182         String optional = null;
2183         if (session.getExtendedProtocol()) {
2184             optional = packet.getOptional();
2185         }
2186         if (!localChannelReference.getFutureRequest().isDone()) {
2187             // end of request
2188             R66Future transfer = localChannelReference.getFutureEndTransfer();
2189             try {
2190                 transfer.await();
2191             } catch (InterruptedException e) {
2192             }
2193             if (transfer.isSuccess()) {
2194                 if (session.getExtendedProtocol() && session.getBusinessObject() != null) {
2195                     if (session.getBusinessObject().getInfo() == null) {
2196                         session.getBusinessObject().setInfo(optional);
2197                     } else {
2198                         String temp = session.getBusinessObject().getInfo();
2199                         session.getBusinessObject().setInfo(optional);
2200                         optional = temp;
2201                     }
2202                 } else if (session.getExtendedProtocol() && 
2203                         transfer.getResult().other == null && optional != null) {
2204                     transfer.getResult().other = optional;
2205                 }
2206                 localChannelReference.validateRequest(transfer.getResult());
2207             }
2208         }
2209         session.setStatus(1);
2210         if (packet.isToValidate()) {
2211             session.newState(ENDREQUESTS);
2212             packet.validate();
2213             if (session.getExtendedProtocol()) {
2214                 packet.setOptional(optional);
2215             }
2216             session.newState(ENDREQUESTR);
2217             try {
2218                 ChannelUtils.writeAbstractLocalPacket(localChannelReference,
2219                         packet, true);
2220             } catch (OpenR66ProtocolPacketException e) {
2221             }
2222         } else {
2223             session.newState(ENDREQUESTR);
2224         }
2225         if (runner != null && runner.isSelfRequested()) {
2226             ChannelCloseTimer.closeFutureChannel(channel);
2227         }
2228     }
2229     /**
2230      * Receive a Shutdown request
2231      * @param channel
2232      * @param packet
2233      * @throws OpenR66ProtocolShutdownException
2234      * @throws OpenR66ProtocolNotAuthenticatedException
2235      * @throws OpenR66ProtocolBusinessException
2236      */
2237     private void shutdown(Channel channel, ShutdownPacket packet)
2238             throws OpenR66ProtocolShutdownException,
2239             OpenR66ProtocolNotAuthenticatedException,
2240             OpenR66ProtocolBusinessException {
2241         if (!session.isAuthenticated()) {
2242             throw new OpenR66ProtocolNotAuthenticatedException(
2243                     "Not authenticated while Shutdown received");
2244         }
2245         boolean isAdmin = session.getAuth().isAdmin();
2246         boolean isKeyValid = Configuration.configuration.isKeyValid(packet.getKey());
2247         if (isAdmin && isKeyValid) {
2248             if (Configuration.configuration.r66Mib != null) {
2249                 Configuration.configuration.r66Mib.notifyStartStop(
2250                         "Shutdown Order received effective in "+
2251                         Configuration.configuration.TIMEOUTCON+" ms", 
2252                         session.getAuth().getUser());
2253             }
2254             throw new OpenR66ProtocolShutdownException("Shutdown Type received");
2255         }
2256         logger.error("Invalid Shutdown command: from "+session.getAuth().getUser()+" AdmValid: "+isAdmin+" KeyValid: "+isKeyValid);
2257         throw new OpenR66ProtocolBusinessException("Invalid Shutdown comand");
2258     }
2259     /**
2260      * Business Request (channel should stay open)
2261      * 
2262      * Note: the thread called should manage all writeback informations, as well as 
2263      * status, channel closing if needed or not.
2264      * 
2265      * @param channel
2266      * @param packet
2267      * @throws OpenR66ProtocolNotAuthenticatedException
2268      * @throws OpenR66ProtocolPacketException
2269      */
2270     private void businessRequest(Channel channel, BusinessRequestPacket packet)
2271             throws OpenR66ProtocolNotAuthenticatedException,
2272             OpenR66ProtocolPacketException {
2273         if (!session.isAuthenticated()) {
2274             throw new OpenR66ProtocolNotAuthenticatedException(
2275                     "Not authenticated while BusinessRequest received");
2276         }
2277         if (!Configuration.configuration.businessWhiteSet.contains(session.getAuth().getUser())) {
2278             throw new OpenR66ProtocolNotAuthenticatedException(
2279                     "Not allow to execute a BusinessRequest");
2280         }
2281         session.setStatus(200);
2282         String argRule = packet.getSheader();
2283         int delay = packet.getDelay();
2284         boolean argTransfer  = packet.isToValidate();
2285         if (argTransfer) {
2286             session.newState(BUSINESSD);
2287         }
2288         ExecJavaTask task = new ExecJavaTask(argRule+" "+
2289                 AbstractBusinessRequest.BUSINESSREQUEST+" "+argTransfer, 
2290                 delay, null, session);
2291         task.run();
2292         session.setStatus(201);
2293         if (task.isSuccess()) {
2294             session.setStatus(202);
2295             logger.info("Task done: "+argRule);
2296         } else {
2297             R66Result result = task.getFutureCompletion().getResult();
2298             if (result == null) {
2299                 result = new R66Result(session, false, ErrorCode.ExternalOp, session.getRunner());
2300             }
2301             logger.info("Task in Error:"+argRule+"\n"+result);
2302             if (! result.isAnswered) {
2303                 packet.invalidate();
2304                 session.newState(ERROR);
2305                 ErrorPacket error = new ErrorPacket(
2306                     "BusinessRequest in error: for "+packet.toString()+" since "+
2307                     result.getMessage(),
2308                     result.code.getCode(), ErrorPacket.FORWARDCLOSECODE);
2309                 ChannelUtils.writeAbstractLocalPacket(localChannelReference, error, true);
2310                 session.setStatus(203);
2311             }
2312             session.setStatus(204);
2313         }
2314     }
2315 
2316     /**
2317      * Try to finalize the request if possible
2318      * @param errorValue in case of Error
2319      * @throws OpenR66ProtocolSystemException
2320      * @throws OpenR66RunnerErrorException
2321      */
2322     private void tryFinalizeRequest(R66Result errorValue)
2323     throws OpenR66RunnerErrorException, OpenR66ProtocolSystemException {
2324         session.tryFinalizeRequest(errorValue);
2325     }
2326 }