Skip to content

Commit ca80255

Browse files
committed
changes for allowing both jetty shared server or standalone netty server
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
1 parent 3fdf04c commit ca80255

71 files changed

Lines changed: 2977 additions & 626 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,8 @@ public class ApiConstants {
372372
public static final String LIMIT_CPU_USE = "limitcpuuse";
373373
public static final String LIST_HOSTS = "listhosts";
374374
public static final String LOCATION_TYPE = "locationtype";
375+
public static final String LOG_IDS = "logids";
376+
public static final String LOGS_WEB_SERVER_ENABLED = "logswebserverenabled";
375377
public static final String LOCK = "lock";
376378
public static final String LUN = "lun";
377379
public static final String LBID = "lbruleid";
@@ -1334,8 +1336,6 @@ public class ApiConstants {
13341336
public static final String OBJECT_STORAGE_LIMIT = "objectstoragelimit";
13351337
public static final String OBJECT_STORAGE_TOTAL = "objectstoragetotal";
13361338

1337-
public static final String LOGS_WEB_SERVER_ENABLED = "logswebserverenabled";
1338-
13391339
public static final String PARAMETER_DESCRIPTION_ACTIVATION_RULE = "Quota tariff's activation rule. It can receive a JS script that results in either " +
13401340
"a boolean or a numeric value: if it results in a boolean value, the tariff value will be applied according to the result; if it results in a numeric value, the " +
13411341
"numeric value will be applied; if the result is neither a boolean nor a numeric value, the tariff will not be applied. If the rule is not informed, the tariff " +

api/src/main/java/org/apache/cloudstack/api/BaseResponse.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
// under the License.
1717
package org.apache.cloudstack.api;
1818

19+
import java.util.ArrayList;
20+
import java.util.Arrays;
21+
import java.util.List;
22+
1923
import com.google.gson.annotations.SerializedName;
2024

2125
import com.cloud.serializer.Param;
@@ -32,9 +36,9 @@ public abstract class BaseResponse implements ResponseObject {
3236
@Param(description = "the current status of the latest async job acting on this object")
3337
private Integer jobStatus;
3438

35-
@SerializedName(ApiConstants.CONTEXT_ID)
36-
@Param(description = "the ID of the executing context")
37-
private String contextId;
39+
@SerializedName(ApiConstants.LOG_IDS)
40+
@Param(description = "the IDs of the logs for the request")
41+
private List<String> logsIds;
3842

3943
public BaseResponse() {
4044
}
@@ -89,12 +93,15 @@ public void setJobStatus(Integer jobStatus) {
8993
}
9094

9195
@Override
92-
public String getContextId() {
93-
return contextId;
96+
public List<String> getLogIds() {
97+
return logsIds;
9498
}
9599

96100
@Override
97-
public void setContextId(String contextId) {
98-
this.contextId = contextId;
101+
public void addLogIds(String... logId) {
102+
if (this.logsIds == null) {
103+
logsIds = new ArrayList<>();
104+
}
105+
this.logsIds.addAll(Arrays.asList(logId));
99106
}
100107
}

api/src/main/java/org/apache/cloudstack/api/ResponseObject.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
// under the License.
1717
package org.apache.cloudstack.api;
1818

19+
import java.util.List;
20+
1921
public interface ResponseObject {
2022
/**
2123
* Get the name of the API response
@@ -76,8 +78,8 @@ public interface ResponseObject {
7678
*/
7779
void setJobStatus(Integer jobStatus);
7880

79-
String getContextId();
80-
void setContextId(String contextId);
81+
List<String> getLogIds();
82+
void addLogIds(String... contextId);
8183

8284
public enum ResponseView {
8385
Full,

api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,23 @@
1919
import java.util.ArrayList;
2020
import java.util.List;
2121

22-
import org.apache.cloudstack.api.ApiArgValidator;
23-
import org.apache.cloudstack.api.ApiErrorCode;
24-
import org.apache.cloudstack.api.ServerApiException;
25-
import org.apache.cloudstack.api.response.DomainResponse;
26-
import org.apache.cloudstack.api.response.ManagementServerResponse;
27-
import org.apache.commons.lang3.StringUtils;
28-
2922
import org.apache.cloudstack.api.APICommand;
3023
import org.apache.cloudstack.api.ApiConstants;
24+
import org.apache.cloudstack.api.ApiErrorCode;
3125
import org.apache.cloudstack.api.BaseListCmd;
3226
import org.apache.cloudstack.api.Parameter;
27+
import org.apache.cloudstack.api.ServerApiException;
3328
import org.apache.cloudstack.api.response.AccountResponse;
3429
import org.apache.cloudstack.api.response.ClusterResponse;
3530
import org.apache.cloudstack.api.response.ConfigurationResponse;
31+
import org.apache.cloudstack.api.response.DomainResponse;
3632
import org.apache.cloudstack.api.response.ImageStoreResponse;
3733
import org.apache.cloudstack.api.response.ListResponse;
34+
import org.apache.cloudstack.api.response.ManagementServerResponse;
3835
import org.apache.cloudstack.api.response.StoragePoolResponse;
3936
import org.apache.cloudstack.api.response.ZoneResponse;
4037
import org.apache.cloudstack.config.Configuration;
38+
import org.apache.commons.lang3.StringUtils;
4139

4240
import com.cloud.exception.InvalidParameterValueException;
4341
import com.cloud.utils.Pair;
@@ -100,7 +98,6 @@ public class ListCfgsByCmd extends BaseListCmd {
10098
type = CommandType.UUID,
10199
entityType = ManagementServerResponse.class,
102100
description = "the ID of the Management Server to update the parameter value for corresponding management server",
103-
validations = ApiArgValidator.PositiveNumber,
104101
since = "4.21.0")
105102
private Long managementServerId;
106103

api/src/main/java/org/apache/cloudstack/api/command/admin/config/ResetCfgCmd.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,16 @@
2323
import org.apache.cloudstack.api.BaseCmd;
2424
import org.apache.cloudstack.api.Parameter;
2525
import org.apache.cloudstack.api.ServerApiException;
26-
import org.apache.cloudstack.api.response.ImageStoreResponse;
27-
import org.apache.cloudstack.api.response.ManagementServerResponse;
28-
import org.apache.cloudstack.framework.config.ConfigKey;
29-
3026
import org.apache.cloudstack.api.response.AccountResponse;
3127
import org.apache.cloudstack.api.response.ClusterResponse;
3228
import org.apache.cloudstack.api.response.ConfigurationResponse;
3329
import org.apache.cloudstack.api.response.DomainResponse;
30+
import org.apache.cloudstack.api.response.ImageStoreResponse;
31+
import org.apache.cloudstack.api.response.ManagementServerResponse;
3432
import org.apache.cloudstack.api.response.StoragePoolResponse;
3533
import org.apache.cloudstack.api.response.ZoneResponse;
3634
import org.apache.cloudstack.config.Configuration;
35+
import org.apache.cloudstack.framework.config.ConfigKey;
3736

3837
import com.cloud.user.Account;
3938
import com.cloud.utils.Pair;
@@ -89,7 +88,6 @@ public class ResetCfgCmd extends BaseCmd {
8988
type = CommandType.UUID,
9089
entityType = ManagementServerResponse.class,
9190
description = "the ID of the Management Server to update the parameter value for corresponding management server",
92-
validations = ApiArgValidator.PositiveNumber,
9391
since = "4.21.0")
9492
private Long managementServerId;
9593

api/src/main/java/org/apache/cloudstack/api/response/CapabilitiesResponse.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public class CapabilitiesResponse extends BaseResponse {
154154
private Boolean additionalConfigEnabled;
155155

156156
@SerializedName(ApiConstants.LOGS_WEB_SERVER_ENABLED)
157-
@Param(description = "true if Logs Web Server plugin is enabled, false otherwise", since = "4.21.0")
157+
@Param(description = "true if Logs Web Server plugin is enabled, false otherwise", since = "4.23.0")
158158
private boolean logsWebServerEnabled;
159159

160160
public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.apache.cloudstack.cluster;
19+
20+
import com.cloud.agent.api.Command;
21+
22+
public interface ClusterCommandProcessor {
23+
boolean supportsCommand(Class<?> clazz);
24+
String processCommand(Command cmd);
25+
}

client/pom.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@
5252
<groupId>org.eclipse.jetty</groupId>
5353
<artifactId>jetty-util</artifactId>
5454
</dependency>
55+
<dependency>
56+
<groupId>org.eclipse.jetty.websocket</groupId>
57+
<artifactId>websocket-server</artifactId>
58+
</dependency>
59+
<dependency>
60+
<groupId>javax.websocket</groupId>
61+
<artifactId>javax.websocket-api</artifactId>
62+
</dependency>
5563
<dependency>
5664
<groupId>com.mysql</groupId>
5765
<artifactId>mysql-connector-j</artifactId>
@@ -116,6 +124,11 @@
116124
<artifactId>cloud-framework-spring-lifecycle</artifactId>
117125
<version>${project.version}</version>
118126
</dependency>
127+
<dependency>
128+
<groupId>org.apache.cloudstack</groupId>
129+
<artifactId>cloud-framework-websocket-server</artifactId>
130+
<version>${project.version}</version>
131+
</dependency>
119132
<dependency>
120133
<groupId>org.apache.cloudstack</groupId>
121134
<artifactId>cloud-plugin-storage-volume-adaptive</artifactId>

client/src/main/java/org/apache/cloudstack/ServerDaemon.java

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,14 @@
2727
import java.util.Arrays;
2828
import java.util.Properties;
2929

30-
import com.cloud.api.ApiServer;
30+
import org.apache.cloudstack.framework.websocket.server.common.WebSocketRouter;
31+
import org.apache.cloudstack.utils.server.ServerPropertiesUtil;
32+
import org.apache.cloudstack.websocket.JettyWebSocketServlet;
3133
import org.apache.commons.daemon.Daemon;
3234
import org.apache.commons.daemon.DaemonContext;
3335
import org.apache.commons.lang3.StringUtils;
36+
import org.apache.logging.log4j.LogManager;
37+
import org.apache.logging.log4j.Logger;
3438
import org.eclipse.jetty.jmx.MBeanContainer;
3539
import org.eclipse.jetty.server.ForwardedRequestCustomizer;
3640
import org.eclipse.jetty.server.HttpConfiguration;
@@ -46,14 +50,14 @@
4650
import org.eclipse.jetty.server.handler.RequestLogHandler;
4751
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
4852
import org.eclipse.jetty.server.session.SessionHandler;
53+
import org.eclipse.jetty.servlet.ServletHolder;
4954
import org.eclipse.jetty.util.ssl.KeyStoreScanner;
5055
import org.eclipse.jetty.util.ssl.SslContextFactory;
5156
import org.eclipse.jetty.util.thread.QueuedThreadPool;
5257
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
5358
import org.eclipse.jetty.webapp.WebAppContext;
54-
import org.apache.logging.log4j.Logger;
55-
import org.apache.logging.log4j.LogManager;
5659

60+
import com.cloud.api.ApiServer;
5761
import com.cloud.utils.Pair;
5862
import com.cloud.utils.PropertiesUtil;
5963
import com.cloud.utils.server.ServerProperties;
@@ -74,12 +78,6 @@ public class ServerDaemon implements Daemon {
7478
private static final String BIND_INTERFACE = "bind.interface";
7579
private static final String CONTEXT_PATH = "context.path";
7680
private static final String SESSION_TIMEOUT = "session.timeout";
77-
private static final String HTTP_ENABLE = "http.enable";
78-
private static final String HTTP_PORT = "http.port";
79-
private static final String HTTPS_ENABLE = "https.enable";
80-
private static final String HTTPS_PORT = "https.port";
81-
private static final String KEYSTORE_FILE = "https.keystore";
82-
private static final String KEYSTORE_PASSWORD = "https.keystore.password";
8381
private static final String WEBAPP_DIR = "webapp.dir";
8482
private static final String ACCESS_LOG = "access.log";
8583
private static final String REQUEST_CONTENT_SIZE_KEY = "request.content.size";
@@ -96,8 +94,8 @@ public class ServerDaemon implements Daemon {
9694
private Server server;
9795

9896
private boolean httpEnable = true;
99-
private int httpPort = 8080;
100-
private int httpsPort = 8443;
97+
private int httpPort = ServerPropertiesUtil.HTTP_PORT;
98+
private int httpsPort = ServerPropertiesUtil.HTTPS_PORT;
10199
private int sessionTimeout = 30;
102100
private int maxFormContentSize = DEFAULT_REQUEST_CONTENT_SIZE;
103101
private int maxFormKeys = DEFAULT_REQUEST_MAX_FORM_KEYS;
@@ -140,12 +138,12 @@ public void init(final DaemonContext context) {
140138
}
141139
setBindInterface(properties.getProperty(BIND_INTERFACE, null));
142140
setContextPath(properties.getProperty(CONTEXT_PATH, "/client"));
143-
setHttpEnable(Boolean.valueOf(properties.getProperty(HTTP_ENABLE, "true")));
144-
setHttpPort(Integer.valueOf(properties.getProperty(HTTP_PORT, "8080")));
145-
setHttpsEnable(Boolean.valueOf(properties.getProperty(HTTPS_ENABLE, "false")));
146-
setHttpsPort(Integer.valueOf(properties.getProperty(HTTPS_PORT, "8443")));
147-
setKeystoreFile(properties.getProperty(KEYSTORE_FILE));
148-
setKeystorePassword(properties.getProperty(KEYSTORE_PASSWORD));
141+
setHttpEnable(Boolean.valueOf(properties.getProperty(ServerPropertiesUtil.KEY_HTTP_ENABLE, "true")));
142+
setHttpPort(Integer.valueOf(properties.getProperty(ServerPropertiesUtil.KEY_HTTP_PORT, "8080")));
143+
setHttpsEnable(Boolean.valueOf(properties.getProperty(ServerPropertiesUtil.KEY_HTTPS_ENABLE, "false")));
144+
setHttpsPort(Integer.valueOf(properties.getProperty(ServerPropertiesUtil.KEY_HTTPS_PORT, "8443")));
145+
setKeystoreFile(properties.getProperty(ServerPropertiesUtil.KEY_KEYSTORE_FILE));
146+
setKeystorePassword(properties.getProperty(ServerPropertiesUtil.KEY_KEYSTORE_PASSWORD));
149147
setWebAppLocation(properties.getProperty(WEBAPP_DIR));
150148
setAccessLogFile(properties.getProperty(ACCESS_LOG, "access.log"));
151149
setSessionTimeout(Integer.valueOf(properties.getProperty(SESSION_TIMEOUT, "30")));
@@ -199,7 +197,7 @@ public void start() throws Exception {
199197
createHttpConnector(httpConfig);
200198

201199
// Setup handlers
202-
Pair<SessionHandler,HandlerCollection> pair = createHandlers();
200+
Pair<SessionHandler, HandlerCollection> pair = createHandlers();
203201
server.setHandler(pair.second());
204202

205203
// Extra config options
@@ -287,14 +285,45 @@ private void createHttpsConnector(final HttpConfiguration httpConfig) {
287285
}
288286
}
289287
}
288+
/**
289+
* Adds a Jetty-native WebSocket servlet to the provided WebAppContext when the
290+
* server is operating in same-port mode. The method checks the
291+
* `websocket.server.port` server property; if that property is set and differs
292+
* from this server's HTTP port, registration is skipped because a standalone
293+
* WebSocket server is assumed.
294+
*
295+
* @param webApp the WebAppContext to which the WebSocket servlet will be added
296+
*/
297+
protected void addWebSocketHandler(final WebAppContext webApp) {
298+
try {
299+
if (!JettyWebSocketServlet.isWebSocketServletEnabled()) {
300+
logger.info("WebSocket Server is not enabled, embedded WebSocket Server will not be running");
301+
return;
302+
}
303+
Integer port = JettyWebSocketServlet.getWebSocketServletPort();
304+
if (port == null) {
305+
logger.info("WebSocket Server port is configured, embedded WebSocket Server will not be running");
306+
return;
307+
}
308+
final ServletHolder ws = new ServletHolder(new JettyWebSocketServlet());
309+
webApp.addServlet(ws, WebSocketRouter.WEBSOCKET_PATH_PREFIX + "/*");
310+
logger.info("Embedded WebSocket Server initialized at {}/* with port: {}",
311+
WebSocketRouter.WEBSOCKET_PATH_PREFIX, port);
312+
} catch (Exception e) {
313+
logger.warn("Failed to initialize embedded WebSocket server", e);
314+
}
315+
}
290316

291-
private Pair<SessionHandler,HandlerCollection> createHandlers() {
317+
private Pair<SessionHandler, HandlerCollection> createHandlers() {
292318
final WebAppContext webApp = new WebAppContext();
293319
webApp.setContextPath(contextPath);
294320
webApp.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");
295321
webApp.setMaxFormContentSize(maxFormContentSize);
296322
webApp.setMaxFormKeys(maxFormKeys);
297323

324+
// Enable WebSockets
325+
addWebSocketHandler(webApp);
326+
298327
// GZIP handler
299328
final GzipHandler gzipHandler = new GzipHandler();
300329
gzipHandler.addIncludedMimeTypes("text/html", "text/xml", "text/css", "text/plain", "text/javascript", "application/javascript", "application/json", "application/xml");

0 commit comments

Comments
 (0)