Commit 862dea04 authored by ymwang's avatar ymwang

平台设计

parents
/bishe-edge-center/target/
*.iml
/bishe-utils/target/
/bishe-edge-center/log/
/bishe-cloud-center/target/
/bishe-test/target/
/.idea/
/log/
This diff is collapsed.
# 项目描述
基于边缘计算场景的计算和网络融合平台
基于Docker和Open vSwitch开发,可用于构建分布式边缘计算、网络环境仿真等场景。
## 功能概览
* 网络编排
* 网络自动变形
* 函数化寻址
* 逻辑拓扑规划
* 计算资源管理
* 容器动态扩缩容
* 容器计算和网络应用快速构建
## 开发人员简介
* 谢建斌
* 王一鸣
* 刘建瓯
* 张夏童
## 更新说明
1. 使用域名替换配置中的IP,防止多人多次修改配置类并进行提交,避免合并分支时出现冲突的问题。
如果有需要在自己的电脑上进行部署,需要通过修改本机host的方式来修改对应节点的IP。
2. 测试代码
## 项目更新说明
1、迁移分散存储代码
2、迁移分散计算代码
# 范例项目说明
## 注意
这是一个范例项目,请勿在此项目中添加新的业务代码
## 平台应用创建流程
1. 当需要创建一个平台应用时,需要在apps目录中创建对应的module,以便进行应用的管理。
2. 新建module中必须包含以下依赖:
```xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>cnf-client-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
```
其中的`spring-boot-starter-web`可以变更为`spring-boot-starter`,具体根据是否有web应用需求而定。
3. 新建module必须包含以下plugin,以防止打Jar包时出现找不到主类的问题:
```xml
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
```
4. 应用中必须有主类,主类应该符合SpringBoot项目的主类编写方式。
## 警告
* 所有的应用禁止引用除starter之外的平台Jar包,包括:
* cnf-cloud-center
* cnf-edge-center
* cnf-test
* cnf-cloud-ipservice
* 其他基础工具包
<?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>cnf</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cnf-app-demo</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>cnf-client-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package top.ninwoo.cnf.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoMain {
public static void main(String[] args) {
SpringApplication.run(DemoMain.class, args);
}
}
<?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>cnf</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cnf-case-dis</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>cnf-client-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package top.ninwoo;
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);
}
}
package top.ninwoo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import top.ninwoo.bishe.starter.service.NetworkService;
import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@RestController
public class TestController {
@Resource
private NetworkService networkService;
@GetMapping("/start")
public String start(String ip, String t, String selfName, String targetName, float div) {
int i = (int) (40 * div);
networkService.addQos(11111L, targetName, i + "mbit", "100ms");
networkService.addQos(11111L, selfName, (40 - i) +"mbit", "100ms");
runCmd("iperf -c " + ip + " -t " + t);
networkService.addQos(11111L, targetName, "40mbit", "100ms");
return "success";
}
private 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;
}
}
bishe.app.app-name=dis
bishe.app.cloud-url=192.168.0.108:9091
\ No newline at end of file
FROM centos
MAINTAINER Joliu<ljo0412@live.com>
RUN yum install -y http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm &&\
yum install -y iperf iptables tc
RUN yum install -y net-tools.x86_64
RUN echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
RUN mkdir -p /tmp/static
COPY jdk1.8.0_111 jdk1.8.0_111
ENV JAVA_HOME=/jdk1.8.0_111
ENV PATH=$JAVA_HOME/bin:$PATH
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ADD dbc-business-server-0.0.1-SNAPSHOT.jar server.jar
ENTRYPOINT ["java","-jar","server.jar"]
\ No newline at end of file
deb http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial-security main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial-updates main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial-proposed main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial-backports main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial-security main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial-updates main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial-proposed main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial-backports main restricted universe multiverse
<?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>cnf-distributed-business-computing</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cnf-distri-test</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>cnf-client-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.influxdb</groupId>
<artifactId>influxdb-java</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package top.ninwoo.distri.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DistriTestMain {
public static void main(String[] args) {
SpringApplication.run(DistriTestMain.class, args);
}
}
<?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>cnf-distributed-business-computing</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dbc-business-client</artifactId>
<dependencies>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dbc-commom-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dbc-business-utils</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>cnf-client-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--这里写上main方法所在类的路径-->
<configuration>
<mainClass>top.ninwoo.dbc.client.ClientStarter</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package top.ninwoo.dbc.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
//这个注解告诉我们,这是一个springboot项目
@SpringBootApplication
@EnableAsync
public class ClientStarter {
public static void main(String[] args) {
SpringApplication.run(ClientStarter.class,args);
}
}
package top.ninwoo.dbc.client.configure;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@Configuration
@EnableAsync // 开启异步调用 多线程
public class AsyncTaskConfig{
@Bean("taskExecutor")
public Executor taskExecutor() {
// 新建一个任务执行器
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(10);////核心线程池大小
taskExecutor.setMaxPoolSize(30);// 设置最大的线程数量
taskExecutor.setQueueCapacity(25);// 等待队列
taskExecutor.initialize();// 如果不初始化,导致找不到执行器
return taskExecutor;
}
}
package top.ninwoo.dbc.client.configure;
import top.ninwoo.dbc.api.service.DistributedComService;
import top.ninwoo.dbc.utils.FileServiceImplement;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ClientConfigure {
@Primary
@Bean(name="fileRestTemplates")
public RestTemplate restTemplate(ClientHttpRequestFactory factory){
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(5000);//单位为ms
factory.setConnectTimeout(5000);//单位为ms
return factory;
}
@Bean
public DistributedComService distributedComService() {
return new FileServiceImplement();
}
}
package top.ninwoo.dbc.client.configure;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/file/**").addResourceLocations("file:/tmp/statics/");
//registry.addResourceHandler("/file/**").addResourceLocations("file:/F:/resources/static/");
super.addResourceHandlers(registry);
}
}
package top.ninwoo.dbc.client.controller;
import top.ninwoo.dbc.api.po.FileSlice;
import top.ninwoo.dbc.client.service.FileService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class ClientController {
/* @RequestMapping("/helloClient")
@ResponseBody
public String helloClient(){
return "hello,client";
}*/
@Resource
private FileService fileService;
@GetMapping("test1")
public String sendData(String name) {
FileSlice fileSlice = new FileSlice();
fileSlice.setFileBytes(name.getBytes());
fileSlice.setFileId(1111L);
String result = fileService.sendFileSlice("127.0.0.1:8080", fileSlice);
return result;
}
/* @GetMapping("sendFile")
public String sendFile(String name, Long fileId) {
BufferedImage image = fileService.readImage(name);
return fileService.sendFile(fileId, image);
}*/
@GetMapping("getFile")
public String getFile(String name, Long fileId) {
return fileService.getFile(name, fileId);
}
}
package top.ninwoo.dbc.client.controller;
import top.ninwoo.dbc.client.service.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.IOException;
@Controller
public class FileController {
@Autowired
private FileService fileService;
@Value("${dbc.directory.output}")
private String directoryOutput;
/*文件上传*/
// 访问路径为:http://ip:port/upload
@RequestMapping(value = "/upload",method = RequestMethod.GET)
public String upload() {
return "fileUpload";
}
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public String upload(@RequestParam("file") MultipartFile file, @RequestParam("fileId") Long fileId) {
if (!file.isEmpty()) {
try {
//BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(file.getOriginalFilename())));
//FileOutputStream out = new FileOutputStream(new File(file.getOriginalFilename()));
BufferedImage image = ImageIO.read(file.getInputStream());
fileService.sendFile(fileId,image);
/*out.flush();
out.close();*/
} catch (FileNotFoundException e) {
e.printStackTrace();
return "上传失败," + e.getMessage();
} catch (IOException e) {
e.printStackTrace();
return "上传失败," + e.getMessage();
}
return "上传成功!";
} else {
return "上传失败,因为文件是空的.";
}
}
/*文件下载*/
//访问路径为:http://ip:port/download?name=x.jpg&fileId=1111
@RequestMapping("download")
public String view(String name, Long fileId, Model model) {
fileService.getFile(name, fileId);
model.addAttribute("fileName", name);
return "fileDownload";
}
}
package top.ninwoo.dbc.client.service;
import top.ninwoo.bishe.starter.service.NetworkService;
import top.ninwoo.dbc.api.po.*;
import top.ninwoo.dbc.api.service.DistributedComService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.annotation.PostConstruct;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;
//import top.ninwoo.bishe.starter.service.NetworkService;
/**
* 文件服务
*/
@Service
public class FileService{
@Value("${dbc.directory.output}")
private String directoryOutput;
@Qualifier(value="fileRestTemplates")
@Autowired
private RestTemplate restTemplate;
@Autowired
private NetworkService networkService;
@Autowired
private DistributedComService distributedComService;
private String[] ipList=null;
@PostConstruct
public void init() {
ipList = getIpList(11113l,"dbc_server");
System.out.println(Arrays.toString(ipList));
}
/*获取容器ip*/
/* String[] ipList = new String[]{"127.0.0.1:8080","127.0.0.1:8081","127.0.0.1:8082","127.0.0.1:8083","127.0.0.1:8084",
"127.0.0.1:8085","127.0.0.1:8086"};*/
public String[] getIpList(Long clusterId, String appName) {
List<String> ipListS = networkService.getIpListByAppName(clusterId, appName);//用于存储容器ip的list集合
String[] containerIp = new String[ipListS.size()];//将集合中的元素存在数组里,因为下边用的是数组
for (int i = 0; i < ipListS.size(); i++) {
if(!ipListS.isEmpty()){
String ip_tmp = ipListS.get(i);
String[] split_list = ip_tmp.split("/");
containerIp[i] = split_list[0]+":8082";
}
}
return containerIp;
}
/**
* 发送文件到分布式节点
* @param fileId
* @param bufferedImage
* @return
*/
@Async("taskExecutor")
public String sendFile(Long fileId, BufferedImage bufferedImage) {
// 通过集群服务器接口获取当前集群的节点数量
//int sliceNum = ipList.length;
ipList = getIpList(11113l,"dbc_server");
int sliceNum = ipList.length;
// todo 这里需要制定文件的fileId
SplitResult splitResult = distributedComService.fileSplit(bufferedImage, sliceNum);
int ipIndex = 0;
for (FileSlice slice : splitResult.getFileSliceList()) {
slice.setFileId(fileId);
//异常处理
while(true){
try {
sendFileSlice(ipList[ipIndex], slice);
ipIndex = (ipIndex + 1) % ipList.length;
break;
}catch (Exception e){
ipIndex = (ipIndex + 1) % ipList.length;
}
}
}
return "success";
/*for (FileSlice slice : splitResult.getFileSliceList()) {
slice.setFileId(fileId);
String result = sendFileSlice(ipList[ipIndex], slice);
ipIndex = (ipIndex + 1) % ipList.length;
if(result.equals("failed")) {
return "fail";
}
}
return "success";*/
}
// 发送文件切片到目标地址
public String sendFileSlice(String targetIp, FileSlice fileSlice) {
ResponseEntity<String> response = restTemplate.postForEntity("http://" + targetIp + "/data/put/", fileSlice, String.class);
if (!response.getStatusCode().is2xxSuccessful()) {
return "failed!";
}
return response.getBody();
}
public Set<FileSlice> getFileSlice(String targetIp, Long fileId) {
FileSlice[] fileSlices = restTemplate.getForObject("http://" + targetIp + "/data/get/" + fileId, FileSlice[].class);
HashSet<FileSlice> fileSliceSet = new HashSet<>();
fileSliceSet.addAll(Arrays.asList(fileSlices));
return fileSliceSet;
}
public String getFile(String fileName, Long fileId) {
ipList = getIpList(11113l,"dbc_server");
int sliceNum = ipList.length;
//int sliceNum = ipList.length;
Set<FileSlice> result = new HashSet<>();
/* for (String ip : ipList) {
Set<FileSlice> fileSliceSet = getFileSlice(ip, fileId); //将fileId=1的碎片收回,HashSet无序收回
result.addAll(fileSliceSet);
}*/
//异常处理
for (int index = 0; index < ipList.length; index++) {
try {
Set<FileSlice> fileSliceSet = getFileSlice(ipList[index], fileId);
result.addAll(fileSliceSet);
}catch (Exception e){
}
}
List<FileSlice> list = new ArrayList<>(result);
SplitResult splitResult = new SplitResult();
splitResult.setFileSliceList(sortList(list));
ComputingResult computingResult = distributedComService.sliceComputing(splitResult);
MergeResult mergeResult = distributedComService.sliceMerge(computingResult,sliceNum);
try {
saveFile(fileName, mergeResult);
return "success";
} catch (Exception e) {
e.printStackTrace();
return "fail";
}
}
//给List集合里的元素进行排序
public List<FileSlice> sortList(List<FileSlice> list){
//List<FileSlice> list = new ArrayList<FileSlice>();
for (int i = 0; i < list.size(); i++) {
for (int j = list .size()-1; j > i; j--) {
int no= list.get(j).getSliceId();
int no_1= list.get(j-1).getSliceId();
if (no<no_1) {
//互换位置
FileSlice fil = list.get(j);
list.set(j, list.get(j-1));
list.set(j-1, fil );
}
}
}
return list;
}
public void saveFile(String fileName, MergeResult mergeResult) {
BufferedImage images = mergeResult.getImages();
//输出拼接后的图像
try {
ImageIO.write(images, "jpg", new File(directoryOutput + fileName));
} catch (IOException e) {
e.printStackTrace();
}
}
}
#项目端口
server.port=8999
#接入云端的端口设置
bishe.app.app-name=joliu
#bishe.app.cloud-url=192.168.31.156:9090
bishe.app.cloud-url=192.168.81.1:9091
#容器里的挂载目录
dbc.directory.output=/tmp/statics/
#dbc.directory.output=/F:/resources/static/
#thymeleaf
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.servlet.content-type=text/html
spring.thymeleaf.cache=false
# 设置文件上传的大小
spring.servlet.multipart.max-file-size=1024000000000MB
spring.servlet.multipart.max-request-size=1024000000000MB
\ No newline at end of file
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>文件显示</title>
</head>
<body>
<hr/>
<!--<a href="jpg/1.jpg">预览图片</a>-->
<!--<a href="@{/getFile/(fileName=${fileName},fileId=${fileId})}">预览图片</a>-->
<img th:src="file+'/'+${fileName}">
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<hr/>
<form method="POST" enctype="multipart/form-data" action="/upload" id="uploadForm">
<p>
文件:<input type="file" name="file" />
</p>
<p>
文件ID:<input type="text" name="fileId" palcegolder="请输入" />
</p>
<p>
<input type="submit" value="上传" />
</p>
</form>
</body>
</html>
\ 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>cnf-distributed-business-computing</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dbc-business-cloud-cli</artifactId>
<dependencies>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dbc-commom-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dbc-business-utils</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>cnf-client-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--这里写上main方法所在类的路径-->
<configuration>
<mainClass>top.ninwoo.dbc.cloud.client.CloudClientStarter</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package top.ninwoo.dbc.cloud.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//这个注解告诉我们,这是一个springboot项目
@SpringBootApplication
public class CloudClientStarter {
public static void main(String[] args) {
SpringApplication.run(CloudClientStarter.class,args);
}
}
package top.ninwoo.dbc.cloud.client.configure;
import top.ninwoo.dbc.api.service.DistributedComService;
import top.ninwoo.dbc.utils.FileServiceImplement;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class CloudClientCong {
@Primary
@Bean(name="cloudRestTemplates")
public RestTemplate restTemplate(ClientHttpRequestFactory factory){
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(5000);//单位为ms
factory.setConnectTimeout(5000);//单位为ms
return factory;
}
@Bean
public DistributedComService distributedComService() {
return new FileServiceImplement();
}
}
package top.ninwoo.dbc.cloud.client.configure;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/file/**").addResourceLocations("file:/tmp/static/");
//registry.addResourceHandler("/file/**").addResourceLocations("file:/F:/resources/static/");
super.addResourceHandlers(registry);
}
}
package top.ninwoo.dbc.cloud.client.controller;
import org.springframework.stereotype.Controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import top.ninwoo.dbc.cloud.client.service.FileCloService;
import java.io.FileNotFoundException;
import java.io.IOException;
@Controller
public class FilesController {
@Autowired
private FileCloService fileCloService;
@Value("${dbc.directory.output}")
private String directoryOutput;
/*文件上传*/
// 访问路径为:http://ip:port/upload
@RequestMapping(value = "/upload",method = RequestMethod.GET)
public String upload() {
return "fileUpload";
}
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public String upload(@RequestParam("file") MultipartFile file, @RequestParam("fileId") Long fileId) {
if (!file.isEmpty()) {
try {
byte[] fileBytes = file.getBytes();
fileCloService.sendFile(fileId,fileBytes);
/*out.flush();
out.close();*/
} catch (FileNotFoundException e) {
e.printStackTrace();
return "上传失败," + e.getMessage();
} catch (IOException e) {
e.printStackTrace();
return "上传失败," + e.getMessage();
}
return "上传成功!";
} else {
return "上传失败,因为文件是空的.";
}
}
/*文件下载*/
//访问路径为:http://ip:port/download?name=x.jpg&fileId=1111
@RequestMapping("download")
public String view(String name, Long fileId, Model model) {
fileCloService.getFile(name, fileId);
model.addAttribute("fileName", name);
return "fileDownload";
}
}
package top.ninwoo.dbc.cloud.client.service;
import top.ninwoo.dbc.api.po.*;
import top.ninwoo.dbc.api.service.DistributedComService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.*;
@Service
public class FileCloService {
@Value("${dbc.directory.output}")
private String directoryOutput;
@Qualifier(value="cloudRestTemplates")
@Autowired
private RestTemplate restTemplate;
@Autowired
private DistributedComService distributedComService;
String cloudIp = "127.0.0.1:8888";
/**
* 发送文件到云端
* @param fileId
* @param fileBytes
* @return
*/
@Async("taskExecutor")
public String sendFile(Long fileId, byte[] fileBytes) {
// 通过集群服务器接口获取当前集群的节点数量
// todo 这里需要制定文件的fileId
FileCloudSlice fileCloudSlice = new FileCloudSlice();
fileCloudSlice.setFileCloudId(fileId);
fileCloudSlice.setFileByte(fileBytes);
String result = sendFileSlice(cloudIp, fileCloudSlice);
if(result.equals("failed")) {
return "fail";
}
return "success";
}
// 发送文件切片到目标地址
public String sendFileSlice(String targetIp, FileCloudSlice fileCloudSlice) {
ResponseEntity<String> response = restTemplate.postForEntity("http://" + targetIp + "/data/put/", fileCloudSlice, String.class);
if (!response.getStatusCode().is2xxSuccessful()) {
return "failed!";
}
return response.getBody();
}
public Set<FileCloudSlice> getFileSlice(String targetIp, Long fileId) {
FileCloudSlice[] fileCloudSlices = restTemplate.getForObject("http://" + targetIp + "/data/get/" + fileId, FileCloudSlice[].class);
HashSet<FileCloudSlice> fileCloudSliceSet = new HashSet<>();
fileCloudSliceSet.addAll(Arrays.asList(fileCloudSlices));
return fileCloudSliceSet;
}
public String getFile(String fileName, Long fileId) {
Set<FileCloudSlice> result = new HashSet<>();
Set<FileCloudSlice> fileCloudComSet = getFileSlice(cloudIp, fileId);
result.addAll(fileCloudComSet);
List<FileCloudSlice> list = new ArrayList<>(result);
SendResult sendResult = new SendResult();
sendResult.setFileCloudSliceList(list);
CloudComputingResult cloudComputingResult = distributedComService.fileComputing(sendResult);
try {
saveFile(fileName, cloudComputingResult);
return "success";
} catch (Exception e) {
e.printStackTrace();
return "fail";
}
}
public void saveFile(String fileName, CloudComputingResult cloudComputingResult) {
byte[] bytes = cloudComputingResult.getFileComBytes();
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
try {
BufferedImage images = ImageIO.read(bis);
ImageIO.write(images, "jpg", new File(directoryOutput + fileName));
} catch (IOException e) {
e.printStackTrace();
}
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
#项目端口
server.port=8000
#接入云端的端口设置
#bishe.app.app-name=joliu
#bishe.app.cloud-url=192.168.31.156:9090
#容器里的挂载目录
dbc.directory.output=/tmp/static/
#dbc.directory.output=/F:/resources/static/
#thymeleaf
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.servlet.content-type=text/html
spring.thymeleaf.cache=false
# 设置文件上传的大小
spring.servlet.multipart.max-file-size=1024000000000MB
spring.servlet.multipart.max-request-size=1024000000000MB
\ No newline at end of file
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>文件显示</title>
</head>
<body>
<hr/>
<img th:src="file+'/'+${fileName}">
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>文件上传(地面云计算)</title>
</head>
<body>
<hr/>
<form method="POST" enctype="multipart/form-data" action="/upload" id="uploadForm">
<p>
文件:<input type="file" name="file" />
</p>
<p>
文件ID:<input type="text" name="fileId" palcegolder="请输入" />
</p>
<p>
<input type="submit" value="上传" />
</p>
</form>
</body>
</html>
\ 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>cnf-distributed-business-computing</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dbc-business-cloud-server</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dbc-commom-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--这里写上main方法所在类的路径-->
<configuration>
<mainClass>top.ninwoo.dbc.cloud.server.CloudServerStarter</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package top.ninwoo.dbc.cloud.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CloudServerStarter {
public static void main(String[] args) {
SpringApplication.run(CloudServerStarter.class, args);
}
}
package top.ninwoo.dbc.cloud.server.controller;
import org.springframework.web.bind.annotation.*;
import top.ninwoo.dbc.api.po.FileCloudSlice;
import java.util.*;
@RestController
public class CloudServerController {
private static final Map<Long, FileCloudSlice> fileCloudSliceMap = new HashMap<>();
@GetMapping("/hello/{name}/")
public String hello(@PathVariable(name = "name") String name) {
return "Hello " + name;
}
@PostMapping("/data/put/")
public String putData(@RequestBody FileCloudSlice fileCloudSlice) {
if(fileCloudSlice == null) {
return "failed";
}
if(!fileCloudSliceMap.containsKey(fileCloudSlice.getFileCloudId())) {
fileCloudSliceMap.put(fileCloudSlice.getFileCloudId(),fileCloudSlice);
}
fileCloudSliceMap.put(fileCloudSlice.getFileCloudId(),fileCloudSlice);
return "success";
}
@GetMapping("/data/get/{fileId}")
public Set<FileCloudSlice> getData(@PathVariable("fileId") Long fileId) {
try {
return new HashSet<FileCloudSlice>(fileCloudSliceMap.values());
} catch (Exception e) {
throw new RuntimeException("未找到文件");
}
}
}
<?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>cnf-distributed-business-computing</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dbc-business-server</artifactId>
<dependencies>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dbc-commom-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dbc-business-utils</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--这里写上main方法所在类的路径-->
<configuration>
<mainClass>top.ninwoo.dbc.server.ServerStarter</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package top.ninwoo.dbc.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ServerStarter {
public static void main(String[] args) {
SpringApplication.run(ServerStarter.class, args);
}
}
package top.ninwoo.dbc.server.controller;
import org.springframework.web.bind.annotation.*;
import top.ninwoo.dbc.api.po.FileSlice;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@RestController
public class ServerController {
/* @RequestMapping("/hello")
@ResponseBody
public String hello(){
return "hello,springboot";
}*/
private static final Map<Long, Map<Integer, FileSlice>> fileSliceMap = new HashMap<>();
@GetMapping("/hello/{name}/")
public String hello(@PathVariable(name = "name") String name) {
return "Hello " + name;
}
@PostMapping("/data/put/")
public String putData(@RequestBody FileSlice fileSlice) {
if(fileSlice == null) {
return "failed";
}
if(!fileSliceMap.containsKey(fileSlice.getFileId())) {
fileSliceMap.put(fileSlice.getFileId(), new HashMap<>());
}
Map<Integer, FileSlice> sliceMap = fileSliceMap.get(fileSlice.getFileId());
sliceMap.put(fileSlice.getSliceId(), fileSlice);
return "success";
}
@GetMapping("/data/get/{fileId}/{sliceId}")
public FileSlice getData(@PathVariable("fileId") Long fileId, @PathVariable("sliceId") int sliceId) {
try {
return fileSliceMap.get(fileId).get(sliceId);
} catch (Exception e) {
throw new RuntimeException("未找到对应的文件");
}
}
@GetMapping("/data/get/{fileId}")
public Set<FileSlice> getData(@PathVariable("fileId") Long fileId) {
try {
return new HashSet<FileSlice>(fileSliceMap.get(fileId).values());
} catch (Exception e) {
throw new RuntimeException("未找到文件");
}
}
}
<?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>cnf-distributed-business-computing</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dbc-business-utils</artifactId>
<dependencies>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dbc-commom-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package top.ninwoo.dbc.utils;
import top.ninwoo.dbc.api.po.*;
import top.ninwoo.dbc.api.service.DistributedComService;
import org.springframework.stereotype.Service;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Service
public class FileServiceImplement implements DistributedComService {
ImageToArrayUtils itau = new ImageToArrayUtils();
// 图片切分
@Override
public SplitResult fileSplit(BufferedImage bufferedImage, int sliceNum) {
/* // 读入大图
BufferedImage image = itau.readImage(srcOrig);*/
// 分割图片,并将其转化为byte数组
List<byte[]> byteList = itau.imageSplit(bufferedImage,sliceNum);
List<FileSlice> fileSliceList = new ArrayList<>();
for (int i = 0; i < byteList.size(); i++) {
FileSlice fileSlice = new FileSlice();
fileSlice.setFileId(1L);//文件的唯一标识
fileSlice.setSliceId(i);//数据碎片的id
fileSlice.setFileBytes(byteList.get(i));//文件的比特数据
fileSliceList.add(fileSlice);
}
SplitResult splitResult = new SplitResult();
splitResult.setFileSliceList(fileSliceList);
return splitResult;
}
//小图片处理---灰度处理
@Override
public ComputingResult sliceComputing(SplitResult splitResult){
List<FileSlice> fileSliceList = splitResult.getFileSliceList();
List<byte[]> grayByteList = itau.grayImage(fileSliceList);
//把每个小图片转为一个byte数组
//List<byte[]> grayByteList = itau.imageToByte(grayImage);
List<FileSliceComputing> grayfileSliceList = new ArrayList<>();
for (int i = 0; i < grayByteList.size(); i++) {
FileSliceComputing fileSliceComputing = new FileSliceComputing();
fileSliceComputing.setFileId(1L);//文件的唯一标识
fileSliceComputing.setSliceId(i);//数据碎片的id
fileSliceComputing.setFileBytes(grayByteList.get(i));//文件的比特数据
grayfileSliceList.add(fileSliceComputing);
}
ComputingResult computingResult = new ComputingResult();
computingResult.setFileSliceComputingList(grayfileSliceList);
return computingResult;
}
@Override
public MergeResult sliceMerge(ComputingResult computingResult,int sliceNum) {
List<FileSliceComputing> grayfileSliceList = computingResult.getFileSliceComputingList();
BufferedImage finalImg = itau.imageMerge(grayfileSliceList, sliceNum);
MergeResult mergeResult = new MergeResult();
mergeResult.setImages(finalImg);
return mergeResult;
}
public SendResult sendFileSlice(String targetIp, FileSlice fileSlice) {
return null;
}
public FileSlice getFileSlice(String targetIp, Long fileId, int sliceId) {
return null;
}
//地面云计算处理图片
@Override
public CloudComputingResult fileComputing(SendResult sendResult){
List<FileCloudSlice> fileCloudSliceList = sendResult.getFileCloudSliceList();
FileCloudSlice fileCloudSlice = fileCloudSliceList.get(0);
byte[] bytes = fileCloudSlice.getFileByte();
//1、byte[]转为BufferedImage
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
BufferedImage image = null;
try {
image = ImageIO.read(bis);
} catch (IOException e) {
e.printStackTrace();
}
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
//2、BufferedImage进行灰度化处理
int width = image.getWidth();
int height = image.getHeight();
BufferedImage grayImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);//重点,技巧在这个参数BufferedImage.TYPE_BYTE_GRAY
for(int i= 0 ; i < width ; i++){
for(int j = 0 ; j < height; j++){
int rgb = image.getRGB(i, j);
grayImage.setRGB(i, j, rgb);
}
}
//3、灰度化处理后的BufferedImage转为byte[]
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ImageIO.write(grayImage,"jpg",bos);
} catch (IOException e) {
e.printStackTrace();
}
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
byte[] fileComBytes = bos.toByteArray();
CloudComputingResult cloudComputingResult = new CloudComputingResult();
cloudComputingResult.setFileComBytes(fileComBytes);
return cloudComputingResult;
}
}
package top.ninwoo.dbc.utils;
import top.ninwoo.dbc.api.po.FileSlice;
import top.ninwoo.dbc.api.po.FileSliceComputing;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ImageToArrayUtils {
public static int rows = 1 ;
//public static int sliceNum ;
//将image读为BufferedImage
/* public static BufferedImage readImage(String fileName){
//File file = new File(directoryInput+fileName);
File file = new File(fileName);
FileInputStream fis = null;
BufferedImage image = null;
try {
fis = new FileInputStream(file);
image = ImageIO.read(fis);
} catch (Exception e) {
if (fis != null) {
try {
fis.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
throw new RuntimeException("文件读取错误" + e.getMessage());
}
return image;
}*/
public static List<byte[]> imageSplit(BufferedImage images, int sliceNum){
//BufferedImage images = readImage(name);
int cols = sliceNum / rows;
// 计算每个小图的宽度和高度
int chunkWidth = images.getWidth() / cols;
int chunkHeight = images.getHeight() / rows;
int count = 0;
//BufferedImage imgs[] = new BufferedImage[chunks];
BufferedImage imgs[] = new BufferedImage[sliceNum];
for (int x = 0; x < rows; x++) {
for (int y = 0; y < cols; y++) {
//设置小图的大小和类型
imgs[count] = new BufferedImage(chunkWidth, chunkHeight, images.getType());
//写入图像内容
Graphics2D gr = imgs[count++].createGraphics();
gr.drawImage(images, 0, 0,
chunkWidth, chunkHeight,
chunkWidth* y, chunkHeight * x,
chunkWidth * y + chunkWidth,
chunkHeight * x + chunkHeight, null);
gr.dispose();
}
}
//将imgs[]转为相应的byte数组
List<byte[]> byteList = new ArrayList<byte[]>();
for (int i = 0; i < imgs.length; i++) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ImageIO.write(imgs[i],"jpg",bos);
} catch (IOException e) {
e.printStackTrace();
}
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
byteList.add(bos.toByteArray());
}
// 输出小图
/* for (int i = 0; i < imgs.length; i++) {
try {
ImageIO.write(imgs[i], "jpg", new File("F:\\images\\split\\image" + i + ".jpg"));
} catch (IOException e) {
e.printStackTrace();
}
}*/
return byteList;
}
//图片灰度化,同时将grayImage[]转为byte[]数组
public static List<byte[]> grayImage(List<FileSlice> fileSliceList){
BufferedImage images[] = new BufferedImage[fileSliceList.size()];
BufferedImage grayImage[] = new BufferedImage[fileSliceList.size()];
int[] width = new int[fileSliceList.size()];
int[] height = new int[fileSliceList.size()];
for (int i = 0; i < fileSliceList.size(); i++) {
ByteArrayInputStream bis = new ByteArrayInputStream(fileSliceList.get(i).getFileBytes());
try {
images[i] = ImageIO.read(bis);
width[i] = images[i].getWidth();
height[i] = images[i].getHeight();
grayImage[i] = new BufferedImage(width[i], height[i], BufferedImage.TYPE_BYTE_GRAY);//重点,技巧在这个参数BufferedImage.TYPE_BYTE_GRAY
for(int j= 0 ; j < width[i] ; j++){
for(int k = 0 ; k < height[i]; k++){
int rgb = images[i].getRGB(j, k);
grayImage[i].setRGB(j, k, rgb);
}
}
ImageIO.write(grayImage[i], "jpg", new File("\\tmp\\statics\\image" + i + ".jpg"));
} catch (IOException e) {
e.printStackTrace();
}
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
List<byte[]> byteList = new ArrayList<>();
for (int i = 0; i < grayImage.length; i++) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ImageIO.write(grayImage[i],"jpg",bos);
} catch (IOException e) {
e.printStackTrace();
}
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
byteList.add(bos.toByteArray());
}
return byteList;
}
//小图片灰度化后,进行合并
public static BufferedImage imageMerge(List<FileSliceComputing> fileSliceComputingList, int sliceNum){
//byte[]--->BufferedImage
BufferedImage images[] = new BufferedImage[fileSliceComputingList.size()];
for (int i = 0; i < fileSliceComputingList.size(); i++) {
ByteArrayInputStream bis = new ByteArrayInputStream(fileSliceComputingList.get(i).getFileBytes());
try {
images[i] = ImageIO.read(bis);
//ImageIO.write(images[i], "jpg", new File("F:\\images\\grayImage\\image" + i + ".jpg"));
ImageIO.write(images[i], "jpg", new File("\\tmp\\statics\\image" + i + ".jpg"));
} catch (IOException e) {
e.printStackTrace();
}
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
int cols = sliceNum/rows;
int chunks = sliceNum;
int chunkWidth, chunkHeight;
int type;
//读入小图
File[] imgFiles = new File[chunks];
for (int i = 0; i < chunks; i++) {
//imgFiles[i] = new File("F:\\images\\grayImage\\image" + i + ".jpg");
imgFiles[i] = new File("\\tmp\\statics\\image" + i + ".jpg");
}
//创建BufferedImage
BufferedImage[] buffImages = new BufferedImage[chunks];
for (int i = 0; i < chunks; i++) {
try {
buffImages[i] = ImageIO.read(imgFiles[i]);
} catch (IOException e) {
e.printStackTrace();
}
}
type = buffImages[0].getType();
chunkWidth = buffImages[0].getWidth();
chunkHeight = buffImages[0].getHeight();
//设置拼接后图的大小和类型
BufferedImage finalImg = new BufferedImage(chunkWidth * cols, chunkHeight * rows, type);
//写入图像内容
int num = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
finalImg.createGraphics().drawImage(buffImages[num], chunkWidth * j, chunkHeight * i, null);
num++;
}
}
//输出拼接后的图像
/* try {
ImageIO.write(finalImg, "jpeg", new File("D:\\vx-ymwang\\images\\mergeImage\\finalImg.jpg"));
} catch (IOException e) {
e.printStackTrace();
}*/
return finalImg;
}
}
<?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>cnf-distributed-business-computing</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dbc-commom-api</artifactId>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package top.ninwoo.dbc.api.po;
import lombok.Data;
@Data
public class CloudComputingResult {
//private List<FileCloudComputing> fileCloudComputingList;
private byte[] fileComBytes;
}
package top.ninwoo.dbc.api.po;
import lombok.Data;
import java.util.List;
@Data
public class ComputingResult {
private List<FileSliceComputing> fileSliceComputingList;
}
package top.ninwoo.dbc.api.po;
import lombok.Data;
@Data
public class FileCloudComputing {
// 文件的唯一id
private Long fileCloudId;
// 文件的比特数据
private byte[] fileBytes;
}
package top.ninwoo.dbc.api.po;
import lombok.Data;
@Data
public class FileCloudSlice {
// 发送到云端的文件的唯一id
private Long fileCloudId;
// 文件的比特数据
private byte[] fileByte;
}
package top.ninwoo.dbc.api.po;
import lombok.Data;
/**
* @author ymwang
* 文件的切片类
*/
@Data
public class FileSlice {
// 文件的唯一id
private Long fileId;
// 切片的id,唯一且有顺序要求
private int sliceId;
// 文件的比特数据
private byte[] fileBytes;
}
package top.ninwoo.dbc.api.po;
import lombok.Data;
/**
* @author ymwang
* 文件的切片类
*/
@Data
public class FileSliceComputing {
// 文件的唯一id
private Long fileId;
// 切片的id,唯一且有顺序要求
private int sliceId;
// 文件的比特数据
private byte[] fileBytes;
}
package top.ninwoo.dbc.api.po;
import lombok.Data;
import java.awt.image.BufferedImage;
@Data
public class MergeResult {
//private byte[] fileBytes;
private BufferedImage images;
}
package top.ninwoo.dbc.api.po;
import lombok.Data;
import java.util.List;
@Data
public class SendResult {
//发送到云端的文件的包装
private List<FileCloudSlice> fileCloudSliceList;
}
package top.ninwoo.dbc.api.po;
import lombok.Data;
import java.util.List;
@Data
public class SplitResult {
private List<FileSlice> fileSliceList;
}
package top.ninwoo.dbc.api.service;
import top.ninwoo.dbc.api.po.*;
import java.awt.image.BufferedImage;
public interface DistributedComService {
/**
* 文件切片
* @param bufferedImage 图片
* @param sliceNum 切片数量
* @return
*/
SplitResult fileSplit(BufferedImage bufferedImage, int sliceNum);
//SplitResult fileSplit(String fileName, int sliceNum);
/**
* 切片处理
* @param splitResult
* @return
*/
ComputingResult sliceComputing(SplitResult splitResult);
/**
* 切片聚合接口
* @param computingResult
* @param sliceNum 切片数量
* @return
*/
MergeResult sliceMerge(ComputingResult computingResult, int sliceNum);
/**
* 切片发送服务
* @param targetIp
* @param fileSlice
* @return
*/
SendResult sendFileSlice(String targetIp, FileSlice fileSlice);
/**
* 指定地址的ip获取切片
* @param targetIp
* @param fileId
* @param sliceId
* @return
*/
FileSlice getFileSlice(String targetIp, Long fileId, int sliceId);
/**
* 切片在云端做计算的接口
* @param sendResult 文件的比特数据
* @return
*/
CloudComputingResult fileComputing(SendResult sendResult);
}
<?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>cnf</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<!--删掉root文件下的src文件夹后,添加的语句-->
<packaging>pom</packaging>
<modules>
<module>dbc-business-client</module>
<module>dbc-business-cloud-cli</module>
<module>dbc-business-cloud-server</module>
<module>dbc-business-server</module>
<module>dbc-business-utils</module>
<module>dbc-commom-api</module>
<module>cnf-distri-test</module>
</modules>
<artifactId>cnf-distributed-business-computing</artifactId>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dbc-commom-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dbc-business-client</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${springboot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${springboot.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>${thymeleaf.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<!-- <version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>-->
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/
FROM centos
MAINTAINER Joliu<ljo0412@live.com>
RUN yum install -y http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm &&\
yum install -y iperf iptables tc
RUN yum install -y net-tools.x86_64
RUN echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
RUN mkdir -p /tmp/static
COPY jdk1.8.0_111 jdk1.8.0_111
ENV JAVA_HOME=/jdk1.8.0_111
ENV PATH=$JAVA_HOME/bin:$PATH
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ADD dfs-transfer-server-0.0.1-SNAPSHOT.jar server.jar
ENTRYPOINT ["java","-jar","server.jar"]
\ No newline at end of file
deb http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial-security main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial-updates main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial-proposed main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial-backports main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial-security main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial-updates main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial-proposed main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu-old-releases/ubuntu/ xenial-backports main restricted universe multiverse
<?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>cnf-distributed-file-transfer</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dfs-common-api</artifactId>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.ujmp</groupId>
<artifactId>ujmp-core</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package top.ninwoo.commonapi.po;
import lombok.Data;
/**
* @author ljo
* 文件的切片类
*/
@Data
public class FileSlice {
// 文件的唯一id
private Long fileId;
// 切片的id,唯一且有顺序要求
private int sliceId;
// 索引的偏移量
private Long start;
// 文件比特数据的有效长度 - 这个值设置的原因是 fileBytes可能有补位的情况。
private int size;
/* private Long size;*/
// 文件的比特数据
private byte[] fileBytes;
}
package top.ninwoo.commonapi.po;
import lombok.Builder;
import lombok.Getter;
import java.math.BigDecimal;
@Builder
@Getter
public class Fraction {
private BigDecimal mole;
private BigDecimal deno;
private boolean negate = false;
}
package top.ninwoo.commonapi.po;
import lombok.Data;
@Data
public class MergeResult extends Result {
private byte[] fileBytes;
public byte[] getFileBytes() {
return fileBytes;
}
public void setFileBytes(byte[] fileBytes) {
this.fileBytes = fileBytes;
}
}
package top.ninwoo.commonapi.po;
import lombok.Data;
@Data
public class Result {
private boolean success;
private String errMsg;
}
package top.ninwoo.commonapi.po;
import lombok.Data;
@Data
public class SendResult extends Result {
}
package top.ninwoo.commonapi.po;
import lombok.Data;
import java.util.List;
@Data
public class SplitResult extends Result {
private List<FileSlice> fileSliceList;
}
package top.ninwoo.commonapi.service;
import top.ninwoo.commonapi.po.FileSlice;
import top.ninwoo.commonapi.po.MergeResult;
import top.ninwoo.commonapi.po.SendResult;
import top.ninwoo.commonapi.po.SplitResult;
/**
* @author ljo
* 用于发送文件的接口
*/
public interface TransferService {
/**
* 文件切片
* @param fileBytes
* @param sliceNum 切片数量(经过冗余之后的数量)
* @param origNum 原始数组切分的数量
* @return
*/
SplitResult fileSplit(byte[] fileBytes, int sliceNum, int origNum);
/**
* 切片聚合接口
* @param splitResult
* @param sliceNum 切片数量(经过冗余之后的数量)
* @param sliceNum origNum 原始数组切分的数量
* @return
*/
MergeResult sliceMerge(SplitResult splitResult, int sliceNum, int origNum);
/**
* 切片发送服务
* @param targetIp
* @param fileSlice
* @return
*/
SendResult sendFileSlice(String targetIp, FileSlice fileSlice);
/**
* 指定地址的ip获取切片
* @param targetIp
* @param fileId
* @param sliceId
* @return
*/
FileSlice getFileSlice(String targetIp, Long fileId, int sliceId);
}
<?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>cnf-distributed-file-transfer</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dfs-file-utils</artifactId>
<dependencies>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dfs-common-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.ujmp/ujmp-core -->
<dependency>
<groupId>org.ujmp</groupId>
<artifactId>ujmp-core</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package top.ninwoo.app.dfs.service;
import top.ninwoo.commonapi.po.*;
import top.ninwoo.commonapi.service.TransferService;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
public class FileTransferServiceImpl implements TransferService {
@Override
public SplitResult fileSplit(byte[] fileBytes, int sliceNum, int origNum) {
EncodeAndDecode encode = new EncodeAndDecode();
/*1、将传进来的byte数组拆分,也即原数组等大小拆分,同时转为BigInteger型,并将其转置成m*1型*/
BigInteger[][] filebytesBigInt = encode.fileByteSplit(fileBytes,origNum);
//encode.printMartixInt(filebytesBigInt);
/*2 将filebytes(BigInteger型)转为BigDecimal型*/
BigDecimal[][] filebytesBigDec = encode.bigIntToDecimal(filebytesBigInt);
/*3、创建编码矩阵---上半部分的单位矩阵+下半部分的范德蒙矩阵*/
BigDecimal[][] encodeDecimal = encode.encodeMatrix(origNum,sliceNum-origNum);
/*4、生成编码数据块encodeDataMatrix(BigInteger型数组(m+shards)*1)*/
//两个BigInteger型数组相乘
BigDecimal[][] encodeDataMatrixBigDec = encode.encodeData(encodeDecimal,filebytesBigDec);
/*5、将BigDecimal转为BigInteger*/
BigInteger[] encodeDataMatrixTran = encode.bigDecToInt(encodeDataMatrixBigDec);
/*6、将数据碎片数组包装成方法返回值类型*/
List<FileSlice> fileSliceList = new ArrayList<>();
for (int j = 0; j < encodeDataMatrixTran.length; j++) {
FileSlice fileSlice = new FileSlice();
fileSlice.setFileId(1L);//文件的唯一标识
fileSlice.setSliceId(j);//数据碎片的id
fileSlice.setSize(fileBytes.length);//文件比特数据的有效长度
fileSlice.setFileBytes(encodeDataMatrixTran[j].toByteArray());//文件的比特数据
fileSliceList.add(fileSlice);
}
SplitResult splitResult = new SplitResult();
splitResult.setFileSliceList(fileSliceList);
return splitResult;//这是最后要返回的东西,也就是图片分割的结果
}
@Override
public MergeResult sliceMerge(SplitResult splitResult, int sliceNum, int origNum) {
EncodeAndDecode encode = new EncodeAndDecode();
List<FileSlice> fileSliceListInput = splitResult.getFileSliceList();
BigInteger[][] encodeDataBigInt = new BigInteger[fileSliceListInput.size()][1]; //从fileSliceList中任取m个数据碎片---7
for (int i = 0; i < fileSliceListInput.size(); i++) {
encodeDataBigInt[i][0] = new BigInteger(fileSliceListInput.get(i).getFileBytes());
}
//encodeDataBigInt转为encodeDataBigDec
BigDecimal[][] encodeDataBigDec = encode.bigIntToDecimal(encodeDataBigInt);
/*从编码矩阵中取对应的行,形成新的encodeMatrixNew*/
BigDecimal[][] encodeMatrix = encode.encodeMatrix(origNum,sliceNum-origNum);
BigDecimal[][] encodeMatrixNew = new BigDecimal[fileSliceListInput.size()][fileSliceListInput.size()];
for (int i = 0; i < encodeMatrixNew.length; i++) {
for (int j = 0; j < encodeMatrixNew[0].length; j++) {
encodeMatrixNew[i][j] = encodeMatrix[fileSliceListInput.get(i).getSliceId()][j];
}
}
/*求新的编码矩阵的逆矩阵*/
Fraction[][] encodeMatrixNewInv = encode.getReverseMartrix(encodeMatrixNew);
/*两矩阵相乘*/
BigDecimal[][] origDataBigDec = encode.encodeData(encodeMatrixNewInv,encodeDataBigDec);
/*BigDecimal转BigInteger*/
BigInteger[] origDataBigInt = encode.bigDecToInt(origDataBigDec);
/*origDataBigInt型数组转为byte数组(origDataBytes)*/
byte[] fileByteDest = encode.bigIntegerToBytes(origDataBigInt,fileSliceListInput.get(0).getSize());
MergeResult mergeResult = new MergeResult();
mergeResult.setFileBytes(fileByteDest);
return mergeResult;
}
@Override
public SendResult sendFileSlice(String targetIp, FileSlice fileSlice) {
return null;
}
@Override
public FileSlice getFileSlice(String targetIp, Long fileId, int sliceId) {
return null;
}
}
\ 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>cnf-distributed-file-transfer</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dfs-transfer-client</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dfs-common-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dfs-file-utils</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>cnf-client-starter</artifactId>
<!--<version>1.0-SNAPSHOT</version>-->
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--这里写上main方法所在类的路径-->
<configuration>
<mainClass>top.ninwoo.app.dfs.client.ClientStart</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package top.ninwoo.app.dfs.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
public class ClientStart {
public static void main(String[] args) {
SpringApplication.run(ClientStart.class, args);
}
}
\ No newline at end of file
package top.ninwoo.app.dfs.client.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@Configuration
@EnableAsync // 开启异步调用 多线程
public class AsyncTaskConfig{
@Bean("taskExecutor")
public Executor taskExecutor() {
// 新建一个任务执行器
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(10);////核心线程池大小
taskExecutor.setMaxPoolSize(30);// 设置最大的线程数量
taskExecutor.setQueueCapacity(25);// 等待队列
taskExecutor.initialize();// 如果不初始化,导致找不到执行器
return taskExecutor;
}
}
package top.ninwoo.app.dfs.client.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import top.ninwoo.app.dfs.service.FileTransferServiceImpl;
import top.ninwoo.commonapi.service.TransferService;
@Configuration
public class MainConfig {
@Primary
@Bean(name="fileRestTemplate")
public RestTemplate restTemplate(ClientHttpRequestFactory factory){
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(20000);//单位为ms
factory.setConnectTimeout(20000);//单位为ms
return factory;
}
@Bean
public TransferService transferService() {
return new FileTransferServiceImpl();
}
}
package top.ninwoo.app.dfs.client.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/file/**").addResourceLocations("file:/tmp/static/");
//registry.addResourceHandler("/file/**").addResourceLocations("file:/F:/resources/static");
super.addResourceHandlers(registry);
}
}
package top.ninwoo.app.dfs.client.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import top.ninwoo.app.dfs.client.service.FileService;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
@Controller
public class FileController {
@Autowired
private FileService fileService;
/*文件上传*/
// 访问路径为:http://ip:port/upload
@RequestMapping(value = "/upload", method = RequestMethod.GET)
public String upload() {
return "fileUpload";
}
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public String upload(@RequestParam("file") MultipartFile file, @RequestParam("fileId") Long fileId) {
if (!file.isEmpty()) {
try {
//BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(file.getOriginalFilename())));
FileOutputStream out = new FileOutputStream(new File(file.getOriginalFilename()));
byte[] bytes = file.getBytes();
fileService.sendFile(fileId,bytes);
//out.write(file.getBytes());
out.flush();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
return "上传失败," + e.getMessage();
} catch (IOException e) {
e.printStackTrace();
return "上传失败," + e.getMessage();
}
return "上传成功!";
} else {
return "上传失败,因为文件是空的.";
}
}
/*文件下载*/
// 访问路径为:http://ip:port/upload
/* @RequestMapping(value = "/view", method = RequestMethod.GET)
public String download() {
return "fileFind";
}*/
/*文件下载*/
//访问路径为:http://ip:port/download?name=x.jpg&fileId=1111
@RequestMapping("download")
public String view(String name, Long fileId, Model model) {
fileService.getFile(name, fileId);
model.addAttribute("fileName", name);
return "fileDownload";
}
}
package top.ninwoo.app.dfs.client.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.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import top.ninwoo.app.dfs.client.service.FileService;
import top.ninwoo.commonapi.po.FileSlice;
@RestController
public class TestController {
@Autowired
private FileService fileService;
@RequestMapping("/hello")
@ResponseBody
public String hello(){
return "hello,SpringBoot";
}
@GetMapping("test1")
public String sendData(String name) {
FileSlice fileSlice = new FileSlice();
fileSlice.setFileBytes(name.getBytes());
fileSlice.setFileId(1111L);
fileSlice.setSize(name.getBytes().length);
fileSlice.setStart(0L);
/*String result = fileService.sendFileSlice("127.0.0.1:8080", fileSlice);*/
String result = fileService.sendFileSlice("172.17.3", fileSlice);
return result;
}
/* @GetMapping("sendFile")
public String sendFile(String name, Long fileId) {
byte[] bytes = fileService.readFile(name);
return fileService.sendFile(fileId, bytes);
}*/
@GetMapping("getFile")
public String getFile(String name, Long fileId) {
return fileService.getFile(name, fileId);
}
}
package top.ninwoo.app.dfs.client.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import top.ninwoo.bishe.starter.service.NetworkService;
import top.ninwoo.commonapi.po.FileSlice;
import top.ninwoo.commonapi.po.MergeResult;
import top.ninwoo.commonapi.po.SplitResult;
import top.ninwoo.commonapi.service.TransferService;
import javax.annotation.PostConstruct;
import java.io.FileOutputStream;
import java.util.*;
/**
* 文件服务
*/
@Service
public class FileService {
@Value("${dfs.directory.output}")
private String directoryOutput;
@Qualifier(value="fileRestTemplate")
@Autowired
private RestTemplate restTemplate;
@Autowired
private NetworkService networkService;
@Autowired
private TransferService transferService;
private String[] ipList=null;
@PostConstruct
public void init() {
ipList = getIpList(11112l,"dfs_server");
System.out.println(Arrays.toString(ipList));
}
/*获取容器ip*/
/* String[] ipList = new String[]{"127.0.0.1:8080","127.0.0.1:8081","127.0.0.1:8082","127.0.0.1:8083","127.0.0.1:8084",
"127.0.0.1:8085","127.0.0.1:8086","127.0.0.1:8087", "127.0.0.1:8088","127.0.0.1:8089",
"127.0.0.1:8180","127.0.0.1:8181","127.0.0.1:8182","127.0.0.1:8183","127.0.0.1:8184"};*/
public String[] getIpList(Long clusterId, String appName) {
List<String> ipListS = networkService.getIpListByAppName(clusterId, appName);//用于存储容器ip的list集合
String[] containerIp = new String[ipListS.size()];//将集合中的元素存在数组里,因为下边用的是数组
for (int i = 0; i < ipListS.size(); i++) {
if(!ipListS.isEmpty()){
String ip_tmp = ipListS.get(i);
String[] split_list = ip_tmp.split("/");
containerIp[i] = split_list[0]+":8084";
}
}
return containerIp;
}
/**
* 发送文件到分布式节点
* @param fileId
* @param fileBytes
* @return
*/
@Async("taskExecutor")
public String sendFile(Long fileId, byte[] fileBytes) {
// 通过集群服务器接口获取当前集群的节点数量
ipList = this.getIpList(11112l,"dfs_server");
int sliceNum = ipList.length;
//int sliceNum = 30;
int origNum = 6;
// todo 这里需要制定文件的fileId
SplitResult splitResult = transferService.fileSplit(fileBytes, sliceNum, origNum);
//顺序,依次发送碎片到各个服务器
int ipIndex = 0;
for (FileSlice slice : splitResult.getFileSliceList()) {
slice.setFileId(fileId);
while(true){
try {
sendFileSlice(ipList[ipIndex], slice);
ipIndex = (ipIndex + 1) % ipList.length;
break;
}catch (Exception e){
ipIndex = (ipIndex + 1) % ipList.length;
}
}
}
return "success";
}
// 发送文件切片到目标地址
public String sendFileSlice(String targetIp, FileSlice fileSlice) {
ResponseEntity<String> response = restTemplate.postForEntity("http://" + targetIp + "/data/put/", fileSlice, String.class);
if (!response.getStatusCode().is2xxSuccessful()) {
return "failed!";
}
return response.getBody();
}
public Set<FileSlice> getFileSlice(String targetIp, Long fileId) {
FileSlice[] fileSlices = restTemplate.getForObject("http://" + targetIp + "/data/get/" + fileId, FileSlice[].class);
HashSet<FileSlice> fileSliceSet = new HashSet<>();
fileSliceSet.addAll(Arrays.asList(fileSlices));
return fileSliceSet;
}
public String getFile(String fileName, Long fileId) {
ipList = this.getIpList(11112l,"dfs_server");
int sliceNum = ipList.length;
//int sliceNum = 30;
int origNum = 6;
Set<FileSlice> result = new HashSet<>();
//异常处理
for (int index = 0; index < ipList.length; index++) {
try {
Set<FileSlice> fileSliceSet = getFileSlice(ipList[index], fileId);
result.addAll(fileSliceSet);
}catch (Exception e){
}
if(result.size() >= origNum) {
break;
}
}
//System.out.println("result:"+result.size());
/*for (String ip : ipList) {
Set<FileSlice> fileSliceSet = getFileSlice(ip, fileId);
result.addAll(fileSliceSet);
if(result.size() >= origNum) {
break;
}
}*/
if(result.size() < origNum) {
throw new RuntimeException("不可恢复的文件");
}
SplitResult splitResult = new SplitResult();
splitResult.setFileSliceList(new ArrayList<>(result));
MergeResult mergeResult = transferService.sliceMerge(splitResult, sliceNum, origNum);
try {
saveFile(fileName, mergeResult);
return "success";
} catch (Exception e) {
e.printStackTrace();
return "fail";
}
}
public void saveFile(String fileName, MergeResult mergeResult) throws Exception {
byte[] fileByte = mergeResult.getFileBytes();
//将字节数组转为文件----可以验证读取图片到byte数组是否正确
FileOutputStream fos = new FileOutputStream(directoryOutput + fileName);
/*FileOutputStream fos = new FileOutputStream("F:/恢复.PNG");*/
fos.write(fileByte, 0, fileByte.length);
fos.close();
}
}
\ No newline at end of file
server.port=8099
bishe.app.app-name=joliu
#bishe.app.cloud-url=192.168.31.156:9090
bishe.app.cloud-url=192.168.81.1:9091
dfs.directory.output=/tmp/static/
#thymeleaf
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.servlet.content-type=text/html
spring.thymeleaf.cache=false
# ļϴĴС
spring.servlet.multipart.max-file-size=1024000000000MB
spring.servlet.multipart.max-request-size=1024000000000MB
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>文件显示</title>
</head>
<body>
<hr/>
<!--<a href="jpg/1.jpg">预览图片</a>-->
<!--<a href="@{/getFile/(fileName=${fileName},fileId=${fileId})}">预览图片</a>-->
<img th:src="file+'/'+${fileName}">
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<hr/>
<form method="POST" enctype="multipart/form-data" action="/upload" id="uploadForm">
<p>
文件:<input type="file" name="file" />
</p>
<p>
文件ID:<input type="text" name="fileId" palcegolder="请输入" />
</p>
<p>
<input type="submit" value="上传" />
</p>
</form>
</body>
</html>
\ 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>cnf-distributed-file-transfer</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dfs-transfer-server</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dfs-common-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.ujmp/ujmp-core -->
<dependency>
<groupId>org.ujmp</groupId>
<artifactId>ujmp-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--这里写上main方法所在类的路径-->
<configuration>
<mainClass>top.ninwoo.app.dfs.ServerStarter</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package top.ninwoo.app.dfs;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ServerStarter {
public static void main(String[] args) {
SpringApplication.run(ServerStarter.class, args);
}
}
package top.ninwoo.app.dfs.controller;
import org.springframework.web.bind.annotation.*;
import top.ninwoo.commonapi.po.FileSlice;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@RestController
public class FileSliceTranferController {
private static final Map<Long, Map<Integer, FileSlice>> fileSliceMap = new HashMap<>();
@GetMapping("/hello/{name}/")
public String hello(@PathVariable(name = "name") String name) {
return "Hello " + name;
}
@PostMapping("/data/put/")
public String putData(@RequestBody FileSlice fileSlice) {
if(fileSlice == null) {
return "failed";
}
if(!fileSliceMap.containsKey(fileSlice.getFileId())) {
fileSliceMap.put(fileSlice.getFileId(), new HashMap<>());
}
Map<Integer, FileSlice> sliceMap = fileSliceMap.get(fileSlice.getFileId());
sliceMap.put(fileSlice.getSliceId(), fileSlice);
return "success";
}
@GetMapping("/data/get/{fileId}/{sliceId}")
public FileSlice getData(@PathVariable("fileId") Long fileId, @PathVariable("sliceId") int sliceId) {
try {
return fileSliceMap.get(fileId).get(sliceId);
} catch (Exception e) {
throw new RuntimeException("未找到对应的文件");
}
}
@GetMapping("/data/get/{fileId}")
public Set<FileSlice> getData(@PathVariable("fileId") Long fileId) {
try {
return new HashSet<FileSlice>(fileSliceMap.get(fileId).values());
} catch (Exception e) {
throw new RuntimeException("未找到文件");
}
}
}
\ No newline at end of file
package top.ninwoo.app.dfs.repository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import top.ninwoo.commonapi.po.FileSlice;
import java.io.*;
import java.util.Arrays;
@Repository
@Slf4j
public class FileSliceRepository {
/*private static final String PATH = "E:\\code\\bs-app\\distributed-file-transfer\\output\\";*/
private static final String PATH = "F:\\output\\";
private static final int DEFAULT_LENGTH = 1000;
public FileSlice getFileSlice(Long fileId, int sliceId) {
FileSlice fileSlice = new FileSlice();
fileSlice.setSliceId(sliceId);
fileSlice.setFileId(fileId);
fileSlice.setStart(0L);
ByteArrayOutputStream out = null;
try {
InputStream in = new FileInputStream(PATH + fileId + "-" + sliceId + ".data");
out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024 * 4];
int n = 0;
while ((n = in.read(buffer)) != -1) {
out.write(buffer, 0, n);
}
} catch (Exception e) {
e.printStackTrace();
}
byte[] bytes = Arrays.copyOf(out.toByteArray(), DEFAULT_LENGTH);
fileSlice.setFileBytes(bytes);
fileSlice.setSize(out.toByteArray().length);
return fileSlice;
}
public void saveFileSlice(FileSlice slice) {
OutputStream os = null;
try {
File file = new File(PATH + slice.getFileId() + "-" + slice.getSliceId() + ".data");
file.createNewFile();
os = new FileOutputStream(file);
byte[] targetBytes = Arrays.copyOf(slice.getFileBytes(), slice.getSize());
os.write(targetBytes);
os.flush();
} catch (Exception e) {
log.error("save fileSlice Error:{}", e.getMessage());
} finally {
if (os != null) {
try {
os.close();
} catch (Exception e) {
log.error("file close error!");
}
}
}
}
}
package top.ninwoo.app.dfs.service;
import org.springframework.stereotype.Service;
import top.ninwoo.app.dfs.util.Fraction;
import top.ninwoo.commonapi.po.FileSlice;
import top.ninwoo.commonapi.po.MergeResult;
import top.ninwoo.commonapi.po.SendResult;
import top.ninwoo.commonapi.po.SplitResult;
import top.ninwoo.commonapi.service.TransferService;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
@Service
public class FileTransferServiceImpl implements TransferService {
@Override
public SplitResult fileSplit(byte[] fileBytes, int sliceNum, int origNum) {
EncodeAndDecode encode = new EncodeAndDecode();
/*1、将传进来的byte数组拆分,也即原数组等大小拆分,同时转为BigInteger型,并将其转置成m*1型*/
BigInteger[][] filebytesBigInt = encode.fileByteSplit(fileBytes,origNum);
//encode.printMartixInt(filebytesBigInt);
/*2 将filebytes(BigInteger型)转为BigDecimal型*/
BigDecimal[][] filebytesBigDec = encode.bigIntToDecimal(filebytesBigInt);
/*3、创建编码矩阵---上半部分的单位矩阵+下半部分的范德蒙矩阵*/
BigDecimal[][] encodeDecimal = encode.encodeMatrix(origNum,sliceNum-origNum);
/*4、生成编码数据块encodeDataMatrix(BigInteger型数组(m+shards)*1)*/
//两个BigInteger型数组相乘
BigDecimal[][] encodeDataMatrixBigDec = encode.encodeData(encodeDecimal,filebytesBigDec);
/*5、将BigDecimal转为BigInteger*/
BigInteger[] encodeDataMatrixTran = encode.bigDecToInt(encodeDataMatrixBigDec);
/*6、将数据碎片数组包装成方法返回值类型*/
List<FileSlice> fileSliceList = new ArrayList<>();
for (int j = 0; j < encodeDataMatrixTran.length; j++) {
FileSlice fileSlice = new FileSlice();
fileSlice.setFileId(1L);//文件的唯一标识
fileSlice.setSliceId(j);//数据碎片的id
fileSlice.setSize(fileBytes.length);//文件比特数据的有效长度
fileSlice.setFileBytes(encodeDataMatrixTran[j].toByteArray());//文件的比特数据
fileSliceList.add(fileSlice);
}
SplitResult splitResult = new SplitResult();
splitResult.setFileSliceList(fileSliceList);
return splitResult;//这是最后要返回的东西,也就是图片分割的结果
}
@Override
public MergeResult sliceMerge(SplitResult splitResult, int sliceNum, int origNum) {
EncodeAndDecode encode = new EncodeAndDecode();
List<FileSlice> fileSliceListInput = splitResult.getFileSliceList();
BigInteger[][] encodeDataBigInt = new BigInteger[fileSliceListInput.size()][1]; //从fileSliceList中任取m个数据碎片---7
for (int i = 0; i < fileSliceListInput.size(); i++) {
encodeDataBigInt[i][0] = new BigInteger(fileSliceListInput.get(i).getFileBytes());
}
//encodeDataBigInt转为encodeDataBigDec
BigDecimal[][] encodeDataBigDec = encode.bigIntToDecimal(encodeDataBigInt);
/*从编码矩阵中取对应的行,形成新的encodeMatrixNew*/
BigDecimal[][] encodeMatrix = encode.encodeMatrix(origNum,sliceNum-origNum);
BigDecimal[][] encodeMatrixNew = new BigDecimal[fileSliceListInput.size()][fileSliceListInput.size()];
for (int i = 0; i < encodeMatrixNew.length; i++) {
for (int j = 0; j < encodeMatrixNew[0].length; j++) {
encodeMatrixNew[i][j] = encodeMatrix[fileSliceListInput.get(i).getSliceId()][j];
}
}
/*求新的编码矩阵的逆矩阵*/
Fraction[][] encodeMatrixNewInv = encode.getReverseMartrix(encodeMatrixNew);
/*两矩阵相乘*/
BigDecimal[][] origDataBigDec = encode.encodeData(encodeMatrixNewInv,encodeDataBigDec);
/*BigDecimal转BigInteger*/
BigInteger[] origDataBigInt = encode.bigDecToInt(origDataBigDec);
/*origDataBigInt型数组转为byte数组(origDataBytes)*/
byte[] fileByteDest = encode.bigIntegerToBytes(origDataBigInt,fileSliceListInput.get(0).getSize());
MergeResult mergeResult = new MergeResult();
mergeResult.setFileBytes(fileByteDest);
return mergeResult;
}
@Override
public SendResult sendFileSlice(String targetIp, FileSlice fileSlice) {
return null;
}
@Override
public FileSlice getFileSlice(String targetIp, Long fileId, int sliceId) {
return null;
}
}
package top.ninwoo.app.dfs.util;
import lombok.Builder;
import lombok.Getter;
import java.math.BigDecimal;
@Builder
@Getter
public class Fraction {
private BigDecimal mole;
private BigDecimal deno;
private boolean negate = false;
}
<?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>cnf</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cnf-distributed-file-transfer</artifactId>
<packaging>pom</packaging>
<modules>
<module>dfs-common-api</module>
<module>dfs-file-utils</module>
<module>dfs-transfer-client</module>
<module>dfs-transfer-server</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>cnf-client-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dfs-transfer-server</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dfs-common-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>dfs-file-utils</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${springboot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${springboot.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>-->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>${thymeleaf.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.ujmp/ujmp-core -->
<dependency>
<groupId>org.ujmp</groupId>
<artifactId>ujmp-core</artifactId>
<version>${ujmp.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<target>8</target>
<source>8</source>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ 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>cnf</artifactId>
<groupId>top.ninwoo</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cnf-weixingsim</artifactId>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>top.ninwoo</groupId>
<artifactId>cnf-client-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.influxdb</groupId>
<artifactId>influxdb-java</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package top.ninwoo.weixingsim;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class WxMain {
public static void main(String[] args) {
SpringApplication.run(WxMain.class, args);
}
}
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();//Java反射中的getDeclaredFields()方法的用处
for (Field field : fields) {
field.setAccessible(true);//关于field还有一种情况我们需要注意,就是当字段修饰符为private时,我们需要加上:field.setAccessible(true);
if (field.getType() == Float.class) {//获取字段的声明类型field.getType();返回的是一个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;
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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