def _on_message(self, ch, method, properties, body): print "message received!" data = json.loads(api.decrypt_msg( AppModel.objects(nid=self.nid).scalar('private_key').get(), body)) print data server_id = AppModel.objects(nid=self.nid).scalar('master_sid').get() ## access to the shared resource has been permitted if (data['action'] == _ACTION_KEYS[8]): if server_id == data['by']: # for minimum integrity # this data format is to save contents by 'add_comments' function # send all data that is locally stored then it will be filtered to store to # the shared resource inside 'add_comments' function data = { 'permission':True, # this action would be only triggered with master server's permission 'nid':self.nid, 'sid':data['by'], 'content':map(lambda x:{ 'by':x.by, 'created_at':x.timestamp, 'comment':x.comment, 'session_id':x.session_id }, CommentReplicaModel.objects.all()) } app_api.add_comments(**data)
def _store_server_info(self, server_data, nid): try: AppModel.objects(nid=nid).update_one( master_sid=server_data['server_id'], server_public_key=server_data['server_public_key'], common_key_private=server_data['common_key_private']) print "server info updated" self._send_heartbeat(server_data['server_id'], nid) except: logger.error("this client has no information of master server")
def _delete_nodes(target_nids, my_nid): n_obj = AppModel.objects(nid=my_nid) if not isinstance(target_nids, list): if n_obj.update_one(pull__nodes__nid=target_nids)>0: n_obj.get().save() logger.info(target_nids+" deleted") else: logger.error("deleted failed") else: if n_obj.update(pull_all__nodes= map(lambda x:{ 'nid':str(x) }, target_nids))>0: n_obj.get().save() logger.info("deleted many") else: logger.error("deleted many failed") nodes = n_obj.get().nodes for node in nodes: node_obj = json.loads(node.to_json()) print "id: {}".format(node_obj['_id'])
def _add_nodes(nodes, nid): if nodes: active_nodes=[] for node in nodes: if api.uuid_to_obj(node['nid'] is None or api.uuid_to_obj(nid) is None): logger.error("wrong type of user id") elif node['nid'] != nid: active_nodes.append(NodeModel( nid=node['nid'], public_key=node['public_key'])) else: #print "it's yourself" pass if active_nodes: n_obj = AppModel.objects(nid=nid) n_obj.update(add_to_set__nodes=active_nodes) n_obj.get().save() logger.info("new node joined, current active node list") nodes = n_obj.get().nodes for node in nodes: node_obj = json.loads(node.to_json()) print "id: {}".format(node_obj['_id']) else: logger.error("nodes has no element")
def execute_command(self, encrypted_action): print "server calling rpc" data = json.loads( api.decrypt_msg(self.model.private_key, encrypted_action)) action = data['action'] print action ## response from master server has arrived, stop trying to reach other servers if self.timer.is_alive(): self.timer.stop() ## server sent info if (action == api._ACTION_KEYS[0]): self._store_server_info(data['data'], self.model.nid) ## add comments elif(action == api._ACTION_KEYS[5]): data['nid'] = self.model.nid """data['content'].update( { 'nid':self.model.nid, 'sid':data['sid'] })""" return api.encrypt_msg(AppModel.objects( nid=self.model.nid).get().server_public_key, app_api.add_comments(**data))
def _on_message(self, ch, method, properties, body): #try: print "fanout message" data = json.loads(api.decrypt_msg( AppModel.objects(nid=self.nid).scalar('common_key_private').get(), body)) #logger.info(data['action']) ## A node joined the system if (data['action'] == _ACTION_KEYS[1]): app_api._add_nodes(data['data'], self.nid) ## delete nodes left the system elif (data['action'] == _ACTION_KEYS[2]): if not isinstance(data['data'], list): app_api._delete_nodes(data['data']['nid'], self.nid) else: app_api._delete_nodes(data['data'], self.nid) ## common key timeout, needs to be updated elif (data['action'] == _ACTION_KEYS[3]): if app_api._refresh_common_key(self.nid, data['data']['common_key_private']) == False: logger.error("refreshing common key failed") else: logger.info("common key refresehd...")
def _send_heartbeat(self, server_id, nid): retry = 0 while retry < api.MAX_TRY: try: proxy = callme.Proxy( server_id=server_id, amqp_host="localhost", amqp_port=5672, timeout=3) proxy.use_server(server_id).receive_heartbeats(nid, server_id) # try again retry = api.MAX_TRY ## record heartbeat locally as well AppModel.objects(nid=nid).update_one(last_access=api._get_current_time()) is_master_failing = False # try daemon thread #threading.Timer(3, _send_heart_beat).setDaemon(True) threading.Timer(api.CHECK_HEARTBEAT, self._send_heartbeat, [server_id, nid]).start() except: retry += 1 is_master_failing = True print "Server: {} is not responding, trying {} times...".format(server_id, str(retry)) #print "Master server is not responding" ## master server failed if is_master_failing: self.timer = ConnTimeout(api._TIMEOUT, app_api._send_handshake_msg, servers=3, args=[nid, AppModel.objects(nid=nid).get().public_key, AppModel.objects(nid=nid).get().created_at.isoformat()]) self.timer.start() """_send_handshake_msg(
def _refresh_common_key(nid, key): if AppModel.objects(nid=nid).update_one(common_key_private=key)>0: return True else: return False