├── .classpath
├── .gitignore
├── .project
├── LICENSE
├── README.md
├── bin
└── kr
│ └── re
│ └── keti
│ ├── DataProcess$UnitChunk.class
│ ├── DataProcess$UnitEdge.class
│ ├── DataProcess.class
│ ├── EdgeDataAggregator$1.class
│ ├── EdgeDataAggregator.class
│ ├── EdgeDeviceInfoClient$TCP_ResopnseWaiter.class
│ ├── EdgeDeviceInfoClient$UDP_ResponseWaiter.class
│ ├── EdgeDeviceInfoClient.class
│ ├── EdgeFinder$1.class
│ ├── EdgeFinder.class
│ ├── EdgeReceptor$1.class
│ ├── EdgeReceptor$2.class
│ ├── EdgeReceptor$ReceptionEvent.class
│ ├── EdgeReceptor.class
│ ├── MasterWorker.class
│ ├── ReceiveWorker$PacketProcessorImpl$ChunkTransfer.class
│ ├── ReceiveWorker$PacketProcessorImpl.class
│ ├── ReceiveWorker$ReceiveWorkerEvent.class
│ ├── ReceiveWorker.class
│ └── SlaveWorker.class
├── edge_ipList.txt
├── info_device_ex.txt
├── lib
├── bcpkix-jdk15on-1.68.jar
├── bcprov-jdk15on-1.68.jar
├── commons-io-2.11.0.jar
├── kafka-clients-3.4.0.jar
├── kafka_2.13-3.5.1.jar
├── mysql-connector-java-8.0.22.jar
├── org.eclipse.paho.client.mqttv3-1.2.5.jar
├── slf4j-api-2.0.6.jar
├── slf4j-simple-2.0.6.jar
└── sqlite-jdbc-3.27.2.1.jar
├── release
├── EdgeDataAggregator_v1217.jar
├── EdgeDataAggregator_v1220.jar
├── EdgeDataAggregator_v1221.jar
├── EdgeDataAggregator_v221219.jar
├── agent.jar
├── client.jar
├── execute.txt
└── info_device_backup.txt
└── src
└── kr
└── re
└── keti
├── AddressUpdate.java
├── Command.java
├── DataProcess.java
├── FileMonitor.java
├── Main.java
├── RamDiskManager.java
├── RequestProcess.java
├── ResponseProcess.java
├── Ssl.java
├── agent
├── Agent.java
├── AgentPacket.java
├── EdgeDataAggregator.java
├── Kafka.java
└── Mqtt.java
├── database
├── Database.java
├── FileManagementDto.java
├── FileUuidDto.java
├── MysqlDao.java
└── SqliteDao.java
├── os
├── Azure.java
├── Broadcast.java
├── EdgeFinder.java
├── EdgeReceptor.java
├── Linux.java
├── OSProcess.java
├── TcpReceptor.java
├── TcpRequest.java
└── UdpReceptor.java
└── tcp
├── Client.java
├── Server.java
├── TcpPacket.java
├── UnitEdge.java
└── UnitShared.java
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /bin/
2 | /.classpath
3 | .settings/
4 | info_device.txt
5 | .project
6 | src/kr/re/keti/PortNum.java
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | edgedataaggregator
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 엣지컴퓨팅 데이터 공유 관리 S/W
2 | 엣지 컴퓨팅 시스템을 구성된 디바이스들간의 데이터 공유를 위한 프레임워크로서, 시스템을 자동으로 구성하고 디바이스간 데이터 공유와 보안등급 및 접근 정책 관리 등의 주요 기능을 수행함
3 |
4 | # info_device.txt
5 | info_device.txt는 디바이스의 전체적인 정보를 가지는 설정 파일입니다.
6 | ```
7 | uuid // 디바이스 ID
8 | data path // 데이터 폴더 위치
9 | cert path // 인증서 폴더 위치
10 | DBMS // 사용하는 DBMS
11 | database,table,id,password // 데이터베이스, 테이블명, 사용자ID, 사용자PW ','로 구분
12 | mode // upnp or master or slave upnp일시 처음 접속하는 디바이스가 master 나머지는 slave
13 | device IP // 디바이스IP or auto auto
14 | ```
15 |
16 | # 사용
17 | ```
18 | 0 // 종료
19 | 1 // 디바이스 정보 읽기
20 | 2 // 전체 데이터 읽기
21 | 3 // 데이터 상세 정보
22 | 4 // 데이터 읽기 / 분산 공유
23 | 5 // 데이터 쓰기
24 | 6 // 데이터 제거
25 | 7 // 데이터 전송
26 | ```
27 |
--------------------------------------------------------------------------------
/bin/kr/re/keti/DataProcess$UnitChunk.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/DataProcess$UnitChunk.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/DataProcess$UnitEdge.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/DataProcess$UnitEdge.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/DataProcess.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/DataProcess.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/EdgeDataAggregator$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/EdgeDataAggregator$1.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/EdgeDataAggregator.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/EdgeDataAggregator.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/EdgeDeviceInfoClient$TCP_ResopnseWaiter.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/EdgeDeviceInfoClient$TCP_ResopnseWaiter.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/EdgeDeviceInfoClient$UDP_ResponseWaiter.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/EdgeDeviceInfoClient$UDP_ResponseWaiter.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/EdgeDeviceInfoClient.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/EdgeDeviceInfoClient.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/EdgeFinder$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/EdgeFinder$1.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/EdgeFinder.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/EdgeFinder.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/EdgeReceptor$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/EdgeReceptor$1.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/EdgeReceptor$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/EdgeReceptor$2.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/EdgeReceptor$ReceptionEvent.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/EdgeReceptor$ReceptionEvent.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/EdgeReceptor.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/EdgeReceptor.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/MasterWorker.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/MasterWorker.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/ReceiveWorker$PacketProcessorImpl$ChunkTransfer.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/ReceiveWorker$PacketProcessorImpl$ChunkTransfer.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/ReceiveWorker$PacketProcessorImpl.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/ReceiveWorker$PacketProcessorImpl.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/ReceiveWorker$ReceiveWorkerEvent.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/ReceiveWorker$ReceiveWorkerEvent.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/ReceiveWorker.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/ReceiveWorker.class
--------------------------------------------------------------------------------
/bin/kr/re/keti/SlaveWorker.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/bin/kr/re/keti/SlaveWorker.class
--------------------------------------------------------------------------------
/edge_ipList.txt:
--------------------------------------------------------------------------------
1 | slave
2 | 10.0.0.126
--------------------------------------------------------------------------------
/info_device_ex.txt:
--------------------------------------------------------------------------------
1 | 2ce81678-3c50-11ec-807b-3b8fa73906e7
2 | /home//keti/data/
3 | /home/keti/cert/
4 | MySQL
5 | db_name,table_name,db_id,db_pw
6 | upnp
7 | auto
8 |
--------------------------------------------------------------------------------
/lib/bcpkix-jdk15on-1.68.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/lib/bcpkix-jdk15on-1.68.jar
--------------------------------------------------------------------------------
/lib/bcprov-jdk15on-1.68.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/lib/bcprov-jdk15on-1.68.jar
--------------------------------------------------------------------------------
/lib/commons-io-2.11.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/lib/commons-io-2.11.0.jar
--------------------------------------------------------------------------------
/lib/kafka-clients-3.4.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/lib/kafka-clients-3.4.0.jar
--------------------------------------------------------------------------------
/lib/kafka_2.13-3.5.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/lib/kafka_2.13-3.5.1.jar
--------------------------------------------------------------------------------
/lib/mysql-connector-java-8.0.22.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/lib/mysql-connector-java-8.0.22.jar
--------------------------------------------------------------------------------
/lib/org.eclipse.paho.client.mqttv3-1.2.5.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/lib/org.eclipse.paho.client.mqttv3-1.2.5.jar
--------------------------------------------------------------------------------
/lib/slf4j-api-2.0.6.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/lib/slf4j-api-2.0.6.jar
--------------------------------------------------------------------------------
/lib/slf4j-simple-2.0.6.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/lib/slf4j-simple-2.0.6.jar
--------------------------------------------------------------------------------
/lib/sqlite-jdbc-3.27.2.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/lib/sqlite-jdbc-3.27.2.1.jar
--------------------------------------------------------------------------------
/release/EdgeDataAggregator_v1217.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/release/EdgeDataAggregator_v1217.jar
--------------------------------------------------------------------------------
/release/EdgeDataAggregator_v1220.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/release/EdgeDataAggregator_v1220.jar
--------------------------------------------------------------------------------
/release/EdgeDataAggregator_v1221.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/release/EdgeDataAggregator_v1221.jar
--------------------------------------------------------------------------------
/release/EdgeDataAggregator_v221219.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/release/EdgeDataAggregator_v221219.jar
--------------------------------------------------------------------------------
/release/agent.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/release/agent.jar
--------------------------------------------------------------------------------
/release/client.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eunae-park/EdgeComputing_DataAggregator/9693e1f674f3238735541e8dce4bc42a30e1e096/release/client.jar
--------------------------------------------------------------------------------
/release/execute.txt:
--------------------------------------------------------------------------------
1 | java -jar EdgeDataAggregator.jar
2 |
3 | need to write the info_device.txt(guide : info_device_backup.txt)
--------------------------------------------------------------------------------
/release/info_device_backup.txt:
--------------------------------------------------------------------------------
1 | Edge Node UUID
2 | Data Folder DIR/
3 | Cert Folder DIR/
4 | DBMS name
5 | DB information
6 | UPNP mode
7 | upnp information
8 | My IP Address
9 |
10 |
11 | 52.141.20.211
12 | keti.d-sharing.kr
13 | keties.iptime.org
14 | master
15 | 10.0.7.11
16 |
17 |
18 | //DB info
19 | MySQL : DB명,table명,userID,userPW
20 | (ex) mecTrace,file_management,mecTrace,penta&keti0415!
21 | SQLite : DB명,table명,userID,userPW,DB경로
22 |
23 | //upnp info
24 | 자동모드 : upnp
25 | 수동모드 : master
26 | 수동모드 : slave\nmaster_ip
27 |
28 | //My IP Address
29 | 자동으로 가져오기 : auto
30 | 수동설정 : ip 입력
31 |
32 |
33 | 수동모드 - keti.d-sharing.kr or keties.iptime.org
34 | vi /etc/hosts
35 | 127.0.0.1 keti.d-sharing.kr
36 | keti.d-sharing.kr
37 | keties.iptime.org
38 |
--------------------------------------------------------------------------------
/src/kr/re/keti/AddressUpdate.java:
--------------------------------------------------------------------------------
1 | package kr.re.keti;
2 |
3 | import java.io.IOException;
4 | import java.net.DatagramPacket;
5 | import java.net.DatagramSocket;
6 | import java.net.InetAddress;
7 | import java.net.SocketException;
8 | import java.net.UnknownHostException;
9 | import java.util.Random;
10 |
11 |
12 | public class AddressUpdate {
13 | int port;
14 | String address;
15 | Thread thread;
16 | public String localAddressUpdate() {
17 | Random random = new Random();
18 |
19 | port = random.nextInt(49151 - 1024 + 1)+1024;
20 | receive();
21 | try {
22 | Thread.sleep(100);
23 | } catch (Exception e) {
24 | e.printStackTrace();
25 | }
26 | send();
27 |
28 | try {
29 | thread.join();
30 | } catch (Exception e) {
31 | e.printStackTrace();
32 | }
33 | return address;
34 |
35 | }
36 | private void receive() {
37 | thread = new Thread(()->{
38 | try {
39 | byte[] buf = new byte[1024];
40 | DatagramSocket socket = new DatagramSocket(port);
41 | DatagramPacket packet = new DatagramPacket(buf, buf.length);
42 | socket.receive(packet);
43 | address = packet.getAddress().getHostAddress();
44 | socket.close();
45 | } catch (Exception e) {
46 | e.printStackTrace();
47 | }
48 |
49 | });
50 | thread.start();
51 |
52 | }
53 | private void send() {
54 | Thread thread = new Thread(()->{
55 | try {
56 | byte[] buf = "update".getBytes();
57 | DatagramPacket packet = new DatagramPacket(
58 | buf,
59 | buf.length,
60 | InetAddress.getByName("255.255.255.255"),
61 | port
62 | );
63 | DatagramSocket socket = new DatagramSocket();
64 | socket.send(packet);
65 | socket.close();
66 | } catch (Exception e) {
67 | e.printStackTrace();
68 | }
69 | });
70 | thread.start();
71 |
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/kr/re/keti/Command.java:
--------------------------------------------------------------------------------
1 | package kr.re.keti;
2 |
3 | import java.util.Scanner;
4 |
5 | import kr.re.keti.database.Database;
6 | import kr.re.keti.database.FileManagementDto;
7 |
8 | public class Command extends Thread{
9 | Database database;
10 | RequestProcess requestProcess;
11 | Scanner scanner;
12 |
13 | public Command(Database database) {
14 | requestProcess = new RequestProcess(database);
15 | this.database = database;
16 | this.scanner = new Scanner(System.in);
17 | }
18 | @Override
19 | public void run() {
20 | String command;
21 | String type;
22 |
23 | while(!isInterrupted()) {
24 | try {
25 | System.out.println();
26 | System.out.print(">>>");
27 | command = scanner.nextLine();
28 | type = command.split(" ")[0];
29 |
30 | if(command.equals("exit")) break;
31 |
32 |
33 | if(type.matches("[0-9]+")) {
34 | switch(Integer.parseInt(type)) {
35 | case 1: deviceInformation(command); break;
36 | case 2: wholeDataInformation(command); break;
37 | case 3: individualMetaDataInformation(command);break;
38 | case 4: individualDataRead(command); break;
39 | case 5: requestProcess.newEdge("[10.0.0.126]");
40 | }
41 | continue;
42 | }
43 | switch(type) {
44 | case "update": updateFile(); break;
45 | case "help": help(); break;
46 | case "deviceIP": System.out.println("device-IP : "+Main.deviceIP); break;
47 | case "masterIP": System.out.println("master-IP : "+Main.masterIP); break;
48 | case "mode" : System.out.println("device mode : "+Main.mode); break;
49 | case "edgeList": edgeList(); break;
50 | case "deviceInformation": deviceInformation(command); break;
51 | case "wholeDataInformation": wholeDataInformation(command); break;
52 | case "individualMetaDataInformation": individualMetaDataInformation(command);break;
53 | case "distributed": distributed(command); break;
54 | }
55 |
56 | // e.printStackTrace();
57 | } catch (Exception e) {
58 | e.printStackTrace();
59 | }
60 | }
61 | if(scanner != null) scanner.close();
62 | }
63 | private void updateFile() {
64 | FileManagementDto dto = null;
65 | String dataId = "";
66 | while(true) {
67 | System.out.println("File Name : ");
68 | dataId = scanner.nextLine();
69 | if(dataId.equals("exit")) return;
70 | else {
71 | if(database.select(dataId) != null) {
72 | break;
73 | }
74 | else {
75 | System.out.println("not found data ["+dataId+"]");
76 | }
77 | }
78 | }
79 |
80 | while(true) {
81 | System.out.println("Security Level(1 - 5) : ");
82 | try {
83 | int level = Integer.parseInt(scanner.nextLine());
84 | if(level == -1) break;
85 | if(level<0 || level>5) throw new Exception();
86 |
87 | dto.setSecurityLevel(level);
88 | database.update(dto);
89 |
90 | } catch (Exception e) {
91 | e.printStackTrace();
92 | }
93 | break;
94 | }
95 | }
96 | private void help() {
97 | System.out.println("keyword : ");
98 | System.out.println("\thelp, deviceIP, masterIP, mode, edgeList");
99 | System.out.println("\t1. deviceInformation [ip]");
100 | System.out.println("\t2. wholeDataInformation [ip]");
101 | System.out.println("\t3. individualMetaDataInformation [dataid]");
102 | }
103 | private void edgeList() {
104 | String slaveList = requestProcess.requestEdgeList(PortNum.KETI_PORT);
105 | System.out.print("Edge List : "+Main.masterIP+"(master)\t["+slaveList+"]\n");
106 | }
107 | private void deviceInformation(String command) {
108 | String[] commands = command.split(" ");
109 | if(commands.length == 1 || commands[1].equals(Main.deviceIP)) {
110 | System.out.println("request to mine");
111 | String data = requestProcess.deviceInformation();
112 | requestProcess.showDeviceInformation(data);
113 | }
114 | else {
115 | requestProcess.requestDeviceInformation(commands[1], PortNum.KETI_PORT);
116 | }
117 | }
118 | private void wholeDataInformation(String command) {
119 | String[] commands = command.split(" ");
120 | if(commands.length == 1 || commands[1].equals(Main.deviceIP)) {
121 | System.out.println("request to mine");
122 | String data = requestProcess.wholeDataInformation();
123 | requestProcess.wholeDataInformation(data);
124 | }
125 | else {
126 | System.out.println("request to "+commands[1]);
127 | requestProcess.requestWholeDataInformation(commands[1], PortNum.KETI_PORT);;
128 | }
129 | }
130 | private void individualMetaDataInformation(String command) {
131 | String[] commands = command.split(" ");
132 | if(commands.length <2) {
133 | System.out.println("NO DataID");
134 | }
135 | else {
136 | requestProcess.requestIndividualMetaDataInformation(PortNum.KETI_PORT, commands[1]);
137 | }
138 | }
139 | private void individualDataRead(String command) {
140 | String[] commands = command.split(" ");
141 | if(commands.length <2) {
142 | System.out.println("not dataid");
143 | }
144 | else {
145 | String dataid = commands[1];
146 | requestProcess.requestIndividualDataRead(PortNum.KETI_PORT, dataid);
147 |
148 | }
149 | }
150 | private void distributed(String command) {
151 | String[] commands = command.split(" ");
152 | if(commands.length <2) {
153 | System.out.println("not dataid");
154 | }
155 | else {
156 | String dataid = commands[1];
157 | requestProcess.requestIndividualDataRead(PortNum.KETI_PORT, dataid);
158 | }
159 |
160 | }
161 | }
162 |
163 |
--------------------------------------------------------------------------------
/src/kr/re/keti/FileMonitor.java:
--------------------------------------------------------------------------------
1 | package kr.re.keti;
2 |
3 | import java.io.BufferedInputStream;
4 | import java.io.ByteArrayOutputStream;
5 | import java.io.File;
6 | import java.io.FileInputStream;
7 | import java.io.IOException;
8 | import java.nio.file.Files;
9 | import java.nio.file.StandardCopyOption;
10 | import java.util.HashSet;
11 | import java.util.Set;
12 | import java.util.UUID;
13 |
14 | import org.apache.commons.io.monitor.FileAlterationListener;
15 | import org.apache.commons.io.monitor.FileAlterationMonitor;
16 | import org.apache.commons.io.monitor.FileAlterationObserver;
17 |
18 | import kr.re.keti.agent.Agent;
19 | import kr.re.keti.database.Database;
20 | import kr.re.keti.database.FileManagementDto;
21 | import kr.re.keti.database.FileUuidDto;
22 |
23 | public class FileMonitor{
24 | private Agent agent;
25 | private String dir;
26 | private Database database;
27 | // private DataProcess dataProcess;
28 | private static Set ignoredFiles = new HashSet();;
29 | private FileAlterationMonitor monitor;
30 | private Ssl ssl;
31 |
32 | public FileMonitor(String dir, Agent agent, Database database, long interval) {
33 | this.dir = dir;
34 | this.agent = agent;
35 | this.database = database;
36 | this.monitor = new FileAlterationMonitor(interval);
37 | ssl = Ssl.getInstance();
38 | }
39 | public void start() {
40 | File directory = new File(dir);
41 | FileAlterationObserver observer = new FileAlterationObserver(directory);
42 | FileAlterationListener listener = new FileAlterationListener() {
43 | @Override
44 | public void onStop(FileAlterationObserver arg0) {
45 | }
46 | @Override
47 | public void onStart(FileAlterationObserver arg0) {
48 | }
49 | @Override
50 | public void onFileCreate(File file) {
51 | System.out.println("File create : "+file);
52 | String fileName = file.getName();
53 | if(fileName.endsWith(".swp")) return;
54 | if (ignoredFiles.contains(fileName)) return;
55 |
56 | int dotIndex = fileName.lastIndexOf(".");
57 | String dataid = (dotIndex > 0) ? fileName.substring(0, dotIndex) : fileName;
58 |
59 | String sign = ssl.sign(file.getPath());
60 | String uuid = UUID.randomUUID().toString();
61 | uuid = uuid.replace("-", "");
62 | FileManagementDto dto = new FileManagementDto(file, sign, uuid);
63 |
64 | FileUuidDto uuidDto = new FileUuidDto(dataid, uuid);
65 | dto = new FileManagementDto(file, uuid, sign);
66 | dto.setLinkedEdge(Main.deviceIP);
67 | database.insert(uuidDto);
68 | database.insert(dto);
69 |
70 | String metaData = dto.toString();
71 | byte[] message = DataProcess.messageCreate("REQ", Main.deviceIP, "010", metaData);
72 | agent.send(message);
73 |
74 | File destFile = new File(Main.ramFolder + File.separator + fileName);
75 | try {
76 | Files.copy(file.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
77 | } catch (IOException e) {
78 | e.printStackTrace();
79 | }
80 |
81 | byte[] data = readFile(file);
82 | String dataSize = data.length+"";
83 | message = DataProcess.messageCreate(data, "REQ", Main.deviceIP, "011", uuid, dataSize);
84 | agent.send(message);
85 |
86 | }
87 | @Override
88 | public void onFileChange(File file) {
89 | System.out.println("File change : "+file);
90 | String fileName = file.getName();
91 | if(fileName.endsWith(".swp")) return;
92 | if (ignoredFiles.contains(fileName)) return;
93 |
94 | int dotIndex = fileName.lastIndexOf(".");
95 | String dataid = (dotIndex > 0) ? fileName.substring(0, dotIndex) : fileName;
96 | String sign = ssl.sign(fileName);
97 |
98 | FileManagementDto dto = new FileManagementDto(file, dataid, sign);
99 | database.update(dto);
100 | byte[] data = readFile(file);
101 | String dataSize = data.length+"";
102 | byte[] message = DataProcess.messageCreate(data, "REQ", Main.deviceIP, "012", dataid, dataSize);
103 | agent.send(message);
104 | }
105 | @Override
106 | public void onFileDelete(File file) {
107 | System.out.println("File delete : "+file);
108 | String fileName = file.getName();
109 | if(fileName.endsWith(".swp")) return;
110 | if (ignoredFiles.contains(fileName)) return;
111 |
112 | int dotIndex = fileName.lastIndexOf(".");
113 | String dataid = (dotIndex > 0) ? fileName.substring(0, dotIndex) : fileName;
114 |
115 | byte[] message = DataProcess.messageCreate("REQ", Main.deviceIP, "013", dataid);
116 |
117 | database.delete("file_uuid", fileName);
118 | database.delete("file_management", dataid);
119 | RamDiskManager.getInstance().deleteRamFile(fileName);
120 | agent.send(message);
121 | }
122 | @Override
123 | public void onDirectoryCreate(File directory) {
124 | }
125 | @Override
126 | public void onDirectoryChange(File directory) {
127 | }
128 | @Override
129 | public void onDirectoryDelete(File directory) {
130 | }
131 | };
132 |
133 | observer.addListener(listener);
134 | monitor.addObserver(observer);
135 | try {
136 | monitor.start();
137 | } catch (Exception e) {
138 | e.printStackTrace();
139 | }
140 | }
141 | public void stop() {
142 | try {
143 | monitor.stop();
144 | } catch (Exception e) {
145 | e.printStackTrace();
146 | }
147 | }
148 |
149 | public static void ignoreFile(String fileName) {
150 | ignoredFiles.add(fileName);
151 | }
152 |
153 | public static void unignoreFile(String fileName) {
154 | ignoredFiles.remove(fileName);
155 | }
156 | public static Set getIgnoreFile() {
157 | return ignoredFiles;
158 | }
159 |
160 |
161 | private byte[] readFile(File file) {
162 | byte[] data = null;
163 | try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
164 | ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
165 | byte[] buffer = new byte[1024];
166 | int bytesRead;
167 | while ((bytesRead = bis.read(buffer)) != -1) {
168 | bos.write(buffer, 0, bytesRead);
169 | }
170 | data = bos.toByteArray();
171 | } catch (IOException e) {
172 | e.printStackTrace();
173 | }
174 | return data;
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/src/kr/re/keti/Main.java:
--------------------------------------------------------------------------------
1 | package kr.re.keti;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.File;
5 | import java.io.FileNotFoundException;
6 | import java.io.FileReader;
7 | import java.io.FileWriter;
8 | import java.io.IOException;
9 | import java.net.InetAddress;
10 | import java.net.UnknownHostException;
11 | import java.nio.file.Files;
12 | import java.nio.file.Path;
13 | import java.time.LocalDateTime;
14 | import java.time.format.DateTimeFormatter;
15 |
16 |
17 | import kr.re.keti.agent.Agent;
18 | import kr.re.keti.database.Database;
19 | import kr.re.keti.database.MysqlDao;
20 | import kr.re.keti.database.SqliteDao;
21 | import kr.re.keti.os.Azure;
22 | import kr.re.keti.os.EdgeFinder;
23 | import kr.re.keti.os.Linux;
24 | import kr.re.keti.os.OSProcess;
25 |
26 | public class Main {
27 | public static String uuid;
28 | public static String deviceIP;
29 | public static String masterIP = "None";
30 | public static String storageFolder;
31 | public static String certFolder;
32 | public static String ramFolder;
33 | public static String mode;
34 | public static String programStartTime = programStartTime();
35 | public static OSProcess process;
36 | public static void main(String[] args){
37 | // -----------------IP in args---------------------------------------------
38 | if(args.length >0 ) {
39 | try {
40 | InetAddress addr = InetAddress.getByName(args[args.length - 1]);
41 | deviceIP = addr.getHostAddress();
42 | } catch (Exception e) {
43 | e.printStackTrace();
44 | }
45 | }
46 |
47 | Database database = null;
48 |
49 | //----------------------file read--------------------------
50 | try {
51 | FileReader file = new FileReader("info_device.txt");
52 | BufferedReader br = new BufferedReader(file);
53 |
54 | database = EdgeInformation(br);
55 |
56 | if(br!=null) br.close();
57 | if(file!=null) file.close();
58 | } catch (Exception e) {
59 | e.printStackTrace();
60 | }
61 |
62 | //----------------OS-----------------------------------
63 | String osName = System.getProperty("os.name");
64 | if(osName.equals("Linux")) {
65 | String osVersion = System.getProperty("os.version");
66 | if(osVersion.indexOf("azure") != -1) {
67 | process = new Azure();
68 | }
69 | else {
70 | process = new Linux();
71 | }
72 | }
73 | else if(osName.equals("Windows")) {
74 | System.out.println("\t**System is Windows**");
75 | }
76 |
77 | Ssl.selfSignedCertificate(certFolder, certFolder+"Private/", certFolder+"Private/private.key", 365);
78 | //--------------------Master Find---------------------------------
79 | masterIP = process.getMaster();
80 | if(masterIP.equals("none") || masterIP.equals(deviceIP)) {
81 | mode = "master";
82 | masterIP = deviceIP;
83 | process.start();
84 | }
85 | else {
86 | mode = "slave";
87 | }
88 |
89 |
90 | DataProcess dataProcess = new DataProcess(database);
91 | dataProcess.initWholeDataInformation();
92 |
93 |
94 | //------------------------master found----------------------------------
95 | Agent agent = Agent.getInstance();
96 | agent.setDatabase(database);
97 | agent.start();
98 |
99 |
100 | if(mode.equals("master")) {
101 | System.out.println("Waiting for connections from slaves...");
102 | }
103 | else {
104 | System.out.println("* Master found: " + masterIP + "\n");
105 | agent.send(("{[{REQ::"+deviceIP+"::001::EDGE_LIST}]}").getBytes());
106 |
107 | try {
108 | byte[] keyData = Files.readAllBytes(Path.of(certFolder+"Private/pub.key"));
109 | int keySize = keyData.length;
110 | byte[] start = ("{[{REQ::"+deviceIP+"::019::public_key::"+keySize+"::").getBytes();
111 | byte[] end = "}]}".getBytes();
112 |
113 | byte[] data = new byte[start.length + keyData.length + end.length];
114 | System.arraycopy(start, 0, data, 0, start.length);
115 | System.arraycopy(keyData, 0, data, start.length, keyData.length);
116 | System.arraycopy(end, 0, data, start.length + keyData.length, end.length);
117 |
118 | agent.send(data);
119 | } catch (Exception e) {
120 | e.printStackTrace();
121 | }
122 | }
123 |
124 | FileMonitor fileMonitor = new FileMonitor(storageFolder, agent, database, 500);
125 | try {
126 | fileMonitor.start();
127 | } catch (Exception e) {
128 | e.printStackTrace();
129 | }
130 | try {
131 | Thread.sleep(EdgeFinder.DEFAULT_WAITING_TIME+100);
132 | edgeIPList();
133 | } catch (Exception e) {
134 | e.printStackTrace();
135 | }
136 |
137 | //-----------------------command-------------------------------------
138 | Runtime.getRuntime().addShutdownHook(new Thread(() -> {
139 | Command.interrupted();
140 | shutdown();
141 | }
142 | try {
143 | Command command = new Command(database);
144 | command.setName("command");
145 | command.start();
146 | command.join();
147 | } catch (Exception e) {
148 | e.printStackTrace();
149 | }
150 |
151 | //-----------------------program exit---------------------------------
152 | shutdown();
153 | System.exit(0);
154 | }
155 |
156 | private static Database EdgeInformation(BufferedReader br) {
157 | Database database = null;
158 | System.out.println("==================================================================");
159 | try {
160 | //------------------------uuid-----------------------
161 | uuid = br.readLine();
162 | if(uuid == null) {
163 | System.out.println(" * Input the UUID of Edge Device.");
164 | System.exit(0);
165 | }
166 | else {
167 | System.out.println(" * UUID of Edge Device. : " + uuid);
168 | }
169 |
170 | //------------------------cert-----------------------
171 |
172 | //------------------------storage-----------------------
173 | storageFolder = br.readLine();
174 | if(storageFolder == null) {
175 | System.out.println(" * Input the Name of Main Path with storage.");
176 | System.exit(0);
177 | }
178 | else {
179 | System.out.println(" * Name of Main Path with storage : " + storageFolder);
180 | File folder = new File(storageFolder);
181 | if(!folder.exists()) folder.mkdir();
182 | }
183 |
184 | certFolder = br.readLine();
185 | if(certFolder == null) {
186 | System.out.println(" * Input the Name of Main Path with cert.");
187 | System.exit(0);
188 | }
189 | else {
190 | System.out.println(" * Name of Main Path with cert : " + certFolder);
191 | File folder = new File(certFolder);
192 | if(!folder.exists()) folder.mkdir();
193 |
194 | folder = new File(certFolder +"Private");//private key and original crt file
195 | if(!folder.exists()) folder.mkdir();
196 |
197 | folder = new File(certFolder +"Vehicle"); // copy crt file
198 | if(!folder.exists()) folder.mkdir();
199 |
200 | folder = new File(certFolder+"keys"); // public key file
201 | if(!folder.exists()) folder.mkdir();
202 | }
203 |
204 |
205 | //------------------------ram-----------------------
206 | ramFolder = br.readLine();
207 | if(ramFolder == null) {
208 | System.out.println(" * Input the Name of Main Path with ram.");
209 | System.exit(0);
210 | }
211 | else {
212 | System.out.println(" * Name of Main Path with ram : " + ramFolder);
213 | File folder = new File(ramFolder);
214 | if(!folder.exists()) folder.mkdir();
215 |
216 | folder = new File(ramFolder+"chunk");
217 | if(!folder.exists()) folder.mkdir();
218 |
219 | folder = new File(ramFolder+"time");
220 | if(!folder.exists()) folder.mkdir();
221 | }
222 |
223 | //------------------------DB-----------------------
224 | String databaseType = br.readLine();
225 | System.out.println(" * DBMS used by EdgeNode : " + databaseType);
226 | if(databaseType.equals("MySQL")) {
227 | String line = br.readLine();
228 | String[] dbInfo = line.split(",");
229 | if(dbInfo.length != 3) {
230 | System.out.println(" * Input DB Infomation in info_device.txt(ex:DB name,table name,user ID,user PW).");
231 | System.exit(0);
232 | }
233 | String databaseName = dbInfo[0];
234 | String id = dbInfo[1];
235 | String pw = dbInfo[2];
236 | database = new MysqlDao(databaseName, id, pw);
237 | }
238 |
239 | else if(databaseType.equals("SQLite")) {
240 | String line = br.readLine();
241 | String[] dbInfo = line.split(",");
242 | if(dbInfo.length != 2) {
243 | System.out.println(" * Input DB Infomation in info_device.txt(ex:DB path, DB name,table name).");
244 | System.exit(0);
245 | }
246 | String path = dbInfo[0];
247 | String databaseName = dbInfo[1];
248 | database = new SqliteDao(path, databaseName);
249 | }
250 | else {
251 | System.out.println(" * Input DBMS used by EdgeNode(ex:MySQL, SQLite).");
252 | System.exit(0);
253 | }
254 |
255 | //------------------------mode-----------------------
256 | mode = br.readLine();
257 | if(!(mode.equals("master") || mode.equals("slave") || mode.equals("upnp"))) {
258 | System.out.println(" * Input UPnP mode(ex:upnp, master, slave&master_ip).");
259 | System.exit(0);
260 | }
261 |
262 | //------------------------IP-----------------------
263 | deviceIP = br.readLine();
264 | if(deviceIP.equals("auto")) {
265 | deviceIP = InetAddress.getLocalHost().getHostAddress();
266 | }
267 | else if(deviceIP != null) {
268 | try {
269 | InetAddress inetAddress = InetAddress.getByName(deviceIP);
270 | deviceIP = inetAddress.getHostAddress();
271 | } catch (Exception e) {
272 | e.printStackTrace();
273 | }
274 | }
275 | else {
276 | System.out.println(" * Input IP(ex:DNS, Logical address, auto).");
277 | System.exit(0);
278 | }
279 |
280 | if(deviceIP.startsWith("192.168") || deviceIP.startsWith("127.0")) {
281 | deviceIP = new AddressUpdate().localAddressUpdate();
282 | }
283 | System.out.println(" * IP Address of Edge Device : " + deviceIP);
284 |
285 | //----------------------------------------------
286 | return database;
287 | } catch (Exception e) {
288 | e.printStackTrace();
289 | }
290 | return null;
291 | }
292 | private static void edgeIPList() {
293 | try {
294 | FileWriter writer = new FileWriter("edge_ipList.txt", false);
295 | if(mode.equals("master")) {
296 | writer.write("master\n");
297 | writer.flush();
298 | }
299 | else {
300 | writer.write("slave\n");
301 | writer.flush();
302 | writer.write(masterIP);
303 | writer.flush();
304 | }
305 | if(writer != null) writer.close();
306 | // TODO Auto-generated catch block
307 | } catch (Exception e) {
308 | e.printStackTrace();
309 | }
310 | }
311 | private static String programStartTime() {
312 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
313 | LocalDateTime currentDateTime = LocalDateTime.now();
314 | String start = currentDateTime.format(formatter);
315 | return start;
316 |
317 | }
318 | private static void shutdown() {
319 | Agent agent = Agent.getInstance();
320 | agent.send(("{[{REQ::"+deviceIP+"::-1}]}").getBytes());
321 |
322 | process.stop();
323 |
324 | String path = System.getProperty("user.dir");
325 | System.out.println(path);
326 | File directory = new File(path);
327 | File[] files = directory.listFiles();
328 |
329 | for(File file : files) {
330 | if(file.getName().startsWith("paho")) {
331 | delete(file);
332 | }
333 | }
334 |
335 | agent.stop();
336 | }
337 | private static void delete(File file) {
338 | if(file.isDirectory()) {
339 | File[] files = file.listFiles();
340 | if(files != null) {
341 | for(File subFile : files) {
342 | delete(subFile);
343 | }
344 | }
345 | }
346 |
347 | file.delete();
348 |
349 | }
350 | }
351 |
--------------------------------------------------------------------------------
/src/kr/re/keti/RamDiskManager.java:
--------------------------------------------------------------------------------
1 | package kr.re.keti;
2 | import java.io.File;
3 | import java.io.FileOutputStream;
4 | import java.io.IOException;
5 | import java.nio.file.Files;
6 | import java.nio.file.StandardCopyOption;
7 | import java.util.HashMap;
8 | import java.util.Map;
9 |
10 | public class RamDiskManager {
11 | public static RamDiskManager instance = null;
12 | private String ramDiskPath;
13 | private String diskPath;
14 | private long maxRamDiskSize;
15 | private Map fileSizes;
16 |
17 | public static RamDiskManager getInstance() {
18 | if(instance == null) {
19 | System.out.println("RamDiskManager is null");
20 | }
21 | return instance;
22 | }
23 | public static RamDiskManager getInstance(String ramDiskPath, String diskPath, long maxRamDiskSize) {
24 | if(instance == null) {
25 | instance = new RamDiskManager(ramDiskPath, diskPath, maxRamDiskSize);
26 | }
27 | return instance;
28 | }
29 | private RamDiskManager(String ramDiskPath, String diskPath, long maxRamDiskSize) {
30 | this.ramDiskPath = ramDiskPath;
31 | this.diskPath = diskPath;
32 | this.maxRamDiskSize = maxRamDiskSize;
33 | this.fileSizes = new HashMap<>();
34 | }
35 |
36 | public void createFile(String fileName, byte[] data) {
37 | FileMonitor.ignoreFile(fileName);
38 | // Check if there is enough space in the ramdisk
39 | long totalSize = 0;
40 | for (long size : fileSizes.values()) {
41 | totalSize += size;
42 | }
43 | if (totalSize + data.length > maxRamDiskSize) {
44 | // Not enough space, delete the oldest file
45 | String oldestFile = null;
46 | long oldestTime = Long.MAX_VALUE;
47 | for (Map.Entry entry : fileSizes.entrySet()) {
48 | File file = new File(ramDiskPath + File.separator + entry.getKey());
49 | if (file.lastModified() < oldestTime) {
50 | oldestTime = file.lastModified();
51 | oldestFile = entry.getKey();
52 | }
53 | }
54 | if (oldestFile != null) {
55 | deleteRamFile(oldestFile);
56 | }
57 | }
58 |
59 | // Create the file in the ramdisk
60 | File file = new File(ramDiskPath + File.separator + fileName);
61 | try (FileOutputStream fos = new FileOutputStream(file)) {
62 | fos.write(data);
63 | fileSizes.put(fileName, (long) data.length);
64 | } catch (IOException e) {
65 | e.printStackTrace();
66 | }
67 |
68 | // Copy the file to the disk
69 | copyFileToDisk(fileName);
70 | try {
71 | Thread.sleep(600);
72 | } catch (InterruptedException e) {
73 | e.printStackTrace();
74 | }
75 | FileMonitor.unignoreFile(fileName);
76 | }
77 |
78 | public void deleteFile(String fileName) {
79 | FileMonitor.ignoreFile(fileName);
80 | File file = new File(diskPath + File.separator + fileName);
81 | if (file.exists()) {
82 | file.delete();
83 | }
84 | deleteRamFile(fileName);
85 | try {
86 | Thread.sleep(600);
87 | } catch (InterruptedException e) {
88 | e.printStackTrace();
89 | }
90 | FileMonitor.unignoreFile(fileName);
91 | }
92 | public void deleteRamFile(String fileName) {
93 | File file = new File(ramDiskPath + File.separator + fileName);
94 | if (file.exists()) {
95 | file.delete();
96 | fileSizes.remove(fileName);
97 | }
98 | }
99 |
100 | private void copyFileToDisk(String fileName) {
101 | // Copy the file from the ramdisk to the disk
102 | File srcFile = new File(ramDiskPath + File.separator + fileName);
103 | File destFile = new File(diskPath + File.separator + fileName);
104 | try {
105 | Files.copy(srcFile.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
106 | } catch (IOException e) {
107 | e.printStackTrace();
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/kr/re/keti/RequestProcess.java:
--------------------------------------------------------------------------------
1 | package kr.re.keti;
2 |
3 | import java.io.File;
4 | import java.io.FileInputStream;
5 | import java.io.FileNotFoundException;
6 | import java.io.FileOutputStream;
7 | import java.io.IOException;
8 | import java.io.OutputStream;
9 | import java.net.Socket;
10 | import java.sql.Timestamp;
11 | import java.util.ArrayList;
12 | import java.util.Arrays;
13 | import java.util.HashMap;
14 | import java.util.List;
15 | import java.util.Map;
16 | import java.util.concurrent.atomic.AtomicInteger;
17 |
18 | import kr.re.keti.agent.Agent;
19 | import kr.re.keti.agent.AgentPacket;
20 | import kr.re.keti.database.Database;
21 | import kr.re.keti.database.FileManagementDto;
22 |
23 | public class RequestProcess extends DataProcess{
24 | Database database;
25 |
26 | public RequestProcess(Database database) {
27 | super(database);
28 | this.database = database;
29 | }
30 | // ------------------------------------------pub/sub--------------------------------------------------
31 | public void newEdge(String data) {
32 | String request = "{[{REQ::"+Main.deviceIP+"::010::"+data+"}]}";
33 | agent.send(request.getBytes());
34 | }
35 | // ------------------------------------------TCP--------------------------------------------------
36 | public void requestDeviceInformation(String address, int port) {
37 | if(ipCheck(address)) {
38 | System.out.println("request to "+address);
39 | byte[] request = ("{[{REQ::"+address+"::001::DEV_STATUS}]}").getBytes();
40 | String response = new String(agent.send(address, request));
41 |
42 | String[] array = response.substring(8, response.indexOf("}]}")).split("::");
43 | String data = array[2];
44 | showDeviceInformation(data);
45 | }
46 | else {
47 | System.out.println("not found: "+address);
48 | }
49 | }
50 | public FileManagementDto requestMetaDataInformation(String address, int port, String dataid) {
51 | String request = "{[{REQ::"+address+"::003::"+dataid+"}]}";
52 |
53 | String response = new String(agent.send(address, request.getBytes()));
54 | System.out.println("requestProcess response : "+response);
55 | response = messageFormat(response);
56 | String data = response.split("::")[3];
57 | if(data.equals("none")) return null;
58 |
59 | String datas[] = data.split("#");
60 | FileManagementDto dto = new FileManagementDto();
61 | dto.setDataId(dataid);
62 | dto.setTimestamp(Timestamp.valueOf(datas[1]));
63 | dto.setFileType(datas[2]);
64 | dto.setDataType(Integer.parseInt(datas[3]));
65 | dto.setSecurityLevel(Integer.parseInt(datas[4]));
66 | dto.setDataPriority(Integer.parseInt(datas[5]));
67 | dto.setDataSign(datas[6]);
68 | dto.setCert(datas[7]);
69 | dto.setDirectory(datas[8]);
70 | dto.setLinkedEdge(datas[9]);
71 | dto.setDataSize(Integer.parseInt(datas[10]));
72 | return dto;
73 | }
74 | public void requestWholeDataInformation(String address, int port) {
75 | if(ipCheck(address)) {
76 | byte[] request = ("{[{REQ::"+address+"::002::DATA_INFO}]}").getBytes();
77 | String response = new String(agent.send(address, request));
78 | response = messageFormat(response);
79 | String data = response.split("::")[3];
80 | wholeDataInformation(data);
81 | }
82 | else {
83 | System.out.println("not found: "+address);
84 | }
85 | }
86 | public void requestIndividualMetaDataInformation(int port, String dataid) {
87 | ArrayList existsEdge = new ArrayList<>();
88 | System.out.println("request to mine");
89 | FileManagementDto dto = (FileManagementDto) database.select("file_management", dataid);
90 | String fileAddress = "none";
91 | if(dto != null) {
92 | existsEdge.add(Main.deviceIP);
93 | fileAddress = "mine";
94 | }
95 |
96 | if(Main.mode.equals("slave")) {
97 | System.out.println("request to "+Main.masterIP);
98 | FileManagementDto temp = requestMetaDataInformation(Main.masterIP, port, dataid);
99 | if(temp != null) {
100 | existsEdge.add(Main.masterIP);
101 | if(dto ==null) {
102 | dto = temp;
103 | fileAddress = Main.masterIP;
104 | }
105 | }
106 | }
107 |
108 | String slaves = requestEdgeList(port);
109 | String[] slaveList = slaves.split(", ");
110 | if(!slaves.equals("none")) {
111 | for(String address : slaveList) {
112 | if(!Main.deviceIP.equals(address)) {
113 | System.out.println("request to "+address);
114 | FileManagementDto temp = requestMetaDataInformation(address, port, dataid);
115 | if(temp != null) {
116 | existsEdge.add(address);
117 | if(dto ==null) {
118 | dto = temp;
119 | fileAddress = address;
120 | }
121 | }
122 | }
123 | }
124 | }
125 | if(dto ==null) {
126 | System.out.println("* Anyone doesn't have MetaData.");
127 | }
128 | else {
129 | System.out.print("* [");
130 | for(int i=0; i edgeList = new ArrayList<>();
159 | edgeList.add(Main.masterIP);
160 | edgeList.addAll(Arrays.asList(slaveList));
161 |
162 | ArrayList existsEdge = new ArrayList<>();
163 | Map> edgeChunkMap = new HashMap<>();
164 | Map chunkSshMap = new HashMap<>();
165 |
166 | FileManagementDto metaData = (FileManagementDto) database.select("file_management", dataid);
167 |
168 | //-------------------------existsEdge-------------------------------------------
169 | // if(metaData != null) return null;
170 | for(String edge : edgeList) {
171 | if(edge.equals(Main.deviceIP)) continue;
172 |
173 | FileManagementDto dto = requestMetaDataInformation(edge, port, dataid);
174 | if(dto != null) {
175 | if(metaData == null) metaData = dto;
176 | existsEdge.add(edge);
177 | }
178 | }
179 | String fileName = dataid+"."+metaData.getFileType();
180 |
181 | int currentChunk = 1;
182 | int dataSize = (int) metaData.getDataSize();
183 |
184 | int remainingChunks = dataSize / STANDARD_SIZE - currentChunk + 1;
185 | int chunksPerEdge = remainingChunks / existsEdge.size();
186 | int extraChunks = remainingChunks % existsEdge.size();
187 |
188 | for (String edge : existsEdge) {
189 | int edgeChunks = chunksPerEdge + (extraChunks > 0 ? 1 : 0);
190 | extraChunks--;
191 | List edgeChunksList = new ArrayList<>();
192 | for (int i = 0; i < edgeChunks; i++) {
193 | edgeChunksList.add(fileName+"_" + currentChunk);
194 | currentChunk++;
195 | }
196 | edgeChunkMap.put(edge, edgeChunksList);
197 | }
198 |
199 | //----------------------------chunk 401 message--------------------------------------------
200 | // [debug] chunk file list
201 | // for (Map.Entry> entry : edgeChunkMap.entrySet()) {
202 | // String edge = entry.getKey();
203 | // List chunkList = entry.getValue();
204 | //
205 | // System.out.println("Edge: " + edge);
206 | // System.out.println("Chunk List:");
207 | // for (String chunk : chunkList) {
208 | // System.out.println(chunk);
209 | // }
210 | // System.out.println();
211 | // }
212 |
213 | for (Map.Entry> entry : edgeChunkMap.entrySet()) {
214 | String edge = entry.getKey();
215 | List chunkList = entry.getValue();
216 |
217 | String chunk = chunkList.get(0);
218 | String[] stringItem = chunk.split("_");
219 | int start = Integer.parseInt(stringItem[stringItem.length-1]);
220 |
221 | chunk = chunkList.get(chunkList.size() - 1);
222 | stringItem = chunk.split("_");
223 | int finish = Integer.parseInt(stringItem[stringItem.length-1]);
224 |
225 | String request = "{[{REQ::"+edge+"::401::"+dataid+"::"+start+"::"+finish+"}]}";
226 | String response = new String(agent.send(edge, request.getBytes()));
227 | response = messageFormat(response);
228 | String[] responseArray = response.split("::");
229 | String result = responseArray[responseArray.length-1];
230 | if(!result.equals("success")) {
231 | edgeChunkMap.remove(edge);
232 | continue;
233 | }
234 | }
235 |
236 |
237 | System.out.println("* Edge List with Data Separation Completed : "+edgeChunkMap.keySet());
238 | for (Map.Entry> entry : edgeChunkMap.entrySet()) {
239 | String edge = entry.getKey();
240 | List chunkList = entry.getValue();
241 |
242 | String chunk = chunkList.get(0);
243 | String[] stringItem = chunk.split("_");
244 | int start = Integer.parseInt(stringItem[stringItem.length-1]);
245 |
246 | chunk = chunkList.get(chunkList.size() - 1);
247 | stringItem = chunk.split("_");
248 | int finish = Integer.parseInt(stringItem[stringItem.length-1]);
249 |
250 |
251 | System.out.println("Request to : "+edge+", chunk #"+start+" to #"+finish);
252 | }
253 |
254 | //----------------------------chunk 405 message--------------------------------------------
255 | for(Map.Entry> entry : edgeChunkMap.entrySet()) {
256 | String edge = entry.getKey();
257 | List chunkList = entry.getValue();
258 |
259 |
260 | String startChunk = chunkList.get(0);
261 | String[] stringItem = startChunk.split("_");
262 | int start = Integer.parseInt(stringItem[stringItem.length-1]);
263 |
264 | String finishChunk = chunkList.get(chunkList.size() - 1);
265 | stringItem = finishChunk.split("_");
266 | int finish = Integer.parseInt(stringItem[stringItem.length-1]);
267 |
268 | String request = "{[{REQ::"+edge+"::405::"+dataid+"::"+start+"::"+finish+"}]}";
269 | String response = new String(agent.send(edge, request.getBytes()));
270 | response = messageFormat(response);
271 | String[] responseArray = response.split("::");
272 | String[] sha = Arrays.copyOfRange(responseArray, 4, responseArray.length);
273 |
274 |
275 | for (int i = 0; i < chunkList.size(); i++) {
276 | String chunk = chunkList.get(i);
277 | String sshInfo = sha[i]; // SSH 정보는 sha 배열에서 가져옴
278 | chunkSshMap.put(chunk, sshInfo);
279 | }
280 | }
281 |
282 | // [debug] ssh data
283 | // for (Map.Entry entry : chunkSshMap.entrySet()) {
284 | // String chunk = entry.getKey();
285 | // String sshInfo = entry.getValue();
286 | // System.out.println(chunk + " -> " + sshInfo);
287 | // }
288 | //-------------------------------chunk 406 message------------------------------
289 | try {
290 | Thread.sleep(100);
291 | } catch (InterruptedException e) {
292 | e.printStackTrace();
293 | }
294 | String filePath = Main.storageFolder+"chunk/";
295 | File chunkPath = new File(filePath);
296 | if(!chunkPath.exists()) chunkPath.mkdir();
297 |
298 | AtomicInteger downloadCompleteCount = new AtomicInteger();
299 | int chunkSize = (int) Math.ceil((double)metaData.getDataSize()/STANDARD_SIZE);
300 | Object lock = new Object();
301 |
302 | Thread downloadCompleteThread = new Thread(()->{
303 | int errorCheck = 0;
304 | int beforeCount = -1;
305 | while(true) {
306 | synchronized(lock) {
307 | try {
308 | lock.wait(100);
309 | } catch (InterruptedException e) {
310 | e.printStackTrace();
311 | }
312 | }
313 | int currentCount = downloadCompleteCount.get();
314 | if(beforeCount != currentCount && currentCount 10) {
323 | System.out.println("\tReceive Chunk fail");
324 | break;
325 | }
326 | }
327 | if(currentCount >= chunkSize) {
328 | System.out.println("\tReceive Rate of Chunk :"+currentCount+"/"+chunkSize+" = 100%");
329 | break;
330 | }
331 | }
332 | });
333 | downloadCompleteThread.setName("downloadCompleteThread");
334 | downloadCompleteThread.start();
335 |
336 | chunkSshMap.keySet().forEach(chunkName->{
337 | Thread downloadThread = new Thread(()->{
338 | String ssh = chunkSshMap.get(chunkName);
339 | AgentPacket packet = null;
340 | for (int i=0; i<10; i++) {
341 | try {
342 | Thread.sleep(500);
343 | packet = Agent.unitTable.get(chunkName);
344 | if(packet == null && i >8) {
345 | System.out.println("packet not data "+chunkName);
346 | return;
347 | }
348 | else if(packet == null) continue;
349 | Socket socket = packet.getSocket();
350 | String address = socket.getInetAddress().getHostAddress();
351 | OutputStream outputStream = socket.getOutputStream();
352 | byte[] data = packet.getData();
353 | if(ssh.equals(sha(data))) {
354 | try(FileOutputStream fileOutputStream = new FileOutputStream(filePath+chunkName)){
355 | if(ssh.equals(sha(data))) {
356 | fileOutputStream.write(data);
357 | outputStream.write(("{[{ANS::"+address+"::406::success}]}").getBytes());
358 | outputStream.flush();
359 | int currentCount = downloadCompleteCount.incrementAndGet();
360 | if(currentCount >= chunkSize) {
361 | synchronized (lock) {
362 | lock.notifyAll();
363 | }
364 | }
365 | }
366 | else {
367 | outputStream.write(("{[{ANS::"+address+"::406::fail}]}").getBytes());
368 | outputStream.flush();
369 | }
370 | } catch (FileNotFoundException e) {
371 | e.printStackTrace();
372 | } catch (IOException e) {
373 | e.printStackTrace();
374 | }
375 | }
376 | else {
377 | continue;
378 | }
379 |
380 | socket.close();
381 | return;
382 | } catch (InterruptedException e) {
383 | e.printStackTrace();
384 | } catch (IOException e) {
385 | e.printStackTrace();
386 | }
387 | }
388 | System.out.println("die "+chunkName);
389 | });
390 | downloadThread.setName(chunkName+"DownLoadThread");
391 | downloadThread.start();
392 | });
393 |
394 | try {
395 | downloadCompleteThread.join();
396 | } catch (InterruptedException e) {
397 | e.printStackTrace();
398 | }
399 | if(chunkSize != downloadCompleteCount.get()) return;
400 | //-------------------------------chunk 444 message------------------------------
401 | Thread mergeThread = new Thread(()->{
402 | try (FileOutputStream outputStream = new FileOutputStream(Main.storageFolder+fileName);){
403 | for(int i=1; i<= chunkSize; i++) {
404 | String chunkName = fileName+"_"+i;
405 | FileInputStream inputStream = new FileInputStream(Main.storageFolder+"chunk/"+chunkName);
406 | byte[] buffer = new byte[1024];
407 | int length;
408 | while((length = inputStream.read(buffer)) >0 ) {
409 | outputStream.write(buffer, 0, length);
410 | }
411 | inputStream.close();
412 | }
413 | } catch (IOException e) {
414 | e.printStackTrace();
415 | }
416 | });
417 | mergeThread.setName(fileName+"MergeThread");
418 | mergeThread.start();
419 |
420 | try {
421 | mergeThread.join();
422 | String fileSsh = sha(fileName);
423 | String responseSsh;
424 | int i=0;
425 | do {
426 | i++;
427 | Thread.sleep(100);
428 | String request = "{[{REQ::"+existsEdge.get(0)+"::444::"+fileName+"}]}";
429 | byte[] response = agent.send(existsEdge.get(0), request.getBytes());
430 | responseSsh = messageFormat(new String(response)).split("::")[3];
431 | }while(i < 10 && !responseSsh.equals(fileSsh));
432 | if(i>9) {
433 | System.out.println("file ssh not equals");
434 | return;
435 | }
436 | else {
437 | System.out.println("* Recieved Data SHA code is th same as original.");
438 | System.out.println("\tOriginal Data SHA code :\t"+responseSsh);
439 | System.out.println("\tRecieved Data SHA code :\t"+fileSsh);
440 | System.out.println("* "+existsEdge+" : have Data.");
441 | }
442 | } catch (InterruptedException e) {
443 | e.printStackTrace();
444 | }
445 | // return null;
446 | }
447 |
448 | }
449 |
--------------------------------------------------------------------------------
/src/kr/re/keti/ResponseProcess.java:
--------------------------------------------------------------------------------
1 | package kr.re.keti;
2 |
3 | import java.io.File;
4 | import java.io.FileInputStream;
5 | import java.io.FileNotFoundException;
6 | import java.io.FileOutputStream;
7 | import java.io.IOException;
8 | import java.io.InputStream;
9 | import java.io.OutputStream;
10 |
11 | import kr.re.keti.database.Database;
12 | import kr.re.keti.database.FileManagementDto;
13 | import kr.re.keti.os.OSProcess;
14 |
15 | public class ResponseProcess extends DataProcess{
16 | Database database;
17 |
18 | public ResponseProcess(Database database) {
19 | super(database);
20 | this.database = database;
21 | }
22 |
23 |
24 | public String responseInitEdgeList(String address) {
25 | String response = "{[{ANS::"+address+"::001::success}]}";
26 | return response;
27 | }
28 | public String responseEdgeList(String address) {
29 | String response = "{[{ANS::"+address+"::001::"+OSProcess.getEdgeListAsString()+"}]}";
30 | return response;
31 | }
32 | public String responseDeviceInformation(String address) {
33 | String response = "{[{ANS::"+address+"::001::"+deviceInformation()+"}]}";
34 | return response;
35 | }
36 | public String responseWholeDataInformation(String address) {
37 | String response = "{[{ANS::"+address+"::002::"+wholeDataInformation()+"}]}";
38 | System.out.println("response : "+response);
39 | return response;
40 | }
41 | public String responseMetaDataInformation(String address, String dataid) {
42 | String response = "{[{ANS::"+address+"::003::";
43 |
44 | FileManagementDto dto = (FileManagementDto) database.select("file_management", dataid);
45 | if(dto != null) {
46 | String metaData = dto.getDataId()+"#"+dto.getTimestamp()+"#"+dto.getFileType()
47 | +"#"+dto.getSecurityLevel()+"#"+dto.getDataPriority()+"#"+dto.getAvailabilityPolicy()
48 | +"#"+dto.getDataSign()+"#"+dto.getCert()+"#"+dto.getDirectory()
49 | +"#"+dto.getLinkedEdge()+"#"+dto.getDataSize();
50 | response += metaData+"}]}";
51 | }
52 | else {
53 | response += "none}]}";
54 | }
55 | return response;
56 | }
57 | public String responseIndividualDataRemove(String address, String dataid) {
58 | String response = "{[{ANS::"+address+"::006::";
59 | boolean check = database.delete("file_management", dataid);
60 | if(check) {
61 | response += "permission}]}";
62 | }
63 | else {
64 | response += "fail}]}";
65 | }
66 | return response;
67 | }
68 | public String responseChunkCreate(String address, String dataid, int startIdx, int finishIdx) {
69 | final int CHUNK_SIZE = 1000;
70 | FileManagementDto dto =(FileManagementDto) database.select("file_management", dataid);
71 | String fileName = dataid + "." + dto.getFileType();
72 | String filePath = Main.storageFolder + fileName;
73 | String response = "{[{ANS::" + address + "::401::fail}]}";
74 |
75 | try (InputStream inputStream = new FileInputStream(filePath)) {
76 | File directory = new File(Main.storageFolder + "chunk/");
77 | if (!directory.exists()) directory.mkdirs();
78 |
79 | byte[] buffer = new byte[CHUNK_SIZE];
80 | int chunkCount = 1;
81 | int bytesRead;
82 | while ((bytesRead = inputStream.read(buffer)) != -1) {
83 | if (chunkCount >= startIdx && chunkCount <= finishIdx) { // 청크 개수로 범위 비교
84 | String chunkFileName = fileName + "_" + chunkCount;
85 | String chunkFilePath = directory.getPath() + File.separator + chunkFileName;
86 | try (OutputStream outputStream = new FileOutputStream(chunkFilePath)) {
87 | outputStream.write(buffer, 0, bytesRead);
88 | }
89 | }
90 | chunkCount++;
91 |
92 | if (chunkCount > finishIdx) break;
93 | }
94 |
95 | response = "{[{ANS::" + address + "::401::success}]}";
96 | } catch (FileNotFoundException e) {
97 | e.printStackTrace();
98 | } catch (IOException e) {
99 | e.printStackTrace();
100 | }
101 |
102 | return response;
103 | }
104 |
105 |
106 |
107 | public String responseSha(String address, String dataid) {
108 | String shaCode = sha(dataid);
109 | String response = "{[{ANS::"+address+"::444::"+shaCode+"}]}";
110 | return response;
111 | }
112 | public String responseSha(String address, String dataid, int startIdx, int finishIdx) {
113 | String response = "{[{ANS::"+address+"::405::sha::";
114 | FileManagementDto dto =(FileManagementDto) database.select("file_management", dataid);
115 | String fileName = dataid+"."+dto.getFileType();
116 | for(int i=startIdx; i<=finishIdx;i++) {
117 | String chunkFileName = "chunk/"+fileName+"_"+i;
118 | String shaCode = sha(chunkFileName);
119 | response += (shaCode+"::");
120 | }
121 | response+="}]}";
122 | System.out.println(response);
123 | return response;
124 | }
125 |
126 |
127 | }
128 |
--------------------------------------------------------------------------------
/src/kr/re/keti/Ssl.java:
--------------------------------------------------------------------------------
1 | package kr.re.keti;
2 |
3 | import java.io.BufferedOutputStream;
4 | import java.io.ByteArrayInputStream;
5 | import java.io.File;
6 | import java.io.FileInputStream;
7 | import java.io.FileNotFoundException;
8 | import java.io.FileReader;
9 | import java.io.IOException;
10 | import java.io.InputStream;
11 | import java.io.OutputStream;
12 | import java.math.BigInteger;
13 | import java.nio.file.Files;
14 | import java.nio.file.Paths;
15 | import java.nio.file.StandardOpenOption;
16 | import java.security.InvalidKeyException;
17 | import java.security.KeyFactory;
18 | import java.security.KeyPair;
19 | import java.security.KeyPairGenerator;
20 | import java.security.NoSuchAlgorithmException;
21 | import java.security.PrivateKey;
22 | import java.security.PublicKey;
23 | import java.security.SecureRandom;
24 | import java.security.Security;
25 | import java.security.Signature;
26 | import java.security.SignatureException;
27 | import java.security.cert.CertificateException;
28 | import java.security.cert.X509Certificate;
29 | import java.security.spec.InvalidKeySpecException;
30 | import java.security.spec.X509EncodedKeySpec;
31 | import java.time.Instant;
32 | import java.time.LocalDate;
33 | import java.time.ZoneId;
34 | import java.util.ArrayList;
35 | import java.util.Base64;
36 | import java.util.Date;
37 | import java.util.Map;
38 | import java.util.concurrent.ConcurrentHashMap;
39 |
40 | import javax.security.auth.x500.X500Principal;
41 |
42 | import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
43 | import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
44 | import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
45 | import org.bouncycastle.jce.provider.BouncyCastleProvider;
46 | import org.bouncycastle.openssl.PEMKeyPair;
47 | import org.bouncycastle.openssl.PEMParser;
48 | import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
49 | import org.bouncycastle.operator.ContentSigner;
50 | import org.bouncycastle.operator.OperatorCreationException;
51 | import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
52 | import org.bouncycastle.util.io.pem.PemReader;
53 |
54 | public class Ssl {
55 | public static Ssl instance = new Ssl();
56 | public static ConcurrentHashMap uuidMap = new ConcurrentHashMap<>();
57 | public static ConcurrentHashMap pubKeyMap = new ConcurrentHashMap<>();
58 | private static String certFolder;
59 | private static PrivateKey privateKey;
60 | private static String signatureAlgorithm = "SHA256withRSA";
61 |
62 | public static Ssl getInstance() {
63 | return instance;
64 | }
65 | private Ssl() {
66 |
67 | }
68 |
69 | public static void setting(String path, String priKey, String pubKey) {
70 | certFolder = path;
71 |
72 | File keys = new File(path+"keys");
73 | if(!keys.exists()) keys.mkdir();
74 |
75 | path = path.endsWith("/") ? path : "/";
76 | path += "Private/";
77 | File Folder = new File(path);
78 | if(!Folder.exists()) Folder.mkdir();
79 | String certPath = Folder+"/"+"cert.crt";
80 | String priKeyPath = Folder+"/"+priKey;
81 | String pubKeyPath = Folder+"/"+pubKey;
82 | selfSignedCertificate(certPath, priKeyPath, pubKeyPath, 365);
83 |
84 | privateKey = generatePrivateKey(priKeyPath);
85 | }
86 | public static ArrayList getKeyList() {
87 | ArrayList keyList = new ArrayList<>();
88 |
89 | for (Map.Entry entry : uuidMap.entrySet()) {
90 | String address = entry.getKey();
91 | String uuid = entry.getValue();
92 | PublicKey key = pubKeyMap.get(uuid);
93 | String data = Base64.getEncoder().encodeToString(key.getEncoded());
94 |
95 | String keyData = address+":"+uuid+":"+data;
96 | keyList.add(keyData);
97 | }
98 | return keyList;
99 | }
100 | public static String getUuid(String address) {
101 | String uuid = uuidMap.get(address);
102 | return uuid;
103 | }
104 | public static void addKey(String address, String uuid, String keyData) {
105 | uuidMap.put(address, uuid);
106 |
107 | // for(Map.Entry entry : uuidMap.entrySet()) {
108 | // String key = entry.getKey();
109 | // String value = entry.getValue();
110 | // System.out.println(key+" : "+value);
111 | // }
112 |
113 | String path = certFolder+"keys/"+uuid+".key";
114 | byte[] data = Base64.getDecoder().decode(keyData);
115 | try (OutputStream out = new BufferedOutputStream(Files.newOutputStream(Paths.get(path), StandardOpenOption.CREATE))) {
116 | byte[] buffer = new byte[1024];
117 | int lengthRead;
118 | InputStream in = new ByteArrayInputStream(data);
119 | while ((lengthRead = in.read(buffer)) > 0) {
120 | out.write(buffer, 0, lengthRead);
121 | out.flush();
122 | }
123 | } catch (IOException e) {
124 | e.printStackTrace();
125 | }
126 | PublicKey key = generatePublicKey(path);
127 | pubKeyMap.put(uuid, key);
128 | }
129 | public static String getKey(String address) {
130 | String keyData = "none";
131 | String path = "none";
132 | if(address.equals(Main.deviceIP)) {
133 | path = certFolder+"Private/pub.key";
134 | }
135 | else {
136 | String uuid = uuidMap.get(address);
137 | if(uuid == null) {
138 | System.out.println("[SSL] "+address+"not found");
139 | return keyData;
140 | }
141 | path = certFolder+"keys/"+uuid+".key";
142 | }
143 | byte[] data = null;
144 | try {
145 | FileInputStream fis = new FileInputStream(path);
146 | data = new byte[fis.available()];
147 | fis.read(data);
148 | fis.close();
149 | } catch (IOException e) {
150 | e.printStackTrace();
151 | }
152 | keyData = Base64.getEncoder().encodeToString(data);
153 | return keyData;
154 | }
155 | public static void deleteKey(String address) {
156 | pubKeyMap.remove(address);
157 | }
158 | public static String getPath() {
159 | return certFolder;
160 | }
161 | public void setAlgorithm(String algorithm) {
162 | signatureAlgorithm = algorithm;
163 | }
164 | public String getAlgorithm() {
165 | return signatureAlgorithm;
166 | }
167 | public String sign(String filePath) {
168 | String signatureData = "none";
169 | try {
170 | Signature privateSignature = Signature.getInstance(signatureAlgorithm);
171 | privateSignature.initSign(privateKey);
172 |
173 | try (InputStream in = new FileInputStream(filePath)) {
174 | byte[] buffer = new byte[1024];
175 | int read;
176 | while ((read = in.read(buffer)) != -1) {
177 | privateSignature.update(buffer, 0, read);
178 | }
179 | }
180 |
181 | byte[] signature = privateSignature.sign();
182 | signatureData = Base64.getEncoder().encodeToString(signature);
183 | } catch (IOException | NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
184 | e.printStackTrace();
185 | }
186 | return signatureData;
187 | }
188 | public static boolean verify(String address, String signature, String filePath) {
189 | boolean isVerified = false;
190 |
191 | // 검증할 파일을 로드합니다.
192 | try {
193 |
194 | System.out.println("uuidMap");
195 | for(Map.Entry entry : uuidMap.entrySet()) {
196 | String key = entry.getKey();
197 | String value = entry.getValue();
198 | System.out.println(key+" : "+value);
199 | }
200 | System.out.println("pubkeyMap");
201 | for(Map.Entry entry : pubKeyMap.entrySet()) {
202 | String key = entry.getKey();
203 | PublicKey value = entry.getValue();
204 | System.out.println(key+" : " + (value!=null));
205 | }
206 | System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
207 | String uuid = uuidMap.get(address);
208 | PublicKey key = pubKeyMap.get(uuid);
209 | if(key == null) {
210 | System.out.println("not find public key");
211 | return isVerified;
212 | }
213 | byte[] signatureData = Base64.getDecoder().decode(signature);
214 | byte[] data = Files.readAllBytes(Paths.get(filePath));
215 | Signature publicSignature = Signature.getInstance(signatureAlgorithm);
216 | publicSignature.initVerify(key);
217 | publicSignature.update(data);
218 |
219 | isVerified = publicSignature.verify(signatureData);
220 | } catch (IOException e) {
221 | e.printStackTrace();
222 | } catch (InvalidKeyException e) {
223 | e.printStackTrace();
224 | } catch (NoSuchAlgorithmException e) {
225 | e.printStackTrace();
226 | } catch (SignatureException e) {
227 | e.printStackTrace();
228 | }
229 |
230 | return isVerified;
231 | }
232 | public static PrivateKey generatePrivateKey(String priKeyPath) {
233 | PrivateKey privateKey = null;
234 | try {
235 | PemReader pemReader = new PemReader(new FileReader(priKeyPath));
236 | PEMParser pemParser = new PEMParser(pemReader);
237 | Object object = pemParser.readObject();
238 | JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
239 |
240 | if (object instanceof PEMKeyPair) {
241 | KeyPair kp = converter.getKeyPair((PEMKeyPair) object);
242 | privateKey = kp.getPrivate();
243 | } else if (object instanceof PrivateKeyInfo) {
244 | privateKey = converter.getPrivateKey((PrivateKeyInfo) object);
245 | }
246 | pemParser.close();
247 | } catch (FileNotFoundException e) {
248 | e.printStackTrace();
249 | } catch (IOException e) {
250 | e.printStackTrace();
251 | }
252 | return privateKey;
253 | }
254 | public static PublicKey generatePublicKey(String pubKeyPath) {
255 | PublicKey pubKey = null;
256 | try {
257 | String publicKeyPEM = new String(Files.readAllBytes(Paths.get(pubKeyPath)));
258 | publicKeyPEM = publicKeyPEM.replace("-----BEGIN PUBLIC KEY-----\n", "");
259 | publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", "");
260 | publicKeyPEM = publicKeyPEM.replace("\n", "");
261 | byte[] encodedPublicKey = Base64.getDecoder().decode(publicKeyPEM);
262 |
263 | X509EncodedKeySpec spec = new X509EncodedKeySpec(encodedPublicKey);
264 | KeyFactory kf = KeyFactory.getInstance("RSA");
265 | pubKey = kf.generatePublic(spec);
266 | } catch (IOException e) {
267 | e.printStackTrace();
268 | } catch (NoSuchAlgorithmException e) {
269 | e.printStackTrace();
270 | } catch (InvalidKeySpecException e) {
271 | e.printStackTrace();
272 | }
273 |
274 | return pubKey;
275 | }
276 | public static void selfSignedCertificate(String crtPath, String priKeyPath, String pubKeyPath, long expirationDate) {
277 | selfSignedCertificate(crtPath, priKeyPath, pubKeyPath, expirationDate, "SHA256withRSA");
278 | }
279 | public static void selfSignedCertificate(String crtPath, String priKeyPath, String pubKeyPath, long expirationDate, String signatureAlgorithm) {
280 | try {
281 | if(!new File(crtPath).exists() || ! new File(priKeyPath).exists() || new File(pubKeyPath).exists()) {
282 | Security.addProvider(new BouncyCastleProvider());
283 |
284 | KeyPairGenerator keyPairGenerator;
285 | keyPairGenerator = KeyPairGenerator.getInstance("RSA");
286 | keyPairGenerator.initialize(2048, new SecureRandom());
287 | KeyPair keyPair = keyPairGenerator.generateKeyPair();
288 |
289 | Date notBefore = new Date();
290 | // Date notAfter = new Date(notBefore.getTime() + 3650L * 24 * 60 * 60 * 1000); // 10 years
291 | // 현재 날짜를 가져옵니다.
292 | LocalDate now = LocalDate.now();
293 |
294 | // 10년 후의 날짜를 계산합니다.
295 | LocalDate tenYearsLater = now.plusDays(expirationDate);
296 |
297 | // LocalDate를 Date로 변환합니다.
298 | Instant instant = tenYearsLater.atStartOfDay(ZoneId.systemDefault()).toInstant();
299 |
300 | Date notAfter = Date.from(instant);
301 |
302 | JcaX509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(
303 | new X500Principal("CN=SelfSigned"), BigInteger.ONE, notBefore, notAfter,
304 | new X500Principal("CN=SelfSigned"), keyPair.getPublic());
305 |
306 | ContentSigner signer = new JcaContentSignerBuilder(signatureAlgorithm).build(keyPair.getPrivate());
307 | X509Certificate cert = new JcaX509CertificateConverter().getCertificate(certBuilder.build(signer));
308 |
309 | // 인증서를 PEM 형식으로 변환
310 | String certPem = "-----BEGIN CERTIFICATE-----\n";
311 | certPem += Base64.getEncoder().encodeToString(cert.getEncoded()).replaceAll("(.{64})", "$1\n");
312 | certPem += "\n-----END CERTIFICATE-----\n";
313 |
314 | // 개인 키를 PEM 형식으로 변환
315 | PrivateKey privateKey = keyPair.getPrivate();
316 | String keyPem = "-----BEGIN PRIVATE KEY-----\n";
317 | keyPem += Base64.getEncoder().encodeToString(privateKey.getEncoded()).replaceAll("(.{64})", "$1\n");
318 | keyPem += "\n-----END PRIVATE KEY-----\n";
319 | // PEM 형식의 인증서와 개인 키를 파일로 저장
320 | Files.write(Paths.get(crtPath), certPem.getBytes());
321 | Files.write(Paths.get(priKeyPath), keyPem.getBytes());
322 | // 인증서에서 공개 키를 추출합니다.
323 | PublicKey publicKey = cert.getPublicKey();
324 |
325 | // 공개 키를 PEM 형식으로 변환합니다.
326 | String publicKeyPEM = "-----BEGIN PUBLIC KEY-----\n";
327 | publicKeyPEM += Base64.getEncoder().encodeToString(publicKey.getEncoded()).replaceAll("(.{64})", "$1\n");
328 | publicKeyPEM += "\n-----END PUBLIC KEY-----\n";
329 |
330 | // PEM 형식의 공개 키를 파일로 저장합니다.
331 | Files.write(Paths.get(pubKeyPath), publicKeyPEM.getBytes());
332 | }
333 | } catch (NoSuchAlgorithmException e) {
334 | // TODO Auto-generated catch block
335 | e.printStackTrace();
336 | } catch (OperatorCreationException e) {
337 | // TODO Auto-generated catch block
338 | e.printStackTrace();
339 | } catch (CertificateException e) {
340 | // TODO Auto-generated catch block
341 | e.printStackTrace();
342 | } catch (IOException e) {
343 | // TODO Auto-generated catch block
344 | e.printStackTrace();
345 | }
346 | }
347 | public static String sign(String priKeyPath, String filePath) {
348 | return sign(priKeyPath, filePath, "SHA256withRSA");
349 | }
350 | public static String sign(String priKeyPath, String filePath, String signatureAlgorithm) {
351 | String signatureData = "none";
352 | // 개인 키 파일을 로드합니다.
353 | try {
354 | PemReader pemReader = new PemReader(new FileReader(priKeyPath));
355 | PEMParser pemParser = new PEMParser(pemReader);
356 | Object object = pemParser.readObject();
357 | JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
358 | PrivateKey privateKey = null;
359 |
360 | if (object instanceof PEMKeyPair) {
361 | KeyPair kp = converter.getKeyPair((PEMKeyPair) object);
362 | privateKey = kp.getPrivate();
363 | } else if (object instanceof PrivateKeyInfo) {
364 | privateKey = converter.getPrivateKey((PrivateKeyInfo) object);
365 | }
366 | // 텍스트 파일을 로드합니다.
367 | byte[] data = Files.readAllBytes(Paths.get(filePath));
368 |
369 | // SHA-256 해시를 계산하고, 이를 개인 키로 서명합니다.
370 | Signature privateSignature = Signature.getInstance(signatureAlgorithm);
371 | privateSignature.initSign(privateKey);
372 | privateSignature.update(data);
373 | byte[] signature = privateSignature.sign();
374 | signatureData = Base64.getEncoder().encodeToString(signature);
375 |
376 | pemParser.close();
377 | //// 서명을 파일로 직접 저장합니다.
378 | // Files.write(Paths.get("/home/keti/cert/sign.crt"), signature);
379 | } catch (FileNotFoundException e) {
380 | e.printStackTrace();
381 | } catch (IOException e) {
382 | e.printStackTrace();
383 | } catch (NoSuchAlgorithmException e) {
384 | e.printStackTrace();
385 | } catch (InvalidKeyException e) {
386 | e.printStackTrace();
387 | } catch (SignatureException e) {
388 | e.printStackTrace();
389 | }
390 |
391 | return signatureData;
392 | }
393 | public static boolean verify(byte[] signature, String pubKeyPath, String filePath) {
394 | return verify(signature, pubKeyPath, filePath, "SHA256withRSA");
395 | }
396 | public static boolean verify(byte[] signature, String pubKeyPath, String filePath, String signatureAlgorithm) {
397 | boolean isVerified = false;
398 |
399 | // 공개 키 파일을 로드합니다.
400 | try {
401 | String publicKeyPEM = new String(Files.readAllBytes(Paths.get(pubKeyPath)));
402 | // PEM 형식에서 불필요한 헤더와 푸터를 제거합니다.
403 | publicKeyPEM = publicKeyPEM.replace("-----BEGIN PUBLIC KEY-----\n", "");
404 | publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", "");
405 | publicKeyPEM = publicKeyPEM.replace("\n", "");
406 | // Base64로 인코딩된 키를 디코딩합니다.
407 | byte[] encodedPublicKey = Base64.getDecoder().decode(publicKeyPEM);
408 |
409 | // 바이트 배열을 PublicKey 객체로 변환합니다.
410 | X509EncodedKeySpec spec = new X509EncodedKeySpec(encodedPublicKey);
411 | KeyFactory kf = KeyFactory.getInstance("RSA");
412 | PublicKey publicKey = kf.generatePublic(spec);
413 |
414 | // 서명 파일을 로드합니다.
415 | // byte[] signature = Files.readAllBytes(Paths.get(signPath));
416 |
417 | // 검증할 파일을 로드합니다.
418 | byte[] data = Files.readAllBytes(Paths.get(filePath)); // 실제 파일 경로로 대체하세요.
419 |
420 | // SHA-256 해시를 계산하고, 이를 공개 키로 검증합니다.
421 | Signature publicSignature = Signature.getInstance(signatureAlgorithm);
422 | publicSignature.initVerify(publicKey);
423 | publicSignature.update(data);
424 |
425 | isVerified = publicSignature.verify(signature);
426 | } catch (IOException e) {
427 | e.printStackTrace();
428 | } catch (NoSuchAlgorithmException e) {
429 | e.printStackTrace();
430 | } catch (InvalidKeySpecException e) {
431 | e.printStackTrace();
432 | } catch (InvalidKeyException e) {
433 | e.printStackTrace();
434 | } catch (SignatureException e) {
435 | e.printStackTrace();
436 | }
437 | return isVerified;
438 | }
439 | }
440 |
--------------------------------------------------------------------------------
/src/kr/re/keti/agent/Agent.java:
--------------------------------------------------------------------------------
1 | package kr.re.keti.agent;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.BufferedWriter;
5 | import java.io.File;
6 | import java.io.FileReader;
7 | import java.io.FileWriter;
8 | import java.io.IOException;
9 | import java.net.Socket;
10 | import java.nio.file.Files;
11 | import java.nio.file.Paths;
12 | import java.nio.file.StandardOpenOption;
13 | import java.text.DecimalFormat;
14 | import java.time.LocalTime;
15 | import java.time.format.DateTimeFormatter;
16 | import java.util.ArrayList;
17 | import java.util.Arrays;
18 | import java.util.Base64;
19 | import java.util.Date;
20 | import java.util.Hashtable;
21 | import java.util.List;
22 |
23 | import kr.re.keti.DataProcess;
24 | import kr.re.keti.FileHandler;
25 | import kr.re.keti.Main;
26 | import kr.re.keti.PortNum;
27 | import kr.re.keti.RamDiskManager;
28 | import kr.re.keti.ResponseProcess;
29 | import kr.re.keti.Ssl;
30 | import kr.re.keti.database.Database;
31 | import kr.re.keti.database.FileManagementDto;
32 | import kr.re.keti.database.FileUuidDto;
33 | import kr.re.keti.os.OSProcess;
34 | import kr.re.keti.tcp.UnitEdge;
35 | import kr.re.keti.tcp.UnitShared;
36 |
37 | public class Agent extends EdgeDataAggregator{
38 | private static final Agent instance = new Agent();
39 | public Database database;
40 | public static Hashtable unitTable;
41 | private ResponseProcess responseProcess;
42 | private List logFilters;
43 | private List responseFilters;
44 | private RamDiskManager ramDiskManager;
45 | private Agent() {
46 | logFilters = Arrays.asList(-1, 10, 200, 300, 399, 400, 405, 406, 444, 19, 20);
47 | responseFilters = Arrays.asList();
48 | setStandard(1000);
49 | }
50 |
51 | public static Agent getInstance() {
52 | return instance;
53 | }
54 | public void setDatabase(Database database) {
55 | instance.database = database;
56 | responseProcess = new ResponseProcess(database);
57 | ramDiskManager = RamDiskManager.getInstance(Main.ramFolder, Main.storageFolder);
58 | }
59 | @Override
60 | void receive(AgentPacket packet) {
61 | byte[] originalData = packet.getData();
62 | String dataString = new String(originalData);
63 | if(!(dataString.startsWith("{[{") && dataString.endsWith("}]}"))) return;
64 |
65 | String message = DataProcess.messageFormat(dataString);
66 | String datas[] = message.split("::");
67 | String address = datas[1];
68 | int code = Integer.parseInt(datas[2]);
69 | // if(!address.equals(Main.deviceIP)) {
70 | // if(code==400) {
71 | // if(dataString.length()>500) {
72 | // String[] temp = dataString.split("::");
73 | // temp[temp.length-1] = "...}]}";
74 | // System.out.println(String.join("::", temp));
75 | // }
76 | // else {
77 | // System.out.println(dataString);
78 | // }
79 | // }
80 | // else {
81 | // System.out.println(dataString);
82 | // }
83 | // }
84 |
85 | // if(!address.equals(Main.deviceIP) && code == 400) {
86 | // System.out.println("1================================================================================================");
87 | // System.out.println(address+"::"+datas[3]+": "+LocalTime.now().format(DateTimeFormatter.ofPattern("H:m:s.SSS")));
88 | //// System.out.println(dataString);
89 | // System.out.println("2================================================================================================");
90 | // System.out.println();
91 | //
92 | // }
93 | //-------------------Accept Log--------------------
94 | if(shouldLog(code)) {
95 | System.out.println();
96 | log(message);
97 | }
98 |
99 | //------------------process----------------------
100 | Socket socket = packet.getSocket();
101 | if(socket == null) {
102 | messageProcess(originalData);
103 | }
104 | else {
105 | tcpProcess(packet);
106 | }
107 |
108 | //-----------------Complete Log------------------
109 | if(shouldLog(code)) {
110 | logLine("complete", address);
111 | System.out.print(">>>");
112 | }
113 | }
114 |
115 | private void tcpProcess(AgentPacket packet) {
116 | byte[] originalData = packet.getData();
117 | String dataString = new String(originalData);
118 | String requestData = DataProcess.messageFormat(dataString);
119 | String[] datas = requestData.split("::");
120 | String address = datas[1];
121 | int requestCode = Integer.parseInt(datas[2]);
122 | String response = "none";
123 | switch(requestCode) {
124 | case 1:
125 | String type = datas[3];
126 | switch(type) {
127 | case "EDGE_LIST":
128 | response = responseProcess.responseInitEdgeList(address); break;
129 | case "SLAVE_LIST":
130 | response = responseProcess.responseEdgeList(address); break;
131 | case "DEV_STATUS":
132 | response = responseProcess.responseDeviceInformation(address); break;
133 | }
134 | break;
135 | case 2:
136 | response = responseProcess.responseWholeDataInformation(address); break;
137 | case 3: {
138 | String dataid = datas[3];
139 | if(requestCode == 3) {
140 | response = responseProcess.responseMetaDataInformation(address, dataid);
141 | }
142 | break;
143 | }
144 | case 6:{
145 | String dataid = datas[3];
146 | response = responseProcess.responseIndividualDataRemove(address, dataid);
147 | break;
148 | }
149 | case 20:{
150 | String uuid = datas[3].trim();
151 | String data = datas[4];
152 | String path = Ssl.getPath();
153 | path = path+"keys/"+uuid+".key";
154 |
155 | Ssl.addKey(address, uuid, data);
156 | response = "{[{ANS::"+address+"::020::success}]}";
157 | break;
158 | }
159 | case 399:{
160 | String fileName = datas[3];
161 | String uuid = datas[4];
162 | UnitShared unit = UnitShared.getInstance(fileName, uuid);
163 | unit.addReadyCount();
164 | response = "{[{ANS::"+address+"::399::success}]}";
165 | break;
166 | }
167 | case 400:{
168 | String uuid = datas[3];
169 | uuid = uuid.substring(0, uuid.indexOf("_"));
170 | final String chunkUuid = uuid;
171 | UnitShared unit = UnitShared.getInstanceUuid(chunkUuid);
172 | unit.countAdd(address, datas[3]);
173 | response = "{[{ANS::"+address+"::400::"+datas[3]+"::success}]}";
174 | break;
175 | }
176 | case 401:
177 | case 405:
178 | String dataid = datas[3];
179 | int startIdx = Integer.parseInt(datas[4]);
180 | int finishIdx = Integer.parseInt(datas[5]);
181 | if(requestCode == 401) {
182 | response = responseProcess.responseChunkCreate(address, dataid, startIdx, finishIdx);
183 | }
184 | else if(requestCode == 405) {
185 | response = responseProcess.responseSha(address, dataid, startIdx, finishIdx);
186 | UnitEdge unitEdge = new UnitEdge(database, address, dataid, startIdx, finishIdx);
187 | unitEdge.start();
188 | }
189 | break;
190 | case 406:
191 | Socket socket = packet.getSocket();
192 | if(socket == null) return;
193 |
194 | String chunkName = datas[3];
195 | int chunkLength = Integer.parseInt(datas[4]);
196 | int chunkEndIdx = originalData.length - 3;
197 | int chunkStartIdx = chunkEndIdx - chunkLength;
198 | byte[] data = new byte[chunkLength];
199 | System.arraycopy(originalData, chunkStartIdx, data, 0, chunkLength);
200 | AgentPacket unitPacket = new AgentPacket(socket, data);
201 | unitTable.put(chunkName, unitPacket);
202 | break;
203 | case 444:
204 | String fileName = datas[3];
205 | response = responseProcess.responseSha(address, fileName);
206 | break;
207 | default:
208 | System.out.println("TCP ["+requestCode+"] is undefined ");
209 | }
210 |
211 | //-----------------------------------------------------------------------------
212 | if(packet.getSocket() != null) {
213 | send(packet.getSocket(), response.getBytes());
214 | // System.out.println("receive: "+response+" : "+LocalTime.now().format(DateTimeFormatter.ofPattern("H:m:s.SSS")));
215 | }
216 | if(shouldRespond(requestCode)) {
217 | send(response.getBytes());
218 | }
219 | }
220 | private void messageProcess(byte[] originalMessage) {
221 | String message = DataProcess.messageFormat(new String(originalMessage));
222 | String[] datas = message.split("::");
223 | String address = datas[1];
224 | int code = Integer.parseInt(datas[2]);
225 |
226 | if(address.equals(Main.deviceIP) && code != 200) {
227 | return;
228 | }
229 | switch(code) {
230 | case -1:
231 | break;
232 | case 1:
233 | break;
234 | case 10:{
235 | String data = datas[3];
236 | FileManagementDto dto = DataProcess.metaDataToDto(data);
237 | database.insert(dto);
238 | break;
239 | }
240 | case 11:{
241 | String dataid = datas[3];
242 | FileManagementDto dto = (FileManagementDto) database.select("file_management", dataid);
243 | String extension = dto.getFileType();
244 | String fileName = dataid + "." +extension;
245 | byte[] data = getData(originalMessage);
246 | // ramDiskManager.createFile(fileName, data);
247 | ramDiskManager.download(fileName, data);
248 |
249 | // byte[] sign = Base64.getDecoder().decode(dto.getDataSign());
250 | String sign = dto.getDataSign();
251 | String ipAddress = dto.getLinkedEdge();
252 | try {
253 | Thread.sleep(100);
254 | if(!Ssl.verify(ipAddress, sign, Main.storageFolder+fileName)) {
255 | System.out.println("sign verify fail");
256 | }
257 | } catch (Exception e) {
258 | e.printStackTrace();
259 | }
260 | break;
261 | }
262 | case 12:{
263 | String dataid = datas[3];
264 | FileManagementDto dto = (FileManagementDto) database.select("file_management", dataid);
265 | dto.setDataSize(Long.parseLong(datas[4]));
266 | String extension = dto.getFileType();
267 | String fileName = dataid + "." +extension;
268 | byte[] data = getData(originalMessage);
269 | ramDiskManager.createFile(fileName, data);
270 | database.update(dto);
271 | break;
272 | }
273 | case 13:{
274 | String dataid = datas[3];
275 | FileManagementDto dto = (FileManagementDto) database.select("file_management", dataid);
276 | if(dto == null) break;
277 | database.delete("file_management", dataid);
278 | if(dto.getLinkedEdge().equals(Main.deviceIP)) {
279 | dataid = ((FileUuidDto) database.executeQuery("select * from file_uuid where fileUuid='"+dataid+"';").get(0)).getFileName();
280 | }
281 | String extension = dto.getFileType();
282 | String fileName = dataid+"."+extension;
283 | ramDiskManager.remove(fileName, "");
284 | break;
285 | }
286 | case 14:
287 | break;
288 | case 15:
289 | break;
290 | case 16:
291 | break;
292 | case 19:{
293 | String uuid = datas[3];
294 | String data = datas[5];
295 | Ssl.addKey(address, uuid, data);
296 |
297 |
298 | Agent agent = Agent.getInstance();
299 | String keyData = Ssl.getKey(Main.deviceIP);
300 | agent.send(address, ("{[{REQ::"+Main.deviceIP+"::020::"+Main.uuid+"::"+keyData+"}]}").getBytes());
301 | for(String ip : OSProcess.edgeList) {
302 | if(!ip.equals(address)) {
303 | keyData = Ssl.getKey(ip);
304 | String keyUuid = Ssl.getUuid(ip);
305 | agent.send(address, ("{[{REQ::"+ip+"::020::"+keyUuid+"::"+keyData+"}]}").getBytes());
306 | }
307 | }
308 | break;
309 | }
310 | case 200:{
311 | logSave(message);
312 | break;
313 | }
314 | case 500:{
315 | String data = datas[3];
316 | String[] logData = data.split("#");
317 | FileHandler handler = FileHandler.getInstance();
318 | if(handler.isExists(logData[1])) {
319 | handler.deleteRecord(logData[1]);
320 | }
321 | handler.addRecord(data);
322 | break;
323 | }
324 | case 399:{
325 | String fileName = datas[3];
326 | String uuid = datas[4];
327 | int chunkLength = Integer.parseInt(datas[5]);
328 |
329 | UnitShared unit = UnitShared.getInstance(fileName, uuid);
330 | unit.setLength(chunkLength);
331 |
332 | Agent agent = Agent.getInstance();
333 | byte[] requestMessage = DataProcess.messageCreate("REQ", Main.deviceIP, "399", fileName, "success");
334 | agent.send(address, requestMessage);
335 | break;
336 | }
337 | case 400:{
338 | String chunk = datas[3];
339 | String dataid = chunk.substring(0, chunk.indexOf("_"));
340 | byte[] data = getData(originalMessage);
341 |
342 | UnitShared unit = UnitShared.getInstanceUuid(dataid);
343 | unit.receive(address, chunk, data);
344 |
345 | break;
346 | }
347 | default:
348 | System.out.println("message ["+code+"] is undefined ");
349 | }
350 |
351 | }
352 | private void log(String message) {
353 | String datas[] = message.split("::");
354 | String address = datas[1];
355 | int requestCode = Integer.parseInt(datas[2]);
356 | logLine("Accept",address);
357 | switch(requestCode) {
358 | case 1:
359 | String type = datas[3];
360 | switch(type) {
361 | case "EDGE_LIST": logFun("Edge List Update"); break;
362 | case "SLAVE_LIST": logFun("Newest Edge List"); break;
363 | case "DEV_STATUS": logFun("Device Information"); break;
364 | }
365 | break;
366 | case 2: logFun("Whole Data Information"); break;
367 | case 3: {
368 | String dataid = datas[3];
369 | logData("MetaData Information", dataid);
370 | break;
371 | }
372 | case 6: {
373 | String dataid = datas[3];
374 | logData("Data Remove", dataid);
375 | break;
376 | }
377 | case 11:
378 | case 111:
379 | case 12:
380 | case 112:
381 | case 13:
382 | case 113:
383 | case 14:
384 | case 15:
385 | case 16:{
386 | String dataid = datas[3];
387 | String logMessage[] = {
388 | "create File",
389 | "Update File",
390 | "Delete File",
391 | "Create Directory",
392 | "Update Directory",
393 | "Delete Directory"
394 | };
395 | int messageIdx = -1;
396 | if(requestCode>100) {
397 | messageIdx = requestCode -111;
398 | }
399 | else {
400 | messageIdx = requestCode -11;
401 | }
402 | logData(logMessage[messageIdx], dataid);
403 | break;
404 | }
405 | case 401:{
406 | String dataid = datas[3];
407 | int startIdx = Integer.parseInt(datas[4]);
408 | int finishIdx = Integer.parseInt(datas[5]);
409 | logChunk("Data read", dataid, startIdx, finishIdx);
410 | break;
411 |
412 | }
413 | }
414 |
415 | }
416 | private void logLine(String type, String address) {
417 | Date now = new Date(System.currentTimeMillis());
418 | System.out.println(" <-- "+logFormat.format(now)+"\tData Processing Request from "+address+" : "+type+" -->");
419 |
420 | }
421 | private void logFun(String type) {
422 | System.out.println("\tRequest Function : "+type);
423 | }
424 | private void logData(String type, String dataid) {
425 | logFun(type);
426 | System.out.println("\tDataID : "+dataid);
427 | }
428 | private void logChunk(String type, String dataid, int startIdx, int finishIdx) {
429 | logData(type, dataid);
430 | System.out.println("\tchunk : #"+startIdx+" to #"+finishIdx);
431 | }
432 | private boolean shouldLog(int code) {
433 | if(logFilters.contains(code)) {
434 | return false;
435 | }
436 | return true;
437 | }
438 | private boolean shouldRespond(int code) {
439 | if(responseFilters.contains(code)) {
440 | return true;
441 | }
442 | return false;
443 |
444 | }
445 | private byte[] getData(byte[] originalData) {
446 | String message = DataProcess.messageFormat(new String(originalData));
447 | String[] datas = message.split("::");
448 |
449 | // int fileSize = Integer.parseInt(datas[4]);
450 | String encodingData = datas[5];
451 | byte[] data = Base64.getDecoder().decode(encodingData);
452 | // int dataEndIdx = originalData.length -3;
453 | // int dataStartIdx = dataEndIdx - fileSize;
454 | // byte[] data = new byte[fileSize];
455 | // System.arraycopy(originalData, dataStartIdx, data, 0, fileSize);
456 |
457 | return data;
458 | }
459 | private void logSave(String message) {
460 | String[] datas = message.split("::");
461 |
462 | String address = datas[1];
463 | String status = "";
464 | String metadata = datas[4];
465 | switch(datas[3]) {
466 | case "011":
467 | case "111":
468 | status = "file create"; break;
469 | case "012":
470 | case "112":
471 | status = "file update"; break;
472 | case "013": status = "file delete"; break;
473 | case "014": status = "directory create"; break;
474 | case "015": status = "directory update"; break;
475 | case "016": status = "directory delete"; break;
476 | case "017": status = "Security Level update"; break;
477 | default: return;
478 | }
479 | FileManagementDto dto = new FileManagementDto(metadata);
480 | }
481 | }
482 |
--------------------------------------------------------------------------------
/src/kr/re/keti/agent/AgentPacket.java:
--------------------------------------------------------------------------------
1 | package kr.re.keti.agent;
2 |
3 | import java.net.Socket;
4 | import java.util.function.Consumer;
5 |
6 | public class AgentPacket {
7 | private Socket socket;
8 | private String address;
9 | private int port;
10 | private byte[] data;
11 | private Consumer callback;
12 |
13 | public AgentPacket(byte[] data) {
14 | this.data = data;
15 | }
16 |
17 | public AgentPacket(Socket socket, byte[] data) {
18 | super();
19 | this.socket = socket;
20 | this.data = data;
21 | }
22 |
23 | public AgentPacket(String address, int port, byte[] data) {
24 | super();
25 | this.address = address;
26 | this.port = port;
27 | this.data = data;
28 | }
29 |
30 | public AgentPacket(Socket socket, String address, int port, byte[] data) {
31 | this.socket = socket;
32 | this.address = address;
33 | this.port = port;
34 | this.data = data;
35 | }
36 |
37 | public Socket getSocket() {
38 | return socket;
39 | }
40 |
41 | public void setSocket(Socket socket) {
42 | this.socket = socket;
43 | }
44 |
45 | public String getAddress() {
46 | return address;
47 | }
48 |
49 | public void setAddress(String address) {
50 | this.address = address;
51 | }
52 |
53 | public int getPort() {
54 | return port;
55 | }
56 |
57 | public void setPort(int port) {
58 | this.port = port;
59 | }
60 |
61 | public byte[] getData() {
62 | return data;
63 | }
64 |
65 | public void setData(byte[] data) {
66 | this.data = data;
67 | }
68 |
69 | public void setCallback(Consumer callback) {
70 | this.callback = callback;
71 | }
72 |
73 | public Consumer getCallback() {
74 | return callback;
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/src/kr/re/keti/agent/EdgeDataAggregator.java:
--------------------------------------------------------------------------------
1 | package kr.re.keti.agent;
2 |
3 | import java.io.IOException;
4 | import java.io.OutputStream;
5 | import java.net.Socket;
6 | import java.text.SimpleDateFormat;
7 | import java.util.concurrent.ArrayBlockingQueue;
8 | import java.util.concurrent.CountDownLatch;
9 | import java.util.concurrent.atomic.AtomicReference;
10 | import java.util.function.Consumer;
11 |
12 | import kr.re.keti.PortNum;
13 | import kr.re.keti.database.Database;
14 | import kr.re.keti.tcp.Client;
15 | import kr.re.keti.tcp.Server;
16 |
17 | abstract class EdgeDataAggregator {
18 | protected final SimpleDateFormat logFormat = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss.SSS");
19 | private int STANDARD;
20 | private final int CAPACITY = 5000;
21 | protected Database database;
22 | private ArrayBlockingQueue sendQueue;
23 | private ArrayBlockingQueue sendMqttQueue;
24 | private ArrayBlockingQueue sendTcpQueue;
25 | private ArrayBlockingQueue sendKafkaQueue;
26 | private ArrayBlockingQueue receiveQueue;
27 | private Mqtt mqtt;
28 | private Kafka kafka;
29 | private Server ketiServer;
30 | private Server pentaServer;
31 | private Thread sendThread;
32 | private Thread receiveThread;
33 | private Client client;
34 |
35 | public EdgeDataAggregator() {
36 | STANDARD = 5000;
37 | sendQueue = new ArrayBlockingQueue<>(CAPACITY);
38 | receiveQueue = new ArrayBlockingQueue<>(CAPACITY);
39 | sendMqttQueue = new ArrayBlockingQueue<>(CAPACITY);
40 | sendTcpQueue = new ArrayBlockingQueue<>(CAPACITY);
41 | sendKafkaQueue = new ArrayBlockingQueue<>(CAPACITY);
42 | ketiServer = new Server(PortNum.KETI_PORT, receiveQueue);
43 | pentaServer = new Server(PortNum.PENTA_PROT, receiveQueue);
44 | client = new Client(sendTcpQueue);
45 | }
46 |
47 | public void setStandard(int standard) {
48 | this.STANDARD = standard;
49 | }
50 |
51 | public int getStandard() {
52 | return this.STANDARD;
53 | }
54 |
55 | public void start() {
56 | if(sendThread == null || sendThread.getState() == Thread.State.TERMINATED) {
57 | initSendThread();
58 | sendThread.start();
59 | }
60 | if(receiveThread == null || receiveThread.getState() == Thread.State.TERMINATED) {
61 | initReceiveThread();
62 | receiveThread.start();
63 | }
64 |
65 | mqtt = new Mqtt("/", sendMqttQueue, receiveQueue);
66 | mqtt.start();
67 |
68 | kafka = new Kafka("keti", sendQueue, receiveQueue);
69 | kafka.start();
70 |
71 | client.start();
72 | ketiServer.start();
73 | pentaServer.start();
74 | }
75 |
76 | public void stop() {
77 | if(mqtt != null)
78 | mqtt.stop();
79 | if(kafka != null)
80 | kafka.stop();
81 |
82 | if(sendThread != null) {
83 | sendThread.interrupt();
84 | try {
85 | sendThread.join();
86 | } catch (InterruptedException e) {
87 | e.printStackTrace();
88 | }
89 | }
90 | if(receiveThread != null) {
91 | receiveThread.interrupt();
92 | try {
93 | receiveThread.join();
94 | } catch (InterruptedException e) {
95 | e.printStackTrace();
96 | }
97 | }
98 | }
99 |
100 | private void initReceiveThread() {
101 | receiveThread = new Thread(() -> {
102 | try {
103 | while (!Thread.currentThread().isInterrupted()) {
104 | AgentPacket packet = receiveQueue.take();
105 | receive(packet);
106 | }
107 | } catch (InterruptedException e) {
108 | return;
109 | }
110 | });
111 | receiveThread.setName("sendThread");
112 | }
113 |
114 | public void addReceive(AgentPacket packet) {
115 | try {
116 | receiveQueue.put(packet);
117 | } catch (InterruptedException e) {
118 | e.printStackTrace();
119 | }
120 | }
121 |
122 | private void initSendThread() {
123 | sendThread = new Thread(() -> {
124 | try {
125 | while (!Thread.currentThread().isInterrupted()) {
126 | AgentPacket packet = sendQueue.take();
127 | Socket socket = packet.getSocket();
128 | String address = packet.getAddress();
129 | byte[] data = packet.getData();
130 | int len = data.length;
131 | if(socket != null || address != null) { //TCP
132 | sendTcpQueue.put(packet);
133 | }
134 | else if(len < STANDARD) { // MQTT
135 | sendMqttQueue.put(packet);
136 | }
137 | else if(len >= STANDARD) { // Kafka
138 | sendKafkaQueue.put(packet);
139 | }
140 | }
141 | } catch (InterruptedException e) {
142 | return;
143 | }
144 | });
145 | sendThread.setName("sendKetiThread");
146 | }
147 |
148 | public void send(byte[] data) {
149 | AgentPacket packet = new AgentPacket(data);
150 | try {
151 | sendQueue.put(packet);
152 | } catch (InterruptedException e) {
153 | e.printStackTrace();
154 | }
155 | }
156 |
157 | public byte[] send(String address, byte[] data) {
158 | AtomicReference response = new AtomicReference<>();
159 | try {
160 | if(address != null) {
161 | CountDownLatch latch = new CountDownLatch(1);
162 | Consumer callback = responseData -> {
163 | response.set(responseData);
164 | latch.countDown();
165 | };
166 | int port = portCategorization(new String(data));
167 |
168 | AgentPacket packet = new AgentPacket(address, port, data);
169 | packet.setCallback(callback);
170 | sendTcpQueue.put(packet);
171 | latch.await();
172 | }
173 | else {
174 | send(data);
175 | }
176 |
177 | } catch (InterruptedException e) {
178 | e.printStackTrace();
179 | }
180 | return response.get();
181 | }
182 |
183 | public void send(Socket socket, byte[] data) {
184 | AgentPacket packet = new AgentPacket(socket, data);
185 | if(socket != null) {
186 | String message = new String(data);
187 | if(message.indexOf("ANS") != -1) {
188 | try {
189 | OutputStream outputStream = socket.getOutputStream();
190 | outputStream.write(data);
191 | outputStream.flush();
192 | } catch (IOException e) {
193 | e.printStackTrace();
194 | }
195 | }
196 | }
197 | else {
198 | try {
199 | sendTcpQueue.put(packet);
200 | } catch (InterruptedException e) {
201 | e.printStackTrace();
202 | }
203 | }
204 | }
205 |
206 | public void sendThread() {
207 |
208 | }
209 |
210 | abstract int portCategorization(String massage);
211 |
212 | abstract void receive(AgentPacket packet);
213 |
214 | }
215 |
--------------------------------------------------------------------------------
/src/kr/re/keti/agent/Kafka.java:
--------------------------------------------------------------------------------
1 | package kr.re.keti.agent;
2 |
3 | import java.time.Duration;
4 | import java.util.Arrays;
5 | import java.util.Collections;
6 | import java.util.Properties;
7 | import java.util.concurrent.ArrayBlockingQueue;
8 |
9 | import org.apache.kafka.clients.admin.AdminClient;
10 | import org.apache.kafka.clients.admin.NewTopic;
11 | import org.apache.kafka.clients.consumer.ConsumerConfig;
12 | import org.apache.kafka.clients.consumer.ConsumerRecord;
13 | import org.apache.kafka.clients.consumer.ConsumerRecords;
14 | import org.apache.kafka.clients.consumer.KafkaConsumer;
15 | import org.apache.kafka.clients.producer.Callback;
16 | import org.apache.kafka.clients.producer.KafkaProducer;
17 | import org.apache.kafka.clients.producer.ProducerConfig;
18 | import org.apache.kafka.clients.producer.ProducerRecord;
19 | import org.apache.kafka.clients.producer.RecordMetadata;
20 | import org.apache.kafka.common.serialization.ByteArrayDeserializer;
21 | import org.apache.kafka.common.serialization.ByteArraySerializer;
22 | import org.apache.kafka.common.serialization.StringDeserializer;
23 | import org.apache.kafka.common.serialization.StringSerializer;
24 | import org.slf4j.simple.SimpleLogger;
25 |
26 | import kr.re.keti.Main;
27 | import kr.re.keti.PortNum;
28 |
29 | public class Kafka {
30 | private String topic;
31 | private ArrayBlockingQueue sendQueue;
32 | private ArrayBlockingQueue receiveQueue;
33 | private KafkaProducer producer;
34 | private KafkaConsumer consumer;
35 | private Thread producerThread;
36 | private Thread consumerThread;
37 | private String serverIP;
38 |
39 | public Kafka(String topic, ArrayBlockingQueue sendQueue, ArrayBlockingQueue receiveQueue) {
40 | System.setProperty(SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "OFF");
41 |
42 | serverIP = Main.masterIP + ":" + PortNum.DEFAULT_KAFKA_PORT;
43 | this.topic = topic;
44 | this.sendQueue = sendQueue;
45 | this.receiveQueue = receiveQueue;
46 | producer();
47 | consumer();
48 | }
49 |
50 | public void producer() {
51 | Properties properties = new Properties();
52 | properties.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, serverIP);
53 | properties.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
54 | properties.setProperty(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, ByteArraySerializer.class.getName());
55 |
56 | producer = new KafkaProducer<>(properties);
57 |
58 | }
59 |
60 | public void consumer() {
61 | Properties properties = new Properties();
62 | properties.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, serverIP);
63 | properties.setProperty(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
64 | properties.setProperty(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, ByteArrayDeserializer.class.getName());
65 | properties.setProperty(ConsumerConfig.GROUP_ID_CONFIG, Main.uuid);
66 | // properties.setProperty(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
67 | properties.setProperty(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "latest");
68 | properties.put(ConsumerConfig.CLIENT_ID_CONFIG, Main.uuid);
69 | properties.put(ConsumerConfig.GROUP_INSTANCE_ID_CONFIG, (Main.uuid));
70 |
71 | consumer = new KafkaConsumer<>(properties);
72 | }
73 |
74 | public void admin() {
75 | Properties properties = new Properties();
76 | properties.put("bootstrap.servers", serverIP);
77 | AdminClient adminClient = AdminClient.create(properties);
78 |
79 | int numPartitions = 3;
80 | short replicationFactor = 1;
81 |
82 | // NewTopic 객체 생성
83 | NewTopic newTopic = new NewTopic(topic, numPartitions, replicationFactor);
84 |
85 | // 토픽 생성
86 | adminClient.createTopics(Collections.singletonList(newTopic));
87 |
88 | adminClient.close();
89 |
90 | }
91 |
92 | public void start() {
93 | initThread();
94 | producerThread.start();
95 | consumerThread.start();
96 | }
97 |
98 | public void stop() {
99 | if(producerThread != null)
100 | producerThread.interrupt();
101 | if(consumerThread != null)
102 | consumerThread.interrupt();
103 | producer.close();
104 | consumer.close();
105 | }
106 |
107 | public void initThread() {
108 | producerThread = new Thread(() -> {
109 | try {
110 | while (!Thread.currentThread().isInterrupted()) {
111 | AgentPacket packet = sendQueue.take();
112 | byte[] data = packet.getData();
113 | ProducerRecord producerRecord = new ProducerRecord<>(topic, data);
114 |
115 | producer.send(producerRecord, new Callback() {
116 | @Override
117 | public void onCompletion(RecordMetadata metadata, Exception exception) {
118 | if(exception != null) {
119 | // 데이터 전송이 실패한 경우
120 | // System.err.println("Failed to send data: " + exception.getMessage());
121 | }
122 | else {
123 | // 데이터 전송이 성공한 경우
124 | // System.out.println("Data sent successfully: " + metadata);
125 | }
126 | }
127 | }
128 | }
129 | } catch (Exception e) {
130 | e.printStackTrace();
131 | }
132 | }
133 |
134 | consumerThread = new Thread(() -> {
135 | try {
136 | consumer.subscribe(Arrays.asList(topic));
137 | while (!Thread.currentThread().isInterrupted()) {
138 | ConsumerRecords records = consumer.poll(Duration.ofMillis(100));
139 | for (ConsumerRecord record : records) {
140 | byte[] data = record.value();
141 | AgentPacket packet = new AgentPacket(null, data);
142 | receiveQueue.put(packet);
143 | }
144 | }
145 | } catch (Exception e) {
146 | e.printStackTrace();
147 | }
148 | }
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/src/kr/re/keti/agent/Mqtt.java:
--------------------------------------------------------------------------------
1 | package kr.re.keti.agent;
2 |
3 | import java.util.concurrent.ArrayBlockingQueue;
4 |
5 | import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
6 | import org.eclipse.paho.client.mqttv3.MqttCallback;
7 | import org.eclipse.paho.client.mqttv3.MqttClient;
8 | import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
9 | import org.eclipse.paho.client.mqttv3.MqttException;
10 | import org.eclipse.paho.client.mqttv3.MqttMessage;
11 |
12 | import kr.re.keti.Main;
13 | import kr.re.keti.PortNum;
14 |
15 | public class Mqtt {
16 | private MqttClient client;
17 | private String topic;
18 | private String clientId = MqttClient.generateClientId();
19 | private ArrayBlockingQueue sendQueue, receiveQueue;
20 | private Thread publishThread;
21 | private String address;
22 |
23 | public Mqtt(String topic, ArrayBlockingQueue sendQueue, ArrayBlockingQueue receiveQueue) {
24 | this.topic = topic;
25 | this.sendQueue = sendQueue;
26 | this.receiveQueue = receiveQueue;
27 | address = "tcp://" + Main.masterIP + ":" + PortNum.DEFAULT_MQTT_PORT;
28 | try {
29 | client = new MqttClient(address, clientId);
30 | } catch (Exception e) {
31 | e.printStackTrace();
32 | }
33 | process();
34 |
35 | }
36 |
37 | private void process() {
38 | client.setCallback(new MqttCallback() {
39 | @Override
40 | public void connectionLost(Throwable cause) {
41 | System.out.println("Connection lost");
42 | }
43 |
44 | @Override
45 | public void messageArrived(String topic, MqttMessage message) throws Exception {
46 | String data = message + "";
47 | AgentPacket packet = new AgentPacket(data.getBytes());
48 | receiveQueue.put(packet);
49 | }
50 |
51 | @Override
52 | public void deliveryComplete(IMqttDeliveryToken token) {
53 | // System.out.println("Delivery complete");
54 | }
55 | }
56 | }
57 |
58 | public void start() {
59 | try {
60 | MqttConnectOptions options = new MqttConnectOptions();
61 | options.setCleanSession(true);
62 | options.setAutomaticReconnect(false);
63 | client.connect(options);
64 | client.subscribe(topic);
65 | } catch (Exception e) {
66 | e.printStackTrace();
67 | }
68 |
69 | publishThread = new Thread(() -> {
70 | while (!Thread.currentThread().isInterrupted()) {
71 | try {
72 | AgentPacket packet = sendQueue.take();
73 | byte[] data = packet.getData();
74 | publish(topic, new String(data));
75 | } catch (Exception e) {
76 | e.printStackTrace();
77 | }
78 | }
79 |
80 | }
81 | publishThread.setName("MQTT_publish_Thread");
82 | publishThread.start();
83 |
84 | }
85 |
86 | public void stop() {
87 | publishThread.interrupt();
88 | try {
89 | client.close();
90 | } catch (Exception e) {
91 | e.printStackTrace();
92 | }
93 | }
94 |
95 | public void publish(String topic, String message) throws MqttException {
96 | MqttMessage mqttMessage = new MqttMessage();
97 | mqttMessage.setPayload(message.getBytes());
98 | client.publish(topic, mqttMessage);
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/kr/re/keti/database/Database.java:
--------------------------------------------------------------------------------
1 | package kr.re.keti.database;
2 |
3 | import java.sql.Connection;
4 | import java.util.ArrayList;
5 |
6 | public interface Database {
7 | public Connection getConnection();
8 | public boolean exists(String table, String pk);
9 | public boolean update(Object ObjectDto);
10 | public boolean delete(String table, String pk);
11 | public boolean insert(Object objectDto);
12 | public ArrayList