Commit 72eff040 authored by wutu's avatar wutu

构建了云中心和边缘节点的通信借口,测试了基本功能。

parent 7cb45ac8
...@@ -51,5 +51,17 @@ ...@@ -51,5 +51,17 @@
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>bishe-common-api</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> </dependencies>
</project> </project>
\ No newline at end of file
package top.ninwoo.cloudcenter.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfiguration {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
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;
}
}
...@@ -8,13 +8,17 @@ import org.slf4j.Logger; ...@@ -8,13 +8,17 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import top.ninwoo.common.EdgeNodeEntity;
import top.ninwoo.utils.util.impl.IpUtils; import top.ninwoo.utils.util.impl.IpUtils;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
@Component @Component
public class CloudRegisterCenter implements Register { public class CloudRegisterCenter implements Register {
...@@ -23,12 +27,21 @@ public class CloudRegisterCenter implements Register { ...@@ -23,12 +27,21 @@ public class CloudRegisterCenter implements Register {
private final static String hostAddress = IpUtils.getHostIp("10."); private final static String hostAddress = IpUtils.getHostIp("10.");
// 用于存储全部可用的集群信息
private ConcurrentHashMap<String, EdgeNodeEntity> availableEdgeNodes = new ConcurrentHashMap<>();
@Value("${bs.cloudcenter.name}") @Value("${bs.cloudcenter.name}")
private String cloudCenterName; private String cloudCenterName;
@Value("${server.port}")
private int port;
@Resource @Resource
private CuratorFramework zkClient; private CuratorFramework zkClient;
@Resource
private RestTemplate restTemplate;
// 边缘计算节点的监控器 // 边缘计算节点的监控器
private PathChildrenCache edgeNodesWatcher = null; private PathChildrenCache edgeNodesWatcher = null;
...@@ -68,7 +81,7 @@ public class CloudRegisterCenter implements Register { ...@@ -68,7 +81,7 @@ public class CloudRegisterCenter implements Register {
} else { } else {
// 更新IP地址 // 更新IP地址
LOG.info("Cloud 地址更新"); LOG.info("Cloud 地址更新");
zkClient.setData().forPath("/" + nodeId, hostAddress.getBytes()); zkClient.setData().forPath("/" + nodeId, (hostAddress + ":" + port).getBytes());
} }
} catch (Exception e) { } catch (Exception e) {
LOG.error("创建cloud节点{}失败", nodeId); LOG.error("创建cloud节点{}失败", nodeId);
...@@ -86,6 +99,20 @@ public class CloudRegisterCenter implements Register { ...@@ -86,6 +99,20 @@ public class CloudRegisterCenter implements Register {
watcher.getListenable().addListener((client, event) -> { watcher.getListenable().addListener((client, event) -> {
if(event.getType() == PathChildrenCacheEvent.Type.CHILD_ADDED) { if(event.getType() == PathChildrenCacheEvent.Type.CHILD_ADDED) {
LOG.info("新的节点{}已接入", event.getData().getPath()); LOG.info("新的节点{}已接入", event.getData().getPath());
String newNode = event.getData().getPath();
String newNodeIp = new String(event.getData().getData());
// 通过newNodeIp获取边缘服务器的信息
// 注册信息到中心节点上
// 这里通过网络进行请求,其实也是在做一次测试,查看远程服务器是否符合版本要求,网络是否顺畅
try {
EdgeNodeEntity remoteEdgeNodeInfo = getRemoteEdgeNodeInfo(newNodeIp);
// TODO: 校验版本号是否符合要求
// 以url作为唯一的key值进行存储,url不会重复
availableEdgeNodes.put(newNodeIp, remoteEdgeNodeInfo);
} catch (Exception e) {
LOG.warn("远程边缘节点无法连接:{}", newNodeIp);
e.printStackTrace();
}
} }
else if(event.getType() == PathChildrenCacheEvent.Type.CHILD_REMOVED) { else if(event.getType() == PathChildrenCacheEvent.Type.CHILD_REMOVED) {
LOG.info("节点{}已离线", event.getData().getPath()); LOG.info("节点{}已离线", event.getData().getPath());
...@@ -101,4 +128,24 @@ public class CloudRegisterCenter implements Register { ...@@ -101,4 +128,24 @@ public class CloudRegisterCenter implements Register {
return null; return null;
} }
} }
private EdgeNodeEntity getRemoteEdgeNodeInfo(String url) {
if("".equals(url)) {
LOG.error("要访问的地址不能为空");
throw new IllegalArgumentException("url为空");
}
url = "http://" + url + "/edgeNode/info";
EdgeNodeEntity nodeInfo
= restTemplate.getForEntity(url, EdgeNodeEntity.class).getBody();
LOG.info("接受到的信息{}:", nodeInfo);
return nodeInfo;
}
/**
* 获取全部的可用边缘服务节点
* @return
*/
public List<String> getAvailableEdgeNodes() {
return new ArrayList<String>(availableEdgeNodes.keySet());
}
} }
package top.ninwoo.cloudcenter.service;
import top.ninwoo.cloudcenter.entity.SeparatedClusterConfig;
import top.ninwoo.common.entity.ClusterConfig;
import top.ninwoo.common.entity.NetworkTopology;
import java.util.List;
/**
* 云端的服务接口
*/
public interface CloudService {
String initCluster(ClusterConfig clusterConfig);
List<SeparatedClusterConfig> sendClusterConfigToEdgeNode(List<SeparatedClusterConfig> clusterConfigs);
}
package top.ninwoo.cloudcenter.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import top.ninwoo.cloudcenter.entity.SeparatedClusterConfig;
import top.ninwoo.cloudcenter.register.CloudRegisterCenter;
import top.ninwoo.cloudcenter.service.CloudService;
import top.ninwoo.common.entity.ClusterConfig;
import top.ninwoo.common.entity.ContainerDescription;
import top.ninwoo.common.entity.NetworkTopology;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@Service
public class CloudServiceImpl implements CloudService {
private static final Logger LOG = LoggerFactory.getLogger(CloudServiceImpl.class);
private static final Random randomInt = new Random(14);
private static final String CREATE_CLUSTER = "/createCluster";
// 用于存储配置文件
private ConcurrentHashMap<Long, List<SeparatedClusterConfig>> allClusterConfig
= new ConcurrentHashMap<>();
@Resource
private CloudRegisterCenter cloudRegisterCenter;
@Resource
private RestTemplate restTemplate;
/**
* 这里的拓扑必须限定为逻辑拓扑
* @param clusterConfig
* @return
*/
@Override
public String initCluster(ClusterConfig clusterConfig) {
// TODO: step1: 校验配置是否合法
check(clusterConfig);
// 在数据库中注册该节点
registerClusterInDataBase(clusterConfig);
// TODO: step2: 拆分配置
// TODO: step3: 下发配置到不同的边缘服务节点
// TODO: 保存配置和边缘节点的映射关系
return "";
}
private ClusterConfig registerClusterInDataBase(ClusterConfig clusterConfig) {
clusterConfig.setId(11111);
return clusterConfig;
}
private boolean check(ClusterConfig clusterConfig) {
return true;
}
private List<SeparatedClusterConfig> separateClusterConfig(ClusterConfig clusterConfig) {
// 先校验clusterConfig的模式
String type = clusterConfig.getType();
if("single".equals(type)) {
return singleSeparateClusterConfig(clusterConfig);
}
if("random".equals(type)) {
return randomSeparateClusterConfig(clusterConfig);
}
if("all".equals(type)) {
return allSeparatedClusterConfig(clusterConfig);
}
if(type.startsWith("size:")) {
int size = Integer.parseInt(type.split(":")[1]);
return fixedSpeparatedClusterConfig(clusterConfig, size);
}
throw new IllegalArgumentException("clusterConfig's " + type + " is Illegal!");
}
private List<SeparatedClusterConfig> fixedSpeparatedClusterConfig(ClusterConfig clusterConfig, int size) {
List<String> nodes = chooseEdgeNodes(size);
Map<String, SeparatedClusterConfig> separatedClusterConfigs = new HashMap<>();
for (int i = 0; i < nodes.size(); i++) {
SeparatedClusterConfig separatedClusterConfig = new SeparatedClusterConfig();
separatedClusterConfig.setEdgeNodeId(nodes.get(i));
ClusterConfig config = new ClusterConfig();
config.setId(clusterConfig.getId());
// 只有这里不同
config.setDockers(new ArrayList<>());
NetworkTopology networkTopology = new NetworkTopology();
config.setTopology(networkTopology);
config.setOwner(clusterConfig.getOwner());
config.setCreateTime(clusterConfig.getCreateTime());
config.setType(clusterConfig.getType());
separatedClusterConfig.setClusterConfig(config);
separatedClusterConfigs.put(nodes.get(i), separatedClusterConfig);
}
int index = 0;
// TODO: 拆分配置,构建出新的配置
List<ContainerDescription> dockers = clusterConfig.getDockers();
for (ContainerDescription docker : dockers) {
if("one".equals(docker.getMode())) {
// 该docker全部部署到同一个集群上
// TODO: 这里可以添加一些选择标准
SeparatedClusterConfig separatedClusterConfig = separatedClusterConfigs.get(nodes.get(index));
ClusterConfig edgeClusterConfig = separatedClusterConfig.getClusterConfig();
// 更新edgeColusterClusterConfig上的配置
edgeClusterConfig.getDockers().add(docker);
NetworkTopology topology = edgeClusterConfig.getTopology();
String[] appNames = topology.getAppNames();
int[][] topo = topology.getTopology();
// TODO: 扩大规模
if(appNames == null) {
appNames = new String[]{docker.getDockerContainer().getName()};
topo = new int[][]{{0}};
} else {
appNames = Arrays.copyOf(appNames, appNames.length + 1);
appNames[appNames.length - 1] = docker.getDockerContainer().getName();
// 可能出问题
topo = new int[topo.length + 1][topo.length + 1];
}
topology.setAppNames(appNames);
topology.setTopology(topo);
}
else if(docker.getMode().equals("roundbin")) {
int replicas = docker.getReplicas();
int average = replicas / nodes.size();
for (int i = 0; i < nodes.size(); i++) {
// TODO: 更新集群,更新
}
}
index = (index + 1) % nodes.size();
}
return null;
}
private List<SeparatedClusterConfig> allSeparatedClusterConfig(ClusterConfig clusterConfig) {
List<String> availableEdgeNodes = cloudRegisterCenter.getAvailableEdgeNodes();
return null;
}
private List<SeparatedClusterConfig> randomSeparateClusterConfig(ClusterConfig clusterConfig) {
// 创建随机的
return null;
}
private List<SeparatedClusterConfig> singleSeparateClusterConfig(ClusterConfig clusterConfig) {
// 选择一个节点
List<String> nodes = chooseEdgeNodes(1);
return null;
}
private List<String> chooseEdgeNodes(int num) {
// TODO 可以扩展更多选择方案,比如已计算优先,或者内存优先
ArrayList<String> res = new ArrayList<>(num);
// step1: 获取全部可用的边缘节点
List<String> availableEdgeNodes = cloudRegisterCenter.getAvailableEdgeNodes();
if(availableEdgeNodes.size() <= num) {
return availableEdgeNodes;
}
// step2: 随机挑选一个节点
for (int i = 0; i < num; i++) {
int index = randomInt.nextInt(availableEdgeNodes.size());
res.add(availableEdgeNodes.get(index));
availableEdgeNodes.remove(index);
}
return res;
}
/**
* 下发clusterConfigs到边缘节点
* @param clusterConfigs
* @return
*/
@Override
public List<SeparatedClusterConfig> sendClusterConfigToEdgeNode(List<SeparatedClusterConfig> clusterConfigs) {
// 这里应该做一个判断,edgeNode的ip是否可用,如果不可用,或者未设定,将随机挑选一个进行设置
clusterConfigs.forEach(c -> {
if (c.getEdgeNodeId() == null || "".equals(c.getEdgeNodeId())) {
String edgeNode = chooseEdgeNodes(1).get(0);
c.setEdgeNodeId(edgeNode);
}
// 下发配置
ResponseEntity<Long> response = restTemplate.postForEntity("http://" + c.getEdgeNodeId() + CREATE_CLUSTER, c.getClusterConfig(), Long.class);
if(!response.getStatusCode().is2xxSuccessful()) {
LOG.error("集群配置下发失败:{}:{}", c.getEdgeNodeId(), response.getBody());
}
});
return clusterConfigs;
}
}
package top.ninwoo.cloud;
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.cloudcenter.CloudCenterMain;
import top.ninwoo.cloudcenter.entity.SeparatedClusterConfig;
import top.ninwoo.cloudcenter.service.CloudService;
import top.ninwoo.common.entity.ClusterConfig;
import top.ninwoo.common.entity.ContainerDescription;
import top.ninwoo.common.entity.DockerContainer;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = CloudCenterMain.class)
public class CloudServiceImplTest {
@Autowired
private CloudService cloudService;
@Test
public void sendClusterConfigToEdgeNodeTest() {
ArrayList<SeparatedClusterConfig> clusterConfigs = new ArrayList<>();
SeparatedClusterConfig separatedClusterConfig = new SeparatedClusterConfig();
separatedClusterConfig.setEdgeNodeId("10.174.22.207: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);
separatedClusterConfig.setClusterConfig(clusterConfig);
clusterConfigs.add(separatedClusterConfig);
cloudService.sendClusterConfigToEdgeNode(clusterConfigs);
}
@Test
public void deleteClusterFromEdgeNodeTest() {
}
}
<?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-common-api</artifactId>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package top.ninwoo.common;
/**
* 用于描述边缘服务节点的数据结构
*/
public class EdgeNodeEntity {
private long id;
private String name;
private String url;
private String version;
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public String toString() {
return "EdgeNodeEntity{" +
"id=" + id +
", name='" + name + '\'' +
", url='" + url + '\'' +
'}';
}
}
package top.ninwoo.common.entity;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
* @author joliu
* @date 2019-10-20
* @description 集群的配置类
*/
@Data
public class ClusterConfig {
private long id;
private Date createTime;
private String owner;
private List<ContainerDescription> dockers;
// 集群模式
private String type;
private NetworkTopology topology;
}
package top.ninwoo.common.entity;
import lombok.Data;
/**
* @Author joliu
* @Description 容器具体的描述信息
* @Date Create in 下午2:17 2019/10/20
*/
@Data
public class ContainerDescription {
private String mode;
private int replicas;
// dockerContainer模板
private DockerContainer dockerContainer;
}
package top.ninwoo.common.entity;
import lombok.Data;
/**
* @Author joliu
* @Description
* @Date Create in 下午4:36 2019/11/6
*/
@Data
public class ContainerInfo {
private String id;
private NetworkInfo networkInfo;
private String cpu;
private String mem;
}
package top.ninwoo.common.entity;
import lombok.Data;
@Data
public class DockerContainer {
private String id;
private String image;
private String command;
private long created;
private String status;
private String ports;
// 这里只使用Container.names的第一个元素作为名称
private String name;
}
package top.ninwoo.common.entity;
/**
* @Author joliu
* @Description
* @Date Create in 下午9:51 2019/11/4
*/
public class NetworkInfo {
private String containerId;
private float curRate;
private float errorRate;
private float dropRate;
public String getContainerId() {
return containerId;
}
public void setContainerId(String containerId) {
this.containerId = containerId;
}
public float getCurRate() {
return curRate;
}
public void setCurRate(float curRate) {
this.curRate = curRate;
}
public float getErrorRate() {
return errorRate;
}
public void setErrorRate(float errorRate) {
this.errorRate = errorRate;
}
public float getDropRate() {
return dropRate;
}
public void setDropRate(float dropRate) {
this.dropRate = dropRate;
}
@Override
public String toString() {
return "NetworkInfo{" +
"curRate=" + curRate +
"%, errorRate=" + errorRate +
"%, dropRate=" + dropRate +
"%}";
}
}
package top.ninwoo.common.entity;
import lombok.Data;
/**
* @Author joliu
* @Description 描述网络拓扑, 这个数据结构最终要存储到数据库中
* @Date Create in 下午9:30 2019/11/6
*/
@Data
public class NetworkTopology {
private long topologyId;
private String[] appNames;
private int[][] topology;
/* public NetworkTopology(long topologyId, String[] appNames) {
this.topologyId = topologyId;
this.appNames = appNames;
if(appNames == null || appNames.length < 1) {
throw new RuntimeException("容器的数组不能为空");
}
topology = new int[appNames.length][appNames.length];
}*/
}
package top.ninwoo.common.entity;
import lombok.Data;
/**
* @Author joliu
* @Description
* @Date Create in 下午2:17 2019/10/20
*/
@Data
public class User {
private long userId;
private String password;
}
...@@ -59,6 +59,11 @@ ...@@ -59,6 +59,11 @@
<artifactId>bishe-utils</artifactId> <artifactId>bishe-utils</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>bishe-common-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency> <dependency>
...@@ -68,6 +73,18 @@ ...@@ -68,6 +73,18 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- 对zookeeper的底层api的一些封装 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
<!-- 封装了一些高级特性,如:Cache事件监听、选举、分布式锁、分布式Barrier -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.12.0</version>
</dependency>
</dependencies> </dependencies>
......
...@@ -2,10 +2,15 @@ package top.ninwoo.edgecenter; ...@@ -2,10 +2,15 @@ package top.ninwoo.edgecenter;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import javax.annotation.Resource;
@SpringBootApplication @SpringBootApplication
@EnableScheduling @EnableScheduling
@MapperScan("top.ninwoo.edgecenter.dao") @MapperScan("top.ninwoo.edgecenter.dao")
...@@ -13,4 +18,5 @@ public class EdgeCenterApp { ...@@ -13,4 +18,5 @@ public class EdgeCenterApp {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(EdgeCenterApp.class, args); SpringApplication.run(EdgeCenterApp.class, args);
} }
} }
\ No newline at end of file
...@@ -5,17 +5,27 @@ import org.apache.curator.framework.CuratorFrameworkFactory; ...@@ -5,17 +5,27 @@ import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.curator.retry.ExponentialBackoffRetry;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.support.WebApplicationContextUtils;
import top.ninwoo.edgecenter.register.EdgeNodeRegister;
import javax.annotation.Resource;
@Configuration @Configuration
public class ZookeeperConfiguration { public class ZookeeperConfiguration implements ApplicationContextAware {
private static final Logger LOG = LoggerFactory.getLogger(ZookeeperConfiguration.class); private static final Logger LOG = LoggerFactory.getLogger(ZookeeperConfiguration.class);
@Value("${zookeeper.url}") @Value("${zookeeper.url}")
private String url; private String url;
private ApplicationContext applicationContext = null;
@Bean(destroyMethod = "close") @Bean(destroyMethod = "close")
public CuratorFramework zkClient() { public CuratorFramework zkClient() {
ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3); ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3);
...@@ -29,4 +39,17 @@ public class ZookeeperConfiguration { ...@@ -29,4 +39,17 @@ public class ZookeeperConfiguration {
} }
return client; return client;
} }
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Bean
public ApplicationRunner applicationRunner() {
return args -> {
EdgeNodeRegister bean = applicationContext.getBean(EdgeNodeRegister.class);
bean.registerNode();
};
}
} }
package top.ninwoo.edgecenter.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import top.ninwoo.common.EdgeNodeEntity;
@RestController
@RequestMapping("/edgeNode")
public class EdgeController {
/**
* 获取边缘节点的信息
* @return
*/
@RequestMapping("/info")
public EdgeNodeEntity info() {
// TODO: 需要添加真实的功能
EdgeNodeEntity edgeNodeEntity = new EdgeNodeEntity();
edgeNodeEntity.setId(11111);
edgeNodeEntity.setName("test");
edgeNodeEntity.setUrl("http://www.baidu.com");
return edgeNodeEntity;
}
}
...@@ -2,12 +2,12 @@ package top.ninwoo.edgecenter.controller; ...@@ -2,12 +2,12 @@ package top.ninwoo.edgecenter.controller;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import top.ninwoo.common.entity.DockerContainer;
import top.ninwoo.edgecenter.entity.ClusterConfig; import top.ninwoo.edgecenter.entity.ClusterConfig;
import top.ninwoo.edgecenter.entity.ContainerInfo; import top.ninwoo.edgecenter.entity.ContainerInfo;
import top.ninwoo.edgecenter.entity.NetworkTopology; import top.ninwoo.edgecenter.entity.NetworkTopology;
import top.ninwoo.edgecenter.service.ClusterService; import top.ninwoo.edgecenter.service.ClusterService;
import top.ninwoo.edgecenter.service.TopologyService; import top.ninwoo.edgecenter.service.TopologyService;
import top.ninwoo.utils.entity.DockerContainer;
import top.ninwoo.utils.entity.NetworkInfo; import top.ninwoo.utils.entity.NetworkInfo;
import top.ninwoo.utils.entity.OvsBridge; import top.ninwoo.utils.entity.OvsBridge;
...@@ -26,7 +26,7 @@ public class IndexController { ...@@ -26,7 +26,7 @@ public class IndexController {
@Autowired @Autowired
TopologyService topologyService; TopologyService topologyService;
@RequestMapping("/index") @RequestMapping(value = "/index")
public List<DockerContainer> index(int flag) { public List<DockerContainer> index(int flag) {
List<DockerContainer> containerIds = clusterService.getContainerIds(flag == 0); List<DockerContainer> containerIds = clusterService.getContainerIds(flag == 0);
......
package top.ninwoo.edgecenter.entity; package top.ninwoo.edgecenter.entity;
import lombok.Data; import lombok.Data;
import lombok.Getter;
import top.ninwoo.utils.entity.DockerContainer;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
......
package top.ninwoo.edgecenter.entity; package top.ninwoo.edgecenter.entity;
import lombok.Data; import lombok.Data;
import top.ninwoo.utils.entity.DockerContainer; import top.ninwoo.common.entity.DockerContainer;
import java.util.Date;
/** /**
* @Author joliu * @Author joliu
......
...@@ -5,6 +5,7 @@ import org.apache.zookeeper.CreateMode; ...@@ -5,6 +5,7 @@ import org.apache.zookeeper.CreateMode;
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.beans.factory.annotation.Value;
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import top.ninwoo.utils.util.impl.IpUtils; import top.ninwoo.utils.util.impl.IpUtils;
...@@ -19,6 +20,9 @@ import java.util.UUID; ...@@ -19,6 +20,9 @@ import java.util.UUID;
public class EdgeNodeRegister implements Register { public class EdgeNodeRegister implements Register {
private final static Logger LOG = LoggerFactory.getLogger(EdgeNodeRegister.class); private final static Logger LOG = LoggerFactory.getLogger(EdgeNodeRegister.class);
private boolean isRunning;
@Resource @Resource
CuratorFramework zkClient; CuratorFramework zkClient;
...@@ -27,21 +31,30 @@ public class EdgeNodeRegister implements Register { ...@@ -27,21 +31,30 @@ public class EdgeNodeRegister implements Register {
@Value("${bs.edgenode.name}") @Value("${bs.edgenode.name}")
private String edgeNodeId; private String edgeNodeId;
@PostConstruct
public void init() { @Value("${server.port}")
LOG.info("开始注册边缘节点{}", edgeNodeId); private int port;
regsiterNode(edgeNodeId);
@Value("${bs.edgenode.ip-prefix}")
private String ipPrefix;
public static String nodeId;
@Override
public void registerNode() {
registerNode("random");
} }
@Override @Override
public void regsiterNode(String nodeId) { public void registerNode(String nodeId) {
if(nodeId.equals("random")) { if(nodeId.equals("random")) {
nodeId = UUID.randomUUID().toString(); nodeId = UUID.randomUUID().toString();
} }
edgeNodeId = nodeId;
try { try {
zkClient.create() zkClient.create()
.withMode(CreateMode.EPHEMERAL) .withMode(CreateMode.EPHEMERAL)
.forPath("/" + cloudCenterName + "/" + nodeId, IpUtils.getHostIp("10.").getBytes()); .forPath("/" + cloudCenterName + "/" + nodeId, (IpUtils.getHostIp(ipPrefix) + ":" + port).getBytes());
LOG.info("临时节点【{}】已创建", nodeId); LOG.info("临时节点【{}】已创建", nodeId);
} catch (Exception e) { } catch (Exception e) {
LOG.error("临时节点【{}】创建失败", nodeId); LOG.error("临时节点【{}】创建失败", nodeId);
......
package top.ninwoo.edgecenter.register; package top.ninwoo.edgecenter.register;
public interface Register { public interface Register {
void regsiterNode(String nodeId); void registerNode();
void registerNode(String nodeId);
} }
package top.ninwoo.edgecenter.service; package top.ninwoo.edgecenter.service;
import top.ninwoo.common.entity.DockerContainer;
import top.ninwoo.edgecenter.entity.ClusterConfig; import top.ninwoo.edgecenter.entity.ClusterConfig;
import top.ninwoo.utils.entity.DockerContainer;
import top.ninwoo.utils.entity.NetworkInfo; import top.ninwoo.utils.entity.NetworkInfo;
import top.ninwoo.utils.entity.OvsBridge; import top.ninwoo.utils.entity.OvsBridge;
......
...@@ -4,11 +4,11 @@ import org.slf4j.Logger; ...@@ -4,11 +4,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import top.ninwoo.common.entity.DockerContainer;
import top.ninwoo.edgecenter.entity.ClusterConfig; import top.ninwoo.edgecenter.entity.ClusterConfig;
import top.ninwoo.edgecenter.entity.ContainerDescription; import top.ninwoo.edgecenter.entity.ContainerDescription;
import top.ninwoo.edgecenter.service.ClusterService; import top.ninwoo.edgecenter.service.ClusterService;
import top.ninwoo.edgecenter.service.TopologyService; import top.ninwoo.edgecenter.service.TopologyService;
import top.ninwoo.utils.entity.DockerContainer;
import top.ninwoo.utils.entity.NetworkInfo; import top.ninwoo.utils.entity.NetworkInfo;
import top.ninwoo.utils.entity.OvsBridge; import top.ninwoo.utils.entity.OvsBridge;
import top.ninwoo.utils.service.DockerService; import top.ninwoo.utils.service.DockerService;
...@@ -19,7 +19,6 @@ import top.ninwoo.utils.util.OSUtils; ...@@ -19,7 +19,6 @@ import top.ninwoo.utils.util.OSUtils;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* @author joliu * @author joliu
...@@ -191,6 +190,7 @@ public class ClusterServiceImpl implements ClusterService { ...@@ -191,6 +190,7 @@ public class ClusterServiceImpl implements ClusterService {
public ClusterConfig saveClusterConfig(ClusterConfig clusterConfig) { public ClusterConfig saveClusterConfig(ClusterConfig clusterConfig) {
// TODO: 保存数据到数据库 // TODO: 保存数据到数据库
clusterConfig.setId(11111L); clusterConfig.setId(11111L);
// TODO: 在Zookeeper上注册对应的cluster服务,以便云端开启监听
return clusterConfig; return clusterConfig;
} }
......
...@@ -19,6 +19,7 @@ bs: ...@@ -19,6 +19,7 @@ bs:
name: my-bs-cloud-center name: my-bs-cloud-center
edgenode: edgenode:
name: random name: random
ip-prefix: 192
zookeeper: zookeeper:
url: 127.0.0.1:2181 url: 127.0.0.1:2181
......
...@@ -7,10 +7,10 @@ import org.junit.runner.RunWith; ...@@ -7,10 +7,10 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import top.ninwoo.common.entity.DockerContainer;
import top.ninwoo.edgecenter.entity.ClusterConfig; import top.ninwoo.edgecenter.entity.ClusterConfig;
import top.ninwoo.edgecenter.entity.ContainerDescription; import top.ninwoo.edgecenter.entity.ContainerDescription;
import top.ninwoo.edgecenter.service.ClusterService; import top.ninwoo.edgecenter.service.ClusterService;
import top.ninwoo.utils.entity.DockerContainer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
......
...@@ -10,9 +10,9 @@ import org.slf4j.LoggerFactory; ...@@ -10,9 +10,9 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import top.ninwoo.common.entity.DockerContainer;
import top.ninwoo.utils.entity.ChainEntity; import top.ninwoo.utils.entity.ChainEntity;
import top.ninwoo.utils.entity.ChainType; import top.ninwoo.utils.entity.ChainType;
import top.ninwoo.utils.entity.DockerContainer;
import top.ninwoo.utils.service.DockerService; import top.ninwoo.utils.service.DockerService;
import top.ninwoo.utils.service.OVSService; import top.ninwoo.utils.service.OVSService;
import top.ninwoo.utils.service.OvsDockerService; import top.ninwoo.utils.service.OvsDockerService;
......
...@@ -43,6 +43,12 @@ ...@@ -43,6 +43,12 @@
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
<version>2.6</version> <version>2.6</version>
</dependency> </dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>bishe-common-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies> </dependencies>
</project> </project>
\ No newline at end of file
package top.ninwoo.utils.entity;
public class DockerContainer {
private String id;
private String image;
private String command;
private long created;
private String status;
private String ports;
// 这里只使用Container.names的第一个元素作为名称
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getCommand() {
return command;
}
public void setCommand(String command) {
this.command = command;
}
public long getCreated() {
return created;
}
public void setCreated(long created) {
this.created = created;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getPorts() {
return ports;
}
public void setPorts(String ports) {
this.ports = ports;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
...@@ -2,7 +2,7 @@ package top.ninwoo.utils.service; ...@@ -2,7 +2,7 @@ package top.ninwoo.utils.service;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import top.ninwoo.utils.entity.DockerContainer; import top.ninwoo.common.entity.DockerContainer;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
......
...@@ -8,7 +8,7 @@ import org.springframework.beans.factory.InitializingBean; ...@@ -8,7 +8,7 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import top.ninwoo.utils.entity.DockerContainer; import top.ninwoo.common.entity.DockerContainer;
import top.ninwoo.utils.service.ContainerStatus; import top.ninwoo.utils.service.ContainerStatus;
import top.ninwoo.utils.service.DockerService; import top.ninwoo.utils.service.DockerService;
import top.ninwoo.utils.util.DockerUtils; import top.ninwoo.utils.util.DockerUtils;
...@@ -17,7 +17,6 @@ import java.util.ArrayList; ...@@ -17,7 +17,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
@Service @Service
public class DockerServiceImpl implements DockerService, InitializingBean { public class DockerServiceImpl implements DockerService, InitializingBean {
......
package top.ninwoo.utils.util; package top.ninwoo.utils.util;
import top.ninwoo.utils.entity.DockerContainer; import top.ninwoo.common.entity.DockerContainer;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
......
...@@ -6,18 +6,14 @@ import com.spotify.docker.client.exceptions.ContainerNotFoundException; ...@@ -6,18 +6,14 @@ import com.spotify.docker.client.exceptions.ContainerNotFoundException;
import com.spotify.docker.client.exceptions.DockerException; import com.spotify.docker.client.exceptions.DockerException;
import com.spotify.docker.client.messages.Container; import com.spotify.docker.client.messages.Container;
import com.spotify.docker.client.messages.ContainerInfo; import com.spotify.docker.client.messages.ContainerInfo;
import com.spotify.docker.client.messages.ExecState;
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import top.ninwoo.utils.entity.DockerContainer; import top.ninwoo.common.entity.DockerContainer;
import top.ninwoo.utils.util.DockerUtils; import top.ninwoo.utils.util.DockerUtils;
import top.ninwoo.utils.util.LinuxCtlUtils; import top.ninwoo.utils.util.LinuxCtlUtils;
import top.ninwoo.utils.util.Utils; import top.ninwoo.utils.util.Utils;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
......
...@@ -6,8 +6,8 @@ import org.junit.runner.RunWith; ...@@ -6,8 +6,8 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import top.ninwoo.common.entity.DockerContainer;
import top.ninwoo.utils.config.DockerConfig; import top.ninwoo.utils.config.DockerConfig;
import top.ninwoo.utils.entity.DockerContainer;
import top.ninwoo.utils.service.DockerService; import top.ninwoo.utils.service.DockerService;
import top.ninwoo.utils.util.LinuxCtlUtils; import top.ninwoo.utils.util.LinuxCtlUtils;
......
...@@ -6,8 +6,8 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -6,8 +6,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import top.ninwoo.common.entity.DockerContainer;
import top.ninwoo.utils.config.DockerConfig; import top.ninwoo.utils.config.DockerConfig;
import top.ninwoo.utils.entity.DockerContainer;
import top.ninwoo.utils.util.DockerUtils; import top.ninwoo.utils.util.DockerUtils;
/** /**
......
...@@ -9,10 +9,10 @@ import org.slf4j.LoggerFactory; ...@@ -9,10 +9,10 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import top.ninwoo.common.entity.DockerContainer;
import top.ninwoo.utils.config.DockerConfig; import top.ninwoo.utils.config.DockerConfig;
import top.ninwoo.utils.entity.ChainEntity; import top.ninwoo.utils.entity.ChainEntity;
import top.ninwoo.utils.entity.ChainType; import top.ninwoo.utils.entity.ChainType;
import top.ninwoo.utils.entity.DockerContainer;
import top.ninwoo.utils.entity.TableType; import top.ninwoo.utils.entity.TableType;
import top.ninwoo.utils.service.DockerService; import top.ninwoo.utils.service.DockerService;
import top.ninwoo.utils.util.IptablesUtils; import top.ninwoo.utils.util.IptablesUtils;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
<module>bishe-edge-center</module> <module>bishe-edge-center</module>
<module>bishe-utils</module> <module>bishe-utils</module>
<module>bishe-cloud-center</module> <module>bishe-cloud-center</module>
<module>bishe-common-api</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