mns/mns_tool.py (304 lines of code) (raw):

#coding=utf-8 # Copyright (C) 2015, Alibaba Cloud Computing #Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: #The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import os import sys import string import types import logging import logging.handlers from .mns_exception import * METHODS = ["PUT", "POST", "GET", "DELETE"] PERMISSION_ACTIONS = ["setqueueattributes", "getqueueattributes", "sendmessage", "receivemessage", "deletemessage", "peekmessage", "changevisibility"] class MNSLogger: @staticmethod def get_logger(log_name=None, log_file=None, log_level=logging.INFO): if log_name is None: log_name = "mns_python_sdk" if log_file is None: log_file = os.path.join(os.path.split(os.path.realpath(__file__))[0], "mns_python_sdk.log") logger = logging.getLogger(log_name) if logger.handlers == []: fileHandler = logging.handlers.RotatingFileHandler(log_file, maxBytes=10*1024*1024) formatter = logging.Formatter('[%(asctime)s] [%(name)s] [%(levelname)s] [%(filename)s:%(lineno)d] [%(thread)d] %(message)s', '%Y-%m-%d %H:%M:%S') fileHandler.setFormatter(formatter) logger.addHandler(fileHandler) MNSLogger.validate_loglevel(log_level) logger.setLevel(log_level) return logger @staticmethod def validate_loglevel(log_level): log_levels = [logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL] if log_level not in log_levels: raise MNSClientParameterException("LogLevelInvalid", "Bad value: '%s', expect levels: '%s'." % \ (log_level, ','.join([str(item) for item in log_levels]))) class ValidatorBase: @staticmethod def validate(req): pass @staticmethod def type_validate(item, valid_type, param_name=None, req_id=None): if not (type(item) is valid_type): if param_name is None: raise MNSClientParameterException("TypeInvalid", "Bad type: '%s', '%s' expect type '%s'." % (type(item), item, valid_type), req_id) else: raise MNSClientParameterException("TypeInvalid", "Param '%s' in bad type: '%s', '%s' expect type '%s'." % (param_name, type(item), item, valid_type), req_id) @staticmethod def is_str(item, param_name=None, req_id=None): #if not isinstance(item, unicode): # if param_name is None: # raise MNSClientParameterException("TypeInvalid", "Bad type: '%s', '%s' expect basestring." % (type(item), item), req_id) # else: # raise MNSClientParameterException("TypeInvalid", "Param '%s' in bad type: '%s', '%s' expect basestring." % (param_name, type(item), item), req_id) return @staticmethod def marker_validate(req): ValidatorBase.is_str(req.marker, req_id=req.request_id) @staticmethod def retnumber_validate(req): #ValidatorBase.type_validate(req.ret_number, types.IntType, req_id=req.request_id) ValidatorBase.type_validate(req.ret_number, int, req_id=req.request_id) if (req.ret_number != -1 and req.ret_number <= 0 ): raise MNSClientParameterException("HeaderInvalid", "Bad value: '%s', x-mns-number should larger than 0." % req.ret_number, req.request_id) @staticmethod def name_validate(name, nameType, req_id=None): #type ValidatorBase.is_str(name, req_id=req_id) #length if len(name) < 1: raise MNSClientParameterException("QueueNameInvalid", "Bad value: '%s', the length of %s should larger than 1." % (name, nameType), req_id) @staticmethod def list_condition_validate(req): if req.prefix != "": ValidatorBase.name_validate(req.prefix, "prefix") ValidatorBase.marker_validate(req) ValidatorBase.retnumber_validate(req) class SetAccountAttributesValidator(ValidatorBase): @staticmethod def validate(req): #type if req.logging_bucket is not None: ValidatorBase.is_str(req.logging_bucket, req_id=req.request_id) class QueueValidator(ValidatorBase): @staticmethod def queue_validate(req): ValidatorBase.type_validate(req.visibility_timeout, int, req_id=req.request_id) ValidatorBase.type_validate(req.message_retention_period, int, req_id=req.request_id) ValidatorBase.type_validate(req.delay_seconds, int, req_id=req.request_id) ValidatorBase.type_validate(req.polling_wait_seconds, int, req_id=req.request_id) # value if req.visibility_timeout != -1 and req.visibility_timeout <= 0: raise MNSClientParameterException("QueueAttrInvalid", "Bad value: '%d', visibility timeout should larger than 0." % req.visibility_timeout, req.request_id) if req.maximum_message_size != -1 and req.maximum_message_size <= 0: raise MNSClientParameterException("QueueAttrInvalid", "Bad value: '%d', maximum message size should larger than 0." % req.maximum_message_size, req.request_id) if req.message_retention_period != -1 and req.message_retention_period <= 0: raise MNSClientParameterException("QueueAttrInvalid", "Bad value: '%d', message retention period should larger than 0." % req.message_retention_period, req.request_id) if req.delay_seconds != -1 and req.delay_seconds < 0: raise MNSClientParameterException("QueueAttrInvalid", "Bad value: '%d', delay seconds should larger than 0." % req.delay_seconds, req.request_id) if req.polling_wait_seconds != -1 and req.polling_wait_seconds < 0: raise MNSClientParameterException("QueueAttrInvalid", "Bad value: '%d', polling wait seconds should larger than 0." % req.polling_wait_seconds, req.request_id) if req.logging_enabled is not None and str(req.logging_enabled).lower() not in ("true", "false"): raise MNSClientParameterException("QueueAttrInvalid", "Bad value: '%s', logging enabled should be True/False." % req.logging_enabled, req.request_id) class MessageValidator(ValidatorBase): @staticmethod def sendmessage_attr_validate(req, req_id): #type ValidatorBase.is_str(req.message_body, None, req_id) ValidatorBase.type_validate(req.delay_seconds, int, None, req_id) ValidatorBase.type_validate(req.priority, int, None, req_id) #value if req.message_body == "": raise MNSClientParameterException("MessageBodyInvalid", "Bad value: '', message body should not be ''.", req_id) if req.delay_seconds != -1 and req.delay_seconds < 0: raise MNSClientParameterException("DelaySecondsInvalid", "Bad value: '%d', delay_seconds should larger than 0." % req.delay_seconds, req_id) if req.priority != -1 and req.priority < 0: raise MNSClientParameterException("PriorityInvalid", "Bad value: '%d', priority should larger than 0." % req.priority, req_id) @staticmethod def receiphandle_validate(receipt_handle, req_id): if (receipt_handle == ""): raise MNSClientParameterException("ReceiptHandleInvalid", "The receipt handle should not be null.", req_id) @staticmethod def waitseconds_validate(wait_seconds, req_id): if wait_seconds != -1 and wait_seconds < 0: raise MNSClientParameterException("WaitSecondsInvalid", "Bad value: '%d', wait_seconds should larger than 0." % wait_seconds, req_id) @staticmethod def batchsize_validate(batch_size, req_id): if batch_size != -1 and batch_size < 0: raise MNSClientParameterException("BatchSizeInvalid", "Bad value: '%d', batch_size should larger than 0." % batch_size, req_id) @staticmethod def publishmessage_attr_validate(req): #type ValidatorBase.is_str(req.message_body, "message_body", req_id=req.request_id) ValidatorBase.is_str(req.message_tag, "message_tag", req_id=req.request_id) if req.direct_mail is not None: ValidatorBase.is_str(req.direct_mail.account_name, "account_name of direct mail", req_id=req.request_id) ValidatorBase.is_str(req.direct_mail.subject, "subject of direct mail", req_id=req.request_id) #value if req.message_body == "": raise MNSClientParameterException("MessageBodyInvalid", "Bad value: '', message body should not be ''.", req.request_id) if len(req.message_tag) > 16: raise MNSClientParameterException("MessageTagInvalid", "The length of message tag should be between 1 and 16.", req.request_id) class CreateQueueValidator(QueueValidator): @staticmethod def validate(req): QueueValidator.validate(req) ValidatorBase.name_validate(req.queue_name, "queue_name", req.request_id) QueueValidator.queue_validate(req) class DeleteQueueValidator(QueueValidator): @staticmethod def validate(req): QueueValidator.validate(req) ValidatorBase.name_validate(req.queue_name, "queue_name", req.request_id) class ListQueueValidator(QueueValidator): @staticmethod def validate(req): QueueValidator.validate(req) QueueValidator.list_condition_validate(req) class SetQueueAttrValidator(QueueValidator): @staticmethod def validate(req): QueueValidator.validate(req) ValidatorBase.name_validate(req.queue_name, "queue_name", req.request_id) QueueValidator.queue_validate(req) class GetQueueAttrValidator(QueueValidator): @staticmethod def validate(req): QueueValidator.validate(req) ValidatorBase.name_validate(req.queue_name, "queue_name", req.request_id) class SendMessageValidator(MessageValidator): @staticmethod def validate(req): MessageValidator.validate(req) ValidatorBase.name_validate(req.queue_name, "queue_name", req.request_id) MessageValidator.sendmessage_attr_validate(req, req.request_id) class BatchSendMessageValidator(MessageValidator): @staticmethod def validate(req): MessageValidator.validate(req) ValidatorBase.name_validate(req.queue_name, "queue_name", req.request_id) for entry in req.message_list: MessageValidator.sendmessage_attr_validate(entry, req.request_id) class ReceiveMessageValidator(MessageValidator): @staticmethod def validate(req): MessageValidator.validate(req) ValidatorBase.name_validate(req.queue_name, "queue_name", req.request_id) MessageValidator.waitseconds_validate(req.wait_seconds, req.request_id) class BatchReceiveMessageValidator(MessageValidator): @staticmethod def validate(req): MessageValidator.validate(req) ValidatorBase.name_validate(req.queue_name, "queue_name", req.request_id) MessageValidator.batchsize_validate(req.batch_size, req.request_id) MessageValidator.waitseconds_validate(req.wait_seconds, req.request_id) class DeleteMessageValidator(MessageValidator): @staticmethod def validate(req): MessageValidator.validate(req) ValidatorBase.name_validate(req.queue_name, "queue_name", req.request_id) MessageValidator.receiphandle_validate(req.receipt_handle, req.request_id) class BatchDeleteMessageValidator(MessageValidator): @staticmethod def validate(req): MessageValidator.validate(req) ValidatorBase.name_validate(req.queue_name, "queue_name", req.request_id) for receipt_handle in req.receipt_handle_list: MessageValidator.receiphandle_validate(receipt_handle, req.request_id) class PeekMessageValidator(MessageValidator): @staticmethod def validate(req): MessageValidator.validate(req) ValidatorBase.name_validate(req.queue_name, "queue_name", req.request_id) class BatchPeekMessageValidator(MessageValidator): @staticmethod def validate(req): MessageValidator.validate(req) ValidatorBase.name_validate(req.queue_name, "queue_name", req.request_id) MessageValidator.batchsize_validate(req.batch_size, req.request_id) class ChangeMsgVisValidator(MessageValidator): @staticmethod def validate(req): MessageValidator.validate(req) ValidatorBase.name_validate(req.queue_name, "queue_name", req.request_id) MessageValidator.receiphandle_validate(req.receipt_handle, req.request_id) if (req.visibility_timeout < 0 or req.visibility_timeout > 43200 ): raise MNSClientParameterException("VisibilityTimeoutInvalid", "Bad value: '%d', visibility timeout should between 0 and 43200." % req.visibility_timeout, req.request_id) class TopicValidator(ValidatorBase): @staticmethod def topic_validate(req): #type ValidatorBase.type_validate(req.maximum_message_size, int, "maximum_message_size", req_id=req.request_id) #value if req.maximum_message_size != -1 and req.maximum_message_size <= 0: raise MNSClientParameterException("TopicAttrInvalid", "Bad value: '%s', maximum message size should larger than 0." % req.maximum_message_size, req.request_id) if req.logging_enabled != None and str(req.logging_enabled).lower() not in ("true", "false"): raise MNSClientParameterException("TopicAttrInvalid", "Bad value: '%s', logging enabled should be True/False." % req.logging_enabled, req.request_id) class CreateTopicValidator(TopicValidator): @staticmethod def validate(req): TopicValidator.validate(req) ValidatorBase.name_validate(req.topic_name, "topic_name", req.request_id) TopicValidator.topic_validate(req) class DeleteTopicValidator(TopicValidator): @staticmethod def validate(req): TopicValidator.validate(req) ValidatorBase.name_validate(req.topic_name, "topic_name", req.request_id) class ListTopicValidator(TopicValidator): @staticmethod def validate(req): TopicValidator.validate(req) TopicValidator.list_condition_validate(req) class SetTopicAttrValidator(TopicValidator): @staticmethod def validate(req): TopicValidator.validate(req) ValidatorBase.name_validate(req.topic_name, "topic_name", req.request_id) TopicValidator.topic_validate(req) class GetTopicAttrValidator(TopicValidator): @staticmethod def validate(req): TopicValidator.validate(req) ValidatorBase.name_validate(req.topic_name, "topic_name", req.request_id) class PublishMessageValidator(MessageValidator): @staticmethod def validate(req): MessageValidator.validate(req) ValidatorBase.name_validate(req.topic_name, "topic_name", req.request_id) MessageValidator.publishmessage_attr_validate(req) class SubscriptionValidator(TopicValidator): @staticmethod def subscription_validate(req): TopicValidator.is_str(req.endpoint, "endpoint", req_id=req.request_id) TopicValidator.is_str(req.notify_strategy, "notify_strategy", req_id=req.request_id) TopicValidator.is_str(req.filter_tag, "filter_tag", req_id=req.request_id) TopicValidator.is_str(req.notify_content_format, "notify_content_format", req_id=req.request_id) @staticmethod def filter_tag_validate(filter_tag, req_id): if len(filter_tag) > 16: raise MNSClientParameterException("FilterTagInvalid", "Bad value: '%s', The length of filter tag should be between 1 and 16." % (filter_tag)) class SubscribeValidator(SubscriptionValidator): @staticmethod def validate(req): SubscriptionValidator.validate(req) ValidatorBase.name_validate(req.topic_name, "topic_name", req.request_id) ValidatorBase.name_validate(req.subscription_name, "subscription_name", req.request_id) SubscriptionValidator.subscription_validate(req) SubscriptionValidator.filter_tag_validate(req.filter_tag, req.request_id) class UnsubscribeValidator(SubscriptionValidator): @staticmethod def validate(req): SubscriptionValidator.validate(req) ValidatorBase.name_validate(req.topic_name, "topic_name", req.request_id) ValidatorBase.name_validate(req.subscription_name, "subscription_name", req.request_id) class ListSubscriptionByTopicValidator(SubscriptionValidator): @staticmethod def validate(req): SubscriptionValidator.validate(req) SubscriptionValidator.list_condition_validate(req) class SetSubscriptionAttrValidator(SubscriptionValidator): @staticmethod def validate(req): SubscriptionValidator.validate(req) ValidatorBase.name_validate(req.topic_name, "topic_name", req.request_id) ValidatorBase.name_validate(req.subscription_name, "subscription_name", req.request_id) SubscriptionValidator.subscription_validate(req) class GetSubscriptionAttrValidator(SubscriptionValidator): @staticmethod def validate(req): SubscriptionValidator.validate(req) ValidatorBase.name_validate(req.topic_name, "topic_name", req.request_id) ValidatorBase.name_validate(req.subscription_name, "subscription_name", req.request_id)