0 Replies Latest reply on Nov 20, 2013 9:19 AM by Anthony Krinsky

    TabCmd "rest" interface

    Anthony Krinsky

      Here's a simple, psuedo restful way to run TabCmd from a web-browser via URL.

       

      Because of changes in java security, this solution needs the Apache Exec libraries to run.

      The "CommandLine" class is interesting and I didn't see a straight-forward way to call multiple lines at once. 

       

      TabCmd needs a session...

       

      - login

      - action(s)

      - logoff

       

      If you come up with a better way to do this, share here.

       

      Please modify and adapt to your needs.  I/Tableau assume no responsibility ;-)

       

      <%@ page contentType="text/html;charset=UTF-8"

               language="java"

              %>

      <%@ page import="org.apache.commons.exec.CommandLine" %>

      <%@ page import="org.apache.commons.exec.DefaultExecutor" %>

      <%@ page import="java.io.*" %>

      <%@ page import="java.util.ArrayList" %>

       

      <h2>TabCmd REST url interface</h2><p>

      <%

       

          String username = "admin";

          String password = "admin";

          String connectionUrl = "http://127.0.0.1:8000";

          //using the one in the Tableau directory does not seem to work...

          String tabCmdPath = "C:/CLI/Command Line Utility/tabcmd.exe";

       

          String outputRootPath = "c:/temp";

          String postProcBatch = "c:/temp/dosomething.bat";

          //will get passed the file name as "-f <filename>"

          String action = request.getParameter("action");

          String viewRemotePath = request.getParameter("view");

          String outputFilename = request.getParameter("file");

          String format = request.getParameter("fmt");

          boolean debug = true;

          //set these strings to where the Tableau server is running

       

          File tabCmdFile = new File(tabCmdPath);

          if (!tabCmdFile.exists()) {

              out.print("TabCmd file " + tabCmdPath + " cannot be found.");

              return;

          }

       

          CmdConnection conn = new CmdConnection();

          conn.username = username;

          conn.password = password;

          conn.connectionUrl = connectionUrl;

          conn.tabCmdFile = tabCmdFile;

          conn.outputRootPath = outputRootPath;

          conn.postProcBatch = postProcBatch;

          conn.out = out;

          conn.debug = debug;

          conn.sessionOutput = new com.sun.xml.internal.messaging.saaj.util.ByteOutputStream();

          conn.sessionErrorOutput = new com.sun.xml.internal.messaging.saaj.util.ByteOutputStream();

          conn.sessionInput = null;

       

          //check required params

          if (action == null || action.equalsIgnoreCase("gen")) {

              action = "gen";

              if (format == null) format = "pdf";

              if (viewRemotePath == null) {

                  out.print("Remote path required: " + viewRemotePath);

                  return;

              }

          }

          if (action.equalsIgnoreCase("gen")) {

              if (outputFilename==null)outputFilename=viewRemotePath;

              String outputLocalPath = outputRootPath + outputFilename + "." + format;

              File f = new File(outputLocalPath);

              //make parentd irectories

              f.getParentFile().mkdirs();

              if (f.exists()) f.delete();

              TabCmdOutput results = generate(conn, viewRemotePath, outputLocalPath, format);

              out.print(results.toString());

          }

       

      %>

       

       

      <%!

          // SUPPORT FUNCTIONS...

       

      //////////////////////////////////////////////////////

          //Utility Methods

          //////////////////////////////////////////////////////

          boolean isNullEmpty(String el) {

              if (el == null || el.trim().length() == 0) return true;

              return false;

          }

       

          String joinArgs(String[] args) {

              return joinArgs(args, null);

          }

       

          String joinArgs(String[] args, String[] args2) {

              StringBuffer sb = new StringBuffer();

              for (String arg : args) {

                  if (arg.indexOf(" ") > -1) {

                      sb.append("\"" + arg + "\" ");

                  } else {

                      sb.append(arg + " ");

                  }

              }

              if (args2 != null) {

                  for (String arg : args2) {

                      if (arg.indexOf(" ") > -1) {

      sb.append("\"" + arg + "\" ");

                      } else {

                          sb.append(arg + " ");

                      }

                  }

              }

              return sb.toString().trim();

          }

       

       

          String stackTraceToString(Throwable e) {

              String retValue = null;

              java.io.StringWriter sw = null;

              java.io.PrintWriter pw = null;

              try {

                  sw = new java.io.StringWriter();

                  pw = new java.io.PrintWriter(sw);

                  e.printStackTrace(pw);

                  retValue = sw.toString();

              } finally {

                  try {

                      if (pw != null) pw.close();

                      if (sw != null) sw.close();

                  } catch (java.io.IOException ignore) {

                  }

              }

              return retValue;

          }

       

       

          class CmdConnection {

              String username = "";

              String password = "";

              String connectionUrl = "";

              File tabCmdFile;

              String outputRootPath = "";

              String postProcBatch = "";

              JspWriter out;

              boolean debug;

              OutputStream sessionOutput;

              OutputStream sessionErrorOutput;

              InputStream sessionInput;

          }

       

          class TabCmdOutput {

              private boolean successful = false;

              private ArrayList<String> outputList = new ArrayList<String>();

              private ArrayList<String> errorList = new ArrayList<String>();

       

              public void appendOutput(String s) {

                  outputList.add(s);

              }

       

              public void appendError(String s) {

                  errorList.add(s);

              }

       

              public void setSuccessful(boolean success) {

                  this.successful = success;

              }

       

              public boolean isSuccessful() {

                  return this.successful;

              }

       

              public String getOutputs() {

                  StringBuffer sb = new StringBuffer();

                  for (String o : outputList) sb.append(o + "/n");

                  return sb.toString();

              }

       

              public String getErrors() {

                  StringBuffer sb = new StringBuffer();

                  for (String o : errorList) sb.append(o + "/n");

                  return sb.toString();

              }

       

              public String toString() {

                  return "<b>OUTPUT:</b> " + getOutputs() + "<p>/n<b>ERRORS:</b> " + getErrors() + "<br>/n<b>SUCCESS</b>: " + isSuccessful();

              }

          }

       

      //////////////////////////////////////////////////////

          // Functions

          //////////////////////////////////////////////////////

          public TabCmdOutput connect(CmdConnection conn) throws Exception {

              String cmd = conn.tabCmdFile.getAbsolutePath();

              String[] connectArgs = {cmd, "login", "-s", conn.connectionUrl, "-u", conn.username, "-p", conn.password};

              String[] logoutArgs = {cmd, "logout"};

              String[] lines = new String[2];

              lines[0] = joinArgs(connectArgs);

              lines[1] = joinArgs(logoutArgs);

              TabCmdOutput o = runCommands(conn, lines);

              if (o.toString().toLowerCase().indexOf("succe") > -1) o.setSuccessful(true);

              return o;

          }

       

       

          public TabCmdOutput generate(CmdConnection conn, String viewRemotePath, String outputLocalPath, String format) throws Exception {

              //options

              /*

             --name

             --overwrite

             --project

             --db-username

             --db-password

             --save-db-password

             --thumbnail-username

             --thumbnail-group

             --tabbed

              */

              String cmd = conn.tabCmdFile.getAbsolutePath();

              String[] connectArgs = {cmd, "login", "-s", conn.connectionUrl, "-u", conn.username, "-p", conn.password};

              String[] publishArgs = {cmd, "get", viewRemotePath + "." + format, "-f", outputLocalPath};

              String[] logoutArgs = {cmd, "logout"};

              String[] lines = new String[3];

              lines[0] = joinArgs(connectArgs);

              lines[1] = joinArgs(publishArgs);

              lines[2] = joinArgs(logoutArgs);

              TabCmdOutput o = runCommands(conn, lines);

              if (o.toString().indexOf("Saved") > -1) o.setSuccessful(true);

              return o;

          }

       

      //////////////////////////////////////////////////////

          // Proc runner

      //////////////////////////////////////////////////////

          TabCmdOutput runCommands(CmdConnection conn, String[] lines) throws Exception {

              if (lines == null) return new TabCmdOutput();

              TabCmdOutput o = runCommandLines(conn, lines);

              return o;

          }

       

       

          private TabCmdOutput runCommandLines(CmdConnection conn, String[] lines) {

              //we get an error running this file this way from z5. Rather, install into another tomcat container

              //uninitialized constant OpenSSL::Digest::OPENSSL_VERSION_NUMBER/n const_missing at org/jruby/RubyModule.java:2642/n Digest at C:/Program Files (x86)/Tableau/Tableau

              TabCmdOutput o = new TabCmdOutput();

              java.util.Date today = java.util.Calendar.getInstance().getTime();

              java.text.DateFormat df = new java.text.SimpleDateFormat("MMddyyyyHHmmss");

              int exitValue = 0;

              try {

                  DefaultExecutor executor = new DefaultExecutor();

                  executor.setExitValue(exitValue);

                  executor.setStreamHandler(new org.apache.commons.exec.PumpStreamHandler(conn.sessionOutput, conn.sessionErrorOutput, conn.sessionInput));

      //org.apache.commons.exec.ExecuteWatchdog watchdog = new org.apache.commons.exec.ExecuteWatchdog(50000);

                  //executor.setWatchdog(watchdog);

       

                  if (conn.debug) conn.out.println("Processing " + lines.length + " lines.<br>");

                  String tempFileName = "tbcmd" + df.format(today) + "_" + Math.round(Math.random() / 10000);

                  File tempFile = File.createTempFile(tempFileName, ".bat");

                  tempFile.setWritable(true);

                  if (conn.debug) conn.out.println("Writing batch file to: " + tempFile.getAbsolutePath() + "<br>");

       

                  StringBuffer sb = new StringBuffer();

                  sb.append("REM ======================================\n");

                  sb.append("REM === TabCmd batch file\n");

                  sb.append("REM ======================================\n");

                  for (String line : lines) {

                      if (conn.debug) conn.out.println("Writing line: " + line + "<br>");

                      sb.append(line + "\n");

                  }

                  sb.append("REM ======================================\n");

      //sb.append("pause");

                  java.io.Writer fw = new BufferedWriter(new java.io.OutputStreamWriter(new java.io.FileOutputStream(tempFile)));

                  fw.write(sb.toString());

                  fw.flush();

                  try {

                      fw.close();

                      if (conn.debug) conn.out.println("Closed file.<br>");

                  } catch (Exception exw) {

                  }

                  CommandLine commandLine = new CommandLine(tempFile);           

                  if (conn.debug) conn.out.println("Executing file: " + tempFile.getName() + "<br>");

                  exitValue = executor.execute(commandLine);

      o.appendError(conn.sessionErrorOutput.toString());

                  o.appendOutput(conn.sessionOutput.toString());

       

                  if (exitValue != 0) {

                      o.setSuccessful(false);

                      if (conn.debug) conn.out.println("Errors encountered: "+exitValue+".<br>");

                  } else {

                      o.setSuccessful(true);

                      if (conn.debug) conn.out.println("Success: "+exitValue+"!<br>");

                  }

      //tempFile.delete();

              } catch (Exception ex) {

                  o.setSuccessful(false);

                  if (conn.debug) {

                      try { conn.out.println("Exception running TabCmd: " + stackTraceToString(ex));   } catch (Exception ex2){}

                  }

              }

       

              return o;

          }

       

          String inputStreamToString(InputStream is) throws IOException {

              BufferedReader bReader = new BufferedReader(new InputStreamReader(is));

              StringBuffer sbfFileContents = new StringBuffer();

              String line = null;

       

              //read file line by line

              while ((line = bReader.readLine()) != null) {

                  sbfFileContents.append(line);

              }

       

              //finally convert StringBuffer object to String!

              return sbfFileContents.toString();

          }

       

      %>