Revision 13
server/InterfaceServer.java | ||
---|---|---|
1 |
package server; |
|
2 |
|
|
3 |
import java.rmi.Remote; |
|
4 |
import java.rmi.RemoteException; |
|
5 |
|
|
6 |
// Creating Remote interface for our application |
|
7 |
public interface InterfaceServer extends Remote { |
|
8 |
void backupFile(String path,int replication) throws RemoteException; |
|
9 |
void restoreFile(String path) throws RemoteException; |
|
10 |
void deleteFile(String path) throws RemoteException; |
|
11 |
void manageLocalStorage(int size) throws RemoteException; |
|
12 |
void retrieveLocalInformation() throws RemoteException; |
|
13 |
} |
server/Server.java | ||
---|---|---|
1 |
package server; |
|
2 |
|
|
3 |
import java.io.*; |
|
4 |
import java.nio.charset.StandardCharsets; |
|
5 |
import java.rmi.registry.LocateRegistry; |
|
6 |
import java.rmi.registry.Registry; |
|
7 |
import java.rmi.server.UnicastRemoteObject; |
|
8 |
import java.util.concurrent.Executors; |
|
9 |
import java.util.concurrent.ScheduledThreadPoolExecutor; |
|
10 |
import java.util.concurrent.TimeUnit; |
|
11 |
import java.util.ArrayList; |
|
12 |
import multicastchannels.*; |
|
13 |
import storage.Storage; |
|
14 |
import chunk.*; |
|
15 |
import threads.*; |
|
16 |
|
|
17 |
public class Server implements InterfaceServer { |
|
18 |
private static String protocolVersion;// Protocol Version |
|
19 |
private static String serverId;// Server Id |
|
20 |
private static String serviceAP;// Access Point |
|
21 |
private static ControlChannel mc; |
|
22 |
private static BackupChannel mdb; |
|
23 |
private static RemoteChannel mdr; |
|
24 |
private static ScheduledThreadPoolExecutor threadLauncher; |
|
25 |
private String path; |
|
26 |
private File directory; |
|
27 |
private static Storage storage; |
|
28 |
|
|
29 |
public Server(String args[]) throws IOException { |
|
30 |
// Implement Server constructor |
|
31 |
threadLauncher = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(250); |
|
32 |
protocolVersion = args[0]; |
|
33 |
serverId = args[1]; |
|
34 |
serviceAP = args[2]; |
|
35 |
|
|
36 |
// multicast data recovery channel |
|
37 |
// two arguments -> ip and port |
|
38 |
mc = new ControlChannel(args[3], Integer.parseInt(args[4])); |
|
39 |
mdb = new BackupChannel(args[5], Integer.parseInt(args[6])); |
|
40 |
mdr = new RemoteChannel(args[7], Integer.parseInt(args[8])); |
|
41 |
|
|
42 |
path = "database/" + serverId; |
|
43 |
|
|
44 |
directory = new File(path); |
|
45 |
if (!directory.exists()) { |
|
46 |
directory.mkdirs(); |
|
47 |
// If you require it to make the entire directory path including parents, |
|
48 |
// use directory.mkdirs(); here instead. |
|
49 |
} |
|
50 |
storage = new Storage(); |
|
51 |
|
|
52 |
|
|
53 |
} |
|
54 |
|
|
55 |
public static ControlChannel getmc() { |
|
56 |
return mc; |
|
57 |
} |
|
58 |
|
|
59 |
public static BackupChannel getmdb() { |
|
60 |
return mdb; |
|
61 |
} |
|
62 |
|
|
63 |
public static RemoteChannel getmdr() { |
|
64 |
return mdr; |
|
65 |
} |
|
66 |
|
|
67 |
public static ScheduledThreadPoolExecutor getThreadLauncher() { |
|
68 |
return threadLauncher; |
|
69 |
} |
|
70 |
|
|
71 |
public synchronized void backupFile(String path, int replication) { |
|
72 |
ChunkFile file = new ChunkFile(path, replication); |
|
73 |
storage.addFile(file); |
|
74 |
|
|
75 |
for (int i = 0; i < file.getChunks().size(); i++) { |
|
76 |
|
|
77 |
Chunk chunk = file.getChunks().get(i); |
|
78 |
|
|
79 |
chunk.setRepDegree(replication); |
|
80 |
|
|
81 |
String header = "PUTCHUNK " + protocolVersion + " " + serverId + " " + file.getFileId() + " " |
|
82 |
+ chunk.getNum() + " " + chunk.getRepDegree() + "\r\n\r\n"; |
|
83 |
System.out.println("SENT" + header); |
|
84 |
|
|
85 |
String key = file.getFileId() + "." + chunk.getNum(); |
|
86 |
|
|
87 |
if (!storage.getStoredTimes().containsKey(key)) { |
|
88 |
Server.getStorage().getStoredTimes().put(key, 0); |
|
89 |
} |
|
90 |
|
|
91 |
try { |
|
92 |
byte[] message = createHeader(header, chunk); |
|
93 |
SendMessage sendThread = new SendMessage(message, "mdb"); |
|
94 |
threadLauncher.execute(sendThread); |
|
95 |
Thread.sleep(500); |
|
96 |
Server.getThreadLauncher().schedule( |
|
97 |
new ManagePutchunk(message, 1, file.getFileId(), chunk.getNum(), replication), 1, |
|
98 |
TimeUnit.SECONDS); |
|
99 |
|
|
100 |
} catch (UnsupportedEncodingException | InterruptedException e) { |
|
101 |
e.printStackTrace(); |
|
102 |
} |
|
103 |
} |
|
104 |
} |
|
105 |
|
|
106 |
private byte[] createHeader(String header, Chunk chunk) throws UnsupportedEncodingException { |
|
107 |
byte[] asciiHeader, body, message; |
|
108 |
asciiHeader = header.getBytes(StandardCharsets.US_ASCII); |
|
109 |
body = chunk.getContent(); |
|
110 |
message = new byte[asciiHeader.length + body.length]; |
|
111 |
System.arraycopy(asciiHeader, 0, message, 0, asciiHeader.length); |
|
112 |
System.arraycopy(body, 0, message, asciiHeader.length, body.length); |
|
113 |
|
|
114 |
return message; |
|
115 |
} |
|
116 |
|
|
117 |
public void restoreFile(String path) { |
|
118 |
String filename = null; |
|
119 |
for (int i = 0; i < storage.getFiles().size(); i++) { |
|
120 |
if (storage.getFiles().get(i).getPath().equals(path)) { |
|
121 |
for (int j = 0; j < storage.getFiles().get(i).getChunks().size(); j++) { |
|
122 |
|
|
123 |
String header = "GETCHUNK " + protocolVersion + " " + serverId + " " + storage.getFiles().get(i).getFileId() + " " + storage.getFiles().get(i).getChunks().get(j).getNum() + "\r\n\r\n"; |
|
124 |
System.out.println("Sent " + header); |
|
125 |
|
|
126 |
storage.addRemainingChunks(storage.getFiles().get(i).getFileId(), storage.getFiles().get(i).getChunks().get(j).getNum()); |
|
127 |
filename = new String(storage.getFiles().get(i).getFileId().getBytes(), StandardCharsets.UTF_8); |
|
128 |
SendMessage sendThread = new SendMessage(header.getBytes(StandardCharsets.US_ASCII), "mc"); |
|
129 |
} |
|
130 |
Server.getThreadLauncher().schedule(new ManageRestored(filename), 10, TimeUnit.SECONDS); |
|
131 |
} else System.out.println("ERROR: File was never backed up."); |
|
132 |
} |
|
133 |
} |
|
134 |
|
|
135 |
|
|
136 |
|
|
137 |
public void deleteFile(String path) { |
|
138 |
for (int i = 0; i < storage.getFiles().size(); i++) { |
|
139 |
if (storage.getFiles().get(i).getPath().equals(path)) { |
|
140 |
|
|
141 |
for (int j = 0; j < 10; j++) { |
|
142 |
String header = "DELETE " + protocolVersion + " " + serverId + " "+ storage.getFiles().get(i).getFileId() + "\r\n\r\n"; |
|
143 |
System.out.println("Send DELETE " + header); |
|
144 |
SendMessage sendThread = new SendMessage(header.getBytes(StandardCharsets.US_ASCII), "mc"); |
|
145 |
threadLauncher.execute(sendThread); |
|
146 |
} |
|
147 |
for (int j = 0; j < storage.getFiles().get(i).getChunks().size(); j++) { |
|
148 |
storage.removeStoredOccurrencesEntry(storage.getFiles().get(i).getFileId(), storage.getFiles().get(i).getChunks().get(j).getNum()); |
|
149 |
} |
|
150 |
storage.getFiles().remove(i); |
|
151 |
break; |
|
152 |
} |
|
153 |
} |
|
154 |
|
|
155 |
} |
|
156 |
|
|
157 |
public void manageLocalStorage(int size) { |
|
158 |
|
|
159 |
System.out.println("Specify the maximum disk space used(0 to reclaim all dispace allocated by the server): "); |
|
160 |
} |
|
161 |
|
|
162 |
private static void deserializeStorage() { |
|
163 |
try { |
|
164 |
String filename = "database/" + Server.getServerId() + "/storage.txt"; |
|
165 |
|
|
166 |
File file = new File(filename); |
|
167 |
if (!file.exists()) { |
|
168 |
storage = new Storage(); |
|
169 |
return; |
|
170 |
} |
|
171 |
|
|
172 |
FileInputStream fileIn = new FileInputStream(filename); |
|
173 |
ObjectInputStream in = new ObjectInputStream(fileIn); |
|
174 |
storage = (Storage) in.readObject(); |
|
175 |
in.close(); |
|
176 |
fileIn.close(); |
|
177 |
} catch (IOException i) { |
|
178 |
i.printStackTrace(); |
|
179 |
} catch (ClassNotFoundException c) { |
|
180 |
System.out.println("Storage class not found"); |
|
181 |
c.printStackTrace(); |
|
182 |
} |
|
183 |
} |
|
184 |
|
|
185 |
public void retrieveLocalInformation() { |
|
186 |
|
|
187 |
|
|
188 |
System.out.println("Esta a funcionar -Local Info"); |
|
189 |
} |
|
190 |
|
|
191 |
public int getVersion() { |
|
192 |
return Integer.parseInt(protocolVersion); |
|
193 |
} |
|
194 |
|
|
195 |
public static String getServerId() { |
|
196 |
return serverId; |
|
197 |
} |
|
198 |
|
|
199 |
public String getAccessProtocol() { |
|
200 |
return serviceAP; |
|
201 |
} |
|
202 |
|
|
203 |
public ControlChannel getControlChannel() { |
|
204 |
return mc; |
|
205 |
} |
|
206 |
|
|
207 |
public BackupChannel getBackupChannel() { |
|
208 |
return mdb; |
|
209 |
} |
|
210 |
|
|
211 |
public RemoteChannel getRemoteChannel() { |
|
212 |
return mdr; |
|
213 |
} |
|
214 |
|
|
215 |
public static Storage getStorage() { |
|
216 |
return storage; |
|
217 |
} |
|
218 |
|
|
219 |
private static void serializeStorage() { |
|
220 |
try { |
|
221 |
String filename = "database/" + Server.getServerId() + "/storage.txt"; |
|
222 |
|
|
223 |
File file = new File(filename); |
|
224 |
if (!file.exists()) { |
|
225 |
file.getParentFile().mkdirs(); |
|
226 |
file.createNewFile(); |
|
227 |
} |
|
228 |
|
|
229 |
FileOutputStream fileOut = new FileOutputStream(filename); |
|
230 |
ObjectOutputStream out = new ObjectOutputStream(fileOut); |
|
231 |
out.writeObject(storage); |
|
232 |
out.close(); |
|
233 |
fileOut.close(); |
|
234 |
} catch (IOException i) { |
|
235 |
i.printStackTrace(); |
|
236 |
} |
|
237 |
} |
|
238 |
|
|
239 |
public static void main(String args[]) { |
|
240 |
try { |
|
241 |
if (args.length != 9) { |
|
242 |
System.out.println( |
|
243 |
"ERROR INVALID ARGUMENTS: Server <versionId> <serviceId> <ser_access_point> <mc_ip> <mc_port> <mdb_ip> <mdb_port> <mdr_ip> <mdr_port>"); |
|
244 |
} |
|
245 |
// Instantiating the implementation class |
|
246 |
Server server = new Server(args); |
|
247 |
// Exporting the object of implementation class |
|
248 |
// (here we are exporting the remote object to the stub) |
|
249 |
|
|
250 |
InterfaceServer stub = (InterfaceServer) UnicastRemoteObject.exportObject(server, 0); |
|
251 |
|
|
252 |
// Binding the remote object (stub) in the registry |
|
253 |
Registry registry; |
|
254 |
try { |
|
255 |
registry = LocateRegistry.createRegistry(1099); |
|
256 |
} catch (Exception e) { |
|
257 |
registry = LocateRegistry.getRegistry(); |
|
258 |
|
|
259 |
} |
|
260 |
|
|
261 |
registry.bind(server.serviceAP, stub); |
|
262 |
|
|
263 |
System.err.println("Server ready"); |
|
264 |
} catch (Exception e) { |
|
265 |
System.err.println("Server exception: " + e.toString()); |
|
266 |
e.printStackTrace(); |
|
267 |
} |
|
268 |
deserializeStorage(); |
|
269 |
Runtime.getRuntime().addShutdownHook(new Thread(Server::serializeStorage)); |
|
270 |
} |
|
271 |
|
|
272 |
} |
Also available in: Unified diff