Project

General

Profile

Statistics
| Revision:

root / proj / src / Peer.java @ 1

History | View | Annotate | Download (12.7 KB)

1 1 up20160559
2
import java.io.BufferedInputStream;
3
import java.io.BufferedWriter;
4
import java.io.File;
5
import java.io.FileInputStream;
6
import java.io.FileNotFoundException;
7
import java.io.FileOutputStream;
8
import java.io.FileWriter;
9
import java.io.IOException;
10
import java.io.InputStream;
11
import java.io.ObjectOutputStream;
12
import java.io.OutputStream;
13
import java.net.UnknownHostException;
14
import java.nio.charset.StandardCharsets;
15
import java.nio.file.Files;
16
import java.nio.file.Paths;
17
import java.rmi.registry.LocateRegistry;
18
import java.rmi.registry.Registry;
19
import java.rmi.server.UnicastRemoteObject;
20
import java.security.MessageDigest;
21
import java.util.ArrayList;
22
import java.util.concurrent.TimeUnit;
23
24
25
26
27
public class Peer implements RMI {
28
29
30
        //final static int PORT = 8888;
31
        private static String version;
32
        private static int server_id;
33
        private static int peerID;
34
        private static String mcIp = "224.0.0.3";
35
        private static int mcPort = 8888;
36
        private static String mdbIp;
37
        private static int mdbPort;
38
        private static String mdrIp;
39
        private static int mdrPort;
40
41
        private static Channel mc;
42
        private static Channel mdb;
43
        private static Channel mdr;
44
        private boolean lastChunk = false;
45
46
47
48
        private static StorageSystem storage;
49
50
        private int chunkIterator = 0;
51
        private Peer(String mcIp, int mcPort, String mdbIp, int mdbPort, String mdrIp, int mdrPort) throws IOException {
52
                mc = new Channel(mcIp, mcPort, this);
53
                mdb = new Channel(mdbIp, mdbPort, this);
54
                mdr = new Channel(mdrIp,mdrPort, this);
55
56
                new Thread(mc).start();
57
                new Thread(mdb).start();
58
                new Thread(mdr).start();
59
        }
60
61
62
        public static void main(String[] args) throws UnknownHostException, InterruptedException {
63
64
                setVersion(args[0]);
65
                server_id = Integer.parseInt(args[1]);
66
                peerID = Integer.parseInt(args[2]);
67
                mcIp = args[3];
68
                mcPort = Integer.parseInt(args[4]);
69
                mdbIp = args[5];
70
                mdbPort = Integer.parseInt(args[6]);
71
                mdrIp = args[7];
72
                mdrPort = Integer.parseInt(args[8]);
73
74
                storage = new StorageSystem(peerID);
75
76
77
                try {
78
79
                        Peer obj = new Peer(mcIp, mcPort, mdbIp, mcPort, mdrIp, mcPort);
80
81
                        RMI stub = (RMI) UnicastRemoteObject.exportObject(obj, 0);
82
83
                        // Binding the remote object (stub) in the registry
84
                        Registry registry = LocateRegistry.getRegistry();
85
                        registry.rebind(args[2], stub);
86
87
88
                        System.err.println("Peer ready");
89
90
91
92
93
                } catch (Exception e) {
94
                        System.err.println("Peer exception: " + e.toString());
95
                        e.printStackTrace();
96
                }
97
        }
98
99
100
        public void operation(String operation, String file_path, int rep_degree, double space) { //operator is space for reclaim, rep_degree for back up
101
102
103
                if(operation.equals("BACKUP"))
104
                {
105
106
                        try {
107
                                initiateBackup(file_path, rep_degree);
108
                        } catch (InterruptedException e) {
109
                                // TODO Auto-generated catch block
110
                                e.printStackTrace();
111
                        }
112
113
                }
114
                else if(operation.equals("RESTORE"))
115
                {
116
                        try {
117
                                initiateRestore(file_path);
118
                        } catch (IOException e) {
119
                                // TODO Auto-generated catch block
120
                                e.printStackTrace();
121
                        }
122
123
                }
124
                else if(operation.equals("DELETE"))
125
                {
126
                        try {
127
                                initiateDelete(file_path);
128
                        } catch (Exception e) {
129
                                // TODO Auto-generated catch block
130
                                e.printStackTrace();
131
                        }
132
133
                }
134
                else if(operation == "RECLAIM")
135
                {
136
                        initiateReclaim(space);
137
                }
138
139
140
        }
141
142
143
144
145
146
147
private void initiateReclaim(double space) {
148
149
150
151
                for(int i = 0 ; i < storage.getChunks().size();i++) {
152
                    if(space > 0) {
153
                        Chunk chunk = storage.getChunks().get(i);
154
                        space -= chunk.getsize();
155
156
                        Message msg = new Message("REMOVED", getVersion(), this.getPeerID(), chunk.getFileID(), chunk.getChunkN(), 0 , null);
157
                        byte[] msgByte = msg.sendable();
158
159
                        try {
160
                            mc.sendMessage(msgByte);
161
                        } catch (UnknownHostException e) {
162
                            // TODO Auto-generated catch block
163
                            e.printStackTrace();
164
                        }
165
                        String newfilename = "Peer"+this.getPeerID() + "/"+ chunk.getFileID()+ "/chk" + chunk.getChunkN();
166
167
                        File file = new File(newfilename);
168
                        file.delete();
169
                        storage.deleteChunk(chunk);
170
171
                    }
172
                }
173
174
    }
175
176
177
        private void initiateDelete(String file_path) {
178
    String hash = storage.lookUp(file_path);
179
    byte[] msgByte = null;
180
    Message msg;
181
    msg = new Message("DELETE", getVersion(), this.getPeerID(),hash, 0, 0, null);
182
    msgByte = msg.sendable();
183
    System.out.println(msg.messageToStringPrintable());
184
    try {
185
        mdr.sendMessage(msgByte);
186
187
188
        TimeUnit.SECONDS.sleep(1);
189
190
    } catch (Exception e) {
191
        // TODO Auto-generated catch block
192
        e.printStackTrace();
193
    }
194
195
        }
196
197
        public void lastChunk() {
198
                this.lastChunk = true;
199
                System.out.println("LAST CHUNK");
200
        }
201
202
203
        private void initiateRestore(String file_path) throws IOException { //GETCHUNK <Version> <SenderId> <FileId> <ChunkNo> <CRLF><CRLF>
204
205
                String hash = storage.lookUp(file_path);
206
                int chunkn = 0;
207
                byte[] msgByte = null;
208
                Message msg;
209
                        ///getChunksFromFile(hash);
210
                while(!this.lastChunk) {
211
212
                        chunkn++;
213
214
                        msg = new Message("GETCHUNK", getVersion(), this.getPeerID(),hash,chunkn, 0, null);
215
                        msgByte = msg.sendable();
216
                        System.out.println(msg.messageToStringPrintable());
217
                        try {
218
                                mdr.sendMessage(msgByte);
219
220
221
222
                                TimeUnit.SECONDS.sleep(1);
223
224
                        } catch (Exception e) {
225
                                // TODO Auto-generated catch block
226
                                e.printStackTrace();
227
                        }
228
229
230
                }
231
232
                String newfilename = "Peer"+this.getPeerID() + "/restore/"+file_path;
233
234
        File file = new File(newfilename);
235
236
237
238
        if (!file.exists()) {
239
            file.getParentFile().mkdirs();
240
            file.createNewFile();
241
        }
242
243
        FileOutputStream outputStream = new FileOutputStream(newfilename);
244
245
246
247
            for(int i = 0; i < storage.getChunks().size(); i++) {
248
                       if(storage.getChunks().get(i).getFileID().equals(hash)) {
249
250
                               outputStream.write(storage.getChunks().get(i).getContent());
251
252
                    }
253
            }
254
255
256
257
             outputStream.close();
258
259
            this.lastChunk = false;
260
        }
261
262
263
264
265
        private void initiateBackup(String file_path, int rep_degree) throws InterruptedException {
266
267
                File file = new File(file_path);
268
                String fileID = generateFileID(file);
269
                byte[] msgByte = null;
270
                Message msg;
271
                boolean stored = false;
272
273
                try {
274
                        storage.addFile(file_path, file.lastModified(), fileID);
275
                        storage.serializeFileInfo();
276
                        ArrayList<Chunk> chunks = splitIntoChunksExternal(file, fileID, 64000);
277
278
279
                                for(Chunk chunk : chunks) {
280
281
                                        System.out.println("CHUNK N: "+ chunk.getChunkN()+ " SIZE: " + chunk.getContent().length);
282
                                        msg = new Message("PUTCHUNK", getVersion(), this.getPeerID(), chunk.getFileID(),chunk.getChunkN(), rep_degree, chunk.getContent());
283
                                        msgByte = msg.sendable();
284
                                        System.out.println(msg.messageToStringPrintable());
285
                                        mdb.sendMessage(msgByte);
286
287
                                        for(int i = 0; i < 5 && !stored; i++) {
288
289
                                        TimeUnit.SECONDS.sleep(i);
290
291
                                        if(storedCheck(chunk.getChunkN(), chunk.getFileID()) >= rep_degree) {
292
                                                stored = true;
293
                                        }
294
                                        else {
295
                                                mdb.sendMessage(msgByte);
296
                                                System.out.println(msg.messageToStringPrintable());
297
298
                                        }
299
                                        }
300
                                        stored = false;
301
302
303
                                }
304
305
306
307
                } catch (IOException e) {
308
                        System.err.println("IO Exception: " + e.toString());
309
                        e.printStackTrace();
310
                }
311
312
313
}
314
315
        private int storedCheck(int chunkN, String fileID) {
316
                int timesSaved = 0;
317
318
                for(BackUpInfo info : storage.getBackUps()) {
319
                        if(chunkN == info.getChunkN() && info.getFileID().equals(fileID))
320
                                timesSaved++;
321
                }
322
                return timesSaved;
323
        }
324
325
326
327
328
329
        public int getPeerID() {
330
                return peerID;
331
        }
332
333
        public Channel getMC() {
334
                return mc;
335
        }
336
337
        public Channel getMDB() {
338
                return mdb;
339
        }
340
341
        public Channel getMDR() {
342
                return mdr;
343
        }
344
345
346
347
348
        public void saveChunks() throws IOException{
349
350
                for(int i = 0; i < storage.getChunks().size(); i++) {
351
352
353
                         String filename = "Peer"+this.getPeerID() + "/backup/"+storage.getChunks().get(i).getFileID()+"/chk"+storage.getChunks().get(i).getChunkN();
354
355
                 File file = new File(filename);
356
                 if (!file.exists()) {
357
                     file.getParentFile().mkdirs();
358
                     file.createNewFile();
359
                 }
360
361
                 FileOutputStream fileOut = new FileOutputStream(filename);
362
                 ObjectOutputStream out = new ObjectOutputStream(fileOut);
363
                 out.writeObject(storage.getChunks().get(i).getContent());
364
                 out.close();
365
                 fileOut.close();
366
                }
367
368
        }
369
         public static String sha256hashing(String base) {
370
                try{
371
                    MessageDigest md = MessageDigest.getInstance("SHA-256");
372
                    byte[] hashed = md.digest(base.getBytes("UTF-8"));
373
                    StringBuffer hexString = new StringBuffer();
374
375
                    for (int i = 0; i < hashed.length; i++) {
376
                        String hex = Integer.toHexString(0xff & hashed[i]);
377
                        if(hex.length() == 1) hexString.append('0');
378
                        hexString.append(hex);
379
                    }
380
381
                    return hexString.toString();
382
                } catch(Exception ex){
383
                   throw new RuntimeException(ex);
384
                }
385
            }
386
387
         String generateFileID(File file) {
388
389
                    String aux  =file.getName() + file.lastModified();
390
391
392
                    return sha256hashing(aux);
393
            }
394
395
                public void getChunksFromFile(String hash) throws IOException {
396
397
398
                   try{
399
                        Files.exists(Paths.get("Peer"+this.getPeerID() + "/backup/"+hash+"/"));
400
                   File folder = new File("Peer"+this.getPeerID() + "/backup/"+hash+"/");
401
                   File[] files = folder.listFiles();
402
403
                    for (File file : files)
404
                    {
405
                            chunkIterator++;
406
                            byte[] chunkContent = Files.readAllBytes(file.toPath());
407
                            storage.addChunk(new Chunk(hash,chunkIterator,chunkContent));
408
                    }
409
                    chunkIterator = 0;
410
                   }
411
                   catch(FileNotFoundException ex){
412
                          System.out.println("Chunks not found" + ex.toString());
413
                          ex.printStackTrace();
414
                           }
415
416
417
                }
418
419
420
                public String getVersion() {
421
                        return version;
422
                }
423
424
425
                public static void setVersion(String version) {
426
                        Peer.version = version;
427
                }
428
429
430
                public StorageSystem getStorage() {
431
                        return storage;
432
                }
433
434
                public ArrayList<Chunk> splitIntoChunksExternal(File file, String fileID, int chunk_size) throws IOException
435
            {
436
                        ArrayList<Chunk> filechunks = new ArrayList<Chunk>();
437
438
             Boolean lastChunk = false;
439
             File willBeRead = file;
440
             int FILE_SIZE = (int) willBeRead.length();
441
442
443
             System.out.println("Total File Size: "+FILE_SIZE);
444
445
             byte[] temporary = null;
446
447
             try {
448
              InputStream inStream = null;
449
              int totalBytesRead = 0;
450
451
              try {
452
               inStream = new BufferedInputStream ( new FileInputStream( willBeRead ));
453
454
               int chunkCount = 0;
455
               while ( totalBytesRead < FILE_SIZE )
456
               {
457
458
                int bytesRemaining = FILE_SIZE-totalBytesRead;
459
                if ( bytesRemaining < chunk_size )
460
                {
461
                 chunk_size = bytesRemaining;
462
                 lastChunk = true;
463
                }
464
465
                temporary = new byte[chunk_size]; //Temporary Byte Array
466
                int bytesRead = inStream.read(temporary, 0, chunk_size);
467
                String temp = new String(temporary, StandardCharsets.UTF_8);
468
469
                if ( bytesRead > 0) // If bytes read is not empty
470
                {
471
                 totalBytesRead += bytesRead;
472
                 chunkCount++;
473
                }
474
475
                filechunks.add(new Chunk(fileID,chunkCount, temporary));
476
477
                if(bytesRemaining == 0 && lastChunk)
478
                        filechunks.add(new Chunk(fileID,chunkCount, null));
479
480
                System.out.println("Total Bytes Read: "+ totalBytesRead);
481
               }
482
483
              }
484
              finally {
485
               inStream.close();
486
              }
487
             }
488
             catch (NullPointerException ex)
489
             {
490
                     System.out.println("File not found"+ex.toString());
491
              ex.printStackTrace();
492
             }
493
             catch (FileNotFoundException ex)
494
             {
495
              ex.printStackTrace();
496
             }
497
             catch (IOException ex)
498
             {
499
              ex.printStackTrace();
500
             }
501
502
             return filechunks;
503
            }
504
505
}