def dispatch(self, method, params): """ Called by the servlet: calls the method of an exported service """ # Get the best matching name matching = None len_found = 0 for name in self.__endpoints: if len(name) > len_found and method.startswith(name + "."): # Better matching end point name (longer that previous one) matching = name len_found = len(matching) if matching is None: # No end point name match raise RemoteServiceError("No end point found for: {0}" .format(method)) # Extract the method name. (+1 for the trailing dot) method_name = method[len_found + 1:] # Get the service try: service = self.__endpoints[matching].instance except KeyError: raise RemoteServiceError("Unknown endpoint: {0}".format(matching)) # Get the method method_ref = getattr(service, method_name, None) if method_ref is None: raise RemoteServiceError("Unknown method {0}".format(method)) # Call it (let the errors be propagated) return method_ref(*params)
def __send_request(self, endpoint_uid, proxy, topic_prefix, request_parameters): """ Sends a request to the given topic :param endpoint_uid: Endpoint UID :param proxy: Callable proxy to notify on response :param topic_prefix: Prefix of MQTT topics to use :param request_parameters: Call parameters """ # Prepare the correlation ID correlation_id = str(uuid.uuid4()) try: # Prepare the data request = json.dumps({KEY_DATA: request_parameters, KEY_CORRELATION_ID: correlation_id, KEY_SENDER: self._framework_uid}) except ValueError as ex: raise RemoteServiceError("Cannot convert request to JSON: {0}" .format(ex)) # Keep the callable in the waiting list self.__waiting[correlation_id] = proxy self.__waiting_endpoints.setdefault(endpoint_uid, set()).add(proxy) # Subscribe to the reply self.__mqtt.subscribe(make_topic(topic_prefix, TOPIC_RESPONSE)) # Send the request self.__mqtt.publish(make_topic(topic_prefix, TOPIC_REQUEST), request, qos=2)
def __call__(self, *args, **kwargs): """ Method call """ # Send a request request = [self.__method_name] if args: request.extend(args) # Keyword arguments are ignores self.__publish(self.__uid, self, self.__topic, request) # Wait for an answer self._event.wait() # Act accordingly if self._error: raise RemoteServiceError(self._error) else: return self._result