Project

General

Profile

Statistics
| Revision:

root / proj / src / Peer.java @ 1

History | View | Annotate | Download (12.7 KB)

1

    
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
}