Commit eadd3ecc authored by wutu's avatar wutu

构建新的util基础类

parent de3fd791
/bishe-edge-center/target/
*.iml
/bishe-utils/target/
......@@ -4,7 +4,6 @@ package top.ninwoo.edgecenter;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
......
......@@ -24,6 +24,9 @@ public class ClusterServiceImpl implements ClusterService, Scheduler {
@Autowired
DockerService dockerService;
/**
* 定时更新容器列表
*/
@Scheduled(fixedRate = 5000)
@Override
public void update() {
......@@ -92,27 +95,54 @@ public class ClusterServiceImpl implements ClusterService, Scheduler {
return clusterConfig;
}
/**
* @description 获取集群Id集合
* @return
*/
@Override
public Set<Long> getClusterIds() {
return clustersInfo.keySet();
}
/**
* @description 获取集群中的指定容器的容器组集合
* @param clusterId
* @param containerName
* @return
*/
@Override
public Set<String> getContainerIdsByClusterId(long clusterId, String containerName) {
return clustersInfo.get(clusterId).get(containerName);
}
/**
* @description 删除指定集群的全部容器
* @param clusterId
*/
@Override
public void removeContainersByClusterId(long clusterId) {
if(!clustersInfo.containsKey(clusterId)) {
return;
}
clustersInfo.get(clusterId).keySet().forEach(
c -> removeContainersByClusterIdAndContainerName(clusterId, c)
);
clustersInfo.remove(clusterId);
}
/**
* @description 删除指定容器
* @param clusterId
* @param containerName
*/
@Override
public void removeContainersByClusterIdAndContainerName(long clusterId, String containerName) {
if(!clustersInfo.containsKey(clusterId)) {
return;
}
clustersInfo.get(clusterId).get(containerName).forEach(
c -> dockerService.deleteDockerById(c)
);
clustersInfo.get(clusterId).remove(containerName);
}
}
\ No newline at end of file
......@@ -67,7 +67,5 @@ public class ClusterServiceTest {
@Test
public void testRemoveContainers() {
clusterService.removeContainersByClusterId(clusterId);
// TODO: 实时更新容器列表
// TODO: 没有做边界条件判断
}
}
package top.ninwoo.utils.util;
import top.ninwoo.utils.entity.DockerContainer;
import java.util.List;
import java.util.Map;
/**
* @Author joliu
* @Description docker 的工具接口
* @Date Create in 下午9:21 2019/10/20
*/
public interface DockerUtils {
/**
* @description docker ps
* @return
*/
Map<String, DockerContainer> getContainers();
/**
* @description docker ps -a
* @return
*/
Map<String, DockerContainer> getContainers(boolean isAll);
/**
* @description docker run -itd --name [name] [image] [cmd]
* @param container
* @return
*/
DockerContainer runDocker(DockerContainer container);
DockerContainer getDockerById(String id);
boolean deleteDockerById(String id);
}
package top.ninwoo.utils.util;
/**
* @Author joliu
* @Description linux的工具接口
* @Date Create in 下午9:23 2019/10/20
*/
public interface LinuxCtlUtils {
String runCmd(String cmd);
}
package top.ninwoo.utils.util;
/**
* @Author joliu
* @Description ovs-docker 的工具接口
* @Date Create in 下午9:23 2019/10/20
*/
public interface OvsDockerUtils {
String addPort(String bridgeName, String devName, String containerId, String ip);
}
package top.ninwoo.utils.util;
import top.ninwoo.utils.entity.Ovs;
/**
* @Author joliu
* @Description ovs 的工具接口
* @Date Create in 下午9:24 2019/10/20
*/
public interface OvsUtils {
/**
* ovs-vsctl --version
* @return
*/
boolean isInstall();
/**
* ovs-vsctl show
* @return
*/
Ovs showDetails();
/**
* ovs-vsctl add-br
* @param name
* @return
*/
void addBridge(String name);
/**
* ovs-vsctl set bridge [bridgeName] protocols=[protocols]
* @param bridgeName
* @param protocol
*/
void setBridgeProtocol(String bridgeName, String protocol);
/**
* ovs-vsctl set-controller
* @param bridgeName
* @param host
* @param port
*/
void setController(String bridgeName, String host, int port);
/**
* ovs-vsctl del-br
* @param name
*/
void delBridge(String name);
}
package top.ninwoo.utils.util;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;
import java.lang.annotation.*;
/**
* @Author joliu
* @Description 工具接口的统一父类
* @Date Create in 下午9:22 2019/10/20
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Utils {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
\ No newline at end of file
package top.ninwoo.utils.util.impl;
import com.spotify.docker.client.DockerClient;
import com.spotify.docker.client.exceptions.DockerException;
import com.spotify.docker.client.messages.Container;
import com.spotify.docker.client.messages.ContainerInfo;
import org.springframework.beans.factory.annotation.Autowired;
import top.ninwoo.utils.entity.DockerContainer;
import top.ninwoo.utils.util.DockerUtils;
import top.ninwoo.utils.util.LinuxCtlUtils;
import top.ninwoo.utils.util.Utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author joliu
* @Description
* @Date Create in 下午9:26 2019/10/20
*/
@Utils
public class DockerUtilsImpl implements DockerUtils {
@Autowired
DockerClient dockerClient;
@Autowired
LinuxCtlUtils linuxCtlUtils;
@Override
public Map<String, DockerContainer> getContainers() {
return getContainers(false);
}
@Override
public Map<String, DockerContainer> getContainers(boolean isAll) {
HashMap<String, DockerContainer> containersMap = new HashMap<>();
containersMap.clear();
List<Container> containers =
null;
try {
if(!isAll) {
containers = dockerClient.listContainers(DockerClient.ListContainersParam.withStatusRunning());
} else {
// TODO:这里边还需要在确定
containers = dockerClient.listContainers(DockerClient.ListContainersParam.withStatusCreated());
}
} catch (DockerException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
List<DockerContainer> dockerContainers = convertDockerResult(containers);
dockerContainers.forEach(dockerContainer -> containersMap.put(dockerContainer.getId(), dockerContainer));
return containersMap;
}
/**
* 将DockerClient获取的到结果封装成为我们自定义的数据结构
* @param containers
* @return
*/
public List<DockerContainer> convertDockerResult(List<Container> containers) {
if(containers == null) {
throw new RuntimeException("容器列表不能为null");
}
List<DockerContainer> dockerContainers = new ArrayList<DockerContainer>(containers.size());
containers.forEach(c -> {
DockerContainer container = new DockerContainer();
container.setId(c.id());
container.setCommand(c.command());
container.setCreated(c.created());
container.setPorts(c.portsAsString());
container.setImage(c.image());
container.setStatus(c.status());
container.setName(c.names().get(0));
dockerContainers.add(container);
});
return dockerContainers;
}
@Override
public DockerContainer runDocker(DockerContainer container) {
// TODO: 这里启动Docker容器,需要再研究port如何起作用
// TODO: 这里还需要处理name等属性为空的情况
String cmd = "docker run -itd --name " + container.getName() + " " + container.getImage() + " " + container.getCommand();
String result = linuxCtlUtils.runCmd(cmd);
if(result.contains("Error")) {
throw new RuntimeException("Run Docker failed!:" + cmd);
}
// TODO:需要从Docker中查询处完整的信息
container.setId(result);
return container;
}
/**
* @descprition 这个是通过docker inspect 【dockerid】返回的接口,数据更新
* @param id
* @return
*/
@Override
public DockerContainer getDockerById(String id) {
ContainerInfo containerInfo = null;
try {
containerInfo = dockerClient.inspectContainer(id);
} catch (DockerException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return exchangeFromDockerInfo(containerInfo);
}
public DockerContainer exchangeFromDockerInfo(ContainerInfo containerInfo) {
if(containerInfo == null) {
throw new RuntimeException("ContainerInfo cannot be null");
}
DockerContainer dockerContainer = new DockerContainer();
dockerContainer.setImage(containerInfo.image());
dockerContainer.setName(containerInfo.name());
dockerContainer.setId(containerInfo.id());
dockerContainer.setStatus(containerInfo.state().status());
dockerContainer.setCreated(containerInfo.created().getTime());
return dockerContainer;
}
@Override
public boolean deleteDockerById(String id) {
try {
dockerClient.stopContainer(id, 0);
dockerClient.removeContainer(id);
return true;
} catch (DockerException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return false;
}
}
package top.ninwoo.utils.util.impl;
import top.ninwoo.utils.util.LinuxCtlUtils;
import top.ninwoo.utils.util.Utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* @Author joliu
* @Description
* @Date Create in 下午9:28 2019/10/20
*/
@Utils
public class LinuxCtlUtilsImpl implements LinuxCtlUtils {
@Override
// TODO: 这个函数中的异常处理是一个问题
public String runCmd(String cmd) {
String result = "";
try {
Process exec = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", cmd});
exec.waitFor();
InputStream in = exec.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String msg;
while((msg = br.readLine())!= null && msg.length() > 0) {
result += msg + "\n";
}
if("".equals(result)) {
// 构建Error
InputStream errorStream = exec.getErrorStream();
BufferedReader ebr = new BufferedReader(new InputStreamReader(errorStream));
String eMsg;
while((eMsg = ebr.readLine())!= null && eMsg.length() > 0) {
result += eMsg + "\n";
}
if(result.equals("")) {
return result;
}
result = "Error: " + result;
}
if(result.length() > 0) {
result = result.substring(0, result.length()-1);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return result;
}
}
package top.ninwoo.utils.util.impl;
import org.springframework.beans.factory.annotation.Autowired;
import top.ninwoo.utils.util.LinuxCtlUtils;
import top.ninwoo.utils.util.OvsDockerUtils;
/**
* @Author joliu
* @Description
* @Date Create in 下午9:29 2019/10/20
*/
public class OvsDockerUtilsImpl implements OvsDockerUtils {
@Autowired
LinuxCtlUtils linuxCtlUtils;
@Override
public String addPort(String bridgeName, String devName,String containerId, String ip) {
String cmd = "ovs-docker add-port " + bridgeName + " " + devName + " " + containerId + " --ipaddress=" + ip;
String res = linuxCtlUtils.runCmd(cmd);
if(res.contains("Error")) {
throw new RuntimeException(res);
}
return res;
}
}
package top.ninwoo.utils.util.impl;
import org.springframework.beans.factory.annotation.Autowired;
import top.ninwoo.utils.entity.BridgePort;
import top.ninwoo.utils.entity.Ovs;
import top.ninwoo.utils.entity.OvsBridge;
import top.ninwoo.utils.util.LinuxCtlUtils;
import top.ninwoo.utils.util.OvsUtils;
import top.ninwoo.utils.util.Utils;
import java.util.ArrayList;
import java.util.List;
/**
* @Author joliu
* @Description
* @Date Create in 下午9:29 2019/10/20
*/
@Utils
public class OvsUtilsImpl implements OvsUtils {
@Autowired
LinuxCtlUtils linuxCtlUtils;
@Override
public boolean isInstall() {
// 可能会遇到权限问题
String s = linuxCtlUtils.runCmd("ovs-vsctl --version");
if(s.contains("Error")) {
return false;
} else {
return true;
}
}
@Override
public Ovs showDetails() {
String res = linuxCtlUtils.runCmd("echo 'Vudo3423' | sudo -S ovs-vsctl show");
Ovs ovs = parseOvsString(res);
return ovs;
}
/**
* 将返回的字符串转换为Ovs数据结构
* @param ovsString
* @return
*/
public Ovs parseOvsString(String ovsString) {
if(ovsString == null || "".equals(ovsString)) {
throw new RuntimeException("ovs String cannot be null or empty!");
}
String[] results = ovsString.split("\n");
if(results.length < 2) {
throw new RuntimeException("Illegal ovs Result!");
}
Ovs ovs = new Ovs();
String ovsId = results[0].substring(0,results[0].length()-1);
ovs.setId(ovsId);
String ovsVersion = getValueInString(results[results.length - 1]);
ovs.setOvsVersion(ovsVersion);
int i = 0;
OvsBridge bridge = null;
BridgePort port = null;
List<BridgePort> ports = new ArrayList<>();
List<OvsBridge> bridges = new ArrayList<>();
while(i < results.length) {
// 创建Bridge
if(results[i].contains("Bridge")) {
port = null;
ports.clear();
if(bridge != null) {
// 放入到数组中
bridges.add(bridge);
}
String bridgeId = getValueInString(results[i]);
bridge = new OvsBridge();
bridge.setBridgeId(bridgeId);
}
else if(results[i].contains("Port")) {
if(port != null) {
ports.add(port);
}
String portId = getValueInString(results[i]);
port = new BridgePort();
port.setPortId(portId.replace("\"", ""));
}
else if(results[i].contains("Interface")) {
if(port == null) {
throw new RuntimeException("Cannot find Port");
}
String interfaceId = getValueInString(results[i]);
port.setInterfaceId(interfaceId);
}
else if(results[i].contains("Error")) {
if(port == null) {
throw new RuntimeException("Cannot find Port");
}
String error = getValueInString(results[i]);
port.setError(error);
} else if(results[i].contains("ovs_version")) {
if(port != null) {
ports.add(port);
bridge.setPorts(ports);
bridges.add(bridge);
}
ovs.setBridges(bridges);
}
i++;
}
return ovs;
}
public String getValueInString(String input) {
String value = input.trim().split(" ")[1];
value = value.replaceAll("\"", "");
return value;
}
@Override
public void addBridge(String name) {
String cmd = "echo 'Vudo3423' | sudo -S ovs-vsctl add-br " + name;
String res = linuxCtlUtils.runCmd(cmd);
System.out.println(res);
if(res.contains("Error")) {
throw new RuntimeException("linux bridge has existed!");
}
}
@Override
public void setBridgeProtocol(String bridgeName, String protocol) {
String cmd = "echo 'Vudo3423' | sudo -S ovs-vsctl set bridge " + bridgeName + " protocols=" + protocol;
String res = linuxCtlUtils.runCmd(cmd);
if(res.contains("Error")) {
throw new RuntimeException(res);
}
}
@Override
public void setController(String bridgeName, String host, int port) {
String cmd = "echo 'Vudo3423' | sudo -S ovs-vsctl set-controller " + bridgeName + " tcp:" + host + ":" + port;
String res = linuxCtlUtils.runCmd(cmd);
if(res.contains("Error")) {
throw new RuntimeException(res);
}
}
@Override
public void delBridge(String name) {
String cmd = "echo 'Vudo3423' | sudo -S ovs-vsctl del-br " + name;
String res = linuxCtlUtils.runCmd(cmd);
if(res.contains("Error")) {
throw new RuntimeException("bridge not found!");
}
}
}
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