Commit 63dd43bf authored by wutu's avatar wutu

构建基础的java-api客户端

parent 245e984e
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>bishe</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>bishe-client-starter</artifactId>
<properties>
<dubbo.version>2.7.4.1</dubbo.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.1.2.RELEASE</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>bishe-common-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.0.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package top.ninwoo.bishe.starter.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
@Slf4j
@Configuration
@ComponentScan(value = "top.ninwoo.bishe.starter")
@EnableConfigurationProperties(ClientProperties.class)
public class BisheAppAutoConfiguration {
@Resource
private ClientProperties clientProperties;
@PostConstruct
public void init() {
log.info("开启这个client-starter");
log.info("cloud配置为{}", clientProperties);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
package top.ninwoo.bishe.starter.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "bishe.app")
public class ClientProperties {
private String zookeeperUrl = "zookeeper://127.0.0.1:2181";
private String cloudUrl = "127.0.0.1:9300";
private String appName = "default";
}
package top.ninwoo.bishe.starter.entity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.client.RestTemplate;
import top.ninwoo.common.entity.ContainerInfo;
import top.ninwoo.common.entity.ContainerMonitorInfo;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class ContainerMonitor {
private static final String GET_CONTAINER_INFO_BY_CONTAINER_ID
= "/getContainerMonitorByContainerId?containerId={containerId}";
// 远程edgeNode的ID
private String edgeNodeId;
// 对应cluster的id
private long clusterId;
// 对应的app name
private String appName;
private String monitorUrl;
private String containerId;
private RestTemplate restTemplate;
public ContainerMonitor(ContainerMonitorInfo containerMonitorInfo, RestTemplate restTemplate) {
this.edgeNodeId = containerMonitorInfo.getEdgeNodeId();
this.clusterId = containerMonitorInfo.getClusterId();
this.appName = containerMonitorInfo.getAppName();
this.containerId = containerMonitorInfo.getContainerId();
monitorUrl = "http://" + edgeNodeId + GET_CONTAINER_INFO_BY_CONTAINER_ID;
this.restTemplate = restTemplate;
}
public ContainerInfo getContainerInfo() {
Map<String, Object> param = new HashMap<>();
param.put("containerId", this.containerId);
ContainerInfo containerInfo
= restTemplate.getForObject(monitorUrl, ContainerInfo.class, param);
// 这里可能返回一个null的类,此时需要上级的调用函数做处理
return containerInfo;
}
}
\ No newline at end of file
package top.ninwoo.bishe.starter.service;
import top.ninwoo.common.entity.NetworkTopology;
import top.ninwoo.common.entity.SeparatedClusterConfig;
import java.util.List;
/**
* 操作集群的api接口
*/
public interface ClusterService {
List<SeparatedClusterConfig> sendClusterConfigToEdgeNode(List<SeparatedClusterConfig> configs);
String removeClusterFromEdgeNode(Long clusterId);
}
package top.ninwoo.bishe.starter.service;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import top.ninwoo.bishe.starter.config.ClientProperties;
import top.ninwoo.common.entity.NetworkTopology;
import top.ninwoo.common.entity.SeparatedClusterConfig;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class ClusterServiceImpl implements ClusterService {
private final static String SEND_CLUSTER_CONFIG_TO_EDGE_NODE
= "/cluster/sendClusterConfigToEdgeNode";
private final static String REMOVE_CLUSTER_FROM_EDGE_NODE
= "/cluster/removeClusterFromEdgeNode?clusterId=";
@Resource
private RestTemplate restTemplate;
@Resource
private ClientProperties clientProperties;
@Override
public List<SeparatedClusterConfig> sendClusterConfigToEdgeNode(List<SeparatedClusterConfig> configs) {
Map<String, Object> param = new HashMap<>();
param.put("configs", configs.toArray());
List<SeparatedClusterConfig> results
= restTemplate.postForObject("http://" + clientProperties.getCloudUrl() + SEND_CLUSTER_CONFIG_TO_EDGE_NODE, configs, List.class);
return results;
}
@Override
public String removeClusterFromEdgeNode(Long clusterId) {
return restTemplate.getForObject("http://" + clientProperties.getCloudUrl() +
REMOVE_CLUSTER_FROM_EDGE_NODE + clusterId, String.class);
}
}
package top.ninwoo.bishe.starter.service;
import top.ninwoo.bishe.starter.entity.ContainerMonitor;
import top.ninwoo.common.entity.NetworkTopology;
import java.util.List;
/**
* 网络服务接口
*/
public interface NetworkService {
/**
* 获取逻辑网络拓扑
* @param clusterId
* @return
*/
NetworkTopology getLogicalNetworkTopology(Long clusterId);
List<String> getIpListByAppName(Long clusterId, String appName);
String enableNetworkMonitor(Long clusterId, String appName);
List<ContainerMonitor> getContainerMonitors(Long clusterId, String appName);
}
package top.ninwoo.bishe.starter.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import top.ninwoo.bishe.starter.config.ClientProperties;
import top.ninwoo.bishe.starter.entity.ContainerMonitor;
import top.ninwoo.common.entity.ContainerMonitorInfo;
import top.ninwoo.common.entity.NetworkTopology;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
public class NetworkServiceImpl implements NetworkService {
// 获取 网络的逻辑拓扑
private final static String GET_LOGICAL_NETWORK_TOPOLOGY = "/network/getLogicalNetworkTopology?clusterId={clusterId}";
private final static String GET_IP_LIST_BY_APP_NAME = "/network/getIpListByAppName?clusterId={clusterId}&appName={appName}";
private final static String ENABLE_NETWORK_MONITOR = "/enableNetworkMonitor?clusterId={clusterId}&appName={appName}";
private final static String GET_NETWORK_MONITOR_INFO = "/getNetworkMonitorInfo?clusterId={clusterId}&appName={appName}";
@Resource
ClientProperties clientProperties;
@Resource
RestTemplate restTemplate;
@Override
public NetworkTopology getLogicalNetworkTopology(Long clusterId) {
String cloudUrl = clientProperties.getCloudUrl();
Map<String, Object> param = new HashMap<>();
param.put("clusterId", clusterId);
ResponseEntity<NetworkTopology> response
= restTemplate.getForEntity("http://" + cloudUrl + GET_LOGICAL_NETWORK_TOPOLOGY, NetworkTopology.class, param);
if (!response.getStatusCode().is2xxSuccessful()) {
log.error("网络请求失败");
throw new RuntimeException("网络请求出现异常");
}
return response.getBody();
}
/**
* 通过AppName找到对应的全部ip地址列表
* @param clusterId
* @param appName
* @return
*/
@Override
public List<String> getIpListByAppName(Long clusterId, String appName) {
String cloudUrl = clientProperties.getCloudUrl();
Map<String, Object> param = new HashMap<>();
param.put("clusterId", clusterId);
param.put("appName", appName);
ResponseEntity<List> response = restTemplate.getForEntity("http://" + cloudUrl + GET_IP_LIST_BY_APP_NAME,
List.class, param);
if(!response.getStatusCode().is2xxSuccessful()) {
log.error("网络请求错误");
throw new RuntimeException("网络请求错误");
}
return response.getBody();
}
/**
* 对容器应用开启网速监控
* @param clusterId
* @param appName
* @return
*/
@Override
public String enableNetworkMonitor(Long clusterId, String appName) {
String cloudUrl = clientProperties.getCloudUrl();
Map<String, Object> param = new HashMap<>();
param.put("clusterId", clusterId);
param.put("appName", appName);
// 这里需要构建这个ContainerMonitor
return restTemplate.getForObject("http://" + cloudUrl + ENABLE_NETWORK_MONITOR, String.class, param);
}
/**
* 获取容器监控的钩子程序
* @param clusterId
* @param appName
* @return
*/
@Override
public List<ContainerMonitor> getContainerMonitors(Long clusterId, String appName) {
String cloudUrl = clientProperties.getCloudUrl();
Map<String, Object> param = new HashMap<>();
param.put("clusterId", clusterId);
param.put("appName", appName);
// 这里需要构建这个ContainerMonitor
List<ContainerMonitorInfo> containerMonitorInfos
= restTemplate.getForObject("http://" + cloudUrl + GET_NETWORK_MONITOR_INFO, List.class, param);
List<ContainerMonitor> containerMonitors = new ArrayList<>();
containerMonitorInfos.forEach(c -> {
containerMonitors.add(new ContainerMonitor(c, restTemplate));
});
return containerMonitors;
}
}
\ No newline at end of file
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
top.ninwoo.bishe.starter.config.BisheAppAutoConfiguration
\ No newline at end of file
package top.ninwoo.cloudcenter.controller;
import org.springframework.web.bind.annotation.*;
import top.ninwoo.cloudcenter.service.CloudService;
import top.ninwoo.common.entity.NetworkTopology;
import top.ninwoo.common.entity.SeparatedClusterConfig;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/cluster")
public class ClusterController {
@Resource
CloudService cloudService;
@RequestMapping(value = "/sendClusterConfigToEdgeNode", method = RequestMethod.POST)
public List<SeparatedClusterConfig> sendClusterConfigToEdgeNode(@RequestBody List<SeparatedClusterConfig> clusterConfigs) {
return cloudService.sendClusterConfigToEdgeNode(clusterConfigs);
}
@RequestMapping(value = "/removeClusterFromEdgeNode")
public String removeClusterFromEdgeNode(Long clusterId) {
boolean res = cloudService.deleteClusterFromEdgeNode(clusterId);
if(res) {
return "success";
}
return "fail";
}
}
package top.ninwoo.cloudcenter.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import top.ninwoo.cloudcenter.service.CloudService;
import top.ninwoo.common.entity.ContainerMonitorInfo;
import top.ninwoo.common.entity.NetworkTopology;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@RestController
@RequestMapping("/network")
public class NetworkController {
@Resource
CloudService cloudService;
@RequestMapping(value = "/getLogicalNetworkTopology")
public NetworkTopology getLogicalNetworkTopology(Long clusterId) {
return cloudService.getLogicalNetworkByClusterId(clusterId);
}
@RequestMapping(value = "/getIpListByAppName")
public List<String> getIpListByAppName(Long clusterId, String appName) {
Set<String> ipSet = cloudService.getIpListFromRemoteIpServiceByAppName(clusterId, appName);
// 这里的ipSet是无序的
return new ArrayList<>(ipSet);
}
@RequestMapping(value = "/enableNetworkMonitor")
public String enableNetworkMonitor(Long clusterId, String appName) {
return cloudService.enableNetworkMonitor(clusterId, appName);
}
@RequestMapping(value = "/getNetworkMonitorInfo")
public List<ContainerMonitorInfo> getNetworkMonitor(Long clusterId, String appName) {
// 这里可以理解为是返回一个网络监控的钩子程序,具体的查询还需要通过钩子进行执行
return cloudService.getContainerMonitorInfoByAppName(clusterId, appName);
}
}
package top.ninwoo.cloudcenter.entity;
import top.ninwoo.common.entity.ClusterConfig;
public class SeparatedClusterConfig {
private ClusterConfig clusterConfig;
private String edgeNodeId;
public ClusterConfig getClusterConfig() {
return clusterConfig;
}
public void setClusterConfig(ClusterConfig clusterConfig) {
this.clusterConfig = clusterConfig;
}
public String getEdgeNodeId() {
return edgeNodeId;
}
public void setEdgeNodeId(String edgeNodeId) {
this.edgeNodeId = edgeNodeId;
}
}
package top.ninwoo.cloudcenter.service; package top.ninwoo.cloudcenter.service;
import top.ninwoo.cloudcenter.entity.SeparatedClusterConfig;
import top.ninwoo.common.entity.ClusterConfig; import top.ninwoo.common.entity.ClusterConfig;
import top.ninwoo.common.entity.ContainerMonitorInfo;
import top.ninwoo.common.entity.NetworkTopology; import top.ninwoo.common.entity.NetworkTopology;
import top.ninwoo.common.entity.SeparatedClusterConfig;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
* 云端的服务接口 * 云端的服务接口
...@@ -12,9 +14,17 @@ import java.util.List; ...@@ -12,9 +14,17 @@ import java.util.List;
public interface CloudService { public interface CloudService {
String initCluster(ClusterConfig clusterConfig); String initCluster(ClusterConfig clusterConfig);
Set<String> getIpListFromRemoteIpServiceByAppName(long clusterId, String appName);
List<SeparatedClusterConfig> sendClusterConfigToEdgeNode(List<SeparatedClusterConfig> clusterConfigs); List<SeparatedClusterConfig> sendClusterConfigToEdgeNode(List<SeparatedClusterConfig> clusterConfigs);
boolean deleteClusterFromEdgeNode(long clusterId); boolean deleteClusterFromEdgeNode(long clusterId);
void updateLogicalTopology(long clusterId, NetworkTopology topology); void updateLogicalTopology(long clusterId, NetworkTopology topology);
NetworkTopology getLogicalNetworkByClusterId(Long clusterId);
String enableNetworkMonitor(Long clusterId, String appName);
List<ContainerMonitorInfo> getContainerMonitorInfoByAppName(Long clusterId, String appName);
} }
...@@ -2,15 +2,13 @@ package top.ninwoo.cloudcenter.service.impl; ...@@ -2,15 +2,13 @@ package top.ninwoo.cloudcenter.service.impl;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import top.ninwoo.cloudcenter.entity.SeparatedClusterConfig;
import top.ninwoo.cloudcenter.register.CloudRegisterCenter; import top.ninwoo.cloudcenter.register.CloudRegisterCenter;
import top.ninwoo.cloudcenter.service.CloudService; import top.ninwoo.cloudcenter.service.CloudService;
import top.ninwoo.common.entity.ClusterConfig; import top.ninwoo.common.entity.*;
import top.ninwoo.common.entity.ContainerDescription;
import top.ninwoo.common.entity.NetworkTopology;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.*; import java.util.*;
...@@ -24,8 +22,11 @@ public class CloudServiceImpl implements CloudService { ...@@ -24,8 +22,11 @@ public class CloudServiceImpl implements CloudService {
private static final String DELETE_CLUSTER = "/delCluster"; private static final String DELETE_CLUSTER = "/delCluster";
private static final String DROP_DOCKER_NETWORK = "/dropDockerNetwork?clusterId={clusterId}&appName={appName}&ipList={ipList}"; private static final String DROP_DOCKER_NETWORK = "/dropDockerNetwork?clusterId={clusterId}&appName={appName}&ipList={ipList}";
private static final String CANCEL_DROP_DOCKER_NETWORK = "/cancelDropDockerNetwork?clusterId={clusterId}&appName={appName}&ipList={ipList}"; private static final String CANCEL_DROP_DOCKER_NETWORK = "/cancelDropDockerNetwork?clusterId={clusterId}&appName={appName}&ipList={ipList}";
private static final String REMOTE_IP_LIST_BY_APPNAME = "http://127.0.0.1:23333/getIpListByAppName?clusterId={clusterId}&appName={appName}"; private static final String REMOTE_IP_LIST_BY_APPNAME = "/getIpListByAppName?clusterId={clusterId}&appName={appName}";
private static final String ENABLE_NETWORK_MONITOR = "/enableContainerMonitor?clusterId={clusterId}&containerName={appName}";
@Value("${bs.ipservice.url}")
private String ipServiceUrl;
// 全部的逻辑拓扑 // 全部的逻辑拓扑
// 全部的逻辑拓扑 // 全部的逻辑拓扑
private ConcurrentHashMap<Long, NetworkTopology> allLogicalTopo = new ConcurrentHashMap<>(); private ConcurrentHashMap<Long, NetworkTopology> allLogicalTopo = new ConcurrentHashMap<>();
...@@ -63,20 +64,21 @@ public class CloudServiceImpl implements CloudService { ...@@ -63,20 +64,21 @@ public class CloudServiceImpl implements CloudService {
return ""; return "";
} }
private Set<String> getIpListFromRemoteIpServiceByAppName(long clusterId, String appName) { @Override
public Set<String> getIpListFromRemoteIpServiceByAppName(long clusterId, String appName) {
Map<String, Object> param = new HashMap<>(); Map<String, Object> param = new HashMap<>();
param.put("clusterId", clusterId); param.put("clusterId", clusterId);
param.put("appName", appName); param.put("appName", appName);
ResponseEntity<Set> restEntity = restTemplate.getForEntity(REMOTE_IP_LIST_BY_APPNAME, Set.class, param); ResponseEntity<Set> restEntity = restTemplate.getForEntity("http://" + ipServiceUrl + REMOTE_IP_LIST_BY_APPNAME, Set.class, param);
if(!restEntity.getStatusCode().is2xxSuccessful()) { if(!restEntity.getStatusCode().is2xxSuccessful()) {
LOG.error("远程IP服务无法连接"); LOG.error("远程IP服务无法连接");
throw new RuntimeException("远程服务无法连接:" + REMOTE_IP_LIST_BY_APPNAME); throw new RuntimeException("远程服务无法连接:" + ipServiceUrl + REMOTE_IP_LIST_BY_APPNAME);
} }
return restEntity.getBody(); return restEntity.getBody();
} }
private ClusterConfig registerClusterInDataBase(ClusterConfig clusterConfig) { private ClusterConfig registerClusterInDataBase(ClusterConfig clusterConfig) {
clusterConfig.setId(11111); clusterConfig.setId(11111L);
return clusterConfig; return clusterConfig;
} }
...@@ -279,11 +281,19 @@ public class CloudServiceImpl implements CloudService { ...@@ -279,11 +281,19 @@ public class CloudServiceImpl implements CloudService {
public boolean deleteClusterFromEdgeNode(long clusterId) { public boolean deleteClusterFromEdgeNode(long clusterId) {
Map<String, Object> parameters = new HashMap<>(); Map<String, Object> parameters = new HashMap<>();
parameters.put("clusterId", clusterId); parameters.put("clusterId", clusterId);
if(!allClusterConfig.containsKey(clusterId)) {
LOG.warn("集群{}不存在");
return false;
}
List<SeparatedClusterConfig> separatedClusterConfigs = allClusterConfig.get(clusterId); List<SeparatedClusterConfig> separatedClusterConfigs = allClusterConfig.get(clusterId);
separatedClusterConfigs.forEach(c -> { separatedClusterConfigs.forEach(c -> {
// 调用远程借口删除服务 // 调用远程借口删除服务
restTemplate.getForEntity("http://" + c.getEdgeNodeId() + DELETE_CLUSTER + "?clusterId=" + clusterId, String.class); String res = restTemplate.getForObject("http://" + c.getEdgeNodeId() + DELETE_CLUSTER + "?clusterId=" + clusterId, String.class);
LOG.info("删除集群{}", res);
}); });
// 删除对应的逻辑topo
allLogicalTopo.remove(clusterId);
return true; return true;
} }
...@@ -409,4 +419,71 @@ public class CloudServiceImpl implements CloudService { ...@@ -409,4 +419,71 @@ public class CloudServiceImpl implements CloudService {
allLogicalTopo.put(clusterId, networkTopology); allLogicalTopo.put(clusterId, networkTopology);
} }
@Override
public NetworkTopology getLogicalNetworkByClusterId(Long clusterId) {
if(!allLogicalTopo.containsKey(clusterId)) {
LOG.error("无法找到对应的集群topo");
return null;
}
return allLogicalTopo.get(clusterId);
}
@Override
public String enableNetworkMonitor(Long clusterId, String appName) {
if(!allClusterConfig.containsKey(clusterId)) {
LOG.warn("正在启用一个不存在集群的网络监控");
return "failed";
}
if (!allClusterConfig.containsKey(appName)) {
LOG.warn("正在启用一个不存在的AppName的监控");
return "failed";
}
List<SeparatedClusterConfig> separatedClusterConfigs = allClusterConfig.get(appName);
// 遍历clusterAppName下发,容器监控模块
separatedClusterConfigs.forEach(c -> {
if (c.getClusterConfig().getTopology().containsAppName(appName)) {
// 下发启用monitor监控的指令
Map<String, Object> param = new HashMap<>();
param.put("clusterId", clusterId);
param.put("appName", appName);
ResponseEntity<Boolean> response
= restTemplate.getForEntity("http://" + c.getEdgeNodeId() + ENABLE_NETWORK_MONITOR, Boolean.class, param);
if(!response.getStatusCode().is2xxSuccessful()) {
LOG.warn("集群{}通信失败", c.getEdgeNodeId());
}
if(!response.getBody()) {
LOG.warn("集群{},appName{}指令下发失败", c.getEdgeNodeId(), appName);
}
}
});
return "success";
}
@Override
public List<ContainerMonitorInfo> getContainerMonitorInfoByAppName(Long clusterId, String appName) {
List<ContainerMonitorInfo> containerMonitorInfos = new ArrayList<>();
if(!allClusterConfig.containsKey(clusterId)) {
return containerMonitorInfos;
}
List<SeparatedClusterConfig> separatedClusterConfigs = allClusterConfig.get(clusterId);
if(!separatedClusterConfigs.contains(appName)) {
return containerMonitorInfos;
}
separatedClusterConfigs.forEach( c -> {
if(c.getClusterConfig().getTopology().containsAppName(appName)) {
for (ContainerDescription docker : c.getClusterConfig().getDockers()) {
ContainerMonitorInfo monitorInfo = new ContainerMonitorInfo();
monitorInfo.setAppName(appName);
monitorInfo.setEdgeNodeId(c.getEdgeNodeId());
monitorInfo.setClusterId(clusterId);
monitorInfo.setContainerId(docker.getDockerContainer().getId());
containerMonitorInfos.add(monitorInfo);
}
}
});
return containerMonitorInfos;
}
} }
...@@ -2,8 +2,10 @@ server: ...@@ -2,8 +2,10 @@ server:
port: 9090 port: 9090
zookeeper: zookeeper:
url: 127.0.0.1:2181 url: 192.168.31.154:2181
bs: bs:
cloudcenter: cloudcenter:
name: my-bs-cloud-center name: my-bs-cloud-center
ipservice:
url: 127.0.0.1:23333
\ No newline at end of file
package top.ninwoo.cloud; package top.ninwoo.cloud;
import com.spotify.docker.client.messages.BlockIoStats;
import com.spotify.docker.client.messages.Network;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
...@@ -13,12 +11,8 @@ import org.springframework.http.ResponseEntity; ...@@ -13,12 +11,8 @@ import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import top.ninwoo.cloudcenter.CloudCenterMain; import top.ninwoo.cloudcenter.CloudCenterMain;
import top.ninwoo.cloudcenter.entity.SeparatedClusterConfig;
import top.ninwoo.cloudcenter.service.CloudService; import top.ninwoo.cloudcenter.service.CloudService;
import top.ninwoo.common.entity.ClusterConfig; import top.ninwoo.common.entity.*;
import top.ninwoo.common.entity.ContainerDescription;
import top.ninwoo.common.entity.DockerContainer;
import top.ninwoo.common.entity.NetworkTopology;
import java.util.*; import java.util.*;
......
...@@ -19,4 +19,23 @@ ...@@ -19,4 +19,23 @@
</dependency> </dependency>
</dependencies> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--这里写上main方法所在类的路径-->
<configuration>
<mainClass>top.ninwoo.cloud.ipservice.IpServiceMainApp</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project> </project>
\ No newline at end of file
...@@ -32,4 +32,12 @@ public class IpController { ...@@ -32,4 +32,12 @@ public class IpController {
public String clearIpByClusterId(long clusterId) { public String clearIpByClusterId(long clusterId) {
return ipService.clearIpByClusterId(clusterId); return ipService.clearIpByClusterId(clusterId);
} }
@RequestMapping("/deleteIp")
public String deleteIp(long clusterId, String appName, String containerId, String ip) {
ipService.deleteIp(clusterId, appName, containerId, ip);
return "success";
}
} }
\ No newline at end of file
...@@ -6,6 +6,8 @@ public interface IpService { ...@@ -6,6 +6,8 @@ public interface IpService {
String assignIp(long clusterId, String appName, String containerId, String ipRange); String assignIp(long clusterId, String appName, String containerId, String ipRange);
void deleteIp(long clusterId, String appName, String containerId, String ip);
String getContainerIp(String containerId); String getContainerIp(String containerId);
Set<String> getIpListByAppName(long clusterId, String appName); Set<String> getIpListByAppName(long clusterId, String appName);
......
...@@ -59,6 +59,23 @@ public class IpServiceImpl implements IpService { ...@@ -59,6 +59,23 @@ public class IpServiceImpl implements IpService {
return ip; return ip;
} }
@Override
public void deleteIp(long clusterId, String appName, String containerId, String ip) {
// TODO: 这里应该在加入一个还回ip的功能
if(!ipMap.containsKey(containerId)) {
return;
}
ipMap.remove(containerId);
if(!appIp.containsKey(clusterId)) {
return;
}
Map<String, Set<String>> clusterAppId = appIp.get(clusterId);
if(!clusterAppId.containsKey(appName)) {
return;
}
clusterAppId.get(appName).remove(ip);
}
/** /**
* 通过容器id获取ip地址 * 通过容器id获取ip地址
* @param containerId * @param containerId
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
<artifactId>bishe-common-api</artifactId> <artifactId>bishe-common-api</artifactId>
<packaging>jar</packaging>
<dependencies> <dependencies>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency> <dependency>
......
...@@ -12,7 +12,7 @@ import java.util.List; ...@@ -12,7 +12,7 @@ import java.util.List;
*/ */
@Data @Data
public class ClusterConfig { public class ClusterConfig {
private long id; private Long id;
private Date createTime; private Date createTime;
private String owner; private String owner;
private List<ContainerDescription> dockers; private List<ContainerDescription> dockers;
......
package top.ninwoo.common.entity;
import lombok.Data;
@Data
public class ContainerMonitorInfo {
private String edgeNodeId;
// 对应cluster的id
private long clusterId;
// 对应的app name
private String appName;
private String containerId;
}
...@@ -13,6 +13,17 @@ public class NetworkTopology { ...@@ -13,6 +13,17 @@ public class NetworkTopology {
private String[] appNames; private String[] appNames;
private int[][] topology; private int[][] topology;
public boolean containsAppName(String appName) {
if(topology != null) {
for (int i = 0; i < appNames.length; i++) {
if (appNames[i].equals(appName)) {
return true;
}
}
}
return false;
}
/* public NetworkTopology(long topologyId, String[] appNames) { /* public NetworkTopology(long topologyId, String[] appNames) {
this.topologyId = topologyId; this.topologyId = topologyId;
this.appNames = appNames; this.appNames = appNames;
......
package top.ninwoo.common.entity;
import lombok.Data;
@Data
public class SeparatedClusterConfig {
private ClusterConfig clusterConfig;
private String edgeNodeId;
}
...@@ -88,4 +88,23 @@ ...@@ -88,4 +88,23 @@
</dependencies> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--这里写上main方法所在类的路径-->
<configuration>
<mainClass>top.ninwoo.edgecenter.EdgeCenterApp</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project> </project>
\ No newline at end of file
...@@ -50,6 +50,7 @@ public class IndexController { ...@@ -50,6 +50,7 @@ public class IndexController {
* @return * @return
*/ */
// 这里一次查询需要两秒,需要采用异步进行查询 // 这里一次查询需要两秒,需要采用异步进行查询
// TODO: 这里的containerId指的是容器名称
@RequestMapping("/containerMonitor") @RequestMapping("/containerMonitor")
public List<ContainerInfo> getContainerMonitor(@RequestParam("clusterId") Long clusterId,@RequestParam("containerId") String containerId) { public List<ContainerInfo> getContainerMonitor(@RequestParam("clusterId") Long clusterId,@RequestParam("containerId") String containerId) {
// 获取全部的容器id // 获取全部的容器id
...@@ -68,6 +69,14 @@ public class IndexController { ...@@ -68,6 +69,14 @@ public class IndexController {
return containerInfos; return containerInfos;
} }
@RequestMapping("/getContainerMonitorByContainerId")
public ContainerInfo getContainerMonitorByContainerId(String containerId) {
if(containerInfoMap.containsKey(containerId)) {
return containerInfoMap.get(containerId);
}
return null;
}
@RequestMapping("/enableContainerMonitor") @RequestMapping("/enableContainerMonitor")
public boolean enableNetworkMonitor(long clusterId, String containerName) { public boolean enableNetworkMonitor(long clusterId, String containerName) {
// 先获取全部的容器id // 先获取全部的容器id
......
...@@ -16,5 +16,7 @@ public interface IpService { ...@@ -16,5 +16,7 @@ public interface IpService {
// TODO: 这个应该结合数据库,由云端提供服务,暂时提供一个测试版本 // TODO: 这个应该结合数据库,由云端提供服务,暂时提供一个测试版本
String assignIpString(long clusterId, String appName, String containerId, String networkSegment); String assignIpString(long clusterId, String appName, String containerId, String networkSegment);
String deleteIP(long clusterId, String appName, String containerId, String ip);
String getContainerIp(String containerId); String getContainerIp(String containerId);
} }
...@@ -8,6 +8,7 @@ import top.ninwoo.common.entity.ClusterConfig; ...@@ -8,6 +8,7 @@ import top.ninwoo.common.entity.ClusterConfig;
import top.ninwoo.common.entity.ContainerDescription; import top.ninwoo.common.entity.ContainerDescription;
import top.ninwoo.common.entity.DockerContainer; import top.ninwoo.common.entity.DockerContainer;
import top.ninwoo.edgecenter.service.ClusterService; import top.ninwoo.edgecenter.service.ClusterService;
import top.ninwoo.edgecenter.service.IpService;
import top.ninwoo.edgecenter.service.TopologyService; import top.ninwoo.edgecenter.service.TopologyService;
import top.ninwoo.utils.entity.NetworkInfo; import top.ninwoo.utils.entity.NetworkInfo;
import top.ninwoo.utils.entity.OvsBridge; import top.ninwoo.utils.entity.OvsBridge;
...@@ -49,6 +50,9 @@ public class ClusterServiceImpl implements ClusterService { ...@@ -49,6 +50,9 @@ public class ClusterServiceImpl implements ClusterService {
@Autowired @Autowired
TopologyService topologyService; TopologyService topologyService;
@Autowired
IpService ipService;
/** /**
* 定时更新容器列表 * 定时更新容器列表
*/ */
...@@ -177,6 +181,10 @@ public class ClusterServiceImpl implements ClusterService { ...@@ -177,6 +181,10 @@ public class ClusterServiceImpl implements ClusterService {
cids.remove(cid); cids.remove(cid);
// step 2 删除ovs上多余的网络 // step 2 删除ovs上多余的网络
ovsDockerService.deleteContainerPorts(cid); ovsDockerService.deleteContainerPorts(cid);
// step 3 删除对应的ip地址
String ip = ipService.getContainerIp(cid);
ipService.deleteIP(clusterId, name, cid, ip);
} }
} }
// 把docker容器配置恢复初始状态 // 把docker容器配置恢复初始状态
...@@ -234,7 +242,12 @@ public class ClusterServiceImpl implements ClusterService { ...@@ -234,7 +242,12 @@ public class ClusterServiceImpl implements ClusterService {
LOG.debug("删除应用[" + cName + "]"); LOG.debug("删除应用[" + cName + "]");
// 获取全部的容器id // 获取全部的容器id
clustersInfo.get(clusterId).get(cName).forEach( clustersInfo.get(clusterId).get(cName).forEach(
c -> dockerService.deleteDockerById(c)); c -> {
// 删除对应容器的网络
dockerService.deleteDockerById(c);
String containerIp = ipService.getContainerIp(c);
ipService.deleteIP(clusterId, cName, c, containerIp);
});
} }
); );
clustersInfo.remove(clusterId); clustersInfo.remove(clusterId);
...@@ -252,8 +265,11 @@ public class ClusterServiceImpl implements ClusterService { ...@@ -252,8 +265,11 @@ public class ClusterServiceImpl implements ClusterService {
return; return;
} }
clustersInfo.get(clusterId).get(containerName).forEach( clustersInfo.get(clusterId).get(containerName).forEach(
c -> dockerService.deleteDockerById(c) c -> {
); dockerService.deleteDockerById(c);
String containerIp = ipService.getContainerIp(c);
ipService.deleteIP(clusterId, containerName, c, containerIp);
});
clustersInfo.get(clusterId).remove(containerName); clustersInfo.get(clusterId).remove(containerName);
} }
......
...@@ -26,6 +26,7 @@ public class IpServiceImpl implements IpService { ...@@ -26,6 +26,7 @@ public class IpServiceImpl implements IpService {
// clusterId, String appName, String cid, String ipRange // clusterId, String appName, String cid, String ipRange
private static final String ASSIGN_IP = "/assignIp?clusterId={clusterId}&appName={appName}&cid={cid}&ipRange={ipRange}"; private static final String ASSIGN_IP = "/assignIp?clusterId={clusterId}&appName={appName}&cid={cid}&ipRange={ipRange}";
private static final String GET_IP_BY_CONTAINERID = "/getIpByContainerId?cid="; private static final String GET_IP_BY_CONTAINERID = "/getIpByContainerId?cid=";
private static final String DELETE_IP = "/deleteIp?clusterId={clusterId}&appName={appName}&containerId={containerId}&ip={ip}";
@Value("${bs.ipservice.ip}") @Value("${bs.ipservice.ip}")
private String ipServiceHost; private String ipServiceHost;
...@@ -53,6 +54,15 @@ public class IpServiceImpl implements IpService { ...@@ -53,6 +54,15 @@ public class IpServiceImpl implements IpService {
return forEntity.getBody(); return forEntity.getBody();
} }
@Override
public String deleteIP(long clusterId, String appName, String containerId, String ip) {
Map<String, Object> param = new HashMap<>();
param.put("clusterId", clusterId);
param.put("appName", appName);
param.put("containerId", containerId);
param.put("ip", ip);
return restTemplate.getForObject("http://" + ipServiceHost + DELETE_IP, String.class, param);
}
@Override @Override
public String getContainerIp(String containerId) { public String getContainerIp(String containerId) {
// 更换为远程接口 // 更换为远程接口
......
...@@ -21,7 +21,6 @@ bs: ...@@ -21,7 +21,6 @@ bs:
name: random name: random
ip-prefix: 192 ip-prefix: 192
ipservice: ipservice:
ip: 127.0.0.1:23333 ip: 192.168.31.154:23333
zookeeper: zookeeper:
url: 127.0.0.1:2181 url: 192.168.31.154:2181
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>bishe</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>bishe-test</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>bishe-client-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.1.2.RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package top.ninwoo.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class BisheTestMain {
public static void main(String[] args) {
SpringApplication.run(BisheTestMain.class, args);
}
}
bishe.app.app-name=joliu
bishe.app.cloud-url=192.168.31.154:9090
\ No newline at end of file
package top.ninwoo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import top.ninwoo.bishe.starter.service.ClusterService;
import top.ninwoo.bishe.starter.service.NetworkService;
import top.ninwoo.common.entity.*;
import top.ninwoo.test.BisheTestMain;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = BisheTestMain.class)
public class BisheTests {
@Autowired
private ClusterService clusterService;
@Resource
private NetworkService networkService;
@Test
public void testSendSeparateConfig() {
ArrayList<SeparatedClusterConfig> clusterConfigs = new ArrayList<>();
SeparatedClusterConfig separatedClusterConfig = new SeparatedClusterConfig();
// TODO: 这个ID应该是从借口获取的
separatedClusterConfig.setEdgeNodeId("127.0.0.1:8081");
ClusterConfig clusterConfig = new ClusterConfig();
clusterConfig.setId(11111l);
clusterConfig.setOwner("joliu");
ContainerDescription containerDescription = new ContainerDescription();
containerDescription.setMode("normal");
containerDescription.setReplicas(2);
DockerContainer container = new DockerContainer();
container.setName("Run");
container.setCommand("sh");
container.setImage("joliu/networktest");
containerDescription.setDockerContainer(container);
List<ContainerDescription> cds = new ArrayList<>();
cds.add(containerDescription);
ContainerDescription containerDescription1 = new ContainerDescription();
containerDescription1.setMode("normal");
containerDescription1.setReplicas(3);
DockerContainer container1 = new DockerContainer();
container1.setName("APP");
container1.setCommand("sh");
container1.setImage("joliu/networktest");
containerDescription1.setDockerContainer(container1);
cds.add(containerDescription1);
clusterConfig.setDockers(cds);
NetworkTopology topo = new NetworkTopology();
topo.setAppNames(new String[]{"Run", "APP", "br:ovs1"});
// 这个参数好像没啥用
topo.setTopologyId(11);
topo.setTopology(new int[][]{{0,0,0},{0,0,0},{1,1,0}});
clusterConfig.setTopology(topo);
separatedClusterConfig.setClusterConfig(clusterConfig);
clusterConfigs.add(separatedClusterConfig);
clusterService.sendClusterConfigToEdgeNode(clusterConfigs);
}
@Test
public void removeClusterFromEdgeNodeTest() {
clusterService.removeClusterFromEdgeNode(11111L);
}
@Test
public void getLogicalNetworkTopologyTest() {
NetworkTopology logicalNetworkTopology = networkService.getLogicalNetworkTopology(11111L);
System.out.println(logicalNetworkTopology);
}
@Test
public void getIpListByAppNameTest() {
List<String> ipList = networkService.getIpListByAppName(11111L, "Run");
System.out.println(ipList);
}
}
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
<artifactId>bishe-utils</artifactId> <artifactId>bishe-utils</artifactId>
<packaging>jar</packaging>
<properties> <properties>
<jersey.version>2.27</jersey.version> <jersey.version>2.27</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
<module>bishe-cloud-center</module> <module>bishe-cloud-center</module>
<module>bishe-common-api</module> <module>bishe-common-api</module>
<module>bishe-cloud-ipservice</module> <module>bishe-cloud-ipservice</module>
<module>bishe-client-starter</module>
<module>bishe-test</module>
</modules> </modules>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment