diff --git a/coordinator/src/main/java/org/apache/uniffle/coordinator/ClusterManager.java b/coordinator/src/main/java/org/apache/uniffle/coordinator/ClusterManager.java index d4a80122d4..1990213b36 100644 --- a/coordinator/src/main/java/org/apache/uniffle/coordinator/ClusterManager.java +++ b/coordinator/src/main/java/org/apache/uniffle/coordinator/ClusterManager.java @@ -84,4 +84,6 @@ public interface ClusterManager extends Closeable { /** Add blacklist. */ boolean addExcludedNodes(List excludedNodeIds); + + boolean removeExcludedNodesFromFile(List excludedNodeIds); } diff --git a/coordinator/src/main/java/org/apache/uniffle/coordinator/SimpleClusterManager.java b/coordinator/src/main/java/org/apache/uniffle/coordinator/SimpleClusterManager.java index 3c27b8d897..1bd73dbe40 100644 --- a/coordinator/src/main/java/org/apache/uniffle/coordinator/SimpleClusterManager.java +++ b/coordinator/src/main/java/org/apache/uniffle/coordinator/SimpleClusterManager.java @@ -270,6 +270,21 @@ private synchronized boolean putInExcludedNodesFile(List excludedNodes) return true; } + private synchronized boolean removeExcludedNodesFile(List excludedNodes) + throws IOException { + if (hadoopFileSystem == null) { + return false; + } + Path hadoopPath = new Path(excludedNodesPath); + // Obtains the existing excluded node. + Set alreadyExistExcludedNodes = + parseExcludedNodesFile(hadoopFileSystem.open(hadoopPath)); + // Writes to the new excluded node. + alreadyExistExcludedNodes.removeAll(excludedNodes); + writeExcludedNodes2File(Lists.newArrayList(alreadyExistExcludedNodes)); + return true; + } + @Override public void add(ServerNode node) { ServerNode pre = servers.get(node.getId()); @@ -383,6 +398,19 @@ public boolean addExcludedNodes(List excludedNodeIds) { } } + @Override + public boolean removeExcludedNodesFromFile(List excludedNodeIds) { + try { + if (removeExcludedNodesFile(excludedNodeIds)) { + excludedNodes.removeAll(excludedNodeIds); + return true; + } + } catch (IOException e) { + LOG.warn("Because {}, failed to add blacklist.", e.getMessage()); + } + return false; + } + @VisibleForTesting public void clear() { servers.clear(); diff --git a/coordinator/src/main/java/org/apache/uniffle/coordinator/web/resource/ServerResource.java b/coordinator/src/main/java/org/apache/uniffle/coordinator/web/resource/ServerResource.java index 8db72a19ea..ade6731124 100644 --- a/coordinator/src/main/java/org/apache/uniffle/coordinator/web/resource/ServerResource.java +++ b/coordinator/src/main/java/org/apache/uniffle/coordinator/web/resource/ServerResource.java @@ -233,6 +233,17 @@ public Response handleAddExcludedNodesRequest(Map> return Response.fail("fail"); } + @POST + @Path("/removeExcludeNodes") + @Consumes(MediaType.APPLICATION_JSON) + public Response handleDeleteExcludeNodesRequest(Map> excludeNodes) { + ClusterManager clusterManager = getClusterManager(); + if (clusterManager.removeExcludedNodesFromFile(excludeNodes.get("excludeNodes"))) { + return Response.success("success"); + } + return Response.fail("fail"); + } + private ClusterManager getClusterManager() { return (ClusterManager) servletContext.getAttribute(ClusterManager.class.getCanonicalName()); } diff --git a/dashboard/src/main/webapp/src/api/api.js b/dashboard/src/main/webapp/src/api/api.js index eb4755183b..c0a827f44a 100644 --- a/dashboard/src/main/webapp/src/api/api.js +++ b/dashboard/src/main/webapp/src/api/api.js @@ -94,6 +94,11 @@ export function addShuffleExcludeNodes(params, headers) { return http.post('/server/addExcludeNodes', params, headers, 0) } +// Create an interface for remove blacklist +export function removeShuffleExcludeNodes(params, headers) { + return http.post('/server/removeExcludeNodes', params, headers, 0) +} + // Total number of interfaces for new App export function getAppTotal(params, headers) { return http.get('/app/total', params, headers, 0) diff --git a/dashboard/src/main/webapp/src/main.js b/dashboard/src/main/webapp/src/main.js index 3a3cbdace2..2d2e95d739 100644 --- a/dashboard/src/main/webapp/src/main.js +++ b/dashboard/src/main/webapp/src/main.js @@ -22,7 +22,7 @@ import ElementPlus from 'element-plus' import * as ElementPlusIconsVue from '@element-plus/icons-vue' import 'element-plus/dist/index.css' import router from '@/router' -// import '@/mock' // With this annotation turned on, you can use the front-end mock data without requesting a background interface. +// import '@/mock' // With this annotation turned on, you can use the front-end mock data without requesting a background interface. const app = createApp(App) const pinia = createPinia() diff --git a/dashboard/src/main/webapp/src/pages/serverstatus/ExcludeNodeList.vue b/dashboard/src/main/webapp/src/pages/serverstatus/ExcludeNodeList.vue index c1b5fa0af5..e12768fddd 100644 --- a/dashboard/src/main/webapp/src/pages/serverstatus/ExcludeNodeList.vue +++ b/dashboard/src/main/webapp/src/pages/serverstatus/ExcludeNodeList.vue @@ -17,19 +17,32 @@ @@ -57,20 +70,18 @@