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