Project

General

Profile

Statistics
| Revision:

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
}