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.client;
22  
23  import goldengate.common.database.exception.GoldenGateDatabaseException;
24  import goldengate.common.logging.GgInternalLoggerFactory;
25  import openr66.commander.ClientRunner;
26  import openr66.context.ErrorCode;
27  import openr66.context.R66Result;
28  import openr66.context.task.exception.OpenR66RunnerErrorException;
29  import openr66.database.data.DbTaskRunner;
30  import openr66.protocol.configuration.Configuration;
31  import openr66.protocol.exception.OpenR66ProtocolNoConnectionException;
32  import openr66.protocol.exception.OpenR66ProtocolNotYetConnectionException;
33  import openr66.protocol.exception.OpenR66ProtocolPacketException;
34  import openr66.protocol.localhandler.LocalChannelReference;
35  import openr66.protocol.networkhandler.NetworkTransaction;
36  import openr66.protocol.test.TestRecvThroughClient;
37  import openr66.protocol.utils.R66Future;
38  
39  /**
40   * Class for Recv Through client
41   *
42   * This class does not included the real file transfer since it is up to the business project
43   * to implement how to write new data received from the remote host. If an error occurs,
44   * no transfer log is kept.
45   *
46   * 1) Configuration must have been loaded<br>
47   * <br>
48   * 2) Pipeline and NetworkTransaction must have been initiated:<br>
49   * <tt>     Configuration.configuration.pipelineInit();</tt><br>
50   * <tt>     NetworkTransaction networkTransaction = new NetworkTransaction();</tt><br>
51   * <br>
52   * 3) Prepare the request of transfer:<br>
53   * <tt>     R66Future futureReq = new R66Future(true);</tt><br>
54   * <tt>     RecvThroughHandler rth = new RecvThroughHandler(...);</tt><br>
55   * <tt>     RecvThroughClient transaction = new RecvThroughClient(futureReq, rth, ...);</tt><br>
56   * <tt>     transaction.run();</tt><br>
57   * <br>
58   * 4) If everything is in success, wait for the transfer to finish:<br>
59   * <tt>     futureReq.awaitUninterruptibly();</tt><br>
60   * <tt>     R66Result result = futureReq.getResult();</tt><br>
61   * <br>
62   * 5) If there is the need to re-do, just re-execute the steps from 3 to 4.<br>
63   * Don't forget at the very end to finish the global structure (steps 3 to 4 no more executed):<br>
64   * <tt>     networkTransaction.closeAll();</tt><br>
65   * <br>
66   * <br>
67   * @see TestRecvThroughClient {@link TestRecvThroughClient} Class as example of usage
68   *
69   * @author Frederic Bregier
70   *
71   */
72  public class RecvThroughClient extends AbstractTransfer {
73      protected final NetworkTransaction networkTransaction;
74      protected LocalChannelReference localChannelReference;
75      protected final RecvThroughHandler handler;
76      /**
77       * @param future
78       * @param remoteHost
79       * @param filename
80       * @param rulename
81       * @param fileinfo
82       * @param isMD5
83       * @param blocksize
84       * @param id
85       * @param networkTransaction
86       */
87      public RecvThroughClient(R66Future future, RecvThroughHandler handler, String remoteHost,
88              String filename, String rulename, String fileinfo, boolean isMD5,
89              int blocksize, long id, NetworkTransaction networkTransaction) {
90          // timestart since immediate
91          super(RecvThroughClient.class,
92                  future, filename, rulename, fileinfo, isMD5, remoteHost, blocksize, id, null);
93          this.networkTransaction = networkTransaction;
94          this.handler = handler;
95      }
96      /**
97       * Prior to call this method, the pipeline and NetworkTransaction must have been initialized.
98       * It is the responsibility of the caller to finish all network resources.
99       */
100     public void run() {
101         if (logger == null) {
102             logger = GgInternalLoggerFactory.getLogger(RecvThroughClient.class);
103         }
104         DbTaskRunner taskRunner = this.initRequest();
105         try {
106             ClientRunner runner = new ClientRunner(networkTransaction, taskRunner, future);
107             runner.setRecvThroughHandler(handler);
108             OpenR66ProtocolNotYetConnectionException exc = null;
109             for (int i = 0; i < Configuration.RETRYNB; i++) {
110                 try {
111                     runner.runTransfer();
112                     exc = null;
113                     break;
114                 } catch (OpenR66RunnerErrorException e) {
115                     logger.error("Cannot Transfer", e);
116                     future.setResult(new R66Result(e, null, true,
117                             ErrorCode.Internal, taskRunner));
118                     future.setFailure(e);
119                     return;
120                 } catch (OpenR66ProtocolNoConnectionException e) {
121                     logger.error("Cannot Connect", e);
122                     future.setResult(new R66Result(e, null, true,
123                             ErrorCode.ConnectionImpossible, taskRunner));
124                     future.setFailure(e);
125                     return;
126                 } catch (OpenR66ProtocolPacketException e) {
127                     logger.error("Bad Protocol", e);
128                     future.setResult(new R66Result(e, null, true,
129                             ErrorCode.TransferError, taskRunner));
130                     future.setFailure(e);
131                     return;
132                 } catch (OpenR66ProtocolNotYetConnectionException e) {
133                     logger.debug("Not Yet Connected", e);
134                     exc = e;
135                     continue;
136                 }
137             }
138             if (exc!= null) {
139                 taskRunner.setLocalChannelReference(new LocalChannelReference());
140                 logger.error("Cannot Connect", exc);
141                 future.setResult(new R66Result(exc, null, true,
142                         ErrorCode.ConnectionImpossible, taskRunner));
143                 future.setFailure(exc);
144                 return;
145             }
146         } finally {
147             if (taskRunner != null) {
148                 if (future.isFailed() || nolog) {
149                     try {
150                         taskRunner.delete();
151                     } catch (GoldenGateDatabaseException e) {
152                     }
153                 }
154             }
155         }
156     }
157 
158 }