Commit 4a0f9a68 authored by joliu's avatar joliu Committed by Gitee

!3 合并卫星仿真代码

Merge pull request !3 from Joliu/newWeiXing
parents cc21f268 e9f0b5f2
......@@ -16,4 +16,8 @@ public interface ClusterService {
List<String> getAllEdgeNodeIds();
boolean adjustClusterToEdgeNode(List<SeparatedClusterConfig> configs);
boolean sendLogicTopoToEdgeNode(List<SeparatedClusterConfig> configs);
boolean adjustLogicTopoToEdgeNode(List<SeparatedClusterConfig> configs);
}
......@@ -24,6 +24,10 @@ public class ClusterServiceImpl implements ClusterService {
= "/cluster/getEdgeNodeIds";
private final static String ADJUST_CLUSTER_TO_EDGE_NODE
= "/cluster/adjustCluster";
private final static String SEND_LOGIC_TOPO
= "/cluster/sendLogicTopo";
private final static String ADJUST_LOGIC_TOPO
= "/cluster/adjustLogicTopo";
@Resource
private RestTemplate restTemplate;
......@@ -64,4 +68,28 @@ public class ClusterServiceImpl implements ClusterService {
return result.getStatusCode().is2xxSuccessful();
}
@Override
public boolean sendLogicTopoToEdgeNode(List<SeparatedClusterConfig> configs) {
Map<String, Object> param = new HashMap<>();
param.put("configs", configs.toArray());
ResponseEntity<Boolean> result = restTemplate.postForEntity("http://" + clientProperties.getCloudUrl() + SEND_LOGIC_TOPO, configs, Boolean.class);
return result.getStatusCode().is2xxSuccessful();
}
@Override
public boolean adjustLogicTopoToEdgeNode(List<SeparatedClusterConfig> configs) {
Map<String, Object> param = new HashMap<>();
param.put("configs", configs.toArray());
ResponseEntity<Boolean> result = restTemplate.postForEntity("http://" + clientProperties.getCloudUrl() + ADJUST_LOGIC_TOPO, configs, Boolean.class);
return result.getStatusCode().is2xxSuccessful();
}
}
......@@ -39,4 +39,14 @@ public class ClusterController {
public Boolean adjustClusterToEdgeNode(@RequestBody List<SeparatedClusterConfig> clusterConfigs) {
return cloudService.adjustCluster(clusterConfigs);
}
@RequestMapping(value = "/sendLogicTopo", method = RequestMethod.POST)
public Boolean sendLogicTopoToEdgeNode(@RequestBody List<SeparatedClusterConfig> clusterConfigs) {
return cloudService.sendLogicTopo(clusterConfigs);
}
@RequestMapping(value = "/adjustLogicTopo", method = RequestMethod.POST)
public Boolean adjustLogicTopoToEdgeNode(@RequestBody List<SeparatedClusterConfig> clusterConfigs) {
return cloudService.adjustLogicTopo(clusterConfigs);
}
}
......@@ -37,4 +37,8 @@ public interface CloudService {
Boolean addQos(Long clusterId, String appName, String maxRate, String latency);
boolean adjustCluster(List<SeparatedClusterConfig> clusterConfigs);
boolean sendLogicTopo(List<SeparatedClusterConfig> clusterConfigs);
boolean adjustLogicTopo(List<SeparatedClusterConfig> clusterConfigs);
}
......@@ -21,6 +21,9 @@ public class CloudServiceImpl implements CloudService {
private static final String CREATE_CLUSTER = "/createCluster";
private static final String DELETE_CLUSTER = "/delCluster";
private static final String ADJUST_CLUSTER = "/adjustCluster";
private static final String SEND_LOGICTOPO = "/sendLogicTopo";
private static final String ADJUST_LOGICTOPO = "/adjustLogicTopo";
private static final String ADJUST_LOGICTOPO_BYTOPO = "/adjustLogicTopoBytopo";
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 REMOTE_IP_LIST_BY_APPNAME = "/getIpListByAppName?clusterId={clusterId}&appName={appName}";
......@@ -90,6 +93,46 @@ public class CloudServiceImpl implements CloudService {
return true;
}
@Override
public boolean sendLogicTopo(List<SeparatedClusterConfig> clusterConfigs) {
if(clusterConfigs == null) {
throw new RuntimeException("clusterConfig cannot be null.");
}
try {
clusterConfigs.forEach(c -> {
ResponseEntity<String> response = restTemplate.postForEntity("http://" + c.getEdgeNodeId() + SEND_LOGICTOPO, c.getClusterConfig(), String.class);
if (!response.getStatusCode().is2xxSuccessful()) {
throw new RuntimeException("send Error!");
}
LOG.info("{} send logictopo success!", c.getEdgeNodeId());
});
} catch (Exception e) {
return false;
}
return true;
}
@Override
public boolean adjustLogicTopo(List<SeparatedClusterConfig> clusterConfigs) {
if(clusterConfigs == null) {
throw new RuntimeException("clusterConfig cannot be null.");
}
try {
clusterConfigs.forEach(c -> {
ResponseEntity<String> response = restTemplate.postForEntity("http://" + c.getEdgeNodeId() + ADJUST_LOGICTOPO, c.getClusterConfig(), String.class);
if (!response.getStatusCode().is2xxSuccessful()) {
throw new RuntimeException("send Error!");
}
LOG.info("{} adjust logictopo success!", c.getEdgeNodeId());
});
} catch (Exception e) {
return false;
}
return true;
}
/**
* 这里的拓扑必须限定为逻辑拓扑
* @param clusterConfig
......@@ -258,7 +301,7 @@ public class CloudServiceImpl implements CloudService {
* @return
*/
@Override
public List<SeparatedClusterConfig> sendClusterConfigToEdgeNode(List<SeparatedClusterConfig> clusterConfigs) {
public List<SeparatedClusterConfig> sendClusterConfigToEdgeNode(List<SeparatedClusterConfig> clusterConfigs) {
if(clusterConfigs.size() == 0) {
LOG.warn("下发的集群配置为空。");
return clusterConfigs;
......
server:
port: 9090
port: 9091
zookeeper:
url: 192.168.31.156:2181
......
......@@ -13,6 +13,7 @@ import top.ninwoo.edgecenter.entity.ContainerInfo;
import top.ninwoo.edgecenter.service.ClusterService;
import top.ninwoo.edgecenter.service.IpService;
import top.ninwoo.edgecenter.service.TopologyService;
import top.ninwoo.edgecenter.service.LogicTopoService;
import top.ninwoo.utils.entity.NetworkInfo;
import top.ninwoo.utils.entity.OvsBridge;
import top.ninwoo.utils.service.TcService;
......@@ -32,6 +33,9 @@ public class IndexController {
@Autowired
private TopologyService topologyService;
@Autowired
private LogicTopoService logicTopoService;
@Autowired
private IpService ipService;
......@@ -310,4 +314,47 @@ public class IndexController {
return ips;
}
//下发逻辑拓扑
@RequestMapping(value = "/sendLogicTopo", method = RequestMethod.POST)
public String sendLogicTopo(@RequestBody ClusterConfig clusterConfig) {
if(clusterConfig == null){
return "请传入正确的集群设置";
}
// 使用topo创建工具
String res = logicTopoService.creatLogicTopo(clusterConfig.getId(), clusterConfig.getTopology());
//System.out.println("ok");
return res;
}
//修改逻辑拓扑
@RequestMapping(value = "/adjustLogicTopo", method = RequestMethod.POST)
public String adjustLogicTopo(@RequestBody ClusterConfig clusterConfig) {
if(clusterConfig == null){
return "请传入正确的集群设置";
}
// 判断id
if (clusterConfig.getId() == 0) {
return "没有设置clusterid";
}
String res1 = logicTopoService.modifyLogicTopology(clusterConfig.getId(), clusterConfig.getTopology());
//System.out.println("ok?");
return res1;
}
//
@GetMapping("/getIPbyName")
public String getIPbyname(@RequestParam(name = "appname")String appname,@RequestParam(name = "clusterId")long clusterId) {
Set<String> cid = clusterService.getContainerIdsByClusterId(clusterId, appname);
if (cid == null){
System.out.println("错误的clusterID");
return "获取失败";
}
String appID = ((String) cid.toArray()[0]);
if(appID ==null){
System.out.println("错误的appnmae");
return "获取失败";
}
String appIP = ipService.getContainerIp(appID).split("/")[0];
return appIP;
}
}
\ No newline at end of file
package top.ninwoo.edgecenter.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import top.ninwoo.edgecenter.service.LogicTopoService;
import java.util.List;
@RestController
@RequestMapping("/dockerData")
public class TransferTopoController {
@Autowired
private LogicTopoService logicTopoService;
@GetMapping("/getIPlist")
public List<String> getIPlist(@RequestParam(name = "clusterId")long clusterId) {
//System.out.println("已返回IPlist");
return logicTopoService.getIPlist(clusterId);
}
//需下发逻辑拓扑后才能获得
@GetMapping("/getTopo")
public int[][] getTopo(@RequestParam(name = "clusterId")long clusterId) {
//System.out.println("已返回topo");
return logicTopoService.getTopo(clusterId);
}
}
package top.ninwoo.edgecenter.service;
import top.ninwoo.common.entity.NetworkTopology;
import java.util.List;
//逻辑网络
public interface LogicTopoService {
//通过逻辑拓扑创造逻辑网络
String creatLogicTopo(long clusterId, NetworkTopology logictopo);
//调整逻辑网络
String modifyLogicTopology(long clusterId, NetworkTopology logictopo);
//得到逻辑拓扑
NetworkTopology getLogictopo(NetworkTopology oritopo);
//返回topo到docker容器端
int[][] getTopo(long clusterId);
//返回IPlist到docker容器端
List<String> getIPlist(long clusterId);
}
package top.ninwoo.edgecenter.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import top.ninwoo.common.entity.NetworkTopology;
import top.ninwoo.edgecenter.service.ClusterService;
import top.ninwoo.edgecenter.service.IpService;
import top.ninwoo.edgecenter.service.LogicTopoService;
import top.ninwoo.utils.service.IptablesService;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@Service
public class LogicTopoServiceImpl implements LogicTopoService {
private final static Logger LOG = LoggerFactory.getLogger(TopologyServiceImpl.class);
// 用于存储集群的拓扑
private ConcurrentHashMap<Long, NetworkTopology> clustersTopo = new ConcurrentHashMap<>();
//根据appnames来存储IP
private ConcurrentHashMap<Long, List<String>> clustersIPlist = new ConcurrentHashMap<>();
@Autowired
private ClusterService clusterService;
@Autowired
private IpService ipService;
@Autowired
private IptablesService iptablesService;
@Override
public String creatLogicTopo(long clusterId, NetworkTopology oldtopo) {
List<String> IPlist = new ArrayList<String>();
NetworkTopology logictopo = this.getLogictopo(oldtopo);
if (logictopo == null) {
LOG.warn("集群[" + clusterId + "]未设置网络");
return "集群创建失败";
}
// 校验信息
String[] cNames = logictopo.getAppNames();
int[][] topo = logictopo.getTopology();
if (cNames == null || cNames.length <= 1) {
return "集群创建失败";
}
for(int k=0;k<cNames.length;k++){
Set<String> cid = clusterService.getContainerIdsByClusterId(clusterId, cNames[k]);
if (cid == null){
System.out.println("错误的clusterID");
return "获取失败";
}
String appID = ((String) cid.toArray()[0]);
if(appID ==null){
System.out.println("错误的appnmae");
return "获取失败";
}
String appIP = ipService.getContainerIp(appID).split("/")[0];
IPlist.add(appIP);
}
clustersTopo.put(clusterId, logictopo);
clustersIPlist.put(clusterId,IPlist);
return "success";
}
@Override
public String modifyLogicTopology(long clusterId, NetworkTopology oldtopo) {
NetworkTopology logictopo = this.getLogictopo(oldtopo);
// 先进行校验
if (logictopo == null) {
LOG.error("topoloy不能为空");
return "topoloy不能为空";
}
// 获取clusterId的网络拓扑
if (!clustersTopo.containsKey(clusterId)) {
System.out.println("该集群没有设置topo");
return "该集群没有设置topo";
}
NetworkTopology origTopo = clustersTopo.get(clusterId);
// 校验topoId是否一致
if (origTopo.getTopologyId() != logictopo.getTopologyId()) {
LOG.error("不是相同的网络拓扑,无法更改");
return "不是相同的网络拓扑,无法更改";
}
// 校验成员名称是否相同
for (int i = 0; i < origTopo.getAppNames().length; i++) {
if (!origTopo.getAppNames()[i].equals(logictopo.getAppNames()[i])) {
LOG.error("App名称必须一致");
return "App名称必须一致";
}
}
int[][] origTopoArr = origTopo.getTopology();
int[][] newTopoArr = logictopo.getTopology();
// 校验topo是否一致
if ((origTopoArr.length != newTopoArr.length)
|| (origTopoArr[0].length != newTopoArr[0].length)) {
LOG.error("拓扑大小不一致");
return "拓扑大小不一致";
}
clustersTopo.put(clusterId, logictopo);
return "success";
}
@Override
public NetworkTopology getLogictopo(NetworkTopology oritopo) {
NetworkTopology logictopo = new NetworkTopology();
int flag = 0;
//获取appnames
for (int i = 0; i < oritopo.getAppNames().length - 1; i++) {
if (oritopo.getAppNames()[i].startsWith("br:")) {
break;
}
flag++;
}
String[] appname = new String[flag];
for(int k=0;k<flag;k++){appname[k]=oritopo.getAppNames()[k];}
logictopo.setAppNames(appname);
//获取逻辑拓扑
int[][] logicTopo = new int[flag][flag];
for (int j=1;j<flag;j++){
for (int m=0;m<j;m++){logicTopo[j][m] = oritopo.getTopology()[j][m];}
}
logictopo.setTopology(logicTopo);
logictopo.setTopologyId(oritopo.getTopologyId());
return logictopo;
}
public void addDelDropIPtable(long clusterId, String appName1, String appName2) {
//获取容器ID
Set<String> cid1 = clusterService.getContainerIdsByClusterId(clusterId, appName1);
String appID1 = ((String) cid1.toArray()[0]);
String appIP1 = ipService.getContainerIp(appID1).split("/")[0];
Set<String> cid2 = clusterService.getContainerIdsByClusterId(clusterId, appName2);
String appID2 = ((String) cid2.toArray()[0]);
String appIP2 = ipService.getContainerIp(appID2).split("/")[0];
//dropTraffic(String containerId, String sourceIp, String destinationIp)
//dropTraffic模块 容器ID 源(容器)地址 目的(容器)地址
iptablesService.cancelDropTraffic(appID1, appIP2, appIP1);
iptablesService.cancelDropTraffic(appID2, appIP1, appIP2);
}
public void addDropIPtable(long clusterId, String appName1, String appName2) {
//获取容器ID
Set<String> cid1 = clusterService.getContainerIdsByClusterId(clusterId, appName1);
String appID1 = ((String) cid1.toArray()[0]);
String appIP1 = ipService.getContainerIp(appID1).split("/")[0];
Set<String> cid2 = clusterService.getContainerIdsByClusterId(clusterId, appName2);
String appID2 = ((String) cid2.toArray()[0]);
String appIP2 = ipService.getContainerIp(appID2).split("/")[0];
//dropTraffic(String containerId, String sourceIp, String destinationIp)
//dropTraffic模块 容器ID 源(容器)地址 目的(容器)地址
iptablesService.dropTraffic(appID1, appIP2, appIP1);
iptablesService.dropTraffic(appID2, appIP1, appIP2);
}
@Override
public int[][] getTopo(long clusterId) {
if(!clustersTopo.containsKey(clusterId)){
LOG.error("没有该集群的Topo");
return null;
}
return clustersTopo.get(clusterId).getTopology();
}
@Override
public List<String> getIPlist(long clusterId) {
if(!clustersIPlist.containsKey(clusterId)){
LOG.error("没有该集群的IPlist");
return new ArrayList<String>();
}
return clustersIPlist.get(clusterId);
}
}
......@@ -26,9 +26,9 @@ bs:
name: random
ip-prefix: 192.168.31
ipservice:
ip: 192.168.31.156:23333
ip: 192.168.31.238:23333
sdn-controller:
host: 127.0.0.1
port: 6653
zookeeper:
url: 192.168.31.156:2181
url: 192.168.31.238:2181
......@@ -35,6 +35,12 @@
<artifactId>influxdb-java</artifactId>
<version>2.9</version>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>bishe-weixingsim</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
......
......@@ -27,7 +27,7 @@ public class LunWenTests {
public void test1() {
ArrayList<SeparatedClusterConfig> clusterConfigs = new ArrayList<>();
SeparatedClusterConfig separatedClusterConfig = new SeparatedClusterConfig();
separatedClusterConfig.setEdgeNodeId("127.0.0.1:8081");
separatedClusterConfig.setEdgeNodeId("192.168.190.135:8081");
ClusterConfig clusterConfig = new ClusterConfig();
clusterConfig.setId(11111l);
clusterConfig.setOwner("joliu");
......@@ -75,7 +75,7 @@ public class LunWenTests {
public void test2() {
ArrayList<SeparatedClusterConfig> clusterConfigs = new ArrayList<>();
SeparatedClusterConfig separatedClusterConfig = new SeparatedClusterConfig();
separatedClusterConfig.setEdgeNodeId("127.0.0.1:8081");
separatedClusterConfig.setEdgeNodeId("192.168.190.135:8081");
ClusterConfig clusterConfig = new ClusterConfig();
clusterConfig.setId(11111l);
clusterConfig.setOwner("joliu");
......
<?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-weixingsim</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.weixingsim.entity;
import lombok.Data;
/**
* @description 储存有关星间链路的数据
*/
@Data
public class SimData {
//时间间隔,默认值为10
private int jiange = 10;
//todo:这里因该预设默认值
//星间链路带宽
private double bandwidth = 10e9;
//加性高斯白噪声(AWGN)
private double n0 = 5*10e-15;
//信号发射功率
private double pt = 5*10e3;
//信号发射增益系数
private double gt = 52.5;
//信号接收增益系数
private double gr = 37.5;
//载波波长
private double lamda = 0.05;
//星间信道容量最低容限
private double c0 = 10e9;
public double ptGtGr(){
return pt*gt*gr;
}
public double n0B(){
return n0*bandwidth;
}
}
package top.ninwoo.weixingsim.entity;
import lombok.Data;
@Data
public class WeiXingData {
//卫星的名字,之后可能作为增删改查的唯一标识
private String name;
//地心距离
private Float high;
//根据高度计算得出,规定(默认)逆时针为正方向
private Double speed;
private Boolean tag=true;
//测试用一个角度作为初始相位,后期需要三个角度来算出xyz坐标轴
private Float alpha;
private Float beta;
private Float gamma;
//xyz坐标轴数据
private Double xaxis;
private Double yaxis;
private Double zaxis;
//卫星的序列号
private Integer index;
//运行时间
private Integer lastime = 0;
@Override
public String toString(){
return "卫星名是:"+name+";高度是:"+high+"\n"+"x轴坐标:"+xaxis+"\n"+"y轴坐标:"+yaxis+"\n"+"z轴坐标:"+zaxis;
}
}
package top.ninwoo.weixingsim.service;
import top.ninwoo.weixingsim.entity.SimData;
import top.ninwoo.weixingsim.entity.WeiXingData;
import java.util.List;
/**
* 拓扑网络的服务
* 根据Weixing的服务所得到的List转化为二维数组
*/
public interface Toponet {
/**
* @param weiXingDataList WeiXingData对象
* @return 拓扑图的元素
* @description 得到生成拓扑网络中的所有元素名字,需要自动生成所需的ovs,和docker容器一一对应
*/
String[] getAppNames(List<WeiXingData> weiXingDataList);
/**
* @param weiXingDataList WeiXingData对象
* @return 二维数组,也就是拓扑图
* @description 得到网络拓扑形式类似为 app1 app2 app3 ovs1 ovs2 ovs3
*/
int[][] getTopology(List<WeiXingData> weiXingDataList, SimData simData);
/**
* @param a 具体的卫星a
* @param b 具体的卫星b
* @return a,b之间的距离
* @description 计算距离,在getTopology中调用
*/
Double distance(WeiXingData a, WeiXingData b);
Double channelCapacity(WeiXingData a, WeiXingData b,SimData simData);
/**
@description 记录卫星拓扑的变化历史
*/
/**
* @description 写入一个文本文件中,作为拓扑的历史记录
* @param appNames 传入的卫星名字,取前1/2
* @param topo 卫星拓扑图
*/
void history(String[] appNames,int[][] topo);
/**
* @description 删除历史记lu
*/
void delHistory();
}
package top.ninwoo.weixingsim.service;
import top.ninwoo.weixingsim.entity.WeiXingData;
import java.io.File;
import java.util.List;
import java.util.Map;
/**
* 有关卫星的服务
* 1.解析初始文本,得到初始的卫星状态
* 2.将卫星的状态写入一个List中
* 3.增删改查四种基本功能
*/
public interface Weixing {
/**
* @description 从文本中获取卫星的初始状态,但是其中的数据均为string型
* @param file 传入的文本路径
* @return 返回一个List
*/
List<Map> parseTxt(File file);
/**
* @description 将parseTxt中得到的Map转化为初始的卫星数据
* @param wx WeiXingData类
* @param map parseTxt得到的Map
* @return 单个卫星数据
* @throws IllegalAccessException
*/
WeiXingData initWX(Class wx,Map map)throws IllegalAccessException;
List<WeiXingData> initNet(List<Map> maps) throws IllegalAccessException;
/**
* @description 根据卫星高度计算出卫星的速度,取逆时针为正方向。
* @description 和addAxis不同,只需计算一次即可
* @param wx WeiXingData对象
* @return
*/
List<WeiXingData> addSpeed(List<WeiXingData> wx);
/**
* @description 根据角度,高度,速度和间隔时间t获取卫星的坐标数据
* @param wx WeiXingData对象
* @return
*/
List<WeiXingData> addAxis(List<WeiXingData> wx);
/**
* @description 为每个卫星添加序号值
* @param wx 卫星List
* @return bool类型
*/
boolean addIndex(List<WeiXingData> wx);
/**
* @description 确认index和卫星List的对应关系
* @param wx 卫星List
* @return boolean
*/
boolean checkIndex(List<WeiXingData> wx);
/**
* @description 确保卫星列表中中没有名字重复的卫星
* @param wx 卫星List
*/
void checkWX(List<WeiXingData> wx);
/**
增删改查的功能
*/
/**
* @description 根据提供的appName查找对应的序列号
* @param weiXingDataList 卫星List
* @param appName 卫星名字
* @return index 序列号
*/
Integer findindex(List<WeiXingData> weiXingDataList, String appName);
/**
* @description 查找功能
* @param weiXingDataList 传入的卫星列表
* @param appName 查找的卫星名字
* @return 卫星数据
*/
WeiXingData findWX(List<WeiXingData> weiXingDataList, String appName);
/**
* @description 增加一个卫星,这里无需考虑顺序问题,卫星主要靠名字搜索
* @param weiXingDataList 旧的卫星List数据
* @param newWX 新的卫星数据
* @return 新的卫星List数据
*/
List<WeiXingData> addWX(List<WeiXingData> weiXingDataList, WeiXingData newWX);
/**
* @description 删除指定的卫星
* @param weiXingDataList 旧的卫星List数据
* @param appName 指定卫星的名字
* @return 新的卫星List
*/
List<WeiXingData> delWX(List<WeiXingData> weiXingDataList, String appName);
/**
* @description 修改给定卫星的给定值,只能修改高度
* @param weiXingDataList 旧的卫星List
* @param appName 要修改的卫星名字
* @param field 要修改的属性
* @param val 要改成的值,传入为String类型,可在代码中转化为Double类型的值
* @return 新的卫星List
*/
List<WeiXingData> changeWX(List<WeiXingData> weiXingDataList, String appName, String field, String val);
/**
* @description 初始化拓扑
* @param file 传入文件路径
* @return 返回为卫星List
*/
List<WeiXingData> iniTopo(File file) throws IllegalAccessException;
/**
* @description 改变拓扑
* @param wxData 旧的网络
* @param time 抽样时间
* @return 改变后的网络
*/
List<WeiXingData> changeTopo(List<WeiXingData> wxData,int time);
/**
* @description 增减卫星时需要调用
* @param wxData
* @return
*/
List<WeiXingData> initChangeTopo(List<WeiXingData> wxData);
}
package top.ninwoo.weixingsim.service.impl;
import top.ninwoo.weixingsim.entity.SimData;
import top.ninwoo.weixingsim.entity.WeiXingData;
import top.ninwoo.weixingsim.service.Toponet;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
public class ToponetImpl implements Toponet {
@Override
public String[] getAppNames(List<WeiXingData> weiXingDataList) {
//先判断有多少个docker容器,并生成相对应的ovs
int n = weiXingDataList.size();
//创建docker容器和一个ovs的数组
String[] appNames = new String[n+1];
for(int j=0;j<n;j++){
appNames[j] = weiXingDataList.get(j).getName();
}
appNames[n] = "br:"+ "ovs";
return appNames;
}
@Override
public int[][] getTopology(List<WeiXingData> weiXingDataList, SimData simData) {
int n = weiXingDataList.size();
int[][] topu = new int[n+1][n+1];
//先将docker容器和ovs相连如:app1连br:ovs,app2连br:ovs
for (int i = 0; i < n; i++) {
topu[n][i] = 1;
}
//判断docker之间是否相通
for(int a=0;a<n;a++){
for(int b=a+1;b<n;b++){
//通过距离来判断
double channelCapacity = this.channelCapacity(weiXingDataList.get(a),weiXingDataList.get(b),simData);
if(channelCapacity>=simData.getC0()){
topu[b][a] = 1;
}
}
}
return topu;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@Override
public Double distance(WeiXingData a, WeiXingData b) {
Double r;
r = Math.sqrt(Math.pow(a.getXaxis()-b.getXaxis(),2)+Math.pow(a.getYaxis()-b.getYaxis(),2)+Math.pow(a.getZaxis()-b.getZaxis(),2));
return r;
}
@Override
public Double channelCapacity(WeiXingData a, WeiXingData b, SimData sd) {
double r = this.distance(a, b);
double channelCapacity;
channelCapacity = sd.getBandwidth()*Math.log(1+(sd.ptGtGr()/(Math.pow(4*Math.PI*r*sd.getJiange()/sd.getLamda(),2)*sd.n0B())))/Math.log(2);
return channelCapacity;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@Override
public void history(String[] appNames, int[][] topo) {
File file1 = new File("C:\\WorkSpace\\test\\history.txt");
try {
FileWriter fw = new FileWriter(file1,true);
BufferedWriter bw = new BufferedWriter(fw);
//先写上日期标记
SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS" );
Date d= new Date();
String str = sdf.format(d);
bw.write(str + "开始的拓扑结构"+ "\n");
//todo 需要设计排版
int num = appNames.length;
int[][] logic = new int[num][num];
for(int i = 0; i<num;i++){
for(int m =0;m<num;m++){
logic[i][m] = topo[i+num][m+num];
bw.write(logic[i][m] + " ");
bw.flush();
}
bw.write("\n" );
bw.flush();
}
bw.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void delHistory() {
File file = new File("C:\\WorkSpace\\test\\history.txt");
if (file.exists()) {
file.delete();
}
}
}
package top.ninwoo.weixingsim.service.impl;
import top.ninwoo.weixingsim.entity.WeiXingData;
import top.ninwoo.weixingsim.service.Weixing;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class WeixingImpl implements Weixing {
private static double G = 6.754*Math.pow(10,-11);
private static double EARTHMASS = 5.965*Math.pow(10,24);
private static double GM = G*EARTHMASS;
@Override
public List<Map> parseTxt(File file) {
String str;
List<Map> maps = new ArrayList<Map>();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
while((str = br.readLine()) != null){
if(str.equals("-------------")){
//WeiXing initwx = new WeiXing();
Map<String,String> map = new HashMap();
str = br.readLine();
while(str.equals("-------------")==false){
String[] split = str.split("=");
//if(split(0)==initwx.)
map.put(split[0], split[1]);
str = br.readLine();
}
maps.add(map);
}
}
}catch (Exception e){
e.printStackTrace();
}
return maps;
}
@Override
public WeiXingData initWX(Class wx, Map map) throws IllegalAccessException {
WeiXingData initwx = new WeiXingData();
Field[] fields = wx.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
if (field.getType() == Float.class) {
field.set(initwx, Float.parseFloat((String) map.get(field.getName())));
} else if (field.getType() == String.class) {
field.set(initwx, map.get(field.getName()));
}else if (field.getType() == Boolean.class) {
if(map.get(field.getName()).equals("true")){
field.set(initwx, true);
}else{field.set(initwx, false);}
}
}
return initwx;
}
@Override
public List<WeiXingData> initNet(List<Map> maps) throws IllegalAccessException {
List<WeiXingData> initnet = new ArrayList<>();
for(int i=0;i<maps.size();i++){
WeiXingData wx = new WeiXingData();
wx = this.initWX(WeiXingData.class,maps.get(i));
initnet.add(wx);
}
return initnet;
}
@Override
public List<WeiXingData> addSpeed(List<WeiXingData> wx) {
for(int i=0;i<wx.size();i++){
if(wx.get(i).getTag().equals(true)){
wx.get(i).setSpeed(Math.sqrt(GM/Math.pow(wx.get(i).getHigh(),2)));}
else{wx.get(i).setSpeed((-1)*Math.sqrt(GM/Math.pow(wx.get(i).getHigh(),2)));}
}
return wx;
}
@Override
public List<WeiXingData> addAxis(List<WeiXingData> wx) {
for (int i = 0; i < wx.size(); i++) {
Float High = wx.get(i).getHigh();
Double hudu = Math.toRadians(wx.get(i).getSpeed() * wx.get(i).getLastime());
Double Alpha = Math.toRadians(wx.get(i).getAlpha());
Double Beta = Math.toRadians(wx.get(i).getBeta());
Double Gamma = Math.toRadians(wx.get(i).getGamma());
wx.get(i).setXaxis(High * Math.cos(hudu + Gamma) * Math.sin(Beta) + High * Math.sin(hudu + Gamma) * Math.cos(Alpha) * Math.cos(Beta));
wx.get(i).setYaxis(High * Math.cos(hudu + Gamma) * Math.cos(Beta) - High * Math.sin(hudu + Gamma) * Math.cos(Alpha) * Math.sin(Beta));
wx.get(i).setZaxis(High * Math.sin(hudu + Gamma) * Math.sin(Alpha));
}
return wx;
}
@Override
public boolean addIndex(List<WeiXingData> wx) {
for(int i=0;i<wx.size();i++){
wx.get(i).setIndex(i+1);
}
return true;
}
@Override
public boolean checkIndex(List<WeiXingData> wx) {
boolean k=false;
int tag = 0;
for(int m=0;m<wx.size();m++){
if(wx.get(m).getIndex() == m+1){
tag++;
}else{
wx.get(m).setIndex(m+1);
m=m-1;
}
}
if(tag == wx.size()){
k = true;
}
return k;
}
@Override
public void checkWX(List<WeiXingData> wx) {
for(int i=0;i<wx.size();i++){
for(int j=i+1;j<wx.size();j++){
if(wx.get(i).getName().equals(wx.get(j).getName())){
String str = wx.get(i).getName() + i + j;
wx.get(j).setName(str);
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@Override
public Integer findindex(List<WeiXingData> weiXingDataList, String appName) {
Integer index = 0;
for(int i=0;i<weiXingDataList.size();i++){
if(weiXingDataList.get(i).getName().equals(appName)){
index = weiXingDataList.get(i).getIndex();
break;
}
}
return index;
}
@Override
public WeiXingData findWX(List<WeiXingData> weiXingDataList, String appName) {
WeiXingData wxData = null;
int k = findindex(weiXingDataList,appName);
if(k != 0){
wxData = weiXingDataList.get(k-1);
}
return wxData;
}
//增加和删除卫星需要反求(球坐标)
@Override
public List<WeiXingData> addWX(List<WeiXingData> weiXingDataList, WeiXingData newWX) {
//先判断是否已存在相同名字的卫星
WeiXingData wxdata = findWX(weiXingDataList,newWX.getName());
if(wxdata != null){
//加上时间这一唯一标识
newWX.setName(newWX.getName()+System.currentTimeMillis());
}
weiXingDataList.add(newWX);
//修改坐标系
for(int i=0;i<weiXingDataList.size()-1;i++){
float gamma = (float) (weiXingDataList.get(i).getGamma()+weiXingDataList.get(i).getLastime()*weiXingDataList.get(i).getSpeed());
weiXingDataList.get(i).setGamma(gamma);
weiXingDataList.get(i).setLastime(0);
}
this.addIndex(weiXingDataList);
this.checkIndex(weiXingDataList);
return weiXingDataList;
}
@Override
public List<WeiXingData> delWX(List<WeiXingData> weiXingDataList, String appName) {
//找到该卫星
WeiXingData wxdata = findWX(weiXingDataList,appName);
if(wxdata != null){
weiXingDataList.remove(wxdata.getIndex()-1);
}
//修改坐标系
for(int i=0;i<weiXingDataList.size();i++){
float gamma = (float) (weiXingDataList.get(i).getGamma()+weiXingDataList.get(i).getLastime()*weiXingDataList.get(i).getSpeed());
weiXingDataList.get(i).setGamma(gamma);
weiXingDataList.get(i).setLastime(0);
}
this.addIndex(weiXingDataList);
this.checkIndex(weiXingDataList);
return weiXingDataList;
}
//todo 只考虑增加高度一个选项
@Override
public List<WeiXingData> changeWX(List<WeiXingData> weiXingDataList, String appName, String field, String val) {
return null;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@Override
public List<WeiXingData> iniTopo(File file) throws IllegalAccessException {
List<Map> maps = this.parseTxt(file);
List<WeiXingData> wxData = this.initNet(maps);
wxData = this.initChangeTopo(wxData);
return wxData;
}
@Override
public List<WeiXingData> changeTopo(List<WeiXingData> wxData, int time) {
for(int i=0;i<wxData.size();i++){
wxData.get(i).setLastime(time);
}
wxData = this.addAxis(wxData);
this.addIndex(wxData);
this.checkIndex(wxData);
return wxData;
}
@Override
public List<WeiXingData> initChangeTopo(List<WeiXingData> wxData) {
wxData = this.addSpeed(wxData);
wxData = this.addAxis(wxData);
this.checkWX(wxData);
this.addIndex(wxData);
this.checkIndex(wxData);
return wxData;
}
}
......@@ -17,6 +17,7 @@
<module>bishe-client-starter</module>
<module>bishe-test</module>
<module>bishe-case-dis</module>
<module>bishe-weixingsim</module>
</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