diff --git a/conf/zeppelin-site.xml.template b/conf/zeppelin-site.xml.template index 90989478f97..0f44c62ad51 100755 --- a/conf/zeppelin-site.xml.template +++ b/conf/zeppelin-site.xml.template @@ -31,6 +31,12 @@ Server port. + + zeppelin.server.context.path + / + Context Path of the Web Application + + zeppelin.notebook.dir notebook diff --git a/docs/install/install.md b/docs/install/install.md index a4b3336b6b9..930ddc49e2d 100644 --- a/docs/install/install.md +++ b/docs/install/install.md @@ -82,6 +82,12 @@ Configuration can be done by both environment variable(conf/zeppelin-env.sh) and 8080 Zeppelin server port. Note that port+1 is used for web socket + + ZEPPELIN_SERVER_CONTEXT_PATH + zeppelin.server.context.path + / + Context Path of the Web Application + ZEPPELIN_NOTEBOOK_DIR zeppelin.notebook.dir diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java index 3717eccf142..ea8a0b64c45 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java @@ -85,7 +85,7 @@ public static void main(String[] args) throws Exception { jettyServer = setupJettyServer(conf); // REST api - final ServletContextHandler restApi = setupRestApiContextHandler(); + final ServletContextHandler restApi = setupRestApiContextHandler(conf); // Notebook server final ServletContextHandler notebook = setupNotebookServer(conf); @@ -170,7 +170,7 @@ private static ServletContextHandler setupNotebookServer(ZeppelinConfiguration c ServletContextHandler.SESSIONS); cxfContext.setSessionHandler(new SessionHandler()); - cxfContext.setContextPath("/"); + cxfContext.setContextPath(conf.getServerContextPath()); cxfContext.addServlet(servletHolder, "/ws/*"); cxfContext.addFilter(new FilterHolder(CorsFilter.class), "/*", EnumSet.allOf(DispatcherType.class)); @@ -210,7 +210,7 @@ private static SSLContext getSslContext(ZeppelinConfiguration conf) return scf.getSslContext(); } - private static ServletContextHandler setupRestApiContextHandler() { + private static ServletContextHandler setupRestApiContextHandler(ZeppelinConfiguration conf) { final ServletHolder cxfServletHolder = new ServletHolder(new CXFNonSpringJaxrsServlet()); cxfServletHolder.setInitParameter("javax.ws.rs.Application", ZeppelinServer.class.getName()); cxfServletHolder.setName("rest"); @@ -218,8 +218,8 @@ private static ServletContextHandler setupRestApiContextHandler() { final ServletContextHandler cxfContext = new ServletContextHandler(); cxfContext.setSessionHandler(new SessionHandler()); - cxfContext.setContextPath("/api"); - cxfContext.addServlet(cxfServletHolder, "/*"); + cxfContext.setContextPath(conf.getServerContextPath()); + cxfContext.addServlet(cxfServletHolder, "/api/*"); cxfContext.addFilter(new FilterHolder(CorsFilter.class), "/*", EnumSet.allOf(DispatcherType.class)); @@ -230,12 +230,12 @@ private static WebAppContext setupWebAppContext( ZeppelinConfiguration conf) { WebAppContext webApp = new WebAppContext(); + webApp.setContextPath(conf.getServerContextPath()); File warPath = new File(conf.getString(ConfVars.ZEPPELIN_WAR)); if (warPath.isDirectory()) { // Development mode, read from FS // webApp.setDescriptor(warPath+"/WEB-INF/web.xml"); webApp.setResourceBase(warPath.getPath()); - webApp.setContextPath("/"); webApp.setParentLoaderPriority(true); } else { // use packaged WAR diff --git a/zeppelin-web/src/components/baseUrl/baseUrl.service.js b/zeppelin-web/src/components/baseUrl/baseUrl.service.js index f5eb2df5970..f06eef3c4d5 100644 --- a/zeppelin-web/src/components/baseUrl/baseUrl.service.js +++ b/zeppelin-web/src/components/baseUrl/baseUrl.service.js @@ -32,7 +32,7 @@ angular.module('zeppelinWebApp').service('baseUrlSrv', function() { this.getWebsocketUrl = function() { var wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:'; - return wsProtocol + '//' + location.hostname + ':' + this.getPort() + '/ws'; + return wsProtocol + '//' + location.hostname + ':' + this.getPort() + skipTrailingSlash(location.pathname) + '/ws'; }; this.getRestApiBase = function() { diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java index 19ddceb22de..17964307817 100755 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java @@ -268,6 +268,10 @@ public int getServerPort() { return getInt(ConfVars.ZEPPELIN_PORT); } + public String getServerContextPath() { + return getString(ConfVars.ZEPPELIN_SERVER_CONTEXT_PATH); + } + public String getKeyStorePath() { return getRelativeDir( String.format("%s/%s", @@ -383,6 +387,7 @@ public static enum ConfVars { ZEPPELIN_HOME("zeppelin.home", "../"), ZEPPELIN_ADDR("zeppelin.server.addr", "0.0.0.0"), ZEPPELIN_PORT("zeppelin.server.port", 8080), + ZEPPELIN_SERVER_CONTEXT_PATH("zeppelin.server.context.path", "/"), ZEPPELIN_SSL("zeppelin.ssl", false), ZEPPELIN_SSL_CLIENT_AUTH("zeppelin.ssl.client.auth", false), ZEPPELIN_SSL_KEYSTORE_PATH("zeppelin.ssl.keystore.path", "keystore"),