ClusterRestApi { @GET @Path("/" + RestConstants.NODES) @SubmarineApi public Response getClusterNodes(){ ArrayList<HashMap<String, Object>> nodes = new ArrayList<>(); Map<String, HashMap<String, Object>> clusterMeta = null; Map<String, HashMap<String, Object>> intpMeta = null; clusterMeta = clusterServer.getClusterMeta(ClusterMetaType.SERVER_META, ""); intpMeta = clusterServer.getClusterMeta(ClusterMetaType.INTP_PROCESS_META, ""); for (Map.Entry<String, HashMap<String, Object>> serverMetaEntity : clusterMeta.entrySet()) { if (!serverMetaEntity.getValue().containsKey(ClusterMeta.NODE_NAME)) { continue; } String serverNodeName = (String) serverMetaEntity.getValue().get(ClusterMeta.NODE_NAME); ArrayList<String> arrIntpProcess = new ArrayList<>(); int intpProcCount = 0; for (Map.Entry<String, HashMap<String, Object>> intpMetaEntity : intpMeta.entrySet()) { if (!intpMetaEntity.getValue().containsKey(ClusterMeta.NODE_NAME) && !intpMetaEntity.getValue().containsKey(ClusterMeta.INTP_PROCESS_NAME)) { continue; } String intpNodeName = (String) intpMetaEntity.getValue().get(ClusterMeta.NODE_NAME); if (serverNodeName.equals(intpNodeName)) { intpProcCount++; String intpName = (String) intpMetaEntity.getValue().get(ClusterMeta.INTP_PROCESS_NAME); arrIntpProcess.add(intpName); } } serverMetaEntity.getValue().put(ClusterMeta.INTP_PROCESS_COUNT, intpProcCount); serverMetaEntity.getValue().put(ClusterMeta.INTP_PROCESS_LIST, arrIntpProcess); } for (Map.Entry<String, HashMap<String, Object>> entry : clusterMeta.entrySet()) { String nodeName = entry.getKey(); Map<String, Object> properties = entry.getValue(); Map<String, Object> sortProperties = new HashMap<>(); if (properties.containsKey(ClusterMeta.CPU_USED) && properties.containsKey(ClusterMeta.CPU_CAPACITY)) { float cpuUsed = (long) properties.get(ClusterMeta.CPU_USED) / (float) 100.0; float cpuCapacity = (long) properties.get(ClusterMeta.CPU_CAPACITY) / (float) 100.0; float cpuRate = cpuUsed / cpuCapacity * 100; String cpuInfo = String.format("%.2f / %.2f = %.2f", cpuUsed, cpuCapacity, cpuRate); sortProperties.put(ClusterMeta.CPU_USED + " / " + ClusterMeta.CPU_CAPACITY, cpuInfo + "%"); } if (properties.containsKey(ClusterMeta.MEMORY_USED) && properties.containsKey(ClusterMeta.MEMORY_CAPACITY)) { float memoryUsed = (long) properties.get(ClusterMeta.MEMORY_USED) / (float) (1024 * 1024 * 1024); float memoryCapacity = (long) properties.get(ClusterMeta.MEMORY_CAPACITY) / (float) (1024 * 1024 * 1024); float memoryRate = memoryUsed / memoryCapacity * 100; String memoryInfo = String.format("%.2fGB / %.2fGB = %.2f", memoryUsed, memoryCapacity, memoryRate); sortProperties.put(ClusterMeta.MEMORY_USED + " / " + ClusterMeta.MEMORY_CAPACITY, memoryInfo + "%"); } if (properties.containsKey(ClusterMeta.SERVER_START_TIME)) { Object serverStartTime = properties.get(ClusterMeta.SERVER_START_TIME); if (serverStartTime instanceof LocalDateTime) { LocalDateTime localDateTime = (LocalDateTime) serverStartTime; String dateTime = formatLocalDateTime(localDateTime); sortProperties.put(ClusterMeta.SERVER_START_TIME, dateTime); } else { sortProperties.put(ClusterMeta.SERVER_START_TIME, "Wrong time type!"); } } if (properties.containsKey(ClusterMeta.STATUS)) { sortProperties.put(ClusterMeta.STATUS, properties.get(ClusterMeta.STATUS)); } if (properties.containsKey(ClusterMeta.LATEST_HEARTBEAT)) { Object latestHeartbeat = properties.get(ClusterMeta.LATEST_HEARTBEAT); if (latestHeartbeat instanceof LocalDateTime) { LocalDateTime localDateTime = (LocalDateTime) latestHeartbeat; String dateTime = formatLocalDateTime(localDateTime); sortProperties.put(ClusterMeta.LATEST_HEARTBEAT, dateTime); } else { sortProperties.put(ClusterMeta.LATEST_HEARTBEAT, "Wrong time type!"); } } if (properties.containsKey(ClusterMeta.INTP_PROCESS_LIST)) { sortProperties.put(ClusterMeta.INTP_PROCESS_LIST, properties.get(ClusterMeta.INTP_PROCESS_LIST)); } HashMap<String, Object> node = new HashMap<>(); node.put(ClusterMeta.NODE_NAME, nodeName); node.put(ClusterMeta.PROPERTIES, sortProperties); nodes.add(node); } return new JsonResponse.Builder<ArrayList<HashMap<String, Object>>>(Response.Status.OK) .success(true).result(nodes).build(); }  @VisibleForTesting void setClusterServer(ClusterServer clusterServer); @GET @Path("/" + RestConstants.ADDRESS) @SubmarineApi Response getClusterAddress(); @GET @Path("/" + RestConstants.NODES) @SubmarineApi Response getClusterNodes(); @GET @Path("/" + RestConstants.NODE + "/{nodeName}/{intpName}") @SubmarineApi Response getClusterNode(@PathParam("nodeName") String nodeName,
                                 @PathParam("intpName") String intpName);  }
@Test public void testGetClusterNodes() { when(mockClusterServer.getClusterMeta(ClusterMetaType.SERVER_META, "")).thenReturn(clusterMetas); Response response = clusterRestApi.getClusterNodes(); ArrayList<HashMap<String, Object>> result = getResultListFromResponse(response); Map<String, Object> properties1 = (LinkedTreeMap) result.get(0).get(ClusterMeta.PROPERTIES); Map<String, Object> properties2 = (LinkedTreeMap) result.get(1).get(ClusterMeta.PROPERTIES); assertEquals(nodeName1, result.get(0).get(ClusterMeta.NODE_NAME)); assertEquals("ONLINE", properties1.get("STATUS")); assertEquals("0.50GB / 1.00GB = 50.00%", properties1.get("MEMORY_USED / MEMORY_CAPACITY")); assertEquals("0.20 / 0.40 = 50.00%", properties1.get("CPU_USED / CPU_CAPACITY")); assertEquals(nodeName2, result.get(1).get(ClusterMeta.NODE_NAME)); assertEquals("OFFLINE", properties2.get("STATUS")); assertEquals("0.25GB / 1.00GB = 25.00%", properties2.get("MEMORY_USED / MEMORY_CAPACITY")); assertEquals("0.25 / 0.40 = 62.50%", properties2.get("CPU_USED / CPU_CAPACITY")); }