def async_publish(self, request, callback=None):
        """ Publish asynchronous without block,
            user should check if request is success with callback extends ResponseCallback"""
        if self.__state != MqttConnection.State.CONNECTED:
            raise EnvisionException('async publish is not allowed at state: {}, method is: {}'
                                    .format(self.__state, request.get_method()))
        if callback is None:
            self.fast_publish(request)

        try:
            self.__fill_request(request)
            request.check()
            self.__subscribe_response_if_needed(request)

            token = self.__get_token_with_callback(request, callback)
            self.get_processor().register_response_token(token.get_response_id(), token)

            try:
                self.__do_fast_publish(request)
                if token is None:
                    raise EnvisionException('response token not set')
                self.__mqtt_processor.get_executor().submit(
                    token.wait_for_response(self.__profile.get_operation_timeout()))
            except Exception as e:
                if token is not None:
                    self.get_processor().deregister_response_token(token.get_response_id())
                    token.mark_failure(e)
                else:
                    callback.on_failure()

        except Exception as e:
            raise EnvisionException('[async] publish error: {}, topic is {}'
                                    .format(str(e), request.get_message_topic()))
    def publish(self, request):
        """ This method blocks until the response is received or action timeout is reached"""
        if self.__state != MqttConnection.State.CONNECTED:
            raise EnvisionException('publish is not allowed at state: {}, method is: {}'
                                    .format(self.__state, request.get_method()))
        try:
            self.__fill_request(request)
            request.check()
            self.__subscribe_response_if_needed(request)

            token = self.__get_token(request)
            self.get_processor().register_response_token(token.get_response_id(), token)

            try:
                self.__do_fast_publish(request)
                if token is None:
                    raise EnvisionException('response token not set')
                response = token.wait_for_response(self.__profile.get_operation_timeout())
            except Exception as e:
                MqttConnection.__logger.error('[sync] publish error: {}, topic is: {}'
                                              .format(str(e), request.get_message_topic()))
                if token is not None:
                    self.get_processor().deregister_response_token(token.get_response_id())
                    token.mark_failure(e)
                raise e

            self.__post_publish(request, response)

            return response
        except Exception as e:
            raise EnvisionException('[sync] publish error: {}, topic is {}'
                                    .format(str(e), request.get_message_topic()))
 def fast_publish(self, delivery):
     if self.__state != MqttConnection.State.CONNECTED:
         raise EnvisionException('fast publish is not allowed at state: {}, method is: {}'
                                 .format(self.__state, delivery.get_method()))
     try:
         self.__fill_request(delivery)
         delivery.check()
         self.__do_fast_publish(delivery)
         self.__post_publish(delivery)
     except Exception as e:
         raise EnvisionException('fast publish failed: {}'.format(str(e)))
예제 #4
0
 def sign(cls, app_secret, params, sign_method):
     if StringUtil.is_empty(sign_method):
         raise EnvisionException('sign method is empty')
     content = SignUtil.__make_string(app_secret, params)
     if sign_method == cls.SHA256:
         return cls.sha256_sign(content)
     if sign_method == cls.MD5:
         return cls.md5_sign(content)
     if sign_method == cls.SHA1:
         return cls.sha1_sign(content)
     else:
         raise EnvisionException('invalid sign method')
 def __do_fast_publish(self, delivery):
     """ Deliver request or reply to broker.
         This method blocks until request is sent out and mqtt ack is returned without response"""
     try:
         if self.__paho_client.is_connected():
             if delivery.get_qos() == 0 or delivery.get_qos() == 1:
                 self.__paho_client.publish(delivery.get_message_topic(), delivery.encode(), delivery.get_qos())
             elif delivery.get_qos() == 2:
                 raise EnvisionException('qos 2 not allowed')
             else:
                 raise EnvisionException('invalid qos!')
     except Exception as e:
         raise EnvisionException('publish message failed, message topic: {} \n error message: {}'
                                 .format(delivery.get_message_topic(), str(e)))
예제 #6
0
 def check_not_empty(value, field_name):
     if value is None:
         raise EnvisionException(
             "parameter check error: " + field_name + " is mandatory",
             CODE_ERROR_MISSING_ARGS.get_error_code())
     if isinstance(value, str) and StringUtil.is_empty(value):
         raise EnvisionException(
             "parameter check error: " + field_name + " is mandatory",
             CODE_ERROR_MISSING_ARGS.get_error_code())
     if isinstance(value, list) and not value:
         raise EnvisionException(
             "parameter check error: " + field_name + " is mandatory",
             CODE_ERROR_MISSING_ARGS.get_error_code())
     if isinstance(value, dict) and not value:
         raise EnvisionException(
             "parameter check error: " + field_name + " is mandatory",
             CODE_ERROR_MISSING_ARGS.get_error_code())
예제 #7
0
 def __parse_url(self):
     regions = self.__server_url.split(':')
     if len(regions) == 3:
         self.__protocol = regions[0]
         self.__host = regions[1].replace('//', '')
         self.__port = int(regions[2])
     else:
         raise EnvisionException('invalid uri!')
    def disconnect(self):
        with self.__client_lock:
            if self.__state == MqttConnection.State.DISCONNECTED:
                MqttConnection.__logger.warning('connection is already disconnected')
                return

            if self.__state != MqttConnection.State.CONNECTED:
                raise EnvisionException('client is not at connected state: ' + str(self.__state))

            self.__disconnect_underlying_client()

            self.__state = MqttConnection.State.DISCONNECTED
    def connect(self):
        with self.__client_lock:
            if self.__state != MqttConnection.State.NOT_CONNECTED:
                raise EnvisionException('connect is not allowed at illegal state: ' + str(self.__state))

        rc = self.__do_connect()
        if rc == 0:
            with self.__connection_condition:
                got_it = self.__connection_condition.wait(MqttConnection.__connect_timeout)
                if not got_it:
                    MqttConnection.__logger.error('Client id: [{}] connect timeout'
                                                  .format(self.__profile.get_client_id()))
예제 #10
0
    def __import_decoder(cls):
        try:
            for package in cls.packages.items():
                model = __import__(package[0], fromlist=['mode'])
                if hasattr(model, package[1]):
                    clazz = getattr(model, package[1])
                    if hasattr(clazz(), 'decode'):
                        func = getattr(clazz(), 'decode')
                        cls.decoder_list.append(func)

        except Exception as e:
            raise EnvisionException(e)
    def connect_async(self):
        with self.__client_lock:
            if self.__state != MqttConnection.State.NOT_CONNECTED:
                raise EnvisionException('connect is not allowed at illegal state: ' + str(self.__state))

            self.__state = MqttConnection.State.CONNECTING
            self.__initialize_underlying_client()
            self.__create_connection_options()

            self.__paho_client.connect_async(host=self.__profile.get_host(), port=self.__profile.get_port(),
                                             keepalive=self.__profile.get_keep_alive_interval())
            self.__paho_client.loop_start()
예제 #12
0
    def get_secure_mode(product_key, product_secret, device_key,
                        device_secret):
        if StringUtil.is_not_empty(device_secret):
            return SecureMode(VIA_DEVICE_SECRET, device_key, device_secret)

        if StringUtil.is_not_empty(product_secret):
            if INTEGRATION_DK == device_key:
                # integration use product key as client id
                return SecureMode(VIA_PRODUCT_SECRET_FOR_INTEGRATION,
                                  product_key, product_secret)
            return SecureMode(VIA_PRODUCT_SECRET, device_key, product_secret)

        raise EnvisionException(
            "<device_secret> or <product_secret> should be provided")
    def reconnect(self):
        with self.__client_lock:
            if self.__state != MqttConnection.State.CONNECTED and self.__state != MqttConnection.State.DISCONNECTED:
                raise EnvisionException('reconnect is not allowed at illegal state: ' + str(self.__state))

            self.__disconnect_underlying_client()
            self.__state = MqttConnection.State.DISCONNECTED

            self.__do_connect()
            with self.__connection_condition:
                got_it = self.__connection_condition.wait(MqttConnection.__connect_timeout)
                if not got_it:
                    MqttConnection.__logger.error('Client id: [{}] connect timeout'
                                                  .format(self.__profile.get_client_id()))
    def wait_for_response(self, timeout):
        timestamp = int(round(time.time() * 1000))
        with self.__condition:
            while self.__is_completed() is False:
                try:
                    self.__condition.wait(timeout)
                except Exception as e:
                    self.__exception = e

                if self.__is_completed(
                ) is False and timeout > 0 and timestamp + timeout * 1000 <= int(
                        round(time.time() * 1000)):
                    self.__exception = EnvisionException(
                        'synchronize request timeout')

        self.__invoke_callback()

        if self.__exception is not None:
            raise self.__exception

        return self.__response
예제 #15
0
    def decode(self, topic, payload):
        # format of match result: [(product_key, device_key),...]
        path_list = self.match(topic)
        if not path_list:
            return None
        try:
            path_list = path_list[0]
            arrived_msg = json.loads(payload)
            arrived_object = self.decode_to_object(arrived_msg)
        except Exception as e:
            raise EnvisionException(e)

        arrived_object.set_message_topic(topic)

        if len(path_list) > 0:
            arrived_object.set_product_key(path_list[0])

        if len(path_list) > 1:
            arrived_object.set_device_key(path_list[1])

        return DecodeResult(arrived_object, path_list)
    def __do_connect(self):
        try:
            self.__initialize_underlying_client()
            self.__create_connection_options()

            rc = self.__paho_client.connect(host=self.__profile.get_host(), port=self.__profile.get_port(),
                                            keepalive=self.__profile.get_keep_alive_interval())
            if rc == 0:
                self.__paho_client.loop_start()
            return rc
        except Exception as e:
            MqttConnection.__logger.error('connect failed,  url: {}, err : ' + self.__profile.get_server_url() + str(e))

            self.__state = MqttConnection.State.NOT_CONNECTED

            self.__disconnect_underlying_client()

            if self.__on_connect_failed is not None:
                self.__mqtt_processor.get_executor().submit(self.__on_connect_failed)

            raise EnvisionException('failed to connect: ' + self.__profile.get_server_url() + str(e))
예제 #17
0
 def check(self):
     if self.get_message_size() > MAX_MESSAGE_SIZE:
         raise EnvisionException('message too large, max length is: %s' %
                                 MAX_MESSAGE_SIZE)
     CheckUtil.check_not_empty(self.get_product_key(), 'product key')
     CheckUtil.check_not_empty(self.get_device_key(), 'device key')
 def create_params(self):
     raise EnvisionException('unsupported operation')
 def set_topic_args(self, args):
     if len(args) != 3:
         raise EnvisionException('topic args size not match!')
     self.set_product_key(args[0])
     self.set_device_key(args[1])
     self.set_service_identifier(args[2])
예제 #20
0
 def check_max_size(params, maxsize, field_name):
     if len(params) > maxsize:
         raise EnvisionException(
             CODE_ERROR_ARG_INVALID.getErrorCode(),
             "parameter check error: " + field_name +
             " is invalid, size cannot be large than " + maxsize)
 def get_answer_topic(request):
     if request.get_id() is None:
         raise EnvisionException('request message id not set')
     return request.get_answer_topic() + '_' + request.get_id()
 def timeout_schedule_task():
     self.get_processor().deregister_response_token(answer_topic)
     callback.on_failure(EnvisionException('call back task timeout'))
 def set_id(self, id):
     raise EnvisionException('cannot set raw request message id')
 def create_params(self):
     raise EnvisionException('exception is null')
예제 #25
0
 def set_message_topic(self, topic):
     raise EnvisionException("reply message type can't set topic")
 def mark_success(self, response):
     if response is None:
         raise EnvisionException('response is null')
     self.__response = response
     self.__do_notify()
 def mark_failure(self, exception):
     if exception is None:
         raise EnvisionException('exception is null')
     self.__exception = exception
     self.__do_notify()
예제 #28
0
 def set_qos(self, qos):
     if qos < 0 or qos >= 2:
         raise EnvisionException('qos only support 0,1 in current version')
     self.__qos = qos