public void runShellScript()

in phoenix-queryserver-it/src/it/java/org/apache/phoenix/end2end/SecureQueryServerPhoenixDBIT.java [357:472]


    public void runShellScript(String ... testCli) throws Exception {
        final Entry<String,File> user1 = getUser(1);
        String currentDirectory;
        File file = new File(".");
        currentDirectory = file.getAbsolutePath();
        LOG.debug("Current working directory : "+currentDirectory);
        LOG.debug("PQS_PORT:" + PQS_PORT);
        LOG.debug("PQS_URL: " + PQS_URL);
        ArrayList<String> cmdList = new ArrayList<>();
        // This assumes the test is being run from phoenix/phoenix-queryserver
        cmdList.add(Paths.get(currentDirectory, "src", "it", "bin", "test_phoenixdb.sh").toString());
        cmdList.add(Paths.get(currentDirectory, "..", "python-phoenixdb").toString());
        cmdList.add(user1.getKey() + "@" + KDC.getRealm());
        cmdList.add(user1.getValue().getAbsolutePath());
        final String osName = System.getProperty("os.name").toLowerCase();
        final Kdc kdcType;
        final String kdcImpl = System.getProperty("PHOENIXDB_KDC_IMPL", "");
        if (kdcImpl.isEmpty()) {
          if (osName.indexOf("mac") >= 0) {
            kdcType = Kdc.HEIMDAL;
          } else {
            kdcType = Kdc.MIT;
          }
        } else if (kdcImpl.trim().equalsIgnoreCase(Kdc.HEIMDAL.name())) {
          kdcType = Kdc.HEIMDAL;
        } else {
          kdcType = Kdc.MIT;
        }
        LOG.info("Generating krb5.conf for KDC type:'{}'. OS='{}', PHOENIXDB_KDC_IMPL='{}'", kdcType, osName, kdcImpl);
        File krb5ConfFile = null;
        switch (kdcType) {
            // It appears that we cannot generate a krb5.conf that is compatible with both MIT Kerberos
            // and Heimdal Kerberos that works with MiniKdc. MiniKdc forces a choice between either UDP or
            // or TCP for the KDC port. If we could have MiniKdc support both UDP and TCP, then we might be
            // able to converge on a single krb5.conf for both MIT and Heimdal.
            //
            // With the below Heimdal configuration, MIT kerberos will fail on a DNS lookup to the hostname
            // "tcp/localhost" instead of pulling off the "tcp/" prefix.
            case HEIMDAL:
                int kdcPort = KDC.getPort();
                LOG.info("MINIKDC PORT " + kdcPort);
                // Render a Heimdal compatible krb5.conf
                // Currently kinit will only try tcp if the KDC is defined as
                // kdc = tcp/hostname:port
                StringBuilder krb5conf = new StringBuilder();
                krb5conf.append("[libdefaults]\n");
                krb5conf.append("     default_realm = EXAMPLE.COM\n");
                krb5conf.append("     udp_preference_limit = 1\n");
                krb5conf.append("\n");
                krb5conf.append("[realms]\n");
                krb5conf.append("    EXAMPLE.COM = {\n");
                krb5conf.append("       kdc = localhost:");
                krb5conf.append(kdcPort);
                krb5conf.append("\n");
                krb5conf.append("       kdc = tcp/localhost:");
                krb5conf.append(kdcPort);
                krb5conf.append("\n");
                krb5conf.append("    }\n");

                LOG.info("Writing Heimdal style krb5.conf");
                LOG.info(krb5conf.toString());
                krb5ConfFile = File.createTempFile("krb5.conf", null);
                FileOutputStream fos = new FileOutputStream(krb5ConfFile);
                fos.write(krb5conf.toString().getBytes());
                fos.close();
                LOG.info("krb5.conf written to " + krb5ConfFile.getAbsolutePath());
                cmdList.add(krb5ConfFile.getAbsolutePath());
                break;
            case MIT:
                cmdList.add(System.getProperty("java.security.krb5.conf"));
                LOG.info("Using miniKDC provided krb5.conf  " + KDC.getKrb5conf().getAbsolutePath());
                break;
            default:
                throw new RuntimeException("Unhandled KDC type: " + kdcType);
        }

        cmdList.add(Integer.toString(PQS_PORT));
        cmdList.addAll(Arrays.asList(testCli));

        LOG.info("Running command {}", cmdList.stream().collect(Collectors.joining(" ")));

        Thread outWriter = null;
        Thread errWriter = null;
        try {
          //This will intersperse that script's output to the maven output, but that's better than
          //getting stuck on a full buffer
          Process runPythonProcess = new ProcessBuilder(cmdList).start();
          BufferedReader processOutput = new BufferedReader(
              new InputStreamReader(runPythonProcess.getInputStream()));
          outWriter = new Thread(new StreamCopy(processOutput, new PrintWriter(System.out)));
          outWriter.start();

          BufferedReader processError = new BufferedReader(
              new InputStreamReader(runPythonProcess.getErrorStream()));
          errWriter = new Thread(new StreamCopy(processError, new PrintWriter(System.err)));
          errWriter.start();

          int exitCode = runPythonProcess.waitFor();

          // Not managed by miniKDC so we have to clean up
          if (krb5ConfFile != null)
              krb5ConfFile.delete();

          assertEquals("Subprocess exited with errors", 0, exitCode);
        } finally {
          LOG.info("Test exiting");
          if (outWriter != null) {
            outWriter.stop();
            System.out.flush();
          }
          if (errWriter != null) {
            errWriter.stop();
            System.err.flush();
          }
        }
    }