/*
# Licensed Materials - Property of IBM
# Copyright IBM Corp. 2015
*/
package com.ibm.streamsx.topology.internal.streams;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
import com.google.gson.JsonObject;
import com.ibm.streams.operator.version.Product;
import com.ibm.streams.operator.version.Version;
import com.ibm.streamsx.topology.Topology;
import com.ibm.streamsx.topology.context.ContextProperties;
import com.ibm.streamsx.topology.internal.process.ProcessOutputToLogger;
public class InvokeSc {
static final Logger trace = Topology.STREAMS_LOGGER;
private Set<File> toolkits = new HashSet<>();
private final boolean standalone;
private final String namespace;
private final String mainComposite;
private final File applicationDir;
private final String installDir;
public InvokeSc(JsonObject deploy, boolean standalone, String namespace, String mainComposite,
File applicationDir) throws URISyntaxException, IOException {
super();
this.namespace = namespace;
this.mainComposite = mainComposite;
this.applicationDir = applicationDir;
installDir = Util.getStreamsInstall(deploy, ContextProperties.COMPILE_INSTALL_DIR);
// Version 4.2 onwards deprecates standalone compiler option
// so don't use it to avoid warnings.
if (Util.getStreamsInstall().equals(installDir)) {
Version ver = Product.getVersion();
if ((ver.getVersion() == 4 && ver.getRelease() >= 2)
|| (ver.getVersion() > 4))
standalone = false;
} else {
// TODO: get version of compile install to be used
}
this.standalone = standalone;
addFunctionalToolkit();
}
public void addToolkit(File toolkitDir) throws IOException {
toolkits.add(toolkitDir.getCanonicalFile());
}
private void addFunctionalToolkit() throws URISyntaxException, IOException {
URL location = getClass().getProtectionDomain().getCodeSource()
.getLocation();
// Assumption it is at lib in the toolkit.
// Allow overriding to support test debug in eclipse,
// where the tkroot location relationship to this code isn't as
// isn't as expected during normal execution.
String tkRootPath = System.getProperty(
"com.ibm.streamsx.topology.invokeSc.functionalTkRoot");
if (tkRootPath!=null) {
File tkRoot = new File(tkRootPath);
addToolkit(tkRoot);
return;
}
Path functionaljar = Paths.get(location.toURI());
File tkRoot = functionaljar.getParent().getParent().toFile();
addToolkit(tkRoot);
}
public void invoke() throws Exception, InterruptedException {
File sc = new File(installDir, "bin/sc");
List<String> commands = new ArrayList<>();
String mainCompositeName = namespace + "::" + mainComposite;
commands.add(sc.getAbsolutePath());
commands.add("--rebuild-toolkits");
commands.add("--optimized-code-generation");
commands.add("--num-make-threads=4");
if (standalone)
commands.add("--standalone");
commands.add("-M");
commands.add(mainCompositeName);
commands.add("-t");
commands.add(getToolkitPath());
trace.info("Invoking SPL compiler (sc) for main composite: "
+ mainCompositeName);
trace.info(Util.concatenate(commands));
ProcessBuilder pb = new ProcessBuilder(commands);
// Force the SPL application to use the Java provided by
// Streams to ensure the bundle is not dependent on the
// local JVM install path.
pb.environment().remove("JAVA_HOME");
// Set STREAMS_INSTALL in case it was overriden for compilation
pb.environment().put("STREAMS_INSTALL", installDir);
// Ensure than only the toolkit path set by -t is used.
pb.environment().remove("STREAMS_SPLPATH");
pb.directory(applicationDir);
Process scProcess = pb.start();
ProcessOutputToLogger.log(trace, scProcess);
scProcess.getOutputStream().close();
int rc = scProcess.waitFor();
trace.info("SPL compiler complete: return code=" + rc);
if (rc != 0)
throw new Exception("SPL compilation failed!");
}
private String getToolkitPath() {
StringBuilder sb = new StringBuilder();
boolean first = true;
for (File tk : toolkits) {
if (!first)
sb.append(":");
else
first = false;
sb.append(tk.getAbsolutePath());
}
String splPath = System.getenv("STREAMS_SPLPATH");
if (splPath != null) {
sb.append(":");
sb.append(splPath);
}
String streamsInstallToolkits = installDir + "/toolkits";
if (sb.indexOf(streamsInstallToolkits) == -1) {
sb.append(":");
sb.append(streamsInstallToolkits);
}
trace.info("ToolkitPath:" + sb.toString());
return sb.toString();
}
}