Пример #1
0
    def get_push_target_tag(self, **kwargs):
        """
        Retrieves a single target tag with given id.
    
        Args:
            **kwargs (dict): project_id, target_id, name
                - project_id: project id
                - target_id: target who is tagged with this tag
                - name: name of tag
    
        Returns:
            dict: target tag or error message
        """
        project_id, tag_name = kwargs['project_id'], kwargs['name']
        target = self.get_obj(project_id, 'target', kwargs['target_id'])

        if tag_name not in target.data['push_tags']:
            zlogger.error("Tag is doesn't exist in target's tags. Project id:{},"
                          "target id:{}, tag name:{}".format(project_id,
                                                             kwargs['target_id'],
                                                             tag_name))
            return {"error": {"code": -32006,
                              "message": "Related tag couldn't be found in user's push tags."}}

        tag = self.get_obj(project_id, 'tag', "{}_{}".format(project_id, tag_name))
        tag_type, val = (tag.data['tag_type'], target.data['push_tags'][tag_name])
        value = [] if tag_type == 'key' else [val] if tag_type == 'key-value' else list(val.keys())

        return {'key': tag_name, 'value_read': value}
Пример #2
0
    def create_push_tag(self, **kwargs):
        """
        Creates a single tag with given id.
    
        Args:
            **kwargs (dict): project_id, name, tag_type, value_type
                - project_id: project id
                - name: name of tag
                - tag_type: tag type
                - value_type: value type
    
        Returns:
        """
        bucket = self.get_bucket(kwargs['project_id'], 'tag')

        tag_key = "{}_{}".format(kwargs['project_id'], kwargs['name'])
        if bucket.get(tag_key).exists:
            zlogger.error(" Tag to be saved is already exists. Project id:{}, tag name:{}".format(
                kwargs['project_id'], kwargs['name']))
            return {"error": {"code": -32005, "message": "Invalid value, tag is already exists."}}

        kwargs['possible_values'] = {}
        kwargs.update(self.get_creation_info())
        obj = bucket.new(data=kwargs)
        obj.add_index('tag_bin', kwargs['project_id'])
        obj.key = tag_key
        obj.store()
        zlogger.info("New push tag is created. Project id:{}, tag name:{}".format(
            kwargs['project_id'], kwargs['name']))
Пример #3
0
    def get_obj(self,
                project_id,
                bucket_name,
                obj_id,
                bucket_type=DEFAULT_BUCKET_TYPE):
        """
        Gets obj from riak.

        Args:
            - project_id(str): project id
            - bucket_name (str): bucket name
            - obj_id (str): riak object key 

        Returns:
            - obj (obj): riak obj

        """
        bucket = self.get_bucket(project_id, bucket_name, bucket_type)
        obj = bucket.get(obj_id)

        if not obj.exists:
            zlogger.error("Object not found. Bucket name:{}, id:{}".format(
                bucket.name, obj_id))
            raise KeyError("Object Not Found, bucket:{}, key:{}".format(
                bucket.name, obj_id))

        return obj
Пример #4
0
    def on_log_message(self, ch, method, properties, body):
        """
        Gets log messages from rabbit.

        Args:
            ch: Channel
            method: Method
            properties: Props
            body(dict): Body
                - params(dict): kwargs for methods
                - method(str): methods name

        Returns:
            None
        """

        try:
            body = json.loads(body)
            method_name = body.get('method', None)
            event_worker_method = getattr(self, method_name) if method_name else None
            if event_worker_method is not None:
                event_worker_method(**body['params'])
        except Exception as exc:
            zlogger.error("An error occurred on_log_message method inside EventProcessor."
                          "Exception: {}, ".format(exc))
Пример #5
0
    def get_queues(self, subscriber_id):
        """
        Get subscriber's queues from cache and checks change, if any change about subscriber's 
        queues, cache record is deleted and updated queue info is set to cache.

        Args:
            - subscriber_id (str): Subscriber id

        Returns:
            - active_queues (list): User's active queues list

        """
        is_change = False
        active_queues = []

        cache_key = 'QueueList:{}'.format(subscriber_id)
        queues = self.cache.smembers(cache_key)

        for queue in queues:
            try:
                self.rabbit_cl.get_queue('zopsm', queue.decode())
                active_queues.append(queue.decode())
            except HTTPError as exc:
                zlogger.error("An error occurred: {}".format(exc))
                is_change = True

        if is_change:
            self.cache.delete(cache_key)
            self.cache.sadd(cache_key, *active_queues)

        return active_queues
Пример #6
0
    def update_client(self, **kwargs):
        """
        Updates the client info with given values.
    
        Args:
            **kwargs (dict): project_id, client_id, target_id, validated_client:
                - project_id: project_id
                - client_id: id of client which is desired to be updated
                - target_id: id of user who wants to update the client information, possibly user
                 of the client
                - validated_client: dict of updated client information including clientId, token,
                 appVersion, deviceType, language, country, osVersion.
        Returns:
    
        """
        client = self.get_obj(kwargs['project_id'], 'client', kwargs['client_id'])

        if client.data['target_id'] != kwargs['target_id']:
            zlogger.error("Target id is not equal to wanted client's target. Project id:{}, Target "
                          "id:{}, client id:{}".format(kwargs['project_id'], kwargs['target_id'],
                                                       kwargs['client_id']))
            return {"error": {"code": -32004, "message": "Unauthorized Operation Error"}}

        client.data.update(kwargs['validated_client'])
        client.data['last_update_time'] = datetime.now().strftime(DATETIME_FORMAT)
        client.store()
        zlogger.info("Client data is updated. Project id:{}, "
                     "client id:{}".format(kwargs['project_id'], kwargs['client_id']))
Пример #7
0
    def get_push_client_tag(self, **kwargs):
        """
        Retrieves a single client tag with given id.
    
        Args:
            **kwargs (dict): project_id, client_id, key
                - project_id: project_id
                - client_id: client which is tagged with this tag
                - name: name of tag
    
        Returns:
            dict: client tag
        """
        client = self.get_obj(kwargs['project_id'], 'client', kwargs['client_id'])

        if kwargs['name'] not in client.data['push_tags']:
            zlogger.error("Tag is doesn't exist in client's tags. Project id:{}, client id:{}, "
                          "tag name:{}".format(kwargs['project_id'], kwargs['client_id'],
                                               kwargs['name']))
            return {"error": {"code": -32006,
                              "message": "Related tag couldn't be found in client's push tags."}}

        tag = self.get_obj(kwargs['project_id'], 'tag',
                           "{}_{}".format(kwargs['project_id'], kwargs['name']))
        tag_type, val = (tag.data['tag_type'], client.data['push_tags'][kwargs['name']])
        value = [] if tag_type == 'key' else [val] if tag_type == 'key-value' else list(val.keys())

        return {'key': kwargs['name'], 'value_read': value}
Пример #8
0
    def on_close(self):
        """
        To do when a ws connection close.

        """

        try:
            user_id = self.path_kwargs.get("request_user_id", None)
            if user_id:
                queue_manager.remove_event_listener(self, user_id)
        except Exception as exc:
            zlogger.error(
                "An error occurred on close method inside MyWebSocketHandler. "
                "Exc: {}".format(exc))
Пример #9
0
def find_redis_role(redis_nodes):
    roles = {'master': [], 'slave': []}
    for node in redis_nodes:
        try:
            cache = ZRedis(host=node)
            cache.execute('PING')
        except Exception as e:
            zlogger.error(str(e))
            # If failPassword should be provided because Redis Master expects that.
            cache = ZRedis(host=node,
                           password=redis_db_pw)

        execute_role = cache.execute('ROLE')
        role_of_node = execute_role[0].decode()
        roles[role_of_node].append(node)

    return roles.get('master')[0], random.choice(roles.get('slave' if roles['slave'] else 'master'))
Пример #10
0
    def remove_event_listener(self, listener, user_id):
        """
        Remove listener from listener list.
        
        """
        try:
            if self.event_listeners.get(user_id):
                self.event_listeners[user_id].remove(listener)
                if not self.event_listeners[user_id]:
                    self.channel.queue_delete(
                        queue=self.get_queue_name(user_id))
                    del self.event_listeners[user_id]

        except Exception as exc:
            zlogger.error(
                "An error occurred on remove_event_listener method inside QueueManager. "
                "User Id: {}, Exception: {}".format(user_id, exc))
Пример #11
0
    def open(self, request_user_id, token):
        """
        To do when a new ws connection.

        """
        try:
            user_info, token_ttl = self.get_user_info_and_token(token)

            self.check_validity(user_info, request_user_id, token_ttl)

            IOLoop.current().add_timeout(deadline=timedelta(seconds=token_ttl),
                                         callback=self.token_timeout)
            queue_manager.add_event_listener(self, user_info)
        except Exception as exc:
            zlogger.error(
                "An error occurred on open method inside MyWebSocketHandler. "
                "Exc: {}".format(exc))
            self.close()
Пример #12
0
    def check_validity(self, user_info, request_user_id, token_ttl):
        """
        Checks that token and user_id aren't invalid.

        """
        user_id = user_info.get("user")
        if not user_id or not token_ttl > 60:
            zlogger.error("Unathorized error for value:{}".format(user_id))
            raise web.HTTPError(status_code=401,
                                log_message='Unauthorized error')
            # self.close(code=401, reason="Unauthorized error.")

        elif user_id != request_user_id:
            zlogger.error(
                "Unauthorized error. user_id inside Request parameter({}) and "
                "token(User id: {}) does not match.".format(
                    request_user_id, user_id))
            raise web.HTTPError(status_code=401,
                                log_message='Unauthorized error')
Пример #13
0
    def get_user_info_and_token(self, token):
        """
        According to coming token, finds user info and token ttl  from cache.

        """
        token_key = cache.hmget(CACHE_TOKENS_KEYS, token)[0]
        if not token_key:
            zlogger.error("Unathorized error for token value:{}".format(
                token if token else "-"))
            raise web.HTTPError(status_code=401,
                                log_message='Unauthorized error')
        token_ttl = cache.ttl(token_key.decode())

        stored_value = cache.hgetall(token_key)
        user = {}
        if stored_value:
            for k, v in stored_value.items():
                user[k.decode()] = v.decode()

        return user, token_ttl
Пример #14
0
    def bindings_operation(self, operation, subscriber_id, route_key):
        """
        According to given operation(create binding or delete binding), new bindings are created or 
        existing bindings are removed.

        Args:
            - operation (str): 'create_binding' or 'delete_binding'
            - subscriber_id (str): riak subscriber object key 

        Returns:

        """
        queues = self.get_queues(subscriber_id)
        for queue in queues:
            try:
                getattr(self.rabbit_cl, operation)('zopsm', 'messages', queue,
                                                   route_key)
            except HTTPError as exc:
                zlogger.error(
                    "An error occur on bindings_operation method inside BaseWorkerJobs. "
                    "Exc: {}".format(exc))
Пример #15
0
 def delete_push_message(self, **kwargs):
     """
     Deletes a message with given id if its type is scheduled or automated.
 
     Args:
         **kwargs (dict): project_id, message_id, target_id
             - project_id:
             - message_id:
             - target_id:
     Returns:
 
     """
     message = self.get_obj(kwargs['project_id'], 'push_message', kwargs['message_id'])
     if message.data['target_id'] != kwargs['target_id']:
         zlogger.error("Message's sender is not equal to target. Project id:{}, target id:{}, "
                       "message id:{}".format(kwargs['project_id'], kwargs['target_id'],
                                              kwargs['message_id']))
         return {"error": {"code": -32004, "message": "Unauthorized Operation Error"}}
     message.delete()
     zlogger.info("Message is deleted. Project id:{}, message id:{}".format(
         kwargs['project_id'], kwargs['message_id']))
Пример #16
0
def send_push_message(service_type, tokens, val, project_id):
    """
    Sends push message to clients according to device service_type.

    Args:
        - tokens(list): client token list
        - val(dict): including title, body, service_type, language, icon, image, badge.

    """
    services = {'ios': ios, 'android': android}

    try:

        res = services[service_type](tokens, val, project_id)
        zlogger.info("Push %s succces. project id: %s, success: %s",
                     service_type, project_id, res.successes)
        zlogger.error(
            "Push %s result. project id: %s, failures: %s, errors: %s",
            service_type, project_id, res.failures, res.errors)

    except Exception as e:
        zlogger.error("Unified push error: %s", str(e))
Пример #17
0
    def get_targets_client_ids(self, project_id, target_ids):
        """
        Finds client ids of given target ids list. 

        Args:
            project_id (str): project id
            ids (list): target ids list

        Returns:
            list: client ids

        """
        client_ids = []
        for id in target_ids:
            try:
                target_obj = self.get_obj(project_id, 'target', id)
                client_ids.extend(target_obj.data['clients'].keys())
            except KeyError:
                zlogger.error(
                    "Invalid target id. Key error occured in get_targets_client_ids "
                    "method.Project id: {}, target_id: {}".format(
                        project_id, id))
        return client_ids
Пример #18
0
 def get_push_message(self, **kwargs):
     """
     Retrieves a single message with given message_id to target with given target_id.
 
     *User must be allowed to see the message. So, user must be the sender of the message.
 
     Args:
         **kwargs (dict): project_id, target_id, message_id
             - project_id:
             - target_id:
             - message_id:
 
     Returns:
         dict : message dict including id, creationTime, lastUpdateTime, isDeleted, isActive,
         sender, title, body, type, language, icon, image, badge, audience
     """
     message = self.get_obj(kwargs['project_id'], 'push_message', kwargs['message_id'])
     if message.data['target_id'] != kwargs['target_id']:
         zlogger.error("Message's sender is not equal to target. Project id:{}, target id:{}, "
                       "message id:{}".format(kwargs['project_id'], kwargs['target_id'],
                                              kwargs['message_id']))
         return {"error": {"code": -32004, "message": "Unauthorized Operation Error"}}
     return message.data
Пример #19
0
    def delete_client(self, **kwargs):
        """
        Deletes the client with given id.
    
        Args:
            **kwargs (dict): project_id, client_id, target_id:
                - project_id: project_id
                - client_id: id of client which is desired to be deleted
                - target_id: id of user who wants to delete the client, possibly user of the client
    
        Returns:
    
        """
        client = self.get_obj(kwargs['project_id'], 'client', kwargs['client_id'])

        if client.data['target_id'] != kwargs['target_id']:
            zlogger.error("Target id is not equal to wanted client's target. Project id:{}, Target "
                          "id:{}, client id:{}".format(kwargs['project_id'], kwargs['target_id'],
                                                       kwargs['client_id']))
            return {"error": {"code": -32004, "message": "Unauthorized Operation Error"}}

        target = self.get_obj(kwargs['project_id'], 'target', client.data['target_id'])

        if kwargs['client_id'] not in target.data['clients']:
            zlogger.error("Client id doesn't exist in target's clients. Project id:{},"
                          "target id:{}, client id:{}".format(kwargs['project_id'],
                                                              kwargs['target_id'],
                                                              kwargs['client_id']))
            return {"error": {"code": -32006, "message": "Client id doesn't exist in target"}}

        del target.data['clients'][kwargs['client_id']]

        target.data['last_update_time'] = datetime.now().strftime(DATETIME_FORMAT)
        target.store()
        client.delete()
        zlogger.info("Client is deleted. Project id:{}, client id:{}".format(kwargs['project_id'],
                                                                             kwargs['client_id']))
Пример #20
0
    def get_client(self, **kwargs):
        """
        Returns the client info as dict including clientId, token, appVersion, deviceType, language,
        country, osVersion, creationTime, lastUpdateTime, isDeleted, isActive.
    
        Args:
            **kwargs (dict): project_id, target_id, client_id:
                - project_id: project_id
                - target_id: id of user who wants to get the client information, possibly user 
                - client_id: id of the client whose information is desired
                of the client
    
        Returns:
            dict : client data
        """
        client = self.get_obj(kwargs['project_id'], 'client', kwargs['client_id'])

        if client.data['target_id'] != kwargs['target_id']:
            zlogger.error("Target id is not equal to wanted client's target. Project id:{}, Target "
                          "id:{}, client id:{}".format(kwargs['project_id'], kwargs['target_id'],
                                                       kwargs['client_id']))
            return {"error": {"code": -32004, "message": "Unauthorized Operation Error"}}

        return client.data
Пример #21
0
    def update_push_message(self, **kwargs):
        """
        Updates a message with given id.
    
        Args:
            **kwargs (dict): project_id, message_id, validated_message, target_id
                - project_id: project_id
                - message_id:
                - validated_message: dict of validated message including title, body, type,
                language, icon, image, badge.
                - target_id:
        Returns:
    
        """
        message = self.get_obj(kwargs['project_id'], 'push_message', kwargs['message_id'])
        if message.data['target_id'] != kwargs['target_id']:
            zlogger.error("Message's sender is not equal to target. Project id:{}, target id:{}, "
                          "message id:{}".format(kwargs['project_id'], kwargs['target_id'],
                                                 kwargs['message_id']))
            return {"error": {"code": -32004, "message": "Unauthorized Operation Error"}}
        #todo:if message type is 'ordinary' , message doesnot updated
        if message.data['audience']:
            if not kwargs['validated_message']['audience']:
                zlogger.error("Message audience field can not be null. Project id:{}, target id:{}, "
                              "message id:{}".format(kwargs['project_id'], kwargs['target_id'],
                                                     kwargs['message_id']))
                return {"error": {"code": -32006, "message": "Message audience field can not be null"}}
            else:
                kwargs['validated_message']['consumers'] = {}

        elif message.data['consumers']:
            if not kwargs['validated_message']['consumers']:
                zlogger.error("Message consumers field can not be null. Project id:{}, target id:{}, "
                              "message id:{}".format(kwargs['project_id'], kwargs['target_id'],
                                                     kwargs['message_id']))
                return {"error": {"code": -32006, "message": "Message consumers field can not be null"}}

        message.data.update(kwargs['validated_message'])
        message.data['last_update_time'] = datetime.now().strftime(DATETIME_FORMAT)
        message.store()
        zlogger.info("Message is updated. Project id:{}, message id:{}".format(
            kwargs['project_id'], kwargs['message_id']))
Пример #22
0
    def on_request(self, ch, method, props, body):
        """
        Publishes response by using do_job method
        Args:
            ch: Channel
            method: Method
            props: Properties
            body: Message Body

        Returns:
            None
        """

        err = None
        err_msg = ""
        result = {}
        id = None
        params = {}

        try:
            body = json.loads(body)
            try:
                rabbit_cl = sd_rabbit.get_suitable_client(
                    json.loads(sd_rabbit.rabbit_nodes))
                jobs_inst = self.jobs[body['params']['service']]
                jobs_inst.update_instances(sd_riak.riak_pb, rabbit_cl,
                                           sd_redis.redis_master)
                worker_method = getattr(jobs_inst, body['method'])

                try:
                    params = body['params']
                    result = worker_method(**params)
                    id = body['id']
                except TypeError as e:
                    err_msg = "Invalid params: {}".format(e)
                    err = {"code": -32602, "message": "Invalid Params"}
                except ConnectionRefusedError as e:
                    err_msg = "RiakNode Connection Refused Error: {}".format(e)
                    err = {
                        "error": {
                            "code": -32001,
                            "message": "Internal Error"
                        }
                    }
                except KeyError as e:
                    err_msg = "Object Not Found: {}".format(e)
                    err = {"code": -32002, "message": "Object Not Found"}
            except KeyError as e:
                err_msg = "Invalid Request: {}".format(e)
                err = {"code": -32600, "message": "Invalid Request"}
            except ImportError as e:
                err_msg = "Method not found: {}".format(e)
                err = {"code": -32601, "message": "Method Not Found"}
        except JSONDecodeError as e:
            err_msg = "Parse error: {}".format(e)
            err = {"code": -32700, "message": "Parse Error"}
        except Exception as e:
            err_msg = "Internal error: {}".format(e)
            err = {"code": -32603, "message": "Internal Error"}

        # Reserved for implementation - defined server - errors.
        # http://www.jsonrpc.org/specification#error_object
        # TODO: -32000 to -32099	Server error

        response = {"jsonrpc": "2.0", "id": id}

        if err or (result and 'error' in result):
            response['error'] = err or result['error']
            msg = "Blocking {blocking}, {method} with correlation id:{corr_id} of " \
                    "project:{project_id} and user:{usr_id}, resulted in an error:{err_msg}".format(
                        method=params.get('method'),
                        corr_id=params.get('id'),
                        project_id=params.get('project_id'),
                        err_msg=err_msg or response['error']['message'],
                        usr_id=params.get('subscriber_id') or params.get('target_id'),
                        blocking=not params.get('trackable')
            )
            zlogger.error(msg)
            if params and params['trackable']:
                zlogger.info("",
                             extra={
                                 "purpose": "event",
                                 "params": {
                                     "trackingId":
                                     params.get('id'),
                                     "data": {
                                         "title": response['error']['message'],
                                         "description": "Event has failed.",
                                         "code": 500,
                                     },
                                     "usr_id":
                                     params.get('subscriber_id')
                                     or params.get('target_id'),
                                 },
                                 "method": "fails_non_blocking_jobs",
                             })
        else:
            response['result'] = result

        ch.basic_publish(exchange='',
                         routing_key=props.reply_to,
                         properties=pika.BasicProperties(
                             correlation_id=props.correlation_id),
                         body=json.dumps(response))

        ch.basic_ack(delivery_tag=method.delivery_tag)