This project has retired. For details please refer to its Attic page.
ExecPlugin xref
View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.chukwa.inputtools.plugin;
20  
21  
22  import java.io.BufferedReader;
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.io.InputStreamReader;
26  import org.json.simple.JSONObject;
27  
28  /**
29   * Runs external command-line tools, captures output.
30   * 
31   * Subclasses are responsible for implementing getCmde(), which determines the
32   * command to be invoked.
33   * 
34   */
35  public abstract class ExecPlugin implements IPlugin {
36    public final int statusOK = 100;
37    public final int statusKO = -100;
38  
39    Process process = null;
40  
41    public ExecPlugin() {
42  
43    }
44  
45    public void stop() {
46      if(process != null)
47        process.destroy();
48    }
49  
50    public int waitFor() throws InterruptedException {
51      return process.waitFor();
52    }
53  
54    public abstract String getCmde();
55  
56    public JSONObject postProcess(JSONObject execResult) {
57      return execResult;
58    }
59  
60    public JSONObject execute() {
61      JSONObject result = new JSONObject();
62      try {
63        result.put("timestamp", System.currentTimeMillis());
64  
65        Runtime runtime = Runtime.getRuntime();
66        process = runtime.exec(getCmde());
67  
68        OutputReader stdOut = new OutputReader(process, Output.stdOut);
69        stdOut.start();
70        OutputReader stdErr = new OutputReader(process, Output.stdErr);
71        stdErr.start();
72        int exitValue = process.waitFor();
73        stdOut.join();
74        stdErr.join();
75        process.getInputStream().close(); //otherwise this implicitly stays open
76        result.put("exitValue", exitValue);
77        result.put("stdout", stdOut.output.toString());
78        result.put("stderr", stdErr.output.toString());
79        result.put("status", statusOK);
80        process.getOutputStream().close();
81        process.getErrorStream().close();
82      } catch (Throwable e) {
83        try {
84          result.put("status", statusKO);
85          result.put("errorLog", e.getMessage());
86          if(e.getMessage().contains("Too many open files")) {
87            //maybe die abruptly?  Error is ir-recoverable and runtime can reboot us.
88  //        System.exit(1); 
89          }
90        } catch (Exception e1) {
91          e1.printStackTrace();
92        }
93        e.printStackTrace();
94      }
95  
96      return postProcess(result);
97    }
98  }
99  
100 
101 enum Output {
102   stdOut, stdErr
103 };
104 
105 
106 class OutputReader extends Thread {
107   private Process process = null;
108   private Output outputType = null;
109   public StringBuilder output = new StringBuilder();
110   public boolean isOk = true;
111 
112   public OutputReader(Process process, Output outputType) {
113     this.process = process;
114     this.outputType = outputType;
115   }
116 
117   public void run() {
118     try {
119       String line = null;
120       InputStream is = null;
121       switch (this.outputType) {
122       case stdOut:
123         is = process.getInputStream();
124         break;
125       case stdErr:
126         is = process.getErrorStream();
127         break;
128 
129       }
130 
131       InputStreamReader isr = new InputStreamReader(is);
132       BufferedReader br = new BufferedReader(isr);
133       while ((line = br.readLine()) != null) {
134         // System.out.println("========>>>>>>>["+line+"]");
135         output.append(line).append("\n");
136       }
137       br.close();
138     } catch (IOException e) {
139       isOk = false;
140       e.printStackTrace();
141     } catch (Throwable e) {
142       isOk = false;
143       e.printStackTrace();
144     }
145   }
146 }