Project

General

Profile

Revision 13

View differences:

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