/* # Licensed Materials - Property of IBM # Copyright IBM Corp. 2015 */ package com.ibm.streamsx.topology.internal.context; import static com.ibm.streamsx.topology.context.ContextProperties.APP_DIR; import static com.ibm.streamsx.topology.context.ContextProperties.TOOLKIT_DIR; import static com.ibm.streamsx.topology.internal.context.remote.DeployKeys.createJobConfigOverlayFile; import static com.ibm.streamsx.topology.internal.context.remote.DeployKeys.deploy; import static com.ibm.streamsx.topology.internal.context.remote.DeployKeys.keepArtifacts; import static com.ibm.streamsx.topology.internal.context.remote.ToolkitRemoteContext.deleteToolkit; import static com.ibm.streamsx.topology.internal.graph.GraphKeys.splAppName; import static com.ibm.streamsx.topology.internal.graph.GraphKeys.splAppNamespace; import static com.ibm.streamsx.topology.internal.gson.GsonUtilities.array; import static com.ibm.streamsx.topology.internal.gson.GsonUtilities.jstring; import static com.ibm.streamsx.topology.internal.gson.GsonUtilities.object; import java.io.File; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.util.concurrent.Future; import java.util.logging.Logger; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.ibm.streamsx.topology.Topology; import com.ibm.streamsx.topology.context.remote.RemoteContext; import com.ibm.streamsx.topology.internal.context.remote.SubmissionResultsKeys; import com.ibm.streamsx.topology.internal.core.InternalProperties; import com.ibm.streamsx.topology.internal.graph.GraphKeys; import com.ibm.streamsx.topology.internal.gson.GsonUtilities; import com.ibm.streamsx.topology.internal.process.CompletedFuture; import com.ibm.streamsx.topology.internal.streams.InvokeSc; /** * Create a Streams bundle using SPL compiler (sc) from a local Streams install. */ public class BundleStreamsContext extends ToolkitStreamsContext { static final Logger trace = Topology.TOPOLOGY_LOGGER; private final boolean standalone; private final boolean keepBundle; public BundleStreamsContext(boolean standalone, boolean keepBundle) { this.standalone = standalone; this.keepBundle = keepBundle; } @Override public Type getType() { return standalone ? Type.STANDALONE_BUNDLE : Type.BUNDLE; } @Override Future<File> action(AppEntity entity) throws Exception { JsonObject submission = entity.submission; JsonObject deploy = deploy(submission); if (deploy.has(APP_DIR)) deploy.add(TOOLKIT_DIR, deploy.get(APP_DIR)); File appDir = super.action(entity).get(); Future<File> bundle = doSPLCompile(appDir, submission); // Create a Job Config Overlays file if this is creating // a sab for subsequent distributed deployment // or keepArtifacts is set. if (!standalone && (keepBundle || keepArtifacts(submission))) createJobConfigOverlayFile(submission, deploy, bundle.get().getParentFile()); // If user asked for the SAB or asked to keep the SAB explicitly if (keepBundle || keepArtifacts(submission)) { final JsonObject submissionResult = GsonUtilities.objectCreate(submission, RemoteContext.SUBMISSION_RESULTS); submissionResult.addProperty(SubmissionResultsKeys.BUNDLE_PATH, bundle.get().getAbsolutePath()); } return bundle; } private Future<File> doSPLCompile(File appDir, JsonObject submission) throws Exception { JsonObject deploy = deploy(submission); JsonObject graph = GraphKeys.graph(submission); String namespace = splAppNamespace(graph); String name = splAppName(graph); InvokeSc sc = new InvokeSc(deploy, standalone, namespace, name, appDir); // Add the toolkits JsonObject splConfig = object(graph, "config", "spl"); if (splConfig != null) { JsonArray toolkits = array(splConfig, InternalProperties.TOOLKITS_JSON); for (JsonElement obj : toolkits) { JsonObject tkinfo = obj.getAsJsonObject(); String root = jstring(tkinfo, "root"); if (root != null) sc.addToolkit(new File(root)); } } sc.invoke(); File outputDir = new File(appDir, "output"); String bundleName = namespace + "." + name + ".sab"; File bundle = new File(outputDir, bundleName); File localBundle = new File(bundle.getName()); Files.copy(bundle.toPath(), localBundle.toPath(), StandardCopyOption.REPLACE_EXISTING); if (!deleteToolkit(appDir, deploy)) trace.info("Keeping toolkit at: " + appDir.getAbsolutePath()); trace.info("Streams Application Bundle produced: " + localBundle.getName()); return new CompletedFuture<File>(localBundle); } }