root / server / Server.java @ 13
History | View | Annotate | Download (8.08 KB)
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 |
} |