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.context.task.localexec;
22  
23  import goldengate.commandexec.client.LocalExecClientHandler;
24  import goldengate.commandexec.client.LocalExecClientPipelineFactory;
25  import goldengate.commandexec.utils.LocalExecResult;
26  import goldengate.common.future.GgFuture;
27  import goldengate.common.logging.GgInternalLogger;
28  import goldengate.common.logging.GgInternalLoggerFactory;
29  
30  import java.net.InetSocketAddress;
31  
32  import openr66.protocol.configuration.Configuration;
33  
34  import org.jboss.netty.bootstrap.ClientBootstrap;
35  import org.jboss.netty.channel.Channel;
36  import org.jboss.netty.channel.ChannelFuture;
37  import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
38  
39  /**
40   * Client to execute external command through GoldenGate Local Exec
41   *
42   * @author Frederic Bregier
43   *
44   */
45  public class LocalExecClient {
46      /**
47       * Internal Logger
48       */
49      private static final GgInternalLogger logger = GgInternalLoggerFactory
50              .getLogger(LocalExecClient.class);
51  
52      static public InetSocketAddress address;
53      // Configure the client.
54      static private ClientBootstrap bootstrapLocalExec;
55      // Configure the pipeline factory.
56      static private LocalExecClientPipelineFactory localExecClientPipelineFactory;
57  
58      /**
59       * Initialize the LocalExec Client context
60       */
61      public static void initialize() {
62          // Configure the client.
63          bootstrapLocalExec = new ClientBootstrap(
64                  new NioClientSocketChannelFactory(
65                          Configuration.configuration.getLocalPipelineExecutor(),
66                          Configuration.configuration.getLocalPipelineExecutor()));
67          // Configure the pipeline factory.
68          localExecClientPipelineFactory =
69                  new LocalExecClientPipelineFactory();
70          bootstrapLocalExec.setPipelineFactory(localExecClientPipelineFactory);
71      }
72  
73      /**
74       * To be called when the server is shutting down to release the resources
75       */
76      public static void releaseResources() {
77          if (bootstrapLocalExec == null) {
78              return;
79          }
80          // Shut down all thread pools to exit.
81          bootstrapLocalExec.releaseExternalResources();
82          localExecClientPipelineFactory.releaseResources();
83      }
84  
85      private Channel channel;
86      private LocalExecResult result;
87  
88      public LocalExecClient() {
89  
90      }
91  
92      public LocalExecResult getLocalExecResult() {
93          return result;
94      }
95  
96      /**
97       * Run one command with a specific allowed delay for execution.
98       * The connection must be ready (done with connect()).
99       * @param command
100      * @param delay
101      * @param futureCompletion
102      */
103     public void runOneCommand(String command, long delay, boolean waitFor, GgFuture futureCompletion) {
104      // Initialize the command context
105         LocalExecClientHandler clientHandler =
106             (LocalExecClientHandler) channel.getPipeline().getLast();
107         clientHandler.initExecClient();
108         // Command to execute
109 
110         ChannelFuture lastWriteFuture = null;
111         String line = delay+" "+command+"\n";
112         // Sends the received line to the server.
113         
114         lastWriteFuture = channel.write(line);
115         if (!waitFor) {
116             futureCompletion.setSuccess();
117             logger.info("Exec OK with {}", command);
118         }
119         // Wait until all messages are flushed before closing the channel.
120         if (lastWriteFuture != null) {
121             if (delay <= 0) {
122                 try {
123                     lastWriteFuture.await();
124                 } catch (InterruptedException e) {
125                 }
126             } else {
127                 try {
128                     lastWriteFuture.await(delay);
129                 } catch (InterruptedException e) {
130                 }
131             }
132         }
133         // Wait for the end of the exec command
134         LocalExecResult localExecResult = clientHandler.waitFor(delay*2);
135         result = localExecResult;
136         if (futureCompletion == null) {
137             return;
138         }
139         if (result.status == 0) {
140             if (waitFor) {
141                 futureCompletion.setSuccess();
142             }
143             logger.info("Exec OK with {}", command);
144         } else if (result.status == 1) {
145             logger.warn("Exec in warning with {}", command);
146             if (waitFor) {
147                 futureCompletion.setSuccess();
148             }
149         } else {
150             logger.error("Status: " + result.status + " Exec in error with " +
151                     command+"\n"+result.result);
152             if (waitFor) {
153                 futureCompletion.cancel();
154             }
155         }
156     }
157 
158     /**
159      * Connect to the Server
160      */
161     public boolean connect() {
162         // Start the connection attempt.
163         ChannelFuture future = bootstrapLocalExec.connect(address);
164 
165         // Wait until the connection attempt succeeds or fails.
166         try {
167             channel = future.await().getChannel();
168         } catch (InterruptedException e) {
169         }
170         if (!future.isSuccess()) {
171             logger.error("Client Not Connected", future.getCause());
172             return false;
173         }
174         return true;
175     }
176     /**
177      * Disconnect from the server
178      */
179     public void disconnect() {
180      // Close the connection. Make sure the close operation ends because
181         // all I/O operations are asynchronous in Netty.
182         try {
183             channel.close().await();
184         } catch (InterruptedException e) {
185         }
186     }
187 }