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 _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 process_msg_add_request(sid, uname, ssid, comment):
    ## if master fails to find slave node, try MAX_TRY times until it
    ## response 503
    retry = 0
    while retry < api.MAX_TRY:
		try:
			node = _get_next_worker(sid)
			if node == None:
			    break
		    
			s_time = api._get_current_time().isoformat()
			response = _send_add_comment_call(**{
				'nid':node,
				'sid':sid,
				'by':uname,
				'session_id':ssid,
				'comment':comment,
				'created_at':s_time
			})

			if not response:
			    retry+=1
			    q.custom_push(api.FAILED_NODES, node)
			    logger.error("failed... trying another node...")

			## execution succeed
			else:
				return api.decrypt_msg(
					WebServerModel.objects(sid=sid).get().private_key, response)

		except:
			retry+=1
			logger.error("failed... trying another node...")

    return {
    	'errorMsg':"chatting is not available at the moment"
    }
def _find_usersession(secure_id, sid):
	pk = WebServerModel.objects(sid=sid).get().private_key
	s_id = api.decrypt_msg(pk, secure_id)

	return UserSession.objects(sid=sid).find_one({"session_id":s_id})