-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmeta-data.py
210 lines (154 loc) · 5.02 KB
/
meta-data.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# -*- coding: utf-8 -*-
# Víctor A. Hernández & José R. Ortiz
# CCOM 4017 – Operating Systems
# Assignment 4: meta-data.py (comes with 7 other files)
# SQL support library. Database info for the metadata server
import sys
from mds_db import *
from Packet import *
import SocketServer
CHUNKLIST_BUFFER = 8192 # must be the same as in meta-data.py; should be big just in case data node list is big
def usage():
print """Usage: python %s <port, default=8000>""" % sys.argv[0]
sys.exit(0)
class MetadataTCPHandler(SocketServer.BaseRequestHandler):
def handle_reg(self, db, p):
"""
Register a new data node to the MDS.
- ACK if successfully registered.
- NAK if problem.
- DUP if duplicate.
"""
print "\t- Adding data node to MDS..."
try:
if db.AddDataNode(p.getAddr(), p.getPort()):
self.request.sendall("ACK")
print "\t- Succesfully added!"
else:
self.request.sendall("DUP")
print "\t- Data node already registered! Resuming activity..."
except:
self.request.sendall("NAK")
print "\t- Couldn't add data node to MDS!"
def handle_list(self, db):
"""
Get the file list from the database and send list to client
- List of tuples if successfully retrieved.
- NAK if problem.
"""
try:
print "\t- Retrieving file list from DFS..."
flist = db.GetFiles()
p = Packet()
p.BuildListResponse(flist)
self.request.sendall(p.getEncodedPacket())
print "\t- Sent file list to ls.py!"
except:
self.request.sendall("NAK")
print "\t- Couldn't retrieve file list from DFS!"
def handle_put(self, db, p):
"""
Insert new file in database and respond with list of available data nodes.
- List of tuples if succesfully inserted
- DUP if trying to insert a duplicate of the file.
"""
# Get (fname, fsize) from packet
fname, fsize = p.getFileInfo()
print "\t- Retrieving file info from packet..."
# Insert file into MDS and send list of available data nodes back to copy.py
if db.InsertFile(fname, fsize):
print "\t- Inserted file into MDS! Sending back available data nodes..."
nodelist = db.GetDataNodes()
q = Packet()
q.BuildPutResponse(nodelist)
self.request.sendall(q.getEncodedPacket())
print "\t- Done!"
else:
self.request.sendall("DUP")
print "\t- File already exists in MDS!"
def handle_get(self, db, p):
"""
Check if file is in database and return list of
server nodes that contain the file.
- List of fname and triple tuples
- NFOUND if fname is not valid (file not present in DFS)
"""
# Get fname from packet
fname = p.getFileName()
print "\t- Retrieving file name from packet..."
# Get fsize and metalist from MDS
fsize, metalist = db.GetFileInode(fname)
if fsize:
print "\t- Sending `get` response to copy.py..."
q = Packet()
q.BuildGetResponse(metalist, fsize)
self.request.sendall(q.getEncodedPacket())
print "\t- Done!"
else:
self.request.sendall("NFOUND")
print "\t- File not found in MDS!"
def handle_blocks(self, db, p):
"""Add the data blocks to the file inode"""
# Fill code to get file name and blocks from packet
print "\t- Retrieving file name and blocklist from packet..."
fname = p.getFileName()
blocklist = p.getDataBlocks()
# Fill code to add blocks to file inode
if db.AddBlockToInode(fname, blocklist):
print "\t- Succesfully added blocks to MDS!"
else:
print "\t- An error ocurred when trying to add blocks to MDS..."
def handle(self):
# Establish a connection with the local database
db = mds_db("dfs.db")
db.Connect()
# Define a packet object to decode packet messages
p = Packet()
# Receive a msg from the list, data-node, or copy clients
msg = self.request.recv(CHUNKLIST_BUFFER)
# Decode the packet received
p.DecodePacket(msg)
# Extract the command part of the received packet
cmd = p.getCommand()
# Invoke the proper action
if cmd == "reg":
# data-node.py polling for registration
print "\nHandling `reg` request from %s:%s..." % (p.getAddr(), p.getPort())
self.handle_reg(db, p)
elif cmd == "list":
# ls.py asking for a list of files
print "\nHandling `ls` request..."
self.handle_list(db)
elif cmd == "put":
# copy.py asking for servers to put data
print "\nHandling `put` request..."
self.handle_put(db, p)
elif cmd == "get":
# copy.py asking for servers to get data
print "\nHandling `get` request..."
self.handle_get(db, p)
elif cmd == "dblks":
# copy.py sending data blocks for file
print "\nHandling `dblks` request..."
self.handle_blocks(db, p)
else:
print "\nNo `cmd` was specified..."
db.Close()
def main():
HOST, PORT = "", 8000
if len(sys.argv) > 1:
try:
PORT = int(sys.argv[1])
except:
usage()
print "Starting server at 'localhost' in port %s..." % PORT
server = SocketServer.TCPServer((HOST, PORT), MetadataTCPHandler)
try:
server.serve_forever()
except KeyboardInterrupt:
print "\nClosing Meta Data Server..."
finally:
server.server_close()
print "Succesfully closed!"
if __name__ == "__main__":
main()