/** * Create the command line for a sql process depending on the meta information supplied. * * @param meta The meta data to create the command line from * @return The string to execute. * @throws KettleException Upon any exception */ public String createCommandLine(IngresVectorwiseLoaderMeta meta) throws KettleException { StringBuffer sb = new StringBuffer(300); if (!Const.isEmpty(meta.getSqlPath())) { try { FileObject fileObject = KettleVFS.getFileObject(environmentSubstitute(meta.getSqlPath()), getTransMeta()); String sqlexec = Const.optionallyQuoteStringByOS(KettleVFS.getFilename(fileObject)); sb.append(sqlexec); // sql @tc-dwh-test.timocom.net,tcp_ip,VW[ingres,pwd]::dwh } catch (KettleFileException ex) { throw new KettleException("Error retrieving command string", ex); } } else { if (meta.isUsingVwload()) { if (isDetailed()) logDetailed("vwload defaults to system path"); sb.append("vwload"); } else { if (isDetailed()) logDetailed("sql defaults to system path"); sb.append("sql"); } } DatabaseMeta dm = meta.getDatabaseMeta(); if (dm != null) { String databaseName = environmentSubstitute(Const.NVL(dm.getDatabaseName(), "")); String password = Encr.decryptPasswordOptionallyEncrypted( environmentSubstitute(Const.NVL(dm.getDatabaseInterface().getPassword(), ""))); String port = environmentSubstitute(Const.NVL(dm.getDatabasePortNumberString(), "")).replace("7", ""); String username = environmentSubstitute(Const.NVL(dm.getDatabaseInterface().getUsername(), "")); String hostname = environmentSubstitute(Const.NVL(dm.getDatabaseInterface().getHostname(), "")); String schemaTable = dm.getQuotedSchemaTableCombination(null, environmentSubstitute(meta.getTablename())); String encoding = environmentSubstitute(Const.NVL(meta.getEncoding(), "")); String fifoFile = Const.optionallyQuoteStringByOS( environmentSubstitute(Const.NVL(meta.getFifoFileName(), ""))); String errorFile = Const.optionallyQuoteStringByOS( environmentSubstitute(Const.NVL(meta.getErrorFileName(), ""))); int maxNrErrors = Const.toInt(environmentSubstitute(Const.NVL(meta.getMaxNrErrors(), "0")), 0); if (meta.isUsingVwload()) { sb.append(" -u ").append(username); sb.append(" -P ").append(password); sb.append(" -f ").append(meta.getDelimiter()).append(""); sb.append(" -t ").append(schemaTable); if (!Const.isEmpty(encoding)) { sb.append(" -C ").append(encoding); } if (!Const.isEmpty(errorFile)) { sb.append(" -l ").append(errorFile); } if (maxNrErrors > 0) { sb.append(" -x ").append(maxNrErrors); } sb.append(" ").append(databaseName); sb.append(" ").append(fifoFile); } else if (meta.isUseDynamicVNode()) { // logical portname in JDBC use a 7 sb.append(" @") .append(hostname) .append(",") .append(port) .append("[") .append(username) .append(",") .append(password) .append("]::") .append(databaseName); } else { // Database Name // sb.append(" ").append(databaseName); if (meta.isUseAuthentication()) { sb.append("-P").append(password); } } } else { throw new KettleException("No connection specified"); } return sb.toString(); }
private void executeShell(Result result, List<RowMetaAndData> cmdRows, String[] args) { FileObject fileObject = null; String realScript = null; FileObject tempFile = null; try { // What's the exact command? String[] base = null; List<String> cmds = new ArrayList<String>(); if (log.isBasic()) { logBasic(BaseMessages.getString(PKG, "JobShell.RunningOn", Const.getOS())); } if (insertScript) { realScript = environmentSubstitute(script); } else { String realFilename = environmentSubstitute(getFilename()); fileObject = KettleVFS.getFileObject(realFilename, this); } if (Const.getOS().equals("Windows 95")) { base = new String[] {"command.com", "/C"}; if (insertScript) { tempFile = KettleVFS.createTempFile( "kettle", "shell.bat", System.getProperty("java.io.tmpdir"), this); fileObject = createTemporaryShellFile(tempFile, realScript); } } else if (Const.getOS().startsWith("Windows")) { base = new String[] {"cmd.exe", "/C"}; if (insertScript) { tempFile = KettleVFS.createTempFile( "kettle", "shell.bat", System.getProperty("java.io.tmpdir"), this); fileObject = createTemporaryShellFile(tempFile, realScript); } } else { if (insertScript) { tempFile = KettleVFS.createTempFile( "kettle", "shell", System.getProperty("java.io.tmpdir"), this); fileObject = createTemporaryShellFile(tempFile, realScript); } base = new String[] {KettleVFS.getFilename(fileObject)}; } // Construct the arguments... if (argFromPrevious && cmdRows != null) { // Add the base command... for (int i = 0; i < base.length; i++) { cmds.add(base[i]); } if (Const.getOS().equals("Windows 95") || Const.getOS().startsWith("Windows")) { // for windows all arguments including the command itself // need to be // included in 1 argument to cmd/command. StringBuffer cmdline = new StringBuffer(300); cmdline.append('"'); cmdline.append(Const.optionallyQuoteStringByOS(KettleVFS.getFilename(fileObject))); // Add the arguments from previous results... for (int i = 0; i < cmdRows.size(); i++) { // Normally just one row, but once in a while to remain compatible we have multiple. RowMetaAndData r = cmdRows.get(i); for (int j = 0; j < r.size(); j++) { cmdline.append(' '); cmdline.append(Const.optionallyQuoteStringByOS(r.getString(j, null))); } } cmdline.append('"'); cmds.add(cmdline.toString()); } else { // Add the arguments from previous results... for (int i = 0; i < cmdRows.size(); i++) { // Normally just one row, but once in a while to remain compatible we have multiple. RowMetaAndData r = cmdRows.get(i); for (int j = 0; j < r.size(); j++) { cmds.add(Const.optionallyQuoteStringByOS(r.getString(j, null))); } } } } else if (args != null) { // Add the base command... for (int i = 0; i < base.length; i++) { cmds.add(base[i]); } if (Const.getOS().equals("Windows 95") || Const.getOS().startsWith("Windows")) { // for windows all arguments including the command itself // need to be // included in 1 argument to cmd/command. StringBuffer cmdline = new StringBuffer(300); cmdline.append('"'); cmdline.append(Const.optionallyQuoteStringByOS(KettleVFS.getFilename(fileObject))); for (int i = 0; i < args.length; i++) { cmdline.append(' '); cmdline.append(Const.optionallyQuoteStringByOS(args[i])); } cmdline.append('"'); cmds.add(cmdline.toString()); } else { for (int i = 0; i < args.length; i++) { cmds.add(args[i]); } } } StringBuffer command = new StringBuffer(); Iterator<String> it = cmds.iterator(); boolean first = true; while (it.hasNext()) { if (!first) { command.append(' '); } else { first = false; } command.append(it.next()); } if (log.isBasic()) { logBasic(BaseMessages.getString(PKG, "JobShell.ExecCommand", command.toString())); } // Build the environment variable list... ProcessBuilder procBuilder = new ProcessBuilder(cmds); Map<String, String> env = procBuilder.environment(); String[] variables = listVariables(); for (int i = 0; i < variables.length; i++) { env.put(variables[i], getVariable(variables[i])); } if (getWorkDirectory() != null && !Const.isEmpty(Const.rtrim(getWorkDirectory()))) { String vfsFilename = environmentSubstitute(getWorkDirectory()); File file = new File(KettleVFS.getFilename(KettleVFS.getFileObject(vfsFilename, this))); procBuilder.directory(file); } Process proc = procBuilder.start(); // any error message? StreamLogger errorLogger = new StreamLogger(log, proc.getErrorStream(), "(stderr)", true); // any output? StreamLogger outputLogger = new StreamLogger(log, proc.getInputStream(), "(stdout)"); // kick them off Thread errorLoggerThread = new Thread(errorLogger); errorLoggerThread.start(); Thread outputLoggerThread = new Thread(outputLogger); outputLoggerThread.start(); proc.waitFor(); if (log.isDetailed()) { logDetailed(BaseMessages.getString(PKG, "JobShell.CommandFinished", command.toString())); } // What's the exit status? result.setExitStatus(proc.exitValue()); if (result.getExitStatus() != 0) { if (log.isDetailed()) { logDetailed( BaseMessages.getString( PKG, "JobShell.ExitStatus", environmentSubstitute(getFilename()), "" + result.getExitStatus())); } result.setNrErrors(1); } // wait until loggers read all data from stdout and stderr errorLoggerThread.join(); outputLoggerThread.join(); // close the streams // otherwise you get "Too many open files, java.io.IOException" after a lot of iterations proc.getErrorStream().close(); proc.getOutputStream().close(); } catch (IOException ioe) { logError( BaseMessages.getString( PKG, "JobShell.ErrorRunningShell", environmentSubstitute(getFilename()), ioe.toString()), ioe); result.setNrErrors(1); } catch (InterruptedException ie) { logError( BaseMessages.getString( PKG, "JobShell.Shellinterupted", environmentSubstitute(getFilename()), ie.toString()), ie); result.setNrErrors(1); } catch (Exception e) { logError( BaseMessages.getString( PKG, "JobShell.UnexpectedError", environmentSubstitute(getFilename()), e.toString()), e); result.setNrErrors(1); } finally { // If we created a temporary file, remove it... // if (tempFile != null) { try { tempFile.delete(); } catch (Exception e) { BaseMessages.getString( PKG, "JobShell.UnexpectedError", tempFile.toString(), e.toString()); } } } if (result.getNrErrors() > 0) { result.setResult(false); } else { result.setResult(true); } }