Skip to content

Commit 2ae789d

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 686534a commit 2ae789d

File tree

70 files changed

+2815
-612
lines changed

Some content is hidden

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

70 files changed

+2815
-612
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,8 @@ public class ApiConstants {
377377
public static final String LIMIT_CPU_USE = "limitcpuuse";
378378
public static final String LIST_HOSTS = "listhosts";
379379
public static final String LOCATION_TYPE = "locationtype";
380+
public static final String LOG_IDS = "logids";
381+
public static final String LOGS_WEB_SERVER_ENABLED = "logswebserverenabled";
380382
public static final String LOCK = "lock";
381383
public static final String LUN = "lun";
382384
public static final String LBID = "lbruleid";
@@ -1354,8 +1356,6 @@ public class ApiConstants {
13541356
public static final String OBJECT_STORAGE_LIMIT = "objectstoragelimit";
13551357
public static final String OBJECT_STORAGE_TOTAL = "objectstoragetotal";
13561358

1357-
public static final String LOGS_WEB_SERVER_ENABLED = "logswebserverenabled";
1358-
13591359
public static final String PARAMETER_DESCRIPTION_ACTIVATION_RULE = "Quota tariff's activation rule. It can receive a JS script that results in either " +
13601360
"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 " +
13611361
"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: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ public class ListCfgsByCmd extends BaseListCmd {
9999
type = CommandType.UUID,
100100
entityType = ManagementServerResponse.class,
101101
description = "the ID of the Management Server to update the parameter value for corresponding management server",
102-
validations = ApiArgValidator.PositiveNumber,
103102
since = "4.21.0")
104103
private Long managementServerId;
105104

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
@@ -164,7 +164,7 @@ public class CapabilitiesResponse extends BaseResponse {
164164
private Map<String, Object> vpnCustomerGatewayParameters;
165165

166166
@SerializedName(ApiConstants.LOGS_WEB_SERVER_ENABLED)
167-
@Param(description = "true if Logs Web Server plugin is enabled, false otherwise", since = "4.21.0")
167+
@Param(description = "true if Logs Web Server plugin is enabled, false otherwise", since = "4.23.0")
168168
private boolean logsWebServerEnabled;
169169

170170
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: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,14 @@
2626
import java.net.URL;
2727
import java.util.Properties;
2828

29+
import org.apache.cloudstack.framework.websocket.server.common.WebSocketRouter;
30+
import org.apache.cloudstack.utils.server.ServerPropertiesUtil;
31+
import org.apache.cloudstack.websocket.JettyWebSocketServlet;
2932
import org.apache.commons.daemon.Daemon;
3033
import org.apache.commons.daemon.DaemonContext;
3134
import org.apache.commons.lang3.StringUtils;
35+
import org.apache.logging.log4j.LogManager;
36+
import org.apache.logging.log4j.Logger;
3237
import org.eclipse.jetty.jmx.MBeanContainer;
3338
import org.eclipse.jetty.server.HttpConfiguration;
3439
import org.eclipse.jetty.server.HttpConnectionFactory;
@@ -43,13 +48,12 @@
4348
import org.eclipse.jetty.server.handler.RequestLogHandler;
4449
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
4550
import org.eclipse.jetty.server.session.SessionHandler;
51+
import org.eclipse.jetty.servlet.ServletHolder;
4652
import org.eclipse.jetty.util.ssl.KeyStoreScanner;
4753
import org.eclipse.jetty.util.ssl.SslContextFactory;
4854
import org.eclipse.jetty.util.thread.QueuedThreadPool;
4955
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
5056
import org.eclipse.jetty.webapp.WebAppContext;
51-
import org.apache.logging.log4j.Logger;
52-
import org.apache.logging.log4j.LogManager;
5357

5458
import com.cloud.utils.Pair;
5559
import com.cloud.utils.PropertiesUtil;
@@ -88,8 +92,8 @@ public class ServerDaemon implements Daemon {
8892
private Server server;
8993

9094
private boolean httpEnable = true;
91-
private int httpPort = 8080;
92-
private int httpsPort = 8443;
95+
private int httpPort = ServerPropertiesUtil.HTTP_PORT;
96+
private int httpsPort = ServerPropertiesUtil.HTTPS_PORT;
9397
private int sessionTimeout = 30;
9498
private int maxFormContentSize = DEFAULT_REQUEST_CONTENT_SIZE;
9599
private int maxFormKeys = DEFAULT_REQUEST_MAX_FORM_KEYS;
@@ -132,12 +136,12 @@ public void init(final DaemonContext context) {
132136
}
133137
setBindInterface(properties.getProperty(BIND_INTERFACE, null));
134138
setContextPath(properties.getProperty(CONTEXT_PATH, "/client"));
135-
setHttpEnable(Boolean.valueOf(properties.getProperty(ServerProperties.HTTP_ENABLE, "true")));
136-
setHttpPort(Integer.valueOf(properties.getProperty(ServerProperties.HTTP_PORT, "8080")));
137-
setHttpsEnable(Boolean.valueOf(properties.getProperty(ServerProperties.HTTPS_ENABLE, "false")));
138-
setHttpsPort(Integer.valueOf(properties.getProperty(ServerProperties.HTTPS_PORT, "8443")));
139-
setKeystoreFile(properties.getProperty(ServerProperties.KEYSTORE_FILE));
140-
setKeystorePassword(properties.getProperty(KEYSTORE_PASSWORD));
139+
setHttpEnable(Boolean.valueOf(properties.getProperty(ServerPropertiesUtil.KEY_HTTP_ENABLE, "true")));
140+
setHttpPort(Integer.valueOf(properties.getProperty(ServerPropertiesUtil.KEY_HTTP_PORT, "8080")));
141+
setHttpsEnable(Boolean.valueOf(properties.getProperty(ServerPropertiesUtil.KEY_HTTPS_ENABLE, "false")));
142+
setHttpsPort(Integer.valueOf(properties.getProperty(ServerPropertiesUtil.KEY_HTTPS_PORT, "8443")));
143+
setKeystoreFile(properties.getProperty(ServerPropertiesUtil.KEY_KEYSTORE_FILE));
144+
setKeystorePassword(properties.getProperty(ServerPropertiesUtil.KEY_KEYSTORE_PASSWORD));
141145
setWebAppLocation(properties.getProperty(WEBAPP_DIR));
142146
setAccessLogFile(properties.getProperty(ACCESS_LOG, "access.log"));
143147
setSessionTimeout(Integer.valueOf(properties.getProperty(SESSION_TIMEOUT, "30")));
@@ -190,7 +194,7 @@ public void start() throws Exception {
190194
createHttpConnector(httpConfig);
191195

192196
// Setup handlers
193-
Pair<SessionHandler,HandlerCollection> pair = createHandlers();
197+
Pair<SessionHandler, HandlerCollection> pair = createHandlers();
194198
server.setHandler(pair.second());
195199

196200
// Extra config options
@@ -263,14 +267,45 @@ private void createHttpsConnector(final HttpConfiguration httpConfig) {
263267
}
264268
}
265269
}
270+
/**
271+
* Adds a Jetty-native WebSocket servlet to the provided WebAppContext when the
272+
* server is operating in same-port mode. The method checks the
273+
* `websocket.server.port` server property; if that property is set and differs
274+
* from this server's HTTP port, registration is skipped because a standalone
275+
* WebSocket server is assumed.
276+
*
277+
* @param webApp the WebAppContext to which the WebSocket servlet will be added
278+
*/
279+
protected void addWebSocketHandler(final WebAppContext webApp) {
280+
try {
281+
if (!JettyWebSocketServlet.isWebSocketServletEnabled()) {
282+
logger.info("WebSocket Server is not enabled, embedded WebSocket Server will not be running");
283+
return;
284+
}
285+
Integer port = JettyWebSocketServlet.getWebSocketServletPort();
286+
if (port == null) {
287+
logger.info("WebSocket Server port is configured, embedded WebSocket Server will not be running");
288+
return;
289+
}
290+
final ServletHolder ws = new ServletHolder(new JettyWebSocketServlet());
291+
webApp.addServlet(ws, WebSocketRouter.WEBSOCKET_PATH_PREFIX + "/*");
292+
logger.info("Embedded WebSocket Server initialized at {}/* with port: {}",
293+
WebSocketRouter.WEBSOCKET_PATH_PREFIX, port);
294+
} catch (Exception e) {
295+
logger.warn("Failed to initialize embedded WebSocket server", e);
296+
}
297+
}
266298

267-
private Pair<SessionHandler,HandlerCollection> createHandlers() {
299+
private Pair<SessionHandler, HandlerCollection> createHandlers() {
268300
final WebAppContext webApp = new WebAppContext();
269301
webApp.setContextPath(contextPath);
270302
webApp.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");
271303
webApp.setMaxFormContentSize(maxFormContentSize);
272304
webApp.setMaxFormKeys(maxFormKeys);
273305

306+
// Enable WebSockets
307+
addWebSocketHandler(webApp);
308+
274309
// GZIP handler
275310
final GzipHandler gzipHandler = new GzipHandler();
276311
gzipHandler.addIncludedMimeTypes("text/html", "text/xml", "text/css", "text/plain", "text/javascript", "application/javascript", "application/json", "application/xml");

0 commit comments

Comments
 (0)