Skip to content

Commit a2f8e4e

Browse files
committed
[#1401][part-1] The dashboard supports multiple Coordinator links.
1 parent b43bbd8 commit a2f8e4e

27 files changed

+552
-124
lines changed

conf/dashboard.conf

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
rss.dashboard.http.port 19997
2+
coordinator.web.address http://coordinator.hostname00:19998/,http://coordinator.hostname01:19998/,http://coordinator.hostname02:19998/

coordinator/src/main/java/org/apache/uniffle/coordinator/CoordinatorServer.java

+5
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ public class CoordinatorServer extends ReconfigurableBase {
6161
private final CoordinatorConf coordinatorConf;
6262
private JettyServer jettyServer;
6363
private ServerInterface server;
64+
65+
public JettyServer getJettyServer() {
66+
return jettyServer;
67+
}
68+
6469
private ClusterManager clusterManager;
6570
private AssignmentStrategy assignmentStrategy;
6671
private DynamicClientConfService dynamicClientConfService;

coordinator/src/test/java/org/apache/uniffle/coordinator/CoordinatorServerTest.java

+14
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
package org.apache.uniffle.coordinator;
1919

20+
import org.eclipse.jetty.server.Server;
2021
import org.junit.jupiter.api.Test;
2122

2223
import org.apache.uniffle.common.util.ExitUtils;
@@ -26,6 +27,19 @@
2627

2728
public class CoordinatorServerTest {
2829

30+
@Test
31+
public void TestCoordinator() throws Exception {
32+
CoordinatorConf coordinatorConf = new CoordinatorConf();
33+
coordinatorConf.setInteger("rss.rpc.server.port", 9537);
34+
coordinatorConf.setInteger("rss.jetty.http.port", 9528);
35+
coordinatorConf.setInteger("rss.rpc.executor.size", 10);
36+
coordinatorConf.setInteger("rss.rpc.dashboard.port", 8080);
37+
CoordinatorServer cs1 = new CoordinatorServer(coordinatorConf);
38+
Server server = cs1.getJettyServer().getServer();
39+
server.start();
40+
server.join();
41+
}
42+
2943
@Test
3044
public void test() throws Exception {
3145
CoordinatorConf coordinatorConf = new CoordinatorConf();

dashboard/src/main/java/org/apache/uniffle/dashboard/web/JettyServerFront.java

+10-5
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
package org.apache.uniffle.dashboard.web;
1919

2020
import java.net.BindException;
21+
import java.util.Map;
2122
import java.util.concurrent.LinkedBlockingQueue;
2223
import java.util.concurrent.ThreadPoolExecutor;
2324
import java.util.concurrent.TimeUnit;
2425

25-
import org.eclipse.jetty.proxy.ProxyServlet;
2626
import org.eclipse.jetty.server.Handler;
2727
import org.eclipse.jetty.server.HttpConfiguration;
2828
import org.eclipse.jetty.server.HttpConnectionFactory;
@@ -45,6 +45,8 @@
4545
import org.apache.uniffle.common.util.ThreadUtils;
4646
import org.apache.uniffle.dashboard.web.config.DashboardConf;
4747
import org.apache.uniffle.dashboard.web.proxy.WebProxyServlet;
48+
import org.apache.uniffle.dashboard.web.utils.DashboardUtils;
49+
import org.apache.uniffle.dashboard.web.views.GainCoordinatorsServlet;
4850

4951
public class JettyServerFront {
5052

@@ -91,7 +93,9 @@ private void setRootServletHandler() {
9193
HandlerList handlers = new HandlerList();
9294
ResourceHandler resourceHandler = addResourceHandler();
9395
String coordinatorWebAddress = conf.getString(DashboardConf.COORDINATOR_WEB_ADDRESS);
94-
ServletContextHandler servletContextHandler = addProxyHandler(coordinatorWebAddress);
96+
Map<String, String> stringStringMap = DashboardUtils.convertToMap(coordinatorWebAddress);
97+
98+
ServletContextHandler servletContextHandler = addProxyHandler(stringStringMap);
9599
handlers.setHandlers(new Handler[] {resourceHandler, servletContextHandler});
96100
server.setHandler(handlers);
97101
}
@@ -105,11 +109,12 @@ private static ResourceHandler addResourceHandler() {
105109
return resourceHandler;
106110
}
107111

108-
private static ServletContextHandler addProxyHandler(String coordinatorWebAddress) {
109-
ProxyServlet proxyServlet = new WebProxyServlet(coordinatorWebAddress);
110-
ServletHolder holder = new ServletHolder(proxyServlet);
112+
private static ServletContextHandler addProxyHandler(Map<String, String> serverAddresses) {
111113
ServletContextHandler contextHandler = new ServletContextHandler();
114+
ServletHolder holder = new ServletHolder(new WebProxyServlet(serverAddresses));
112115
contextHandler.addServlet(holder, "/api/*");
116+
ServletHolder servletHolder = new ServletHolder(new GainCoordinatorsServlet(serverAddresses));
117+
contextHandler.addServlet(servletHolder, "/web/*");
113118
return contextHandler;
114119
}
115120

dashboard/src/main/java/org/apache/uniffle/dashboard/web/proxy/WebProxyServlet.java

+10-5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
package org.apache.uniffle.dashboard.web.proxy;
1919

20+
import java.util.Map;
2021
import javax.servlet.http.HttpServletRequest;
2122
import javax.servlet.http.HttpServletResponse;
2223

@@ -28,21 +29,24 @@
2829

2930
public class WebProxyServlet extends ProxyServlet {
3031

31-
private String targetAddress;
32-
3332
private static final Logger LOG = LoggerFactory.getLogger(WebProxyServlet.class);
3433

35-
public WebProxyServlet(String targetAddress) {
36-
this.targetAddress = targetAddress;
34+
private Map<String, String> serverAddressesMap;
35+
36+
public WebProxyServlet(Map<String, String> serverAddressesMap) {
37+
this.serverAddressesMap = serverAddressesMap;
3738
}
3839

3940
@Override
4041
protected String rewriteTarget(HttpServletRequest clientRequest) {
4142
if (!validateDestination(clientRequest.getServerName(), clientRequest.getServerPort())) {
4243
return null;
4344
}
45+
String targetAddress = serverAddressesMap.get(clientRequest.getHeader("targetAddress"));
46+
if (targetAddress == null) {
47+
targetAddress = "http://localhost:19997/";
48+
}
4449
StringBuilder target = new StringBuilder();
45-
4650
if (targetAddress.endsWith("/")) {
4751
targetAddress = targetAddress.substring(0, targetAddress.length() - 1);
4852
}
@@ -51,6 +55,7 @@ protected String rewriteTarget(HttpServletRequest clientRequest) {
5155
if (query != null) {
5256
target.append("?").append(query);
5357
}
58+
System.out.println(targetAddress);
5459
return target.toString();
5560
}
5661

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* 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, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.uniffle.dashboard.web.utils;
19+
20+
import java.util.HashMap;
21+
import java.util.Map;
22+
23+
import com.google.common.collect.Maps;
24+
25+
public class DashboardUtils {
26+
public static Map<String, String> convertToMap(String coordinatorStr) {
27+
HashMap<String, String> stringMap = Maps.newHashMap();
28+
String[] coordinators = coordinatorStr.split(",");
29+
for (String coordinator : coordinators) {
30+
String[] split = coordinator.split("//");
31+
String[] split1 = split[1].split(":");
32+
stringMap.put(split1[0], coordinator);
33+
}
34+
return stringMap;
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* 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, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.uniffle.dashboard.web.views;
19+
20+
import java.io.IOException;
21+
import java.util.Map;
22+
import javax.servlet.http.HttpServlet;
23+
import javax.servlet.http.HttpServletRequest;
24+
import javax.servlet.http.HttpServletResponse;
25+
26+
import com.google.gson.Gson;
27+
28+
public class GainCoordinatorsServlet extends HttpServlet {
29+
30+
private Map<String, String> serverAddresses;
31+
32+
public GainCoordinatorsServlet(Map<String, String> serverAddresses) {
33+
this.serverAddresses = serverAddresses;
34+
}
35+
36+
@Override
37+
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
38+
resp.setContentType("application/json");
39+
Gson gson = new Gson();
40+
Response<Map<String, String>> success = Response.success(serverAddresses);
41+
resp.getWriter().write(gson.toJson(success));
42+
}
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* 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, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.uniffle.dashboard.web.views;
19+
20+
public class Response<T> {
21+
private static final int SUCCESS_CODE = 0;
22+
private static final int ERROR_CODE = -1;
23+
private int code;
24+
private T data;
25+
private String msg;
26+
27+
public Response() {}
28+
29+
public Response(int code, T data, String msg) {
30+
this.code = code;
31+
this.data = data;
32+
this.msg = msg;
33+
}
34+
35+
public static <T> Response<T> success(T data) {
36+
return new Response<>(SUCCESS_CODE, data, "success");
37+
}
38+
39+
public static <T> Response<T> fail(String msg) {
40+
return new Response<>(ERROR_CODE, null, msg);
41+
}
42+
43+
public static <T> Response<T> fail(String msg, int code) {
44+
return new Response<>(code, null, msg);
45+
}
46+
47+
public int getCode() {
48+
return code;
49+
}
50+
51+
public void setCode(int code) {
52+
this.code = code;
53+
}
54+
55+
public T getData() {
56+
return data;
57+
}
58+
59+
public void setData(T data) {
60+
this.data = data;
61+
}
62+
63+
public String getErrMsg() {
64+
return msg;
65+
}
66+
67+
public void setErrMsg(String errMsg) {
68+
this.msg = errMsg;
69+
}
70+
}

dashboard/src/main/webapp/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"core-js": "^3.8.3",
3333
"element-plus": "^2.3.6",
3434
"moment": "^2.29.4",
35+
"pinia": "^2.1.7",
3536
"rimraf": "^5.0.1",
3637
"vue": "^3.2.13",
3738
"vue-resource": "^1.5.3",

dashboard/src/main/webapp/src/api/api.js

+29-25
Original file line numberDiff line numberDiff line change
@@ -16,63 +16,67 @@
1616
*/
1717

1818
import http from "@/utils/http";
19-
2019
// Create a Coordinator information interface
21-
export function getCoordinatorServerInfo(params){
22-
return http.get('/coordinator/info', params,{})
20+
export function getCoordinatorServerInfo(params,headers) {
21+
return http.get('/coordinator/info', params, headers, 0)
2322
}
2423

2524
// Create a coordinator configuration file interface
26-
export function getCoordinatorConf(params){
27-
return http.get('/coordinator/conf', params,{})
25+
export function getCoordinatorConf(params,headers) {
26+
return http.get('/coordinator/conf', params, headers, 0)
2827
}
2928

3029
// Create an interface for the total number of nodes
31-
export function getShufflegetStatusTotal(params){
32-
return http.get('/server/nodes/summary', params,{})
30+
export function getShufflegetStatusTotal(params,headers) {
31+
return http.get('/server/nodes/summary', params, headers, 0)
3332
}
3433

3534
// Create an interface for activeNodes
36-
export function getShuffleActiveNodes(params){
37-
return http.get('/server/nodes?status=active', params,{})
35+
export function getShuffleActiveNodes(params,headers) {
36+
return http.get('/server/nodes?status=active', params, headers, 0)
3837
}
3938

4039
// Create an interface for lostNodes
41-
export function getShuffleLostList(params){
42-
return http.get('/server/nodes?status=lost', params,{})
40+
export function getShuffleLostList(params,headers) {
41+
return http.get('/server/nodes?status=lost', params, headers, 0)
4342
}
4443

4544
// Create an interface for unhealthyNodes
46-
export function getShuffleUnhealthyList(params){
47-
return http.get('/server/nodes?status=unhealthy', params,{})
45+
export function getShuffleUnhealthyList(params,headers) {
46+
return http.get('/server/nodes?status=unhealthy', params, headers, 0)
4847
}
4948

5049
// Create an interface for decommissioningNodes
51-
export function getShuffleDecommissioningList(params){
52-
return http.get('/server/nodes?status=decommissioning', params,{})
50+
export function getShuffleDecommissioningList(params,headers) {
51+
return http.get('/server/nodes?status=decommissioning', params, headers, 0)
5352
}
5453

5554
// Create an interface for decommissionedNodes
56-
export function getShuffleDecommissionedList(params){
57-
return http.get('/server/nodes?status=decommissioned', params,{})
55+
export function getShuffleDecommissionedList(params,headers) {
56+
return http.get('/server/nodes?status=decommissioned', params, headers, 0)
5857
}
5958

6059
// Create an interface for excludeNodes
61-
export function getShuffleExcludeNodes(params){
62-
return http.get('/server/nodes?status=excluded', params,{})
60+
export function getShuffleExcludeNodes(params,headers) {
61+
return http.get('/server/nodes?status=excluded', params, headers, 0)
6362
}
6463

6564
// Total number of interfaces for new App
66-
export function getAppTotal(params){
67-
return http.get('/app/total', params,{})
65+
export function getAppTotal(params,headers) {
66+
return http.get('/app/total', params, headers, 0)
6867
}
6968

7069
// Create an interface for the app basic information list
71-
export function getApplicationInfoList(params){
72-
return http.get('/app/appInfos', params,{})
70+
export function getApplicationInfoList(params,headers) {
71+
return http.get('/app/appInfos', params, headers, 0)
7372
}
7473

7574
// Create an interface for the number of apps for a user
76-
export function getTotalForUser(params){
77-
return http.get('/app/userTotal', params,{})
75+
export function getTotalForUser(params,headers) {
76+
return http.get('/app/userTotal', params, headers, 0)
77+
}
78+
79+
// Obtain the configured coordinator server list
80+
export function getAllCoordinatorAddrees(params) {
81+
return http.get('/coordinatorList', params, {}, 1)
7882
}

0 commit comments

Comments
 (0)