/** * Copyright 2014 Eediom Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.araqne.logdb.query.command; import java.io.IOException; import java.util.Arrays; import java.util.List; import org.araqne.logdb.QueryCommand; import org.araqne.logdb.Row; import org.araqne.logdb.RowBatch; import org.araqne.logdb.Strings; import org.araqne.logdb.TimeSpan; import org.araqne.logdb.query.expr.Expression; import org.slf4j.LoggerFactory; /** * @since 2.4.24 * @author xeraph * */ public class Exec extends QueryCommand { private final org.slf4j.Logger slog = LoggerFactory.getLogger(Exec.class); private String command; private List<Expression> args; private final int argCount; private final TimeSpan timeout; public Exec(String command, List<Expression> args, TimeSpan timeout) { this.command = command; this.args = args; this.argCount = args.size(); this.timeout = timeout; } public String getCommand() { return command; } public List<Expression> getArguments() { return args; } @Override public String getName() { return "exec"; } @Override public void onPush(Row row) { runCommand(row); pushPipe(row); } @Override public void onPush(RowBatch rowBatch) { if (rowBatch.selectedInUse) { for (int i = 0; i < rowBatch.size; i++) { int p = rowBatch.selected[i]; Row row = rowBatch.rows[p]; runCommand(row); } } else { for (int i = 0; i < rowBatch.size; i++) { Row row = rowBatch.rows[i]; runCommand(row); } } pushPipe(rowBatch); } private void runCommand(Row row) { try { String[] cmdArray = new String[argCount + 1]; cmdArray[0] = command; for (int i = 1; i <= argCount; i++) { Object value = args.get(i - 1).eval(row); cmdArray[i] = value == null ? "" : value.toString(); } if (slog.isDebugEnabled()) slog.debug("araqne logdb: exec command [{}]", Arrays.asList(cmdArray)); Process p = Runtime.getRuntime().exec(cmdArray); p.getInputStream().close(); p.getOutputStream().close(); p.getErrorStream().close(); if (timeout != null) { long expire = System.nanoTime() + timeout.getMillis() * 1000000; while (true) { try { p.exitValue(); break; } catch (IllegalThreadStateException e) { if (expire <= System.nanoTime()) { p.destroy(); break; } // not yet terminated Thread.sleep(10); } } } else { p.waitFor(); } } catch (IOException e) { slog.error("araqne logdb: exec failed: " + command, e); } catch (InterruptedException e) { } } @Override public String toString() { String timeoutOpt = ""; if (timeout != null) timeoutOpt = " timeout=" + timeout; return "exec" + timeoutOpt + " " + command + " " + Strings.join(args, ", "); } }