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]>'].

Reply via email to