def set_elements(self, elements): """Set the elements dict from a serialized dict""" deserialized = OrderedDict() for k, v in elements.items(): if k != "typeid": k = deserialize_object(k, str_) deserialized[k] = deserialize_object(v, VArrayMeta) return self.set_endpoint_data("elements", deserialized)
def _regenerate_block(self, block, d): for field in list(block): if field not in ("health", "meta"): block.remove_endpoint(field) for field, value in d.items(): if field == "health": # Update health attribute value = deserialize_object(value) # type: NTScalar block.health.set_value(value=value.value, alarm=value.alarm, ts=value.timeStamp) elif field == "meta": value = deserialize_object(value) # type: BlockMeta meta = block.meta # type: BlockMeta for k in meta.call_types: meta.apply_change([k], value[k]) elif field != "typeid": # No need to set writeable_functions as the server will do it block.set_endpoint_data(field, value)
def on_message(self, message): """ Pass on received message to Process Args: message(str): Received message """ d = json_decode(message) request = deserialize_object(d, Request) request.context = self self.servercomms.on_request(request)
def update_part_configure_args(self, response): # Decorate validate and configure with the sum of its parts if isinstance(response, Delta): # Check if the changes contain more than just writeable change writeable_path = [ c[0] and c[0][-1] == "writeable" for c in response.changes ] if all(writeable_path): return else: # Return or Error is the end of our subscription, log and ignore self.log.debug("update_part_configure_args got response %r", response) return for change in response.changes: if change[0]: # Update self.configure_model.apply_change(*change) else: # Replace # TODO: should we make apply_change handle this? self.configure_model = deserialize_object(change[1]) # Extract the bits we need metas = OrderedDict() defaults = OrderedDict() required = [] for k, meta in self.configure_model.takes.elements.items(): if k not in self.ignore_configure_args: # Copy the meta so it belongs to the Controller we report to # TODO: should we pass the serialized version? metas[k] = deserialize_object(meta.to_dict()) if k in self.configure_model.defaults: defaults[k] = self.configure_model.defaults[k] if k in self.configure_model.takes.required: required.append(k) # Notify the controller that we have some new parameters to take self.registrar.report(ConfigureParamsInfo(metas, required, defaults))
def on_message(self, message): """ Pass on received message to Process Args: message(str): Received message """ logging.debug(message) d = json.loads(message, object_pairs_hook=OrderedDict) request = deserialize_object(d, Request) request.context = self self.servercomms.on_request(request)
def on_message(self, message): """ Pass response from server to process receive queue Args: message(str): Received message """ try: self.log_debug("Got message %s", message) d = json_decode(message) response = deserialize_object(d, Response) self.send_to_caller(response) except Exception as e: # If we don't catch the exception here, tornado will spew odd # error messages about 'HTTPRequest' object has no attribute 'path' self.log_exception("on_message(%r) failed", message)
def update_part_configure_args(self, response, without=()): # Decorate validate and configure with the sum of its parts if isinstance(response, Delta): # Check if the changes contain more than just writeable change writeable_path = [c[0] and c[0][-1] == "writeable" for c in response.changes] if not all(writeable_path): response.apply_changes_to(self.serialized_configure) configure_model = deserialize_object( self.serialized_configure, MethodModel) # Put data on the queue, so if spawns are handled out of # order we still get the most up to date data self.configure_args_update_queue.put((configure_model, without)) self.spawn(self._update_part_configure_args).wait() else: # Return or Error is the end of our subscription, log and ignore self.log.debug( "update_part_configure_args got response %r", response) return
def on_message(self, message): # called in tornado's thread if self._writeable is None: # Work out if the remote ip is within the netmask of any of our # interfaces. If not, Put and Post are forbidden ipv4_ip = self.request.remote_ip if ipv4_ip == "::1": # Special case IPV6 loopback ipv4_ip = "127.0.0.1" remoteaddr = struct.unpack("!I", socket.inet_aton(ipv4_ip))[0] self._writeable = max(v(remoteaddr) for v in self._validators) log.info("Puts and Posts are %s from %s", "allowed" if self._writeable else "forbidden", self.request.remote_ip) msg_id = -1 try: d = json_decode(message) try: msg_id = d['id'] except KeyError: raise FieldError('id field not present in JSON message') request = deserialize_object(d, Request) request.set_callback(self.on_response) if isinstance(request, Subscribe): assert msg_id not in self._id_to_mri, \ "Duplicate subscription ID %d" % msg_id self._id_to_mri[msg_id] = request.path[0] if isinstance(request, Unsubscribe): mri = self._id_to_mri[msg_id] else: mri = request.path[0] if isinstance(request, (Put, Post)) and not self._writeable: raise ValueError("Put/Post is forbidden from %s" % self.request.remote_ip) log.info("Request: %s", request) self._registrar.report(builtin.infos.RequestInfo(request, mri)) except Exception as e: log.exception("Error handling message:\n%s", message) error = Error(msg_id, e) error_message = error.to_dict() self.write_message(json_encode(error_message))
def _send_to_server(self): request = self._send_queue.get(timeout=0) try: request = deserialize_object(request, Request) response = None if isinstance(request, Get): response = self._execute_get(request) elif isinstance(request, Put): response = self._execute_put(request) elif isinstance(request, Post): response = self._execute_rpc(request) elif isinstance(request, Subscribe): self._execute_monitor(request) elif isinstance(request, Unsubscribe): response = self._execute_unsubscribe(request) else: raise UnexpectedError("Unexpected request %s", request) except Exception as e: _, response = request.error_response(e) if response: request.callback(response)
def on_message(self, message): """Pass response from server to process receive queue Args: message(str): Received message """ try: self.log.debug("Got message %s", message) d = json_decode(message) response = deserialize_object(d, Response) if isinstance(response, (Return, Error)): request, old_id = self._request_lookup.pop(response.id) if request.generate_key() in self._subscription_keys: self._subscription_keys.pop(request.generate_key()) else: request, old_id = self._request_lookup[response.id] response.set_id(old_id) # TODO: should we spawn here? request.callback(response) except Exception: # If we don't catch the exception here, tornado will spew odd # error messages about 'HTTPRequest' object has no attribute 'path' self.log.exception("on_message(%r) failed", message)
def update_field(response): if not isinstance(response, Delta): # Return or Error is the end of our subscription, log and ignore self.log.debug("Export got response %r", response) return if not ret: # First call, create the initial object ret["export"] = deserialize_object(response.changes[0][1]) context = Context(self.process) if isinstance(ret["export"], AttributeModel): def setter(v): context.put(path, v) else: def setter(*args): context.post(path, *args) ret["setter"] = setter else: # Subsequent calls, update it with self.changes_squashed: for cp, value in response.changes: ob = ret["export"] for p in cp[:-1]: ob = ob[p] getattr(ob, "set_%s" % cp[-1])(value)
def on_message(self, message): """Pass response from server to process receive queue Args: message(str): Received message """ # Called in tornado loop try: self.log.debug("Got message %s", message) d = json_decode(message) response = deserialize_object(d, Response) if isinstance(response, (Return, Error)): request = self._request_lookup.pop(response.id) if isinstance(response, Error): # Make the message an exception so it can be raised response.message = ResponseError(response.message) else: request = self._request_lookup[response.id] # Transfer the work of the callback to cothread cothread.Callback(request.callback, response) except Exception: # If we don't catch the exception here, tornado will spew odd # error messages about 'HTTPRequest' object has no attribute 'path' self.log.exception("on_message(%r) failed", message)
def on_message(self, message): # called in tornado's thread d = json_decode(message) request = deserialize_object(d, Request) request.set_callback(self.on_response) self._server_part.on_request(request)
def _update_remote_blocks(self, response): response = deserialize_object(response, Update) # TODO: should we spawn here? self.remote_blocks.set_value(response.value)
def set_choices(self, choices): """Set the choices list""" choices = StringArray(deserialize_object(c, str_) for c in choices) # TODO: what if the value is no longer in the list? return self.set_endpoint_data("choices", choices)
def _update_remote_blocks(self, response): response = deserialize_object(response, Update) cothread.Callback(self.remote_blocks.set_value, response.value)