class ObjectPropetyTest(unittest.TestCase): def setUp(self): self.target = ObjectProperty("object_type", "object_id") def test_constructor(self): self.assertEqual( self.target._object_property[ObjectProperty.OBJECT_TYPE], "object_type") self.assertEqual( self.target._object_property[ObjectProperty.OBJECT_ID], "object_id") def test_object_type(self): self.assertEqual(self.target.object_type, "object_type") def test_object_id(self): self.assertEqual(self.target.object_id, "object_id") def test_get_state(self): self.target._object_property[ObjectProperty.OBJECT_STATE] =\ "object_state" self.assertEqual(self.target.get_state(), "object_state") self.target._object_property[ObjectProperty.OBJECT_STATE] =\ "OBJECT_STATE" self.assertEqual(self.target.get_state(), "OBJECT_STATE") def test_set_state(self): self.target._object_property[ObjectProperty.OBJECT_STATE] =\ "no such state" self.target.set_state("object_state") self.assertEqual( self.target._object_property[ObjectProperty.OBJECT_STATE], "object_state") def test_set_property_with_object_type(self): oldValue = self.target.set_property( ObjectProperty.OBJECT_TYPE, "new value") self.assertEqual(oldValue, None) self.assertEqual( self.target._object_property[ObjectProperty.OBJECT_TYPE], "object_type") def test_set_property_with_object_id(self): oldValue = self.target.set_property(ObjectProperty.OBJECT_ID, "new value") self.assertEqual(oldValue, None) self.assertEqual( self.target._object_property[ObjectProperty.OBJECT_ID], "object_id") def test_set_property_with_new_key(self): oldValue = self.target.set_property("new key", "new value") self.assertEqual(oldValue, None) self.assertEqual(self.target._object_property["new key"], "new value") def test_set_property(self): self.target._object_property["key"] = "old value" oldValue = self.target.set_property("key", "new value") self.assertEqual(oldValue, "old value") self.assertEqual(self.target._object_property["key"], "new value") def test_get_property_with_existing_key(self): self.target._object_property["key"] = "value" self.assertEqual(self.target.get_property("key"), "value") def test_get_property_with_new_key(self): self.assertEqual(self.target.get_property("key"), None) def test_delete_property(self): self.target._object_property["key"] = "value" self.target.delete_property("key") self.assertEqual(self.target.get_property("key"), None) def test_delete_property_with_read_only_key(self): self.target._object_property["super_type"] = "super_type" self.target._object_property["description"] = "description" self.target.delete_property("type") self.target.delete_property("id") self.target.delete_property("super_type") self.target.delete_property("description") self.assertEqual(self.target.get_property("type"), "object_type") self.assertEqual(self.target.get_property("id"), "object_id") self.assertEqual(self.target.get_property("super_type"), "super_type") self.assertEqual(self.target.get_property("description"), "description") def test_put_property(self): prop = {ObjectProperty.OBJECT_TYPE: "new_object_type", ObjectProperty.OBJECT_ID: "new_object_id"} prop["key1"] = "new_val" prop["key3"] = "val3" self.target._object_property["key1"] = "val1" self.target._object_property["key2"] = "val2" self.target.put_property(prop) self.assertEqual(self.target.get_property("type"), "object_type") self.assertEqual(self.target.get_property("id"), "object_id") self.assertEqual(self.target.get_property("key1"), "new_val") self.assertEqual(self.target.get_property("key2"), None) self.assertEqual(self.target.get_property("key3"), "val3") def test_equals(self): prop = {ObjectProperty.OBJECT_TYPE: "object_type", ObjectProperty.OBJECT_ID: "object_id"} self.assertTrue(self.target.equals(prop)) def test_equals_with_different_property(self): prop = ObjectProperty("different_object_type", "object_id") self.assertFalse(self.target.equals(prop)) def test_is_read_only_key(self): self.target._object_property["key"] = "value" self.assertFalse(self.target._ObjectProperty__is_read_only_key("key")) def test_is_read_only_key_with_read_only_key(self): self.target._object_property["super_type"] = "super_type" self.target._object_property["description"] = "description" self.assertTrue( self.target._ObjectProperty__is_read_only_key("type")) self.assertTrue( self.target._ObjectProperty__is_read_only_key("id")) self.assertTrue( self.target._ObjectProperty__is_read_only_key("super_type")) self.assertTrue( self.target._ObjectProperty__is_read_only_key("description")) def test_packed_object(self): self.assertEqual(self.target.packed_object(), {ObjectProperty.OBJECT_TYPE: 'object_type', ObjectProperty.OBJECT_ID: 'object_id'})
class RemoteObject(object): DESCRIPTION = "" CONNECTION_TYPES = "" def __init__(self, arg1, arg2, arg3=None): if arg3 is None: object_id = arg1 dispatcher = arg2 else: object_id = arg1 baseUrl = arg2 dispatcher = arg3 self._object_property = ObjectProperty(self.__class__.__name__, object_id) self._object_property.set_state(ObjectProperty.State.INITIALIZING) self.__set_description() self.__set_connection_types() self._object_settings = {} self.dispatcher = dispatcher if self.dispatcher is None: return self.dispatcher.add_local_object(self) self._event_subscription = EventSubscription(object_id) self.__parser = RequestParser() self.__add_rules() def on_initialize(self, obj_prop): return True def on_finalize(self): logging.debug("on_finalize ObjectID:" + self.object_id) self.dispatcher.remove_local_object(self) @property def object_id(self): return self._object_property.object_id @property def object_property(self): return self._object_property @property def object_settings(self): return self._object_settings @property def state(self): return self._object_property.state def set_state(self, state): prop = self.object_property prop.set_state(state) return self._do_put_property(prop.packed_object()) def __set_description(self): self._object_property.set_property(ObjectProperty.DESCRIPTION, self.DESCRIPTION) def __set_connection_types(self): self._object_property.set_property(ObjectProperty.CONNECTION_TYPES, self.CONNECTION_TYPES) def _request_sync(self, object_id, method, path, body=None): return self.dispatcher.request_sync(Request(object_id, method, path, body)) def _request(self, object_id, method, path, body=None): resp = Response(Response.StatusCode.INTERNAL_SERVER_ERROR, None) try: resp = self._request_sync(object_id, method, path, body) except: logging.error("Exception: Request to " + object_id + " Method:" + method + " Path:" + path) logging.error(traceback.format_exc()) return resp def _publish_event_async(self, event_type, body): return self.dispatcher.publish_event_async(Event(self.object_id, event_type, body)) def _apply_event_subscription(self): return self.dispatcher.subscribe_event(self._event_subscription) def __add_rules(self): rules = [] rules.append({RequestParser.PATTERN: r"^property/?$", RequestParser.METHOD: Request.Method.GET, RequestParser.FUNC: self._do_get_property, RequestParser.PARAMS: 0}) rules.append({RequestParser.PATTERN: r"^property/?$", RequestParser.METHOD: Request.Method.PUT, RequestParser.FUNC: self._do_put_property, RequestParser.PARAMS: 1}) rules.append({RequestParser.PATTERN: r"^settings/?$", RequestParser.METHOD: Request.Method.GET, RequestParser.FUNC: self._do_get_settings, RequestParser.PARAMS: 0}) rules.append({RequestParser.PATTERN: r"^settings/?$", RequestParser.METHOD: Request.Method.PUT, RequestParser.FUNC: self._do_put_settings, RequestParser.PARAMS: 1}) self.__parser.add_rule(rules) def dispatch_request(self, request): try: resp = self.__parser.action(request) if resp.status_code == Response.StatusCode.NOT_FOUND: resp = self._on_request(request) except: logging.error("Exception: Receive Request" + " Method:" + request.method + " Path:" + request.path) logging.error(traceback.format_exc()) resp = Response(Response.StatusCode.INTERNAL_SERVER_ERROR, None) return resp def dispatch_event(self, event): self._do_post_event(event) def _do_get_property(self): logging.debug("Receive GET Property ObjectID:" + self.object_id) return Response(Response.StatusCode.OK, self._object_property) def _do_put_property(self, body): logging.debug("Receive PUT Property ObjectID:" + self.object_id) # check State Change to Finalizing for k, v in body.items(): if k == ObjectProperty.OBJECT_STATE: oldValue = self._object_property.get_property(k) self.on_state_changed(oldValue, v) # update Property if not(self._object_property.equals(body)): self._object_property.put_property(body) return Response(Response.StatusCode.OK, self._object_property) def _do_get_settings(self): logging.debug("Receive GET Settings ObjectID:" + self.object_id) return Response(Response.StatusCode.OK, self._object_settings) def _do_put_settings(self, body): logging.debug("Receive PUT Settings ObjectID:" + self.object_id) if body != self._object_settings: old = copy.deepcopy(self._object_settings) # delete for k in old.keys(): if k not in body: del self._object_settings[k] # add or update for k, v in body.items(): self._object_settings[k] = v self.on_settings_changed(ObjectSettingChanged.Action.UPDATE, old, self._object_settings) return Response(Response.StatusCode.OK, self._object_settings) def _do_post_event(self, event): self.on_event(event) def on_state_changed(self, old_state, new_state): if old_state != ObjectProperty.State.FINALIZING: if new_state == ObjectProperty.State.FINALIZING: self.on_finalize() def on_settings_changed(self, action, prev, curr): event_body = {ObjectSettingChanged.ACTION: action, ObjectSettingChanged.PREV: prev, ObjectSettingChanged.CURR: curr} self._publish_event_async(ObjectSettingChanged.TYPE, event_body) def _on_request(self, request): return Response(Response.StatusCode.BAD_REQUEST, None) def on_event(self, event): # for example: method_name = "_do_event_topologychanged" method_name = "_do_event_" + event.event_type.lower() if hasattr(self, method_name): method = getattr(self, method_name) if callable(method): method(event) return return
class ObjectPropetyTest(unittest.TestCase): def setUp(self): self.target = ObjectProperty("object_type", "object_id") def test_constructor(self): self.assertEqual( self.target._object_property[ObjectProperty.OBJECT_TYPE], "object_type") self.assertEqual( self.target._object_property[ObjectProperty.OBJECT_ID], "object_id") def test_object_type(self): self.assertEqual(self.target.object_type, "object_type") def test_object_id(self): self.assertEqual(self.target.object_id, "object_id") def test_get_state(self): self.target._object_property[ObjectProperty.OBJECT_STATE] =\ "object_state" self.assertEqual(self.target.get_state(), "object_state") self.target._object_property[ObjectProperty.OBJECT_STATE] =\ "OBJECT_STATE" self.assertEqual(self.target.get_state(), "OBJECT_STATE") def test_set_state(self): self.target._object_property[ObjectProperty.OBJECT_STATE] =\ "no such state" self.target.set_state("object_state") self.assertEqual( self.target._object_property[ObjectProperty.OBJECT_STATE], "object_state") def test_set_property_with_object_type(self): oldValue = self.target.set_property(ObjectProperty.OBJECT_TYPE, "new value") self.assertEqual(oldValue, None) self.assertEqual( self.target._object_property[ObjectProperty.OBJECT_TYPE], "object_type") def test_set_property_with_object_id(self): oldValue = self.target.set_property(ObjectProperty.OBJECT_ID, "new value") self.assertEqual(oldValue, None) self.assertEqual( self.target._object_property[ObjectProperty.OBJECT_ID], "object_id") def test_set_property_with_new_key(self): oldValue = self.target.set_property("new key", "new value") self.assertEqual(oldValue, None) self.assertEqual(self.target._object_property["new key"], "new value") def test_set_property(self): self.target._object_property["key"] = "old value" oldValue = self.target.set_property("key", "new value") self.assertEqual(oldValue, "old value") self.assertEqual(self.target._object_property["key"], "new value") def test_get_property_with_existing_key(self): self.target._object_property["key"] = "value" self.assertEqual(self.target.get_property("key"), "value") def test_get_property_with_new_key(self): self.assertEqual(self.target.get_property("key"), None) def test_delete_property(self): self.target._object_property["key"] = "value" self.target.delete_property("key") self.assertEqual(self.target.get_property("key"), None) def test_delete_property_with_read_only_key(self): self.target._object_property["super_type"] = "super_type" self.target._object_property["description"] = "description" self.target.delete_property("type") self.target.delete_property("id") self.target.delete_property("super_type") self.target.delete_property("description") self.assertEqual(self.target.get_property("type"), "object_type") self.assertEqual(self.target.get_property("id"), "object_id") self.assertEqual(self.target.get_property("super_type"), "super_type") self.assertEqual(self.target.get_property("description"), "description") def test_put_property(self): prop = { ObjectProperty.OBJECT_TYPE: "new_object_type", ObjectProperty.OBJECT_ID: "new_object_id" } prop["key1"] = "new_val" prop["key3"] = "val3" self.target._object_property["key1"] = "val1" self.target._object_property["key2"] = "val2" self.target.put_property(prop) self.assertEqual(self.target.get_property("type"), "object_type") self.assertEqual(self.target.get_property("id"), "object_id") self.assertEqual(self.target.get_property("key1"), "new_val") self.assertEqual(self.target.get_property("key2"), None) self.assertEqual(self.target.get_property("key3"), "val3") def test_equals(self): prop = { ObjectProperty.OBJECT_TYPE: "object_type", ObjectProperty.OBJECT_ID: "object_id" } self.assertTrue(self.target.equals(prop)) def test_equals_with_different_property(self): prop = ObjectProperty("different_object_type", "object_id") self.assertFalse(self.target.equals(prop)) def test_is_read_only_key(self): self.target._object_property["key"] = "value" self.assertFalse(self.target._ObjectProperty__is_read_only_key("key")) def test_is_read_only_key_with_read_only_key(self): self.target._object_property["super_type"] = "super_type" self.target._object_property["description"] = "description" self.assertTrue(self.target._ObjectProperty__is_read_only_key("type")) self.assertTrue(self.target._ObjectProperty__is_read_only_key("id")) self.assertTrue( self.target._ObjectProperty__is_read_only_key("super_type")) self.assertTrue( self.target._ObjectProperty__is_read_only_key("description")) def test_packed_object(self): self.assertEqual( self.target.packed_object(), { ObjectProperty.OBJECT_TYPE: 'object_type', ObjectProperty.OBJECT_ID: 'object_id' })
class RemoteObject(object): DESCRIPTION = "" CONNECTION_TYPES = "" def __init__(self, arg1, arg2, arg3=None): if arg3 is None: object_id = arg1 dispatcher = arg2 else: object_id = arg1 baseUrl = arg2 dispatcher = arg3 self._object_property = ObjectProperty(self.__class__.__name__, object_id) self._object_property.set_state(ObjectProperty.State.INITIALIZING) self.__set_description() self.__set_connection_types() self._object_settings = {} self.dispatcher = dispatcher if self.dispatcher is None: return self.dispatcher.add_local_object(self) self._event_subscription = EventSubscription(object_id) self.__parser = RequestParser() self.__add_rules() def on_initialize(self, obj_prop): return True def on_finalize(self): logging.debug("on_finalize ObjectID:" + self.object_id) self.dispatcher.remove_local_object(self) @property def object_id(self): return self._object_property.object_id @property def object_property(self): return self._object_property @property def object_settings(self): return self._object_settings @property def state(self): return self._object_property.state def set_state(self, state): prop = self.object_property prop.set_state(state) return self._do_put_property(prop.packed_object()) def __set_description(self): self._object_property.set_property(ObjectProperty.DESCRIPTION, self.DESCRIPTION) def __set_connection_types(self): self._object_property.set_property(ObjectProperty.CONNECTION_TYPES, self.CONNECTION_TYPES) def _request_sync(self, object_id, method, path, body=None): return self.dispatcher.request_sync( Request(object_id, method, path, body)) def _request(self, object_id, method, path, body=None): resp = Response(Response.StatusCode.INTERNAL_SERVER_ERROR, None) try: resp = self._request_sync(object_id, method, path, body) except: logging.error("Exception: Request to " + object_id + " Method:" + method + " Path:" + path) logging.error(traceback.format_exc()) return resp def _publish_event_async(self, event_type, body): return self.dispatcher.publish_event_async( Event(self.object_id, event_type, body)) def _apply_event_subscription(self): return self.dispatcher.subscribe_event(self._event_subscription) def __add_rules(self): rules = [] rules.append({ RequestParser.PATTERN: r"^property/?$", RequestParser.METHOD: Request.Method.GET, RequestParser.FUNC: self._do_get_property, RequestParser.PARAMS: 0 }) rules.append({ RequestParser.PATTERN: r"^property/?$", RequestParser.METHOD: Request.Method.PUT, RequestParser.FUNC: self._do_put_property, RequestParser.PARAMS: 1 }) rules.append({ RequestParser.PATTERN: r"^settings/?$", RequestParser.METHOD: Request.Method.GET, RequestParser.FUNC: self._do_get_settings, RequestParser.PARAMS: 0 }) rules.append({ RequestParser.PATTERN: r"^settings/?$", RequestParser.METHOD: Request.Method.PUT, RequestParser.FUNC: self._do_put_settings, RequestParser.PARAMS: 1 }) self.__parser.add_rule(rules) def dispatch_request(self, request): try: resp = self.__parser.action(request) if resp.status_code == Response.StatusCode.NOT_FOUND: resp = self._on_request(request) except: logging.error("Exception: Receive Request" + " Method:" + request.method + " Path:" + request.path) logging.error(traceback.format_exc()) resp = Response(Response.StatusCode.INTERNAL_SERVER_ERROR, None) return resp def dispatch_event(self, event): self._do_post_event(event) def _do_get_property(self): logging.debug("Receive GET Property ObjectID:" + self.object_id) return Response(Response.StatusCode.OK, self._object_property) def _do_put_property(self, body): logging.debug("Receive PUT Property ObjectID:" + self.object_id) # check State Change to Finalizing for k, v in body.items(): if k == ObjectProperty.OBJECT_STATE: oldValue = self._object_property.get_property(k) self.on_state_changed(oldValue, v) # update Property if not (self._object_property.equals(body)): self._object_property.put_property(body) return Response(Response.StatusCode.OK, self._object_property) def _do_get_settings(self): logging.debug("Receive GET Settings ObjectID:" + self.object_id) return Response(Response.StatusCode.OK, self._object_settings) def _do_put_settings(self, body): logging.debug("Receive PUT Settings ObjectID:" + self.object_id) if body != self._object_settings: old = copy.deepcopy(self._object_settings) # delete for k in old.keys(): if k not in body: del self._object_settings[k] # add or update for k, v in body.items(): self._object_settings[k] = v self.on_settings_changed(ObjectSettingChanged.Action.UPDATE, old, self._object_settings) return Response(Response.StatusCode.OK, self._object_settings) def _do_post_event(self, event): self.on_event(event) def on_state_changed(self, old_state, new_state): if old_state != ObjectProperty.State.FINALIZING: if new_state == ObjectProperty.State.FINALIZING: self.on_finalize() def on_settings_changed(self, action, prev, curr): event_body = { ObjectSettingChanged.ACTION: action, ObjectSettingChanged.PREV: prev, ObjectSettingChanged.CURR: curr } self._publish_event_async(ObjectSettingChanged.TYPE, event_body) def _on_request(self, request): return Response(Response.StatusCode.BAD_REQUEST, None) def on_event(self, event): # for example: method_name = "_do_event_topologychanged" method_name = "_do_event_" + event.event_type.lower() if hasattr(self, method_name): method = getattr(self, method_name) if callable(method): method(event) return return