Project

General

Profile

Revision 1

Added by Jose Mendes about 6 years ago

imported project

View differences:

project/src/restore.sh
1
javac -cp /Users/zemiguel/IdeaProjects/SDIS-P1/src/ main/java/testapp/TestApp.java
2

  
3
java -Djava.net.preferIPv4Stack=true -Djava.rmi.serv.codebase=file:/Users/zemiguel/IdeaProjects/SDIS-P1/src/main/java/service/ main/java/testapp/TestApp 127.0.0.1/obj RESTORE test1.pdf
project/src/rmipeer.sh
1
find . -type f -name '*.class' -delete
2

  
3
javac -cp /Users/zemiguel/IdeaProjects/SDIS-P1/src/ main/java/peer/Peer.java
4

  
5
java -Djava.net.preferIPv4Stack=true -Djava.rmi.server.codebase=file:/Users/zemiguel/IdeaProjects/SDIS-P1/src/main/java/service/ main/java/peer/Peer 1.0 0 192.168.0.1 224.0.0.0:8000 224.0.0.0:8001 224.0.0.0:8002
project/README.md
1
# SDIS-P1
2

  
3

  
4
## From the src/ folder:
5

  
6
### Compile the Peer:
7
javac main/java/peer/Peer.java
8

  
9

  
10
### Compile the TestApp:
11
javac main/java/testapp/TestApp.java
12

  
13
### Run RMI:
14
rmiregistry &
15

  
16

  
17
### Run Peer that launches RMI:
18
java main/java/peer/Peer <protocol_version> <peer_id> <RMI_Access_Point> <MC_IP>:<MP_PORT> <MDB_IP>:<MDP_PORT> <MDR_IP>:<MDR_PORT>
19

  
20
ex:
21
java main/java/peer/Peer 1.0 0 192.168.0.1 224.0.0.0:8000 224.0.0.0:8001 224.0.0.0:8002
22

  
23
### Run normal peers:
24
java main/java/peer/Peer <protocol_version> <peer_id> <MC_IP>:<MP_PORT> <MDB_IP>:<MDP_PORT> <MDR_IP>:<MDR_PORT>
25

  
26
ex:
27
java main/java/peer/Peer 1.0 1 224.0.0.0:8000 224.0.0.0:8001 224.0.0.0:8002
28

  
29

  
30

  
31
### Run a TestApp:
32

  
33
## Backup:
34
java main/java/testapp/TestApp <rmi_peer_ip>/obj BACKUP <file_path> <replication_degree>
35

  
36
ex:
37
java main/java/testapp/TestApp 127.0.0.1/obj BACKUP /Users/zemiguel/IdeaProjects/SDIS-P1/src/files/test1.pdf 1
38

  
39
## Restore:
40
java main/java/testapp/TestApp <rmi_peer_ip>/obj RESTORE <file_name> <replication_degree>
41

  
42
ex:
43
java main/java/testapp/TestApp 127.0.0.1/obj RESTORE test1.pdf
44

  
45
## Delete:
46
java main/java/testapp/TestApp <rmi_peer_ip>/obj DELETE <file_name>
47

  
48
ex:
49
java main/java/testapp/TestApp 127.0.0.1/obj DELETE test1.pdf
50

  
51
## Reclaim:
52
java main/java/testapp/TestApp <rmi_peer_ip>/obj RECLAIM <amount>
53

  
54
ex:
55
java main/java/testapp/TestApp 127.0.0.1/obj RECLAIM 0
56

  
57
## State:
58
java main/java/testapp/TestApp <rmi_peer_ip>/obj STATE
59

  
60
ex:
61
java main/java/testapp/TestApp 127.0.0.1/obj STATE
project/src/files/test2.txt
1
FICHEIRO DE TESTE
project/src/main/java/database/Database.java
1
package main.java.database;
2

  
3

  
4
import main.java.file.FileChunkID;
5
import main.java.file.FileID;
6
import main.java.peer.Peer;
7

  
8
import java.io.File;
9
import java.io.Serializable;
10
import java.util.ArrayList;
11
import java.util.Iterator;
12
import java.util.List;
13
import java.util.Map;
14
import java.util.concurrent.ConcurrentHashMap;
15

  
16
public class Database implements Serializable {
17

  
18
    private static final long serialVersionUID = 1L;
19

  
20

  
21

  
22
    private ConcurrentHashMap<FileChunkID, ArrayList<Integer>> perceivedRepDeg;
23
    private ConcurrentHashMap<FileChunkID, Integer> desiredRepDeg;
24
    private List<FileID> storedFiles;
25

  
26

  
27
    public Database() {
28

  
29
        storedFiles = new ArrayList<>();
30
        perceivedRepDeg = new ConcurrentHashMap<FileChunkID, ArrayList<Integer>>();
31
        desiredRepDeg = new ConcurrentHashMap<FileChunkID, Integer>();
32
    }
33

  
34

  
35

  
36

  
37
    public synchronized void insertChunkInfo(FileID fileID, int replicationDegree, int chunkNo, int peerID) {
38
        FileChunkID id = new FileChunkID(fileID.toString(), chunkNo);
39

  
40
        perceivedRepDeg.put(id, new ArrayList<>());
41
        perceivedRepDeg.get(id).add(peerID);
42
        desiredRepDeg.put(id, replicationDegree);
43

  
44
        Peer.saveDBToDisk();
45

  
46
    }
47

  
48
    public synchronized void removeChunkInfo(FileChunkID chunkID){
49
        desiredRepDeg.remove(chunkID);
50
        perceivedRepDeg.remove(chunkID);
51
        Peer.saveDBToDisk();
52

  
53
    }
54

  
55
    public void printDatabase() {
56
        /*
57
        For each file whose backup it has initiated:
58
                The file pathname
59
                The backup service id of the file
60
                The desired replication degree
61
                    For each chunk of the file:
62
                        Its id
63
                        Its perceived replication degree
64
         */
65

  
66

  
67

  
68
        System.out.println("----------------------------------------------------");
69

  
70
        System.out.println("Printing Database Info...\n\n");
71

  
72
        if(!storedFiles.isEmpty()){
73
            System.out.println("Files I have backed up: ");
74

  
75

  
76

  
77
            for (FileID fid: storedFiles){
78

  
79
                if(fid.getNumChunks()!=-1){
80
                    System.out.println("\t id: " + fid.toString());
81
                    System.out.println("\t Desired rep degree: " + fid.getDesiredRepDeg());
82
                    System.out.println("\t Chunks: ");
83

  
84
                    Iterator<Map.Entry<FileChunkID, ArrayList<Integer>>> it = perceivedRepDeg.entrySet().iterator();
85
                    while (it.hasNext()) {
86
                        Map.Entry<FileChunkID, ArrayList<Integer>> pair = it.next();
87

  
88
                        FileChunkID cID = pair.getKey();
89

  
90
                        if(cID.getFileID().equals(fid.toString())){
91

  
92
                            ArrayList<Integer> replications = pair.getValue();
93

  
94
                            System.out.println("\t\t ChunkNo:" + cID.getChunkNumber()+ " Perceived Replication Degree:"
95
                            + replications.size());
96
                        }
97

  
98

  
99
                        it.remove(); // avoids a ConcurrentModificationException
100
                    }
101

  
102
                }
103

  
104
            }
105

  
106
            System.out.println("----------------------------------------------------");
107
            System.out.println("Chunks on my system: ");
108
            for (FileID fid: storedFiles){
109

  
110
                if(fid.getNumChunks()==-1){
111

  
112
                    Iterator<Map.Entry<FileChunkID, ArrayList<Integer>>> it = perceivedRepDeg.entrySet().iterator();
113
                    while (it.hasNext()) {
114
                        Map.Entry<FileChunkID, ArrayList<Integer>> pair = it.next();
115

  
116
                        FileChunkID cID = pair.getKey();
117

  
118
                        if(cID.getFileID().equals(fid.toString())){
119

  
120
                            ArrayList<Integer> replications = pair.getValue();
121

  
122
                            File f = new File("peer"+Peer.getID()+"/Backup/"+fid.toString().split("\\.")[0]+
123
                                    "/"+cID.toString());
124

  
125
                            System.out.println("\t\t ChunkNo:" + cID.getChunkNumber()+ " Perceived Replication Degree:"
126
                                    + replications.size() + " Size:"+ f.length());
127
                        }
128

  
129

  
130
                        it.remove(); // avoids a ConcurrentModificationException
131
                    }
132

  
133
                }
134

  
135
            }
136

  
137
            System.out.println("----------------------------------------------------");
138

  
139

  
140

  
141
        }
142

  
143
    }
144

  
145
    public synchronized void insertFile(FileID fileID) {
146

  
147
        if(!storedFiles.contains(fileID)){
148
            storedFiles.add(fileID);
149
            Peer.saveDBToDisk();
150
        }
151
        else {
152
            int i = storedFiles.indexOf(fileID);
153
            storedFiles.get(i).setNumChunks(fileID.getNumChunks());
154
        }
155

  
156
    }
157

  
158
    public synchronized void removeFile(FileID fileID){
159
        storedFiles.remove(fileID);
160

  
161
        Peer.saveDBToDisk();
162

  
163

  
164
    }
165

  
166
    public synchronized int getNumChunksOfFile(FileID fID){
167
        int index = storedFiles.indexOf(fID);
168
        if(index!=-1)
169
            return storedFiles.get(index).getNumChunks();
170
        else
171
            return -1;
172

  
173
    }
174

  
175
    public String printStoredFiles() {
176
        return "\t Stored Files: \n " +
177
                storedFiles.toString() + "\n";
178
    }
179

  
180
    public boolean isFileStored(FileID fID) {
181

  
182

  
183
        return storedFiles.contains(fID);
184
    }
185

  
186

  
187

  
188
    public List<String> getFileChunksofFileID(FileID fileID) {
189

  
190

  
191
        List<String> chunksOfFile = new ArrayList<>();
192

  
193
        printDatabase();
194
        for(FileID fid : storedFiles) {
195
            if(fid.equals(fileID)) {
196

  
197
                for (int i = 0; i < fid.getNumChunks(); i++){
198
                    chunksOfFile.add(fid + "-" + i);
199
                }
200
            }
201

  
202
        }
203

  
204
        return chunksOfFile;
205
    }
206

  
207

  
208
    public synchronized void addNewRepDegCounter(FileChunkID chunkID, Integer repDeg){
209

  
210
        if (!perceivedRepDeg.containsKey(chunkID)) {
211
            perceivedRepDeg.put(chunkID, new ArrayList<>());
212
        }
213

  
214

  
215
        if (!desiredRepDeg.containsKey(chunkID)) {
216
            desiredRepDeg.put(chunkID, repDeg);
217
        }
218

  
219
        System.out.println("SAVING DB");
220
        Peer.saveDBToDisk();
221
    }
222

  
223
    public void removeRepDegCounter(FileChunkID chunkID){
224
        perceivedRepDeg.remove(chunkID);
225
        desiredRepDeg.remove(chunkID);
226
    }
227

  
228
    public synchronized void increasePerceivedRepDeg(FileChunkID chunkID, int senderID){
229

  
230
        if(perceivedRepDeg.containsKey(chunkID)) {
231

  
232
            if (!perceivedRepDeg.get(chunkID).contains(senderID)) {
233
                perceivedRepDeg.get(chunkID).add(senderID);
234
                System.out.println("SAVING DB");
235
                //dumpPerceived();
236
                Peer.saveDBToDisk();
237
            }
238

  
239
        }
240
        else {
241
            perceivedRepDeg.put(chunkID, new ArrayList<>());
242
            perceivedRepDeg.get(chunkID).add(senderID);
243
        }
244

  
245

  
246
    }
247

  
248
    public void dumpPerceived() {
249
        System.out.println("DUMPING PERCEIVED!");
250
        for (FileChunkID name: perceivedRepDeg.keySet()){
251

  
252
            String key =name.toString();
253
            String value = perceivedRepDeg.get(name).toString();
254
            System.out.println(key + " " + value);
255

  
256
        }
257

  
258
    }
259

  
260
    public void decreasePerceivedRepDeg(FileChunkID chunkID, int senderID){
261

  
262

  
263

  
264

  
265

  
266
        if(perceivedRepDeg.containsKey(chunkID)) {
267

  
268
            if (perceivedRepDeg.get(chunkID).contains(senderID)) {
269
                System.out.println("DECRESING FROM: " + perceivedRepDeg.get(chunkID).size());
270
                perceivedRepDeg.get(chunkID).remove(senderID);
271
                if(perceivedRepDeg.get(chunkID).size()==0)
272
                    perceivedRepDeg.remove(chunkID);
273

  
274
                System.out.println("DECRESING TO: " + perceivedRepDeg.get(chunkID).size());
275
                System.out.println("SAVING DB");
276
                Peer.saveDBToDisk();
277
            }
278

  
279
        }
280
    }
281

  
282
    public int getPerceivedRepDeg(FileChunkID chunkID){
283

  
284
        //dumpPerceived();
285

  
286
        if(perceivedRepDeg.containsKey(chunkID))
287
            return perceivedRepDeg.get(chunkID).size();
288
        else
289
            return -1;
290
    }
291

  
292
    public Integer getDesiredRepDeg(FileChunkID chunkID){
293
        if(desiredRepDeg.containsKey(chunkID))
294
            return desiredRepDeg.get(chunkID);
295
        else
296
            return -1;
297
    }
298

  
299

  
300
    public synchronized FileChunkID getHighestPerceivedRepDegChunk() {
301
        FileChunkID best = null;
302
        for (FileChunkID chunkID : perceivedRepDeg.keySet()) {
303
            if (best == null || perceivedRepDeg.get(chunkID).size() > perceivedRepDeg.get(best).size())
304
                best = chunkID;
305

  
306
        }
307

  
308
        return best;
309
    }
310

  
311

  
312
}
project/src/main/java/file/FileChunk.java
1
package main.java.file;
2

  
3
import java.io.Serializable;
4

  
5
public class FileChunk implements Serializable {
6

  
7
    private static final long serialVersionUID = 1L;
8

  
9
    private static final int CHUNK_MAX_SIZE = 64000;
10
    private int replicationDegree;
11
    private int chunkNo;
12
    private FileID fileID;
13
    private byte[] chunkData;
14

  
15
    public FileChunk(int replicationDegree, int chunkNo, FileID fileID, byte[] chunkData) {
16
        this.replicationDegree = replicationDegree;
17
        this.chunkNo = chunkNo;
18
        this.fileID = fileID;
19
        this.chunkData = chunkData;
20
    }
21

  
22
    public int getChunkNo() {
23
        return chunkNo;
24
    }
25

  
26
    public FileID getFileID() {
27
        return fileID;
28
    }
29

  
30
    public byte[] getChunkData() {
31
        return chunkData;
32
    }
33

  
34
    public int getReplicationDegree() {
35
        return replicationDegree;
36
    }
37

  
38
    @Override
39
    public String toString() {
40
        return new String(chunkData);
41
    }
42
}
43

  
project/src/main/java/file/FileChunkID.java
1
package main.java.file;
2

  
3

  
4
import java.io.Serializable;
5

  
6
public class FileChunkID implements Serializable {
7

  
8
    private static final long serialVersionUID = 1L;
9

  
10

  
11
    private String fileID;
12
    private int chunkNumber;
13

  
14
    public FileChunkID(String fileID, int chunkNumber) {
15
        this.fileID = fileID;
16
        this.chunkNumber = chunkNumber;
17
    }
18

  
19
    public String getFileID() {
20
        return fileID;
21
    }
22

  
23
    public int getChunkNumber() {
24
        return chunkNumber;
25
    }
26

  
27
    @Override
28
    public int hashCode() {
29
        int result = 17;
30
        result = 31 * result + fileID.hashCode();
31
        result = 31 * result + chunkNumber;
32

  
33
        return result;
34
    }
35

  
36
    @Override
37
    public boolean equals(Object obj) {
38

  
39
        if (this == obj)
40
            return true;
41

  
42
        if (obj == null)
43
            return false;
44

  
45

  
46
        FileChunkID other = (FileChunkID) obj;
47

  
48
        if (this.chunkNumber != other.chunkNumber)
49
            return false;
50

  
51
        return this.fileID.equals(other.fileID);
52
    }
53

  
54
    @Override
55
    public String toString() {
56
        return fileID + "-" + chunkNumber;
57
    }
58
}
project/src/main/java/file/FileID.java
1
package main.java.file;
2

  
3
import java.io.Serializable;
4

  
5
public class FileID implements Serializable {
6

  
7
    private static final long serialVersionUID = 1L;
8

  
9
    private String fileID;
10
    private int numChunks;
11
    private int desiredRepDeg;
12

  
13

  
14
    public FileID(String fileID, int desiredRepDeg) {
15
        this.fileID = fileID;
16
        this.numChunks = -1;
17
        this.desiredRepDeg = desiredRepDeg;
18

  
19
    }
20

  
21
    @Override
22
    public String toString() {
23
        String[] fileIDSplitted = fileID.split("/");
24
        return fileIDSplitted[fileIDSplitted.length - 1];
25
    }
26
    @Override
27
    public boolean equals(Object o) {
28

  
29

  
30
        if (o == this) {
31
            return true;
32
        }
33

  
34
        if (!(o instanceof FileID)) {
35
            return false;
36
        }
37

  
38
        FileID c = (FileID) o;
39

  
40
        return fileID.equals(c.fileID);
41
    }
42

  
43
    public void setNumChunks(int numChunks) {
44
        this.numChunks = numChunks;
45
    }
46

  
47
    public int getNumChunks() {
48
        return numChunks;
49
    }
50

  
51
    public int getDesiredRepDeg() {
52
        return desiredRepDeg;
53
    }
54
}
project/src/main/java/listeners/Broker.java
1
package main.java.listeners;
2

  
3
import main.java.file.FileChunk;
4
import main.java.file.FileChunkID;
5
import main.java.file.FileID;
6
import main.java.peer.Peer;
7

  
8
import java.io.ByteArrayOutputStream;
9
import java.io.IOException;
10
import java.net.DatagramPacket;
11

  
12
import static main.java.utils.Utilities.*;
13
import static main.java.utils.Constants.*;
14

  
15

  
16
public class Broker {
17

  
18

  
19
    public static void sendSTORED(FileChunkID chunkID) {
20
        byte message[] = messageConstructor("STORED", null, chunkID, null);
21

  
22
        try {
23
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
24
            outputStream.write(message);
25

  
26
            byte messageToSend[] = outputStream.toByteArray();
27

  
28
            Broker.sendToMC(messageToSend);
29
        }
30
        catch(IOException e){
31
            e.printStackTrace();
32
        }
33

  
34
    }
35

  
36
    public static void sendDELETE(FileID fileID) {
37
        byte message[] = messageConstructor("DELETE", null, null, fileID);
38

  
39
        try {
40
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
41
            outputStream.write(message);
42

  
43
            byte messageToSend[] = outputStream.toByteArray();
44

  
45
            Broker.sendToMC(messageToSend);
46
        }
47
        catch(IOException e){
48
            e.printStackTrace();
49
        }
50

  
51

  
52

  
53
    }
54

  
55

  
56

  
57
    public static void sendPUTCHUNK(FileChunk chunk) throws InterruptedException {
58
        byte message[] = messageConstructor("PUTCHUNK", chunk, null, null);
59

  
60

  
61

  
62
        try {
63
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
64
            outputStream.write(message);
65

  
66
            byte messageToSend[] = outputStream.toByteArray();
67

  
68

  
69

  
70

  
71
            Broker.sendToMDB(messageToSend);
72
        }
73
        catch(IOException e){
74
            e.printStackTrace();
75
        }
76
    }
77

  
78
    public static void sendREMOVED(FileChunkID chunkID){
79

  
80
        byte message[] = messageConstructor("REMOVED", null, chunkID, null);
81

  
82

  
83
        try {
84
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
85
            outputStream.write(message);
86

  
87
            byte messageToSend[] = outputStream.toByteArray();
88

  
89
            Broker.sendToMC(messageToSend);
90
        }
91
        catch(IOException e){
92
            e.printStackTrace();
93
        }
94

  
95
    }
96

  
97
    public static void sendGETCHUNK(FileChunkID chunkID) {
98
        byte message[] = messageConstructor("GETCHUNK", null, chunkID, null);
99

  
100
        try {
101
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
102
            outputStream.write(message);
103

  
104
            byte messageToSend[] = outputStream.toByteArray();
105

  
106
            Broker.sendToMC(messageToSend);
107
        }
108
        catch(IOException e){
109
            e.printStackTrace();
110
        }
111

  
112

  
113

  
114
    }
115

  
116
    public static void sendCHUNK(FileChunk chunk, FileChunkID chunkID) {
117
        byte message[] = messageConstructor("CHUNK", chunk, chunkID, null);
118

  
119
        try {
120
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
121
            outputStream.write(message);
122

  
123
            byte messageToSend[] = outputStream.toByteArray();
124

  
125
            Broker.sendToMDR(messageToSend);
126
        }
127
        catch(IOException e){
128
            e.printStackTrace();
129
        }
130

  
131

  
132

  
133
    }
134

  
135
    private static void sendToMDB(byte[] backupMessage) throws InterruptedException {
136

  
137

  
138
        DatagramPacket messagePacket = new DatagramPacket(backupMessage, backupMessage.length, Peer.getMDBListener().address, Peer.getMDBListener().port);
139

  
140
        try {
141
            Peer.getMDBListener().send(messagePacket);
142

  
143
        } catch (IOException e) {
144
            e.printStackTrace();
145
        }
146

  
147

  
148

  
149
    }
150

  
151
    private static void sendToMC(byte[] backupMessage) {
152

  
153

  
154
        DatagramPacket messagePacket = new DatagramPacket(backupMessage, backupMessage.length, Peer.getMCListener().address, Peer.getMCListener().port);
155

  
156

  
157
        try {
158
            Peer.getMCListener().send(messagePacket);
159

  
160
        } catch (IOException e) {
161
            e.printStackTrace();
162
        }
163
    }
164

  
165
    private static void sendToMDR(byte[] restoreMessage) {
166
        DatagramPacket messagePacket = new DatagramPacket(restoreMessage, restoreMessage.length, Peer.getMDRListener().address, Peer.getMDRListener().port);
167

  
168
        try {
169
            Peer.getMDRListener().send(messagePacket);
170
        } catch (IOException e) {
171
            e.printStackTrace();
172
        }
173
    }
174
}
project/src/main/java/listeners/Listener.java
1
package main.java.listeners;
2

  
3

  
4
import main.java.file.FileChunk;
5
import main.java.file.FileChunkID;
6
import main.java.peer.Peer;
7
import main.java.service.PacketHandler;
8
import main.java.utils.Constants;
9

  
10
import java.io.IOException;
11
import java.net.DatagramPacket;
12
import java.net.InetAddress;
13
import java.net.MulticastSocket;
14
import java.util.ArrayList;
15
import java.util.concurrent.ConcurrentHashMap;
16

  
17
import static main.java.utils.Constants.*;
18

  
19

  
20
public class Listener implements Runnable {
21

  
22
    private MulticastSocket multicastSocket;
23
    public InetAddress address;
24
    public int port;
25

  
26
    public volatile ConcurrentHashMap<String, ArrayList<FileChunk>> chunksReceived;
27

  
28
    private ConcurrentHashMap<FileChunkID, ArrayList<String>> storedChunks;
29

  
30
    private ConcurrentHashMap<FileChunkID, ArrayList<String>> putChunks;
31

  
32

  
33

  
34
    public Listener(InetAddress addr, int prt) {
35
        address = addr;
36
        port = prt;
37
        storedChunks = new ConcurrentHashMap<>();
38
        putChunks = new ConcurrentHashMap<>();
39
        chunksReceived = new ConcurrentHashMap<>();
40

  
41
    }
42

  
43

  
44

  
45
    @Override
46
    public void run() {
47

  
48
        try {
49
            multicastSocket = new MulticastSocket(port);
50
            multicastSocket.setTimeToLive(1);
51
            multicastSocket.joinGroup(address);
52

  
53
        } catch (IOException e) {
54
            e.printStackTrace();
55
        }
56

  
57

  
58

  
59
        boolean end = false;
60
        while(!end) {
61

  
62
            byte[] buffer = new byte[PACKET_MAX_SIZE];
63
            Thread t;
64
            try {
65

  
66

  
67
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
68
                multicastSocket.receive(packet);
69

  
70

  
71
                t = new Thread(new PacketHandler(packet));
72
                t.start();
73

  
74
                try {
75
                    t.join();
76
                } catch (InterruptedException e) {
77
                    e.printStackTrace();
78
                }
79

  
80

  
81

  
82

  
83

  
84
            } catch (IOException e) {
85
                e.printStackTrace();
86
            }
87
        }
88

  
89
        multicastSocket.close();
90

  
91

  
92

  
93
    }
94

  
95

  
96
    public void startCountingStoreds(FileChunkID fileChunkID) {
97

  
98
        if (!storedChunks.containsKey(fileChunkID)) {
99
            //System.out.println("Starting to count:" + chunkID.toString());
100
            storedChunks.put(fileChunkID, new ArrayList<>());
101
        }
102

  
103
    }
104

  
105
    public void clearCount(FileChunkID fileChunkID) {
106
        storedChunks.get(fileChunkID).clear();
107
    }
108

  
109
    public int getCount(FileChunkID fileChunkID) {
110
        return storedChunks.get(fileChunkID).size();
111
    }
112

  
113
    public void dumpHashmap() {
114
        for (FileChunkID name: storedChunks.keySet()){
115

  
116
            String key =name.toString();
117
            String value = storedChunks.get(name).toString();
118
            System.out.println(key + " " + value);
119

  
120
        }
121

  
122
    }
123

  
124
    public void stopCounting(FileChunkID fileChunkID) {
125
        storedChunks.remove(fileChunkID);
126
    }
127

  
128
    public void send(DatagramPacket messagePacket) throws IOException {
129
        multicastSocket.send(messagePacket);
130
    }
131

  
132
    public synchronized void countStored(FileChunkID chunkID, String senderID) {
133
        if (storedChunks.containsKey(chunkID))
134
            if (!storedChunks.get(chunkID).contains(senderID)) {
135
                storedChunks.get(chunkID).add(senderID);
136
                Peer.getDb().increasePerceivedRepDeg(chunkID, Integer.parseInt(senderID));
137
            }
138
            else
139
                System.out.println("Already counted this peer");
140

  
141
    }
142
    public synchronized void startCountingPutChunks(FileChunkID chunkID) {
143
        if (!putChunks.containsKey(chunkID))
144
            putChunks.put(chunkID, new ArrayList<>());
145
    }
146

  
147
    public synchronized void countPutChunk(FileChunkID chunkID, String senderID) {
148

  
149
        if (putChunks.containsKey(chunkID))
150
            if (!putChunks.get(chunkID).contains(senderID))
151
                putChunks.get(chunkID).add(senderID);
152

  
153
    }
154

  
155
    public synchronized int getCountPutChunks(FileChunkID chunkID) {
156
        return putChunks.get(chunkID).size();
157
    }
158

  
159
    public synchronized void stopSavingPutChunks(FileChunkID chunkID) {
160
        putChunks.remove(chunkID);
161
    }
162

  
163

  
164
    public boolean isCounting(FileChunkID fileChunkID) {
165
        if(storedChunks.containsKey(fileChunkID))
166
            return true;
167
        else {
168
            return false;
169
        }
170
    }
171

  
172

  
173

  
174
    /*
175
        MDR
176
     */
177
    public synchronized void queueChunk(FileChunk chunk) {
178
        //System.out.println("CHUNK TO MERGE: " + chunk.getFileID().toString());
179
        ArrayList<FileChunk> fileChunks = chunksReceived.get(chunk.getFileID().toString());
180
        fileChunks.add(chunk);
181
        //System.out.println("File Chunks: " + fileChunks);
182

  
183
        //printChunksReceived();
184
        notifyAll();
185
    }
186

  
187
    public synchronized ArrayList<FileChunk> retrieveChunk(String fileID) {
188
        ArrayList<FileChunk> receivedChunks = chunksReceived.get(fileID);
189

  
190
        return receivedChunks;
191
    }
192

  
193
    public void printChunksReceived() {
194
        for (String name: chunksReceived.keySet()){
195

  
196
            String value = chunksReceived.get(name).toString();
197
            System.out.println(name + ": " + value);
198
        }
199
    }
200

  
201

  
202
}
project/src/main/java/peer/Peer.java
1
package main.java.peer;
2

  
3

  
4
import main.java.database.Database;
5
import main.java.file.FileID;
6
import main.java.listeners.Listener;
7
import main.java.protocols.Backup;
8
import main.java.protocols.Delete;
9
import main.java.protocols.Reclaim;
10
import main.java.protocols.Restore;
11
import main.java.service.RMI;
12

  
13
import java.io.IOException;
14
import java.net.InetAddress;
15
import java.net.MulticastSocket;
16

  
17
import java.io.*;
18
import java.net.*;
19
import java.rmi.RemoteException;
20
import java.rmi.registry.LocateRegistry;
21
import java.rmi.registry.Registry;
22
import java.rmi.server.UnicastRemoteObject;
23
import java.util.concurrent.ConcurrentHashMap;
24

  
25
import static main.java.utils.Utilities.getLocalAddress;
26
import static main.java.utils.Constants.*;
27

  
28
public class Peer implements RMI {
29

  
30

  
31

  
32

  
33
    private static Listener MCChannel;  //MC CHANNEL
34
    private static Listener MDBChannel; //BACKUP CHANNEL
35
    private static Listener MDRChannel; //RESTORE CHANNEL
36

  
37
    private static String rmiRemoteObject;
38

  
39
    private static int ID;
40
    private static float protocolVersion;
41

  
42
    private static InetAddress MCAddress;
43
    private static InetAddress MDBAddress;
44
    private static InetAddress MDRAddress;
45

  
46
    private static int MCPort;
47
    private static int MDBPort;
48
    private static int MDRPort;
49

  
50
    private static InetAddress ip;
51

  
52
    private static volatile Database db;
53
    private static Disk disk;
54

  
55
    public static boolean restoring;
56

  
57
    /*
58
        javac -cp /Users/zemiguel/IdeaProjects/SDIS-P1/src/ peer/Peer.java
59
        DENTRO DO /src/: rmiregistry &
60
        usage:
61
        protocol version,the server id, service access point, MC, MDB, MDR
62
        rmi init example:
63
        java -Djava.net.preferIPv4Stack=true -Djava.rmi.server.codebase=file:/Users/zemiguel/IdeaProjects/SDIS-P1/src/
64
        main/java/service/ main/java/peer/Peer 1.0 0 192.168.0.1 224.0.0.0:8000 224.0.0.0:8001 224.0.0.0:8002
65
        1.0, 0, 192.168.0.1, 224.0.0.0:8000, 224.0.0.0:8001, 224.0.0.0:8002
66
        normal peer example:
67
        java peer.Peer 1.0 1 224.0.0.0:8000 224.0.0.0:8001 224.0.0.0:8002
68
    */
69
    public static void main(String[] args) throws IOException, ClassNotFoundException {
70

  
71
        if(!parseArgs(args)) {
72
            System.out.println("Bad arguments");
73
            System.out.println("USAGE (RMI): java peer.Peer <protocol_version> <service_access_point> <MCADDR>:<MCPORT> " +
74
                    "<MDBADDR>:<MDBPORT> <MDRADDR>:<MDRPORT>");
75
            System.out.println("USAGE (NON-RMI): java peer.Peer <protocol_version> <MCADDR>:<MCPORT> " +
76
                    "<MDBADDR>:<MDBPORT> <MDRADDR>:<MDRPORT>");
77
            return;
78
        }
79

  
80

  
81
        ip = getLocalAddress();
82

  
83
        MCChannel = new Listener(MCAddress, MCPort);
84
        MDBChannel = new Listener(MDBAddress, MDBPort);
85
        MDRChannel = new Listener(MDRAddress, MDRPort);
86

  
87
        loadDisk();
88
        loadDatabase();
89

  
90
        db.printDatabase();
91
        disk.printDisk();
92
        restoring = false;
93

  
94

  
95
        System.out.println("Start Listening on MC Channel...");
96
        new Thread(MCChannel).start();
97
        System.out.println("Start Listening on MDB Channel...");
98
        new Thread(MDBChannel).start();
99
        System.out.println("Start Listening on MDR Channel...");
100
        new Thread(MDRChannel).start();
101

  
102
        return;
103

  
104

  
105

  
106

  
107

  
108
    }
109

  
110
    public static void saveDBToDisk() {
111

  
112
        File dir = new File("peer"+getID()+"/database/");
113

  
114
        if(!dir.exists()){
115
            System.out.println("creating directory: " + dir.getName());
116

  
117
            try{
118
                dir.mkdirs();
119
            }
120
            catch(SecurityException se){
121
                se.printStackTrace();
122
            }
123

  
124
        }
125

  
126
        FileOutputStream fos = null;
127
        try {
128
            fos = new FileOutputStream("peer"+getID()+"/database/dbs.data");
129
        } catch (FileNotFoundException e) {
130
            e.printStackTrace();
131
            System.out.println("Database does not exist!");
132
            createDB();
133
            System.out.println("New DB created and saved to disk...");
134
        }
135
        ObjectOutputStream oos = null;
136
        try {
137
            oos = new ObjectOutputStream(fos);
138
        } catch (IOException e) {
139
            e.printStackTrace();
140
        }
141
        try {
142
            assert oos != null;
143
            oos.writeObject(db);
144
        } catch (IOException e) {
145
            e.printStackTrace();
146
        }
147
        try {
148
            oos.close();
149
        } catch (IOException e) {
150
            e.printStackTrace();
151
        }
152

  
153
    }
154

  
155
    private static void createDB() {
156
        db = new Database();
157
        saveDBToDisk();
158
    }
159

  
160
    private static void loadDatabase() {
161
        System.out.println("Loading database...");
162
        try {
163
            FileInputStream fileInputStream = new FileInputStream("peer"+getID()+"/database/dbs.data");
164

  
165
            ObjectInputStream objectInputStream = new ObjectInputStream(
166
                    fileInputStream);
167
            db = (Database) objectInputStream.readObject();
168
            objectInputStream.close();
169
        } catch (FileNotFoundException e) {
170
            System.out.println("Database not found");
171

  
172
            createDB();
173
        } catch (IOException | ClassNotFoundException e) {
174
            e.printStackTrace();
175
        }
176
    }
177

  
178

  
179
    private static boolean parseArgs(String[] args) {
180

  
181
        //args == 6 -> INITIALIZE RMI
182
        if(args.length == 6) {
183

  
184
            protocolVersion = Float.parseFloat(args[0]);
185
            ID = Integer.parseInt(args[1]);
186
            rmiRemoteObject = args[2];
187
            try {
188

  
189
                MCAddress = InetAddress.getByName(args[3].split(":")[0]);
190
                MDBAddress = InetAddress.getByName(args[4].split(":")[0]);
191
                MDRAddress = InetAddress.getByName(args[5].split(":")[0]);
192

  
193
                MCPort = Integer.parseInt(args[3].split(":")[1]);
194
                MDBPort = Integer.parseInt(args[4].split(":")[1]);
195
                MDRPort = Integer.parseInt(args[5].split(":")[1]);
196

  
197

  
198

  
199
            }
200
            catch (UnknownHostException e){
201
                System.out.println("Address not found");
202
                return false;
203
            }
204

  
205
            System.out.println("\t LAUNCHING RMI");
206
            launchRMI();
207

  
208
        } else if (args.length == 5) {//normal peer
209

  
210
            protocolVersion = Float.parseFloat(args[0]);
211
            ID = Integer.parseInt(args[1]);
212

  
213
            try {
214

  
215
                MCAddress = InetAddress.getByName(args[2].split(":")[0]);
216
                MDBAddress = InetAddress.getByName(args[3].split(":")[0]);
217
                MDRAddress = InetAddress.getByName(args[4].split(":")[0]);
218

  
219
                MCPort = Integer.parseInt(args[2].split(":")[1]);
220
                MDBPort = Integer.parseInt(args[3].split(":")[1]);
221
                MDRPort = Integer.parseInt(args[4].split(":")[1]);
222

  
223

  
224

  
225
            }
226
            catch (UnknownHostException e){
227
                System.out.println("Address not found");
228
                return false;
229
            }
230

  
231

  
232
        }
233
        else return false;
234

  
235

  
236
        return true;
237
    }
238

  
239
    private static void launchRMI() {
240

  
241
        //System.setProperty("java.rmi.server.hostname", "localhost");
242

  
243
        //System.setProperty("rmi.server.codebase", "file:/Users/zemiguel/IdeaProjects/SDIS-P1/src/main/java/service/bin/");
244
        try {
245

  
246

  
247
            RMI peer = new Peer();
248

  
249
            RMI stub = (RMI) UnicastRemoteObject.exportObject(peer, 0);
250

  
251
            Registry registry = LocateRegistry.getRegistry();
252
            registry.rebind("obj", stub);
253

  
254
        } catch (Exception e) {
255
            System.err.println("Server exception: " + e.toString());
256
            e.printStackTrace();
257
        }
258

  
259

  
260

  
261
    }
262

  
263

  
264

  
265
    public static Database getDb() {
266
        return db;
267

  
268
    }
269

  
270
    public static Listener getMCListener() {
271
        return MCChannel;
272
    }
273

  
274
    public static Listener getMDBListener() {
275
        return MDBChannel;
276
    }
277

  
278
    public static Listener getMDRListener() {
279
        return MDRChannel;
280
    }
281

  
282
    public static void saveDisk(){
283
        FileOutputStream fos = null;
284
        File dir = new File("peer"+getID()+"/disk/");
285

  
286
        if(!dir.exists()){
287
            System.out.println("creating directory: " + dir.getName());
288

  
289
            try{
290
                dir.mkdirs();
291
            }
292
            catch(SecurityException se){
293
                se.printStackTrace();
294
            }
295

  
296
        }
297

  
298
        try {
299
            fos = new FileOutputStream("peer"+getID()+"/disk/disk.data");
300
        } catch (FileNotFoundException e) {
301
            e.printStackTrace();
302
            System.out.println("Disk does not exist!");
303
            createDisk();
304
            System.out.println("New Disk created and saved to disk...");
305
        }
306
        ObjectOutputStream oos = null;
307
        try {
308
            oos = new ObjectOutputStream(fos);
309
        } catch (IOException e) {
310
            e.printStackTrace();
311
        }
312
        try {
313
            oos.writeObject(disk);
314
        } catch (IOException e) {
315
            e.printStackTrace();
316
        }
317
        try {
318
            oos.close();
319
        } catch (IOException e) {
320
            e.printStackTrace();
321
        }
322
    }
323

  
324
    private static void loadDisk() throws ClassNotFoundException, IOException {
325

  
326
        System.out.println("Loading disk...");
327

  
328
        try {
329
            FileInputStream fileInputStream = new FileInputStream("peer"+getID()+"/disk/disk.data");
330

  
331
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
332
            disk = (Disk) objectInputStream.readObject();
333
            objectInputStream.close();
334
        } catch (FileNotFoundException e) {
335
            System.out.println("Disk not found");
336
            createDisk();
337
        } catch (IOException | ClassNotFoundException e) {
338
            e.printStackTrace();
339
        }
340
    }
341

  
342
    public static void createDisk(){
343
        disk = new Disk();
344
        saveDisk();
345
    }
346

  
347
    @Override
348
    public void backup(File file, int replicationDegree) throws RemoteException {
349

  
350
        Thread t = new Thread(new Backup(file, replicationDegree));
351
        t.start();
352

  
353
        try {
354
            t.join();
355
        } catch (InterruptedException e) {
356
            e.printStackTrace();
357
        }
358

  
359

  
360
    }
361

  
362
    @Override
363
    public void delete(String filePath) throws RemoteException {
364
        Thread t = new Thread(new Delete(new FileID(filePath, 0)));
365

  
366
        t.start();
367

  
368
        try {
369
            t.join();
370
        } catch (InterruptedException e){
371
            e.printStackTrace();
372
        }
373

  
374
    }
375

  
376
    @Override
377
    public void restore(File file) throws RemoteException {
378

  
379
        Thread t = new Thread(new Restore(file));
380
        t.start();
381

  
382
        try {
383
            t.join();
384
        } catch (InterruptedException e) {
385
            e.printStackTrace();
386
        }
387

  
388

  
389
    }
390

  
391
    @Override
392
    public String state() throws RemoteException {
393

  
394
        db.printDatabase();
395
        disk.printDisk();
396
        return null;
397
    }
398

  
399
    @Override
400
    public void reclaim(int amount) throws RemoteException {
401

  
402
        Thread t = new Thread(new Reclaim(amount));
403
        t.start();
404

  
405
        try {
406
            t.join();
407
        } catch (InterruptedException e) {
408
            e.printStackTrace();
409
        }
410

  
411

  
412

  
413
    }
414

  
415

  
416

  
417

  
418
    public static int getID() {
419
        return ID;
420
    }
421

  
422
    public static InetAddress getAddress() {
423
        return ip;
424
    }
425

  
426
    public static float getProtocolVersion() {
427
        return protocolVersion;
428
    }
429

  
430
    public static Disk getDisk(){ return disk; }
431

  
432

  
433
}
project/src/main/java/protocols/Backup.java
1
package main.java.protocols;
2

  
3
import main.java.file.*;
4
import main.java.peer.Peer;
5

  
6

  
7
import java.io.*;
8
import java.util.Arrays;
9

  
10
import static main.java.utils.Constants.*;
11
import static main.java.utils.Utilities.*;
12

  
13
public class Backup implements Runnable{
14

  
15
    private File file;
16
    private int repDeg;
17
    private String encryptedID;
18
    private FileID fileID;
19
    private int fileParts;
20
    //private static Message message;
21

  
22

  
23
    public Backup(File file, int replicationDegree) {
24

  
25
        this.file = file;
26
        this.repDeg = replicationDegree;
27

  
28
    }
29

  
30
    /**
31
     * @param file File to split into chunks and later backed up
32
     * @return Number of chunks that the file was split into
33
     * @throws IOException exception to be thrown in case of an invalid file.
34
     */
35
    public int createChunks(File file) throws IOException {
36

  
37

  
38
        byte[] fileData = loadFileData(file);
39

  
40
        fileParts = fileData.length / CHUNK_MAX_SIZE;
41

  
42

  
43
        String fileName = file.getName();
44

  
45
        ByteArrayInputStream streamBuffer = new ByteArrayInputStream(fileData);
46
        byte[] data = new byte[CHUNK_MAX_SIZE];
47

  
48

  
49
        for(int i = 0; i <= fileParts; i++) {
50
            FileChunkID id = new FileChunkID(file.getName(), i);
51

  
52

  
53
            byte[] chunkData;
54

  
55
            /*
56
                Size of last chunk is always shorter than CHUNK_MAX_SIZE
57
                If the file size is a multiple of CHUNK_MAX_SIZE, the last chunk has size 0.
58
             */
59

  
60
            if(i == fileParts - 1 && file.length() % CHUNK_MAX_SIZE == 0) {
61
                chunkData = new byte[0];
62
            } else {
63
                int bytesRead = streamBuffer.read(data, 0, data.length);
64
                chunkData = Arrays.copyOfRange(data, 0, bytesRead);
65
            }
66

  
67

  
68

  
69
            fileID = new FileID(sha256(file.getName()), repDeg);
70

  
71
            fileID.setNumChunks(fileParts + 1);
72

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff