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();
}
}
}