Revision 2
Final delivery
Peer.java | ||
---|---|---|
1 | 1 |
|
2 | 2 |
import java.io.BufferedInputStream; |
3 | 3 |
import java.io.BufferedWriter; |
4 |
import java.io.ByteArrayInputStream; |
|
5 |
import java.io.ByteArrayOutputStream; |
|
4 | 6 |
import java.io.File; |
5 | 7 |
import java.io.FileInputStream; |
6 | 8 |
import java.io.FileNotFoundException; |
... | ... | |
10 | 12 |
import java.io.InputStream; |
11 | 13 |
import java.io.ObjectOutputStream; |
12 | 14 |
import java.io.OutputStream; |
15 |
import java.io.StringReader; |
|
13 | 16 |
import java.net.UnknownHostException; |
17 |
import java.nio.ByteBuffer; |
|
18 |
import java.nio.channels.FileChannel; |
|
19 |
import java.nio.charset.Charset; |
|
14 | 20 |
import java.nio.charset.StandardCharsets; |
15 | 21 |
import java.nio.file.Files; |
16 | 22 |
import java.nio.file.Paths; |
... | ... | |
19 | 25 |
import java.rmi.server.UnicastRemoteObject; |
20 | 26 |
import java.security.MessageDigest; |
21 | 27 |
import java.util.ArrayList; |
28 |
import java.util.Arrays; |
|
22 | 29 |
import java.util.concurrent.TimeUnit; |
23 | 30 |
|
24 | 31 |
|
... | ... | |
97 | 104 |
} |
98 | 105 |
|
99 | 106 |
|
107 |
|
|
100 | 108 |
public void operation(String operation, String file_path, int rep_degree, double space) { //operator is space for reclaim, rep_degree for back up |
101 | 109 |
|
102 | 110 |
|
... | ... | |
131 | 139 |
} |
132 | 140 |
|
133 | 141 |
} |
134 |
else if(operation == "RECLAIM")
|
|
135 |
{ |
|
136 |
initiateReclaim(space); |
|
142 |
else if(operation.equals("RECLAIM"))
|
|
143 |
{
|
|
144 |
initiateReclaim(space);
|
|
137 | 145 |
} |
146 |
else if(operation.equals("STATE")) |
|
147 |
System.out.print(state()); |
|
148 |
|
|
138 | 149 |
|
139 | 150 |
|
151 |
|
|
140 | 152 |
} |
141 | 153 |
|
142 | 154 |
|
143 | 155 |
|
144 | 156 |
|
145 | 157 |
|
146 |
|
|
147 | 158 |
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(); |
|
159 |
long before = storage.getUsed_storage(); |
|
160 |
while(space < storage.getUsed_storage()) { |
|
161 |
|
|
162 |
//int size = storage.getChunks().get(0).getsize(); |
|
163 |
String fileID = storage.getChunks().get(0).getFileID(); |
|
164 |
int chunkN = storage.getChunks().get(0).getChunkN(); |
|
165 |
|
|
166 |
storage.deleteChunkByFileIDAndChunkN(fileID, chunkN); |
|
167 |
|
|
155 | 168 |
|
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
|
|
169 |
Message msg = new Message("REMOVED", getVersion(), this.getPeerID(),fileID, chunkN, 0 , null);
|
|
170 |
byte[] msgByte = msg.sendable(); |
|
171 |
|
|
172 |
try { |
|
173 |
mc.sendMessage(msgByte); |
|
174 |
} catch (UnknownHostException e) { |
|
175 |
// TODO Auto-generated catch block |
|
163 | 176 |
e.printStackTrace(); |
164 | 177 |
} |
165 |
String newfilename = "Peer"+this.getPeerID() + "/"+ chunk.getFileID()+ "/chk" + chunk.getChunkN(); |
|
178 |
|
|
166 | 179 |
|
167 |
File file = new File(newfilename); |
|
168 |
file.delete(); |
|
169 |
storage.deleteChunk(chunk); |
|
170 |
|
|
171 |
} |
|
172 |
} |
|
180 |
String filename = "Peer"+this.getPeerID()+ "/"+ fileID + "/chk" + chunkN; |
|
181 |
|
|
182 |
File folder = new File(filename); |
|
183 |
|
|
184 |
if (folder.exists()) { |
|
185 |
String[]entries = folder.list(); |
|
186 |
for(String s: entries){ |
|
187 |
File currentFile = new File(folder.getPath(),s); |
|
188 |
currentFile.delete(); |
|
189 |
} |
|
190 |
|
|
191 |
folder.delete(); |
|
192 |
|
|
193 |
} |
|
194 |
} |
|
195 |
|
|
196 |
long reclaimed = before-storage.getUsed_storage(); |
|
197 |
System.out.println("RECLAIMED " +reclaimed+"B of data."); |
|
198 |
|
|
199 |
|
|
200 |
|
|
173 | 201 |
|
174 | 202 |
} |
175 | 203 |
|
... | ... | |
196 | 224 |
|
197 | 225 |
public void lastChunk() { |
198 | 226 |
this.lastChunk = true; |
199 |
System.out.println("LAST CHUNK"); |
|
227 |
|
|
200 | 228 |
} |
201 | 229 |
|
202 |
|
|
203 |
private void initiateRestore(String file_path) throws IOException { //GETCHUNK <Version> <SenderId> <FileId> <ChunkNo> <CRLF><CRLF> |
|
230 |
private void initiateRestore(String file_path) throws IOException { //GETCHUNK <Version> <SenderId> <FileId> <ChunkNo> <CRLF><CRLF> |
|
204 | 231 |
|
205 | 232 |
String hash = storage.lookUp(file_path); |
206 | 233 |
int chunkn = 0; |
207 | 234 |
byte[] msgByte = null; |
208 | 235 |
Message msg; |
209 | 236 |
///getChunksFromFile(hash); |
210 |
while(!this.lastChunk) { |
|
237 |
boolean lastChunkAux = this.lastChunk; |
|
238 |
while(!lastChunkAux) { |
|
211 | 239 |
|
212 | 240 |
chunkn++; |
213 | 241 |
|
... | ... | |
226 | 254 |
e.printStackTrace(); |
227 | 255 |
} |
228 | 256 |
|
229 |
|
|
257 |
lastChunkAux = this.lastChunk; |
|
230 | 258 |
} |
231 | 259 |
|
232 | 260 |
String newfilename = "Peer"+this.getPeerID() + "/restore/"+file_path; |
... | ... | |
260 | 288 |
} |
261 | 289 |
|
262 | 290 |
|
291 |
public String state() { |
|
292 |
String s = ""; |
|
293 |
s += "\n PEER "+this.getPeerID()+" HAS INITIATED PROTOCOL BACK UP ON THE FOLLOWING FILES: \n"; |
|
294 |
for(FileInfo file: storage.getFileInfo()) { |
|
295 |
s+="File Pathname: "+file.getFilename()+"\n"; |
|
296 |
s+="File ID: "+file.getFileID()+"\n"; |
|
297 |
s+="Desired Replication Degree: "+file.getDesiredRepDeg()+"\n "; |
|
298 |
s+="Initiated Chunks: \n"; |
|
299 |
for(BackUpInfo chunk: storage.getBackUps()) { |
|
300 |
s+= "Chunk ID: "+ chunk.getFileID() + "chunk" + chunk.getChunkN()+"\n"; |
|
301 |
s+="Perceived Replication Degree: "+ storage.perceivedRepDeg(chunk.getFileID(), chunk.getChunkN())+"\n"; |
|
302 |
} |
|
303 |
s+="\n PEER "+this.getPeerID()+" IS STORING THE FOLLOWING CHUNKS: \n"; |
|
304 |
for(Chunk storedchunk: storage.getChunks()) { |
|
305 |
s+="Chunk ID: "+ storedchunk.getChunkId()+"\n"; |
|
306 |
s+="Size: "+storedchunk.getsize()+"\n"; |
|
307 |
s+="Perceived Replication Degree: "+storedchunk.getRepDeg()+"\n"; |
|
308 |
} |
|
309 |
s+="PEER STORAGE CAPACITY: " + storage.getSpace_available()+"\n"; |
|
310 |
|
|
311 |
} |
|
312 |
return s; |
|
313 |
} |
|
263 | 314 |
|
264 | 315 |
|
265 | 316 |
private void initiateBackup(String file_path, int rep_degree) throws InterruptedException { |
... | ... | |
267 | 318 |
File file = new File(file_path); |
268 | 319 |
String fileID = generateFileID(file); |
269 | 320 |
byte[] msgByte = null; |
270 |
Message msg; |
|
271 | 321 |
boolean stored = false; |
272 | 322 |
|
273 | 323 |
try { |
274 |
storage.addFile(file_path, file.lastModified(), fileID); |
|
324 |
storage.addFile(file_path, file.lastModified(), fileID, rep_degree);
|
|
275 | 325 |
storage.serializeFileInfo(); |
276 |
ArrayList<Chunk> chunks = splitIntoChunksExternal(file, fileID, 64000);
|
|
326 |
ArrayList<Chunk> chunks = splitIntoChunks(file, fileID, 64000); |
|
277 | 327 |
|
278 | 328 |
|
279 |
for(Chunk chunk : chunks) {
|
|
329 |
for(int i = 0; i < chunks.size(); i++) {
|
|
280 | 330 |
|
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());
|
|
331 |
Message msg = new Message("PUTCHUNK", getVersion(), this.getPeerID(), chunks.get(i).getFileID(),chunks.get(i).getChunkN(), rep_degree,
|
|
332 |
chunks.get(i).getContent());
|
|
283 | 333 |
msgByte = msg.sendable(); |
334 |
|
|
284 | 335 |
System.out.println(msg.messageToStringPrintable()); |
285 | 336 |
mdb.sendMessage(msgByte); |
286 | 337 |
|
287 |
for(int i = 0; i < 5 && !stored; i++) {
|
|
338 |
for(int j = 0; j < 5 && !stored; j++) {
|
|
288 | 339 |
|
289 |
TimeUnit.SECONDS.sleep(i);
|
|
340 |
TimeUnit.SECONDS.sleep(1+j);
|
|
290 | 341 |
|
291 |
if(storedCheck(chunk.getChunkN(), chunk.getFileID()) >= rep_degree) {
|
|
342 |
if(storedCheck(chunks.get(i).getChunkN(), chunks.get(i).getFileID()) >= rep_degree) {
|
|
292 | 343 |
stored = true; |
293 | 344 |
} |
294 | 345 |
else { |
... | ... | |
312 | 363 |
|
313 | 364 |
} |
314 | 365 |
|
315 |
private int storedCheck(int chunkN, String fileID) {
|
|
366 |
public int storedCheck(int chunkN, String fileID) {
|
|
316 | 367 |
int timesSaved = 0; |
317 | 368 |
|
318 | 369 |
for(BackUpInfo info : storage.getBackUps()) { |
... | ... | |
344 | 395 |
|
345 | 396 |
|
346 | 397 |
|
398 |
public void deleteFileFolder(String hash) { |
|
399 |
String foldername = "Peer"+this.getPeerID() + "/backup/"+hash; |
|
400 |
|
|
401 |
File folder = new File(foldername); |
|
402 |
|
|
403 |
if (folder.exists()) { |
|
404 |
String[]entries = folder.list(); |
|
405 |
for(String s: entries){ |
|
406 |
File currentFile = new File(folder.getPath(),s); |
|
407 |
currentFile.delete(); |
|
408 |
} |
|
409 |
|
|
410 |
folder.delete(); |
|
411 |
|
|
412 |
} |
|
413 |
} |
|
347 | 414 |
|
348 | 415 |
public void saveChunks() throws IOException{ |
349 | 416 |
|
... | ... | |
369 | 436 |
public static String sha256hashing(String base) { |
370 | 437 |
try{ |
371 | 438 |
MessageDigest md = MessageDigest.getInstance("SHA-256"); |
372 |
byte[] hashed = md.digest(base.getBytes("UTF-8"));
|
|
439 |
byte[] hashed = md.digest(base.getBytes("UTF8")); |
|
373 | 440 |
StringBuffer hexString = new StringBuffer(); |
374 | 441 |
|
375 | 442 |
for (int i = 0; i < hashed.length; i++) { |
... | ... | |
431 | 498 |
return storage; |
432 | 499 |
} |
433 | 500 |
|
434 |
public ArrayList<Chunk> splitIntoChunksExternal(File file, String fileID, int chunk_size) throws IOException
|
|
501 |
public ArrayList<Chunk> splitIntoChunks(File file, String fileID, int chunk_size) throws IOException |
|
435 | 502 |
{ |
436 | 503 |
ArrayList<Chunk> filechunks = new ArrayList<Chunk>(); |
437 | 504 |
|
... | ... | |
464 | 531 |
|
465 | 532 |
temporary = new byte[chunk_size]; //Temporary Byte Array |
466 | 533 |
int bytesRead = inStream.read(temporary, 0, chunk_size); |
467 |
String temp = new String(temporary, StandardCharsets.UTF_8); |
|
534 |
|
|
468 | 535 |
|
469 | 536 |
if ( bytesRead > 0) // If bytes read is not empty |
470 | 537 |
{ |
... | ... | |
502 | 569 |
return filechunks; |
503 | 570 |
} |
504 | 571 |
|
572 |
|
|
505 | 573 |
} |
Also available in: Unified diff