/*
# Licensed Materials - Property of IBM
# Copyright IBM Corp. 2011, 2014
*/
package com.ibm.streamsx.inet.rest.ops;
import com.ibm.streams.operator.AbstractOperator;
import com.ibm.streams.operator.OperatorContext;
import com.ibm.streams.operator.OperatorContext.ContextCheck;
import com.ibm.streams.operator.compile.OperatorContextChecker;
import com.ibm.streams.operator.metrics.Metric;
import com.ibm.streams.operator.metrics.Metric.Kind;
import com.ibm.streams.operator.model.CustomMetric;
import com.ibm.streams.operator.model.Parameter;
import com.ibm.streamsx.inet.rest.engine.ServletEngine;
import com.ibm.streamsx.inet.rest.engine.ServletEngineMBean;
public abstract class ServletOperator extends AbstractOperator {
private ServletEngineMBean jetty;
public synchronized ServletEngineMBean getJetty() {
return jetty;
}
public synchronized void setJetty(ServletEngineMBean jetty) {
this.jetty = jetty;
}
@Override
public void initialize(OperatorContext context) throws Exception {
super.initialize(context);
setJetty(ServletEngine.getServletEngine(context));
getJetty().registerOperator(getClass().getName(), context, getConduit());
createAvoidCompletionThreadIfNoInputs();
}
protected Object getConduit() {
return null;
}
@Override
public void process(com.ibm.streams.operator.StreamingInput<com.ibm.streams.operator.Tuple> stream, com.ibm.streams.operator.Tuple tuple) throws Exception {
}
@Override
public void allPortsReady() throws Exception {
getJetty().start();
}
@Override
public void shutdown() throws Exception {
getJetty().stop();
}
/*
* The ServletEngine accesses all parameters through the operator
* context, as that is an object that is not specific to each
* operator's class loader.
*/
@Parameter(optional=true, description="Port number for the embedded Jetty HTTP server. Defaults to 8080.")
public void setPort(int port) {}
@Parameter(optional=true, description=CONTEXT_DESC)
public void setContext(String context) {}
@Parameter(optional=true, description=CRB_DESC)
public void setContextResourceBase(String base) {}
@Parameter(optional=true, description="Alias of the certificate to use in the key store. "
+ "When this parameter is set all connections use HTTPS.")
public void setCertificateAlias(String ca) {}
@Parameter(optional=true, description="URL to the key store containing the certificate. "
+ "If a relative file path then it is taken as relative to the application directory.")
public void setKeyStore(String ks) {}
@Parameter(optional=true, description="Password to the key store.")
public void setKeyStorePassword(String ksp) {}
@Parameter(optional=true, description="Password to the certificate. If not provided, defaults to the value of `keyStorePassword`.")
public void setKeyPassword(String kp) {}
@Parameter(optional = true, description = "URL to the trust store containing client certificates. "
+ "If a relative file path then it is taken as relative to the application directory. "
+ "When this parameter is set, client authentication is required.")
public void setTrustStore(String ks) {}
@Parameter(optional = true, description = "Password to the trust store.")
public void setTrustStorePassword(String ksp) {}
// Creates a metric that the ServletEngine will fill in.
private Metric serverPort;
@CustomMetric(description="Jetty (HTTP/HTTPS) server port", kind=Kind.GAUGE)
public void setServerPort(Metric metric) {this.serverPort = metric;}
public Metric getServerPort() { return serverPort; }
// Creates a metric that the ServletEngine will fill in.
private Metric https;
@CustomMetric(description="Jetty SSL/TLS status: 0=HTTP, 1=HTTPS", kind=Kind.GAUGE)
public void setHttps(Metric metric) {this.https = metric;}
public Metric getHttps() { return https; }
@ContextCheck
public static void checkContextParameters(OperatorContextChecker checker) {
checker.checkDependentParameters("context", "contextResourceBase");
checker.checkDependentParameters("contextResourceBase", "context");
checker.checkDependentParameters(ServletEngine.SSL_CERT_ALIAS_PARAM,
ServletEngine.SSL_KEYSTORE_PARAM,
ServletEngine.SSL_KEYSTORE_PASSWORD_PARAM);
checker.checkDependentParameters(ServletEngine.SSL_KEY_PASSWORD_PARAM,
ServletEngine.SSL_CERT_ALIAS_PARAM);
checker.checkDependentParameters(ServletEngine.SSL_TRUSTSTORE_PARAM,
ServletEngine.SSL_TRUSTSTORE_PASSWORD_PARAM,
ServletEngine.SSL_CERT_ALIAS_PARAM);
}
static final String CONTEXT_DESC = "Define a URL context path that maps to the resources defined by" +
"`contextResourceBase`. This allows a composite that invokes this operator in a " +
"toolkit to provide resources regardless of the value of the application's data directory. " +
"For example setting it to *maps* would result in the URL */maps/index.html* " +
"mapping to the file *index.html* in the directory defined by " +
"`contextResourceBase`. Requires the parameter `contextResourceBase` to be set. If " +
"when the operator is initialized the context already exists then no action is taken. This " +
"allows multiple independent composites in the same toolkit to have common `context` " +
"and `contextResourceBase` settings, typically to point to a single set of HTML and " +
"Javascript resources for the toolkit.\\n" +
"\\n" +
"If the operator provides URLs for its input or output ports then they are placed "
+ "in the this context when this parameter is set. This then provides fixed locations "
+ "for the URLs regardless of the depth of the operator invocation in the main composite.\\n" +
"\\n" +
"Only a single context per invocation is supported.";
static final String CRB_DESC = "Directory location of resources that will be available through " +
"the the URL context defined by the parameter `context`. Typically used to allow a toolkit to provide a " +
"set of resources in a fixed location. The set of resources is recommended to be stored in the application_dir/opt directory, " +
"which is automatically included in the bundle by default. " +
"Path of this directory can be absolute or relative, if relative path is specified then it is relative to the application directory. " +
"A set of default resources is included in the toolkit directory under ToolkitDir/opt/resources and will be loaded by the operator. " +
"This default resources can be viewed at `http://hostname:8080/streamsx.inet.resources`. " +
"A path within the application is obtained using the SPL " +
"function `getThisToolkitDir()`. Thus a composite in the file *maps.spl* in the " +
"namespace directory `com.acme.streams.apps.map` might have the following " +
"setting to map `http://127.0.0.1:8080/maps` to `opt/resources/mapinfo` in the application.\\n" +
"\\n" +
" param\\n" +
" context: “maps”\\n" +
" contextResourceBase: getThisToolkitDir() + “/opt/resources/mapinfo”\\n";
}