Skip to content

Commit

Permalink
Bug: 1475924 - Accept admin state in publish request
Browse files Browse the repository at this point in the history
Change-Id: I7389a6abac64f3cbeb3887ceed4d69d82a965ee9
  • Loading branch information
Deepinder Setia committed Jul 24, 2015
1 parent bca23af commit 66d50b0
Showing 1 changed file with 45 additions and 29 deletions.
74 changes: 45 additions & 29 deletions src/discovery/disc_server.py
Expand Up @@ -377,7 +377,7 @@ def api_heartbeat(self):
ctype = bottle.request.headers['content-type']
json_req = {}
try:
if ctype == 'application/xml':
if 'application/xml' in ctype:
data = xmltodict.parse(bottle.request.body.read())
else:
data = bottle.request.json
Expand All @@ -394,27 +394,41 @@ def api_publish(self, end_point = None):
self._debug['msg_pubs'] += 1
ctype = bottle.request.headers['content-type']
json_req = {}
if ctype == 'application/json':
data = bottle.request.json
for service_type, info in data.items():
json_req['name'] = service_type
json_req['info'] = info
elif ctype == 'application/xml':
data = xmltodict.parse(bottle.request.body.read())
for service_type, info in data.items():
json_req['name'] = service_type
json_req['info'] = dict(info)
else:
bottle.abort(400, e)
try:
if 'application/json' in ctype:
data = bottle.request.json
elif 'application/xml' in ctype:
data = xmltodict.parse(bottle.request.body.read())
except Exception as e:
self.syslog('Unable to parse publish request')
self.syslog(bottle.request.body.buf)
bottle.abort(415, 'Unable to parse publish request')

# new format - publish tag to envelop entire content
if 'publish' in data:
data = data['publish']
for key, value in data.items():
json_req[key] = value

# old format didn't include explicit tag for service type
service_type = data.get('service-type', data.keys()[0])

# convert ordered dict to normal dict
try:
json_req[service_type] = data[service_type]
except (ValueError, KeyError, TypeError) as e:
bottle.abort(400, "Unknown service type")

info = json_req[service_type]
admin_state = json_req.get('admin-state', 'up')
if admin_state not in ['up', 'down']:
bottle.abort(400, "Invalid admin state")
remote = json_req.get('remote-addr',
bottle.request.environ['REMOTE_ADDR'])

sig = end_point or publisher_id(
bottle.request.environ['REMOTE_ADDR'], json.dumps(json_req))

# Rx {'name': u'ifmap-server', 'info': {u'ip_addr': u'10.84.7.1',
# u'port': u'8443'}}
info = json_req['info']
service_type = json_req['name']

entry = self._db_conn.lookup_service(service_type, service_id=sig)
if not entry:
entry = {
Expand All @@ -424,16 +438,16 @@ def api_publish(self, end_point = None):
'ts_use': 0,
'ts_created': int(time.time()),
'prov_state': 'new',
'remote': bottle.request.environ.get('REMOTE_ADDR'),
'sequence': str(int(time.time())) + socket.gethostname(),
}
elif 'sequence' not in entry or self.service_expired(entry):
# handle upgrade or republish after expiry
entry['sequence'] = str(int(time.time())) + socket.gethostname()

entry['info'] = info
entry['admin_state'] = 'up'
entry['admin_state'] = admin_state
entry['heartbeat'] = int(time.time())
entry['remote'] = remote

# insert entry if new or timed out
self._db_conn.update_service(service_type, sig, entry)
Expand Down Expand Up @@ -506,9 +520,9 @@ def service_list(self, service_type, pubs):
def api_subscribe(self):
self._debug['msg_subs'] += 1
ctype = bottle.request.headers['content-type']
if ctype == 'application/json':
if 'application/json' in ctype:
json_req = bottle.request.json
elif ctype == 'application/xml':
elif 'application/xml' in ctype:
data = xmltodict.parse(bottle.request.body.read())
json_req = {}
for service_type, info in data.items():
Expand All @@ -521,6 +535,8 @@ def api_subscribe(self):
client_id = json_req['client']
count = reqcnt = int(json_req['instances'])
client_type = json_req.get('client-type', '')
remote = json_req.get('remote-addr',
bottle.request.environ['REMOTE_ADDR'])

assigned_sid = set()
r = []
Expand All @@ -531,11 +547,11 @@ def api_subscribe(self):
if not cl_entry:
cl_entry = {
'instances': count,
'remote': bottle.request.environ.get('REMOTE_ADDR'),
'client_type': client_type,
}
self.create_sub_data(client_id, service_type)
self._db_conn.insert_client_data(service_type, client_id, cl_entry)
cl_entry['remote'] = remote
self._db_conn.insert_client_data(service_type, client_id, cl_entry)

sdata = self.get_sub_data(client_id, service_type)
if sdata:
Expand All @@ -557,7 +573,7 @@ def api_subscribe(self):
if count == 0:
r = [entry['info'] for entry in pubs_active]
response = {'ttl': ttl, service_type: r}
if ctype == 'application/xml':
if 'application/xml' in ctype:
response = xmltodict.unparse({'response': response})
return response

Expand All @@ -577,13 +593,13 @@ def api_subscribe(self):
count -= 1
if count == 0:
response = {'ttl': ttl, service_type: r}
if ctype == 'application/xml':
if 'application/xml' in ctype:
response = xmltodict.unparse({'response': response})
return response


# skip duplicates from existing assignments
pubs = [entry for entry in pubs_active if not entry['service_id'] in assigned_sid]
pubs = [entry for entry in pubs_active if not entry['service_id'] in assigned_sid]

# find instances based on policy (lb, rr, fixed ...)
pubs = self.service_list(service_type, pubs)
Expand All @@ -608,7 +624,7 @@ def api_subscribe(self):


response = {'ttl': ttl, service_type: r}
if ctype == 'application/xml':
if 'application/xml' in ctype:
response = xmltodict.unparse({'response': response})
return response
# end api_subscribe
Expand Down Expand Up @@ -655,7 +671,7 @@ def api_query(self):
(entry['service_id'], json.dumps(result)))

response = {service_type: r}
if ctype == 'application/xml':
if 'application/xml' in ctype:
response = xmltodict.unparse({'response': response})
return response
# end api_subscribe
Expand Down

0 comments on commit 66d50b0

Please sign in to comment.