This is an automated email from the ASF dual-hosted git repository.
bhaisaab pushed a commit to branch CLOUDSTACK-10012
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/CLOUDSTACK-10012 by this push:
new d547efe new server conf file and server daemon changes
d547efe is described below
commit d547efe29109e468b0eff0b328f00141853d4d07
Author: Rohit Yadav <[email protected]>
AuthorDate: Thu Oct 26 15:32:59 2017 +0530
new server conf file and server daemon changes
Signed-off-by: Rohit Yadav <[email protected]>
---
client/conf/server.properties.in | 28 +-
client/src/org/apache/cloudstack/ServerDaemon.java | 297 ++++++++++++++-------
2 files changed, 222 insertions(+), 103 deletions(-)
diff --git a/client/conf/server.properties.in b/client/conf/server.properties.in
index 6f9efb9..e3033de 100644
--- a/client/conf/server.properties.in
+++ b/client/conf/server.properties.in
@@ -15,11 +15,29 @@
# specific language governing permissions and limitations
# under the License.
-listen.interface=0.0.0.0
+# The binding interface used by the management server
+bind.interface=0.0.0.0
+
+# The service context path where URL requests should be served
+context.path=/client
+
+# The HTTP port to be used by the management server
http.port=8080
+
+# Options to configure and enable HTTPS on management server
+#
+# For management server to pickup these configuration settings, the configured
+# keystore file should exists and be readable by the management server.
+https.enable=false
https.port=8443
-keystore.file=/etc/cloudstack/management/cert.jks
-keystore.password=vmops.com
+# The keystore and manager passwords are assumed to be same.
+# For production environments, create and use a separate keystore file than the
+# default `cloud.jks` file that is used internally by the management server.
+https.keystore=/etc/cloudstack/management/cloud.jks
+https.keystore.password=vmops.com
+
+# The path to webapp directory
webapp.dir=/usr/share/cloudstack-management/webapp
-log.dir=/var/log/cloudstack/management/
-access.log.file=/var/log/cloudstack/management/access.log
+
+# The path to access log file
+access.log=/var/log/cloudstack/management/access.log
diff --git a/client/src/org/apache/cloudstack/ServerDaemon.java
b/client/src/org/apache/cloudstack/ServerDaemon.java
index 52ac791..9f5bf22 100644
--- a/client/src/org/apache/cloudstack/ServerDaemon.java
+++ b/client/src/org/apache/cloudstack/ServerDaemon.java
@@ -19,6 +19,7 @@
package org.apache.cloudstack;
import java.io.File;
+import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.URL;
import java.util.ArrayList;
@@ -28,163 +29,223 @@ import java.util.Properties;
import org.apache.commons.daemon.Daemon;
import org.apache.commons.daemon.DaemonContext;
import org.eclipse.jetty.jmx.MBeanContainer;
+import org.eclipse.jetty.server.ForwardedRequestCustomizer;
import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.NCSARequestLog;
-import org.eclipse.jetty.server.NetworkTrafficServerConnector;
import org.eclipse.jetty.server.RequestLog;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.RequestLogHandler;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.eclipse.jetty.util.thread.ThreadPool;
-import org.eclipse.jetty.webapp.Configuration;
+import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
import org.eclipse.jetty.webapp.WebAppContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.cloud.utils.PropertiesUtil;
+import com.google.common.base.Strings;
+
/***
- * Daemon server class to start the embedded server, either through JSVC or
directly inside a JAR.
- * Parameter to configure the jetty server are:
- * - jetty.port: to start jetty on the specific port (default: 8080)
- * - jetty.host: to bind to specific interface (default: null = all)
- * - jetty.requestlog: path to log file for requests (default: request.log)
+ * The ServerDaemon class implements the embedded server, it can be started
either
+ * using JSVC or directly from the JAR along with additional jars not shaded
in the uber-jar.
+ * Configuration parameters are read from server.properties file available on
the classpath.
*/
public class ServerDaemon implements Daemon {
- private static final Logger logger =
LoggerFactory.getLogger(ServerDaemon.class);
+ private static final Logger LOG =
LoggerFactory.getLogger(ServerDaemon.class);
private static final String WEB_XML = "META-INF/webapp/WEB-INF/web.xml";
- private static final String REQUEST_LOG = "request.log";
- private Server jettyServer;
- private int port;
- private String bindInterface;
- private String requestLogFile;
+ /////////////////////////////////////////////////////
+ /////////////// Server Properties ///////////////////
+ /////////////////////////////////////////////////////
+
+ private static final String BIND_INTERFACE = "bind.interface";
+ private static final String CONTEXT_PATH = "context.path";
+ private static final String HTTP_PORT = "http.port";
+ private static final String HTTPS_ENABLE = "https.enable";
+ private static final String HTTPS_PORT = "https.port";
+ private static final String KEYSTORE_FILE = "https.keystore";
+ private static final String KEYSTORE_PASSWORD = "https.keystore.password";
+ private static final String WEBAPP_DIR = "webapp.dir";
+ private static final String ACCESS_LOG = "access.log";
+
+ ////////////////////////////////////////////////////////
+ /////////////// Server Configuration ///////////////////
+ ////////////////////////////////////////////////////////
+
+ private Server server;
+
+ private int httpPort = 8080;
+ private int httpsPort = 8443;
+ private boolean httpsEnable = false;
+ private String accessLogFile = "access.log";
+ private String bindInterface = "0.0.0.0";
+ private String contextPath = "/client";
+ private String keystoreFile;
+ private String keystorePassword;
private String webAppLocation;
- public static void main(String... anArgs) throws Exception {
- ServerDaemon csServer = new ServerDaemon();
- csServer.init(null);
- csServer.start();
- csServer.join();
+ //////////////////////////////////////////////////
+ /////////////// Public methods ///////////////////
+ //////////////////////////////////////////////////
+
+ public static void main(final String... anArgs) throws Exception {
+ final ServerDaemon daemon = new ServerDaemon();
+ daemon.init(null);
+ daemon.start();
}
@Override
- public void init(DaemonContext context) {
- Properties props = System.getProperties();
- setPort(Integer.parseInt(props.getProperty("port", "8080")));
- setBindInterface(props.getProperty("host"));
- setWebAppLocation(props.getProperty("webapp"));
- setRequestLogFile(props.getProperty("requestlog", REQUEST_LOG));
- StringBuilder sb = new StringBuilder("Initializing server daemon on ");
- sb.append(bindInterface == null ? "*" : bindInterface);
- sb.append(":");
- sb.append(port);
- logger.info(sb.toString());
+ public void init(final DaemonContext context) {
+ final File confFile =
PropertiesUtil.findConfigFile("server.properties");
+ if (confFile == null) {
+ LOG.warn(String.format("Server configuration file not found.
Initializing server daemon on %s:%s, with https.enabled=%s, https.port=%s,
context.path=%s",
+ bindInterface, httpPort, httpsEnable, httpsPort,
contextPath));
+ return;
+ }
+
+ LOG.info("Server configuration file found: " +
confFile.getAbsolutePath());
+
+ try {
+ final Properties properties =
PropertiesUtil.loadFromFile(confFile);
+ if (properties == null) {
+ return;
+ }
+ setBindInterface(properties.getProperty(BIND_INTERFACE,
"0.0.0.0"));
+ setContextPath(properties.getProperty(CONTEXT_PATH, "/client"));
+ setHttpPort(Integer.valueOf(properties.getProperty(HTTP_PORT,
"8080")));
+
setHttpsEnable(Boolean.valueOf(properties.getProperty(HTTPS_ENABLE, "false")));
+ setHttpsPort(Integer.valueOf(properties.getProperty(HTTPS_PORT,
"8443")));
+ setKeystoreFile(properties.getProperty(KEYSTORE_FILE));
+ setKeystorePassword(properties.getProperty(KEYSTORE_PASSWORD));
+ setWebAppLocation(properties.getProperty(WEBAPP_DIR));
+ setAccessLogFile(properties.getProperty(ACCESS_LOG, "access.log"));
+ } catch (final IOException e) {
+ LOG.warn("Failed to load configuration from server.properties
file", e);
+ }
+ LOG.info(String.format("Initializing server daemon on %s:%s, with
https.enabled=%s, https.port=%s, context.path=%s",
+ bindInterface, httpPort, httpsEnable, httpsPort, contextPath));
}
@Override
public void start() throws Exception {
- jettyServer = new Server(createThreadPool());
-
- // Setup JMX
- MBeanContainer mbeanContainer = new
MBeanContainer(ManagementFactory.getPlatformMBeanServer());
- jettyServer.addBean(mbeanContainer);
-
- NetworkTrafficServerConnector connector = createConnector();
- jettyServer.addConnector(connector);
+ // Thread pool
+ final QueuedThreadPool threadPool = new QueuedThreadPool();
+ threadPool.setMinThreads(10);
+ threadPool.setMaxThreads(500);
- // This webapp will use jsps and jstl. We need to enable the
- // AnnotationConfiguration in order to correctly
- // set up the jsp container
- Configuration.ClassList classlist = Configuration.ClassList
- .setServerDefault( jettyServer );
- classlist.addBefore(
- "org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
- "org.eclipse.jetty.annotations.AnnotationConfiguration" );
+ // Jetty Server
+ server = new Server(threadPool);
- jettyServer.setHandler(createHandlers());
- jettyServer.setStopAtShutdown(true);
+ // Setup Scheduler
+ server.addBean(new ScheduledExecutorScheduler());
- jettyServer.start();
- }
+ // Setup JMX
+ final MBeanContainer mbeanContainer = new
MBeanContainer(ManagementFactory.getPlatformMBeanServer());
+ server.addBean(mbeanContainer);
+
+ // HTTP config
+ final HttpConfiguration httpConfig = new HttpConfiguration();
+ httpConfig.addCustomizer( new ForwardedRequestCustomizer() );
+ httpConfig.setSecureScheme("https");
+ httpConfig.setSecurePort(httpsPort);
+ httpConfig.setOutputBufferSize(32768);
+ httpConfig.setRequestHeaderSize(8192);
+ httpConfig.setResponseHeaderSize(8192);
+ httpConfig.setSendServerVersion(true);
+ httpConfig.setSendDateHeader(false);
+
+ // HTTP Connector
+ ServerConnector httpConnector = new ServerConnector(server, new
HttpConnectionFactory(httpConfig));
+ httpConnector.setPort(httpPort);
+ httpConnector.setHost(bindInterface);
+ httpConnector.setIdleTimeout(30000);
+ server.addConnector(httpConnector);
+
+ // Setup handlers
+ server.setHandler(createHandlers());
+
+ // Extra config options
+ server.setStopAtShutdown(true);
+
+ // Configure SSL
+ if (httpsEnable && !Strings.isNullOrEmpty(keystoreFile) && new
File(keystoreFile).exists()) {
+ // SSL Context
+ final SslContextFactory sslContextFactory = new
SslContextFactory();
+ // Define keystore path and passwords
+ sslContextFactory.setKeyStorePath(keystoreFile);
+ sslContextFactory.setKeyStorePassword(keystorePassword);
+ sslContextFactory.setKeyManagerPassword(keystorePassword);
+
+ // HTTPS config
+ final HttpConfiguration httpsConfig = new
HttpConfiguration(httpConfig);
+ httpsConfig.addCustomizer(new SecureRequestCustomizer());
+
+ // HTTPS connector
+ final ServerConnector sslConnector = new ServerConnector(server,
+ new SslConnectionFactory(sslContextFactory, "http/1.1"),
+ new HttpConnectionFactory(httpsConfig));
+ sslConnector.setPort(httpsPort);
+ sslConnector.setHost(bindInterface);
+ server.addConnector(sslConnector);
+ }
- public void join() throws InterruptedException {
- jettyServer.join();
+ server.start();
+ server.join();
}
@Override
public void stop() throws Exception {
- jettyServer.stop();
+ server.stop();
}
@Override
public void destroy() {
- jettyServer.destroy();
- }
-
- public void setPort(int port) {
- this.port = port;
- }
-
- public void setBindInterface(String bindInterface) {
- this.bindInterface = bindInterface;
- }
-
- public void setRequestLogFile(String requestLogFile) {
- this.requestLogFile = requestLogFile;
- }
-
- public void setWebAppLocation(String webAppLocation) {
- this.webAppLocation = webAppLocation;
- }
-
- private ThreadPool createThreadPool() {
- QueuedThreadPool threadPool = new QueuedThreadPool();
- threadPool.setMinThreads(10);
- threadPool.setMaxThreads(100);
- return threadPool;
+ server.destroy();
}
- private NetworkTrafficServerConnector createConnector() {
- NetworkTrafficServerConnector connector = new
NetworkTrafficServerConnector(jettyServer);
- connector.setPort(port);
- connector.setHost(bindInterface);
- return connector;
- }
+ ///////////////////////////////////////////////////
+ /////////////// Private methods ///////////////////
+ ///////////////////////////////////////////////////
private HandlerCollection createHandlers() {
- WebAppContext webapp = new WebAppContext();
- webapp.setContextPath("/client");
+ final WebAppContext webApp = new WebAppContext();
+ webApp.setContextPath(contextPath);
- if (webAppLocation == null) {
- webapp.setWar(getShadedWarUrl());
+ if (Strings.isNullOrEmpty(webAppLocation)) {
+ webApp.setWar(getShadedWarUrl());
} else {
- webapp.setWar(webAppLocation);
+ webApp.setWar(webAppLocation);
}
- List<Handler> handlers = new ArrayList<>();
- handlers.add(webapp);
+ final List<Handler> handlers = new ArrayList<>();
+ handlers.add(webApp);
- HandlerList contexts = new HandlerList();
+ final HandlerList contexts = new HandlerList();
contexts.setHandlers(handlers.toArray(new Handler[0]));
- RequestLogHandler log = new RequestLogHandler();
+ final RequestLogHandler log = new RequestLogHandler();
log.setRequestLog(createRequestLog());
- HandlerCollection result = new HandlerCollection();
+ final HandlerCollection result = new HandlerCollection();
result.setHandlers(new Handler[]{log, contexts});
return result;
}
private RequestLog createRequestLog() {
- NCSARequestLog log = new NCSARequestLog();
- File logPath = new File(requestLogFile);
- File parentFile = logPath.getParentFile();
+ final NCSARequestLog log = new NCSARequestLog();
+ final File logPath = new File(accessLogFile);
+ final File parentFile = logPath.getParentFile();
if (parentFile != null) {
parentFile.mkdirs();
}
-
log.setFilename(logPath.getPath());
log.setAppend(true);
log.setLogTimeZone("GMT");
@@ -197,7 +258,47 @@ public class ServerDaemon implements Daemon {
}
private String getShadedWarUrl() {
- String urlStr = getResource(WEB_XML).toString();
+ final String urlStr = getResource(WEB_XML).toString();
return urlStr.substring(0, urlStr.length() - 15);
}
+
+ ///////////////////////////////////////////
+ /////////////// Setters ///////////////////
+ ///////////////////////////////////////////
+
+ public void setBindInterface(String bindInterface) {
+ this.bindInterface = bindInterface;
+ }
+
+ public void setHttpPort(int httpPort) {
+ this.httpPort = httpPort;
+ }
+
+ public void setHttpsPort(int httpsPort) {
+ this.httpsPort = httpsPort;
+ }
+
+ public void setContextPath(String contextPath) {
+ this.contextPath = contextPath;
+ }
+
+ public void setHttpsEnable(boolean httpsEnable) {
+ this.httpsEnable = httpsEnable;
+ }
+
+ public void setKeystoreFile(String keystoreFile) {
+ this.keystoreFile = keystoreFile;
+ }
+
+ public void setKeystorePassword(String keystorePassword) {
+ this.keystorePassword = keystorePassword;
+ }
+
+ public void setAccessLogFile(String accessLogFile) {
+ this.accessLogFile = accessLogFile;
+ }
+
+ public void setWebAppLocation(String webAppLocation) {
+ this.webAppLocation = webAppLocation;
+ }
}
--
To stop receiving notification emails like this one, please contact
['"[email protected]" <[email protected]>'].