def test_add_new_gateway_country(self): node_json = { "external_ip": "foo", "external_port": 123, "network": constants.DEFAULT_NETWORK_NAME, "country": "United States", "node_type": "RELAY" } node = model_loader.load_model(NodeModel, node_json) self.assertEqual(node.country, "United States", "country United States should remains") node_json = { "external_ip": "foo", "external_port": 123, "network": constants.DEFAULT_NETWORK_NAME, "node_type": "RELAY", "country": "Country name after truncation. Very long country that has more than 30 characters" } node = model_loader.load_model(NodeModel, node_json) self.assertEqual(node.country, "Country name after truncation.", "country name should be truncated")
def test_camel_case_model(self): model_dict_snake_case = {"foo_bar_baz_qux": [{"foo_bar_baz_qux": []}]} model_dict_camel_case = {"fooBarBazQux": [{"fooBarBazQux": []}]} snake_result = model_loader.load_model(ModelWithLongNames, model_dict_snake_case) camel_result = model_loader.load_model( ModelWithLongNames, model_dict_camel_case, Case.CAMEL ) self.assertEqual(snake_result, camel_result)
def test_loading_custom_parser(self): model_dict_1 = { "attribute": "123" } model_dict_2 = { "attribute": "000" } result_1 = model_loader.load_model(ModelWithCustomAttribute, model_dict_1) self.assertEqual("foobarbaz", result_1.attribute.foo) result_2 = model_loader.load_model(ModelWithCustomAttribute, model_dict_2) self.assertEqual("qux", result_2.attribute.foo)
def parse_message(self): if not self._parsed: self._parsed = True off = ont_constants.ONT_HDR_COMMON_OFF self._version, = struct.unpack_from("<I", self.buf, off) off += ont_constants.ONT_INT_LEN self._consensus_payload = self._memoryview[off:] off += ont_constants.ONT_HASH_LEN + 2 * ont_constants.ONT_INT_LEN + ont_constants.ONT_SHORT_LEN self._consensus_data_full_len, size = ont_varint_to_int(self.buf, off) off += size self._consensus_payload_header = self._memoryview[:off] self._consensus_data = self._memoryview[off:off + self._consensus_data_full_len] self._consensus_data_str = bytearray(self._consensus_data).decode() self._consensus_data_json = json.loads(self._consensus_data_str) off += self._consensus_data_full_len self._owner_and_signature = self._memoryview[off:] self._consensus_data_type = self._consensus_data_json["type"] if self._consensus_data_type == ont_constants.BLOCK_PROPOSAL_CONSENSUS_MESSAGE_TYPE: encoded_payload = model_loader.load_model( ConsensusMsgPayload, self._consensus_data_json) self._consensus_data_len = encoded_payload.len self._decoded_payload = memoryview( base64.b64decode(encoded_payload.payload)) self.parse_block_vbft_type()
def test_nested_model(self): model_dict = { "foo": 1, "bar": [{"foo": 1, "bar": "123", "baz": [1, 2, 3]}, {"foo": 2, "bar": 234, "baz": [5]}], "baz": {"qux": {"foo": 12, "bar": "999", "baz": []}}, } model_json = json_encoder.to_json(model_dict) dict_result = model_loader.load_model(NestedModel, model_dict) json_result = model_loader.load_model_from_json(NestedModel, model_json) self.assertEqual(dict_result, json_result) self.assertEqual(1, dict_result.foo) bar_field = dict_result.bar self.assertEqual(2, len(bar_field)) self.assertEqual(1, bar_field[0].foo) self.assertEqual("123", bar_field[0].bar) self.assertEqual([1, 2, 3], bar_field[0].baz) baz_field = dict_result.baz self.assertEqual(1, len(baz_field)) self.assertEqual(12, baz_field["qux"].foo) self.assertEqual("999", baz_field["qux"].bar) self.assertEqual([], baz_field["qux"].baz)
def register_node(node_model: NodeModel) -> NodeModel: if not node_model: raise ValueError("Missing node model.") # Let the SDN know who this is. # SDN determines peers and returns full config. node_config = cast(Dict[str, Any], http_service.post_json(SdnRoutes.nodes, node_model)) logger.trace("Registered node. Response: {}", json_encoder.to_json(node_config)) if not node_config: raise EnvironmentError( "Unable to reach SDN and register this node. Please check connection." ) registered_node_model = model_loader.load_model(NodeModel, node_config) if not registered_node_model.source_version: raise ValueError( f"Source version {node_model.source_version} is no longer supported. Please upgrade to the " f"latest version") if registered_node_model.blockchain_network_num == -1: raise ValueError( f"The blockchain network number {node_model.blockchain_network_num} does not exists. Please " f"check the blockchain network startup parameters") return registered_node_model
def _register_node(opts: CommonOpts, node_ssl_service: NodeSSLService) -> NodeModel: temp_node_model = model_loader.load_model(NodeModel, opts.__dict__) if node_ssl_service.should_renew_node_certificate(): temp_node_model.csr = ssl_serializer.serialize_csr( node_ssl_service.create_csr() ) try: node_model = sdn_http_service.register_node(temp_node_model) except ValueError as e: logger.fatal(e) sys.exit(1) except EnvironmentError as e: logger.info( "Unable to contact SDN to register node using {}, attempting to get information from cache", opts.sdn_url, ) cache_info = node_cache.read(opts) if not cache_info or not cache_info.node_model: logger.fatal( "Unable to reach the SDN and no local cache information was found. Unable to start the gateway" ) sys.exit(1) node_model = cache_info.node_model if node_model.should_update_source_version: logger.info( "UPDATE AVAILABLE! An updated software version is available, please download and install the " "latest version" ) return node_model
def fetch_account_model(account_id: str) -> Optional[BdnAccountModelBase]: account_url = SdnRoutes.account.format(account_id) response = cast(Dict[str, Any], http_service.get_json(account_url)) if response: return model_loader.load_model(BdnAccountModelBase, response) else: return None
def fetch_node_attributes(node_id: str) -> Optional[NodeModel]: # Should only be used for test networks. node_url = SdnRoutes.node.format(node_id) opts = cast(Dict[str, Any], http_service.get_json(node_url)) logger.trace("Retrieved config for id {0} : {1}", node_id, opts) if opts: return model_loader.load_model(NodeModel, opts) else: return None
def fetch_gateway_settings(node_id: str) -> GatewaySettingsModel: node_url = SdnRoutes.gateway_settings.format(node_id) gateway_settings = cast(Dict[str, Any], http_service.get_json(node_url)) if not gateway_settings: gateway_settings = GatewaySettingsModel() else: gateway_settings = model_loader.load_model(GatewaySettingsModel, gateway_settings) return gateway_settings
def test_add_new_gateway_continent(self): node_json = { "external_ip": "foo", "external_port": 123, "network": constants.DEFAULT_NETWORK_NAME, "node_type": "RELAY", "continent": "AT" } node = model_loader.load_model(NodeModel, node_json) self.assertEqual(node.continent, None, "Continent AT should changed to None") node_json = { "external_ip": "foo", "external_port": 123, "network": constants.DEFAULT_NETWORK_NAME, "node_type": "RELAY", "continent": "EU" } node = model_loader.load_model(NodeModel, node_json) self.assertEqual(node.continent, "EU", "Continent EU should remains")
def test_basic_model(self): model_dict = {"foo": 1, "bar": "123", "baz": [1, 2, 3]} model_json = json_encoder.to_json(model_dict) dict_result = model_loader.load_model(BasicModel, model_dict) json_result = model_loader.load_model_from_json(BasicModel, model_json) self.assertEqual(dict_result, json_result) self.assertEqual(1, dict_result.foo) self.assertEqual("123", dict_result.bar) self.assertEqual([1, 2, 3], dict_result.baz)
def _load_status_from_file(use_ext: bool, src_ver: str, ip_address: str, continent: str, country: str, update_required: bool, account_id: Optional[str], quota_level: Optional[int]) -> Diagnostics: path = config.get_data_file(STATUS_FILE_NAME) with open(path, "r", encoding="utf-8") as json_file: status_file = json_file.read() try: model_dict = json.loads(status_file) diagnostics = model_loader.load_model(Diagnostics, model_dict) except JSONDecodeError: logger.warning(log_messages.STATUS_FILE_JSON_LOAD_FAIL, path) diagnostics = initialize(use_ext, src_ver, ip_address, continent, country, update_required, account_id, quota_level) return diagnostics
def fetch_blockchain_network( protocol_name: str, network_name: str) -> Optional[BlockchainNetworkModel]: node_url = SdnRoutes.blockchain_network.format(protocol_name, network_name) blockchain_network = cast(Dict[str, Any], http_service.get_json(node_url)) if blockchain_network is None: return None blockchain_network = model_loader.load_model(BlockchainNetworkModel, blockchain_network) return blockchain_network
def test_from_json(self): node_json = { "external_ip": "foo", "external_port": 123, "network": "bad_net_name", "node_type": "RELAY" } node = model_loader.load_model(NodeModel, node_json) self.assertEqual(node_json.get("external_ip"), node.external_ip) self.assertEqual(node_json.get("external_port"), node.external_port) self.assertEqual(node_json.get("network"), node.network) self.assertEqual(NodeType.RELAY, node.node_type)
def fetch_blockchain_networks() -> List[BlockchainNetworkModel]: node_url = SdnRoutes.blockchain_networks blockchain_networks = http_service.get_json(node_url) if not blockchain_networks: logger.warning("BDN does not seem to contain any configured networks.") return [] blockchain_networks = [ model_loader.load_model(BlockchainNetworkModel, b) for b in blockchain_networks ] return blockchain_networks
def test_loading_hex_model(self): model_dict = { "hash": "0xdee4fc78545f68f2db6a538c887f8982bd37360b2986678c46f2ecf53e8b28d0", "data": "0xd883010914846765746888676f312e31342e37856c696e7578", "value": "0xbcb1d1" } result = model_loader.load_model(HexadecimalModel, model_dict) self.assertEqual( Sha256Hash(convert.hex_to_bytes(model_dict["hash"])), result.hash ) self.assertEqual(convert.hex_to_bytes(model_dict["data"]), result.data) self.assertEqual(int(model_dict["value"], 16), result.value)
def _fetch_peers(node_url: str, node_id=None) -> List[OutboundPeerModel]: outbound_peers_response = cast(List[Dict[str, Any]], http_service.get_json(node_url)) logger.debug( "Retrieved outbound peers for node {0} from endpoint {1}: {2}", node_id, node_url, outbound_peers_response) if not outbound_peers_response: logger.warning("BDN returned no peers at endpoint: {}", node_url) return [] outbound_peers = [ model_loader.load_model(OutboundPeerModel, o) for o in outbound_peers_response ] ip_resolver.blocking_resolve_peers(outbound_peers) return outbound_peers
def fetch_blockchain_networks() -> Dict[int, BlockchainNetworkModel]: node_url = SdnRoutes.blockchain_networks sdn_blockchain_networks = http_service.get_json(node_url) if not sdn_blockchain_networks: logger.warning(log_messages.BDN_CONTAINS_NO_CONFIGURED_NETWORKS) return {} assert isinstance(sdn_blockchain_networks, List) blockchain_network_models = [ model_loader.load_model(BlockchainNetworkModel, b) for b in sdn_blockchain_networks ] blockchain_network_dict = { network_model.network_num: network_model for network_model in blockchain_network_models } return blockchain_network_dict
def register_node(node_model: NodeModel) -> NodeModel: if not node_model: raise ValueError("Missing node model.") # Let the SDN know who this is. # SDN determines peers and returns full config. node_config = cast(Dict[str, Any], http_service.post_json(SdnRoutes.nodes, node_model)) logger.trace("Registered node. Response: {}", json_utils.serialize(node_config)) if not node_config: raise EnvironmentError( "Unable to reach SDN and register this node. Please check connection." ) return model_loader.load_model(NodeModel, node_config)
def _fetch_peers(node_url: str, node_id: Optional[str] = None) -> List[OutboundPeerModel]: outbound_peers_response = cast(List[Dict[str, Any]], http_service.get_json(node_url)) logger.debug( "Retrieved outbound peers for node {0} from endpoint {1}: {2}", node_id, node_url, outbound_peers_response) if not outbound_peers_response: logger.warning(log_messages.BDN_RETURNED_NO_PEERS, node_url) return [] outbound_peers = [ model_loader.load_model(OutboundPeerModel, o) for o in outbound_peers_response ] ip_resolver.blocking_resolve_peers(outbound_peers) return outbound_peers
def read(opts: Union["CommonOpts", Namespace]) -> Optional[CacheNetworkInfo]: cache_file_info = None enable_node_cache = opts.__dict__.get("enable_node_cache", False) relative_path = opts.__dict__.get("cookie_file_path", None) if enable_node_cache and relative_path is not None: try: cookie_file_path = config.get_data_file(relative_path) if os.path.exists(cookie_file_path): with open(cookie_file_path, "r") as cookie_file: cache_file_info = model_loader.load_model( CacheNetworkInfo, json.load(cookie_file)) if cache_file_info.source_version != opts.source_version: os.remove(cookie_file_path) else: logger.warning(log_messages.READ_CACHE_FILE_WARNING, cookie_file_path) # pylint: disable=broad-except except Exception as e: logger.error( "Failed when tried to read from cache file: {} with exception: {}", relative_path, str(e)) return cache_file_info
def update_cache_file( opts: "CommonOpts", potential_relay_peers: Optional[List[OutboundPeerModel]] = None, blockchain_peers: Optional[List[BlockchainPeerInfo]] = None, accounts: Optional[Dict[str, Optional[BdnAccountModelBase]]] = None) -> None: data = read(opts) node_model = model_loader.load_model(NodeModel, opts.__dict__) if data is None: data = CacheNetworkInfo(source_version=opts.source_version, relay_peers=potential_relay_peers, blockchain_networks=opts.blockchain_networks, blockchain_peers=blockchain_peers, node_model=node_model, accounts=accounts) else: data.blockchain_networks = opts.blockchain_networks data.node_model = node_model if potential_relay_peers is not None: data.relay_peers = potential_relay_peers if blockchain_peers is not None: data.blockchain_peers = blockchain_peers if accounts is not None: if data.accounts: data.accounts.update(accounts) else: data.accounts = accounts try: cookie_file_path = config.get_data_file(opts.cookie_file_path) os.makedirs(os.path.dirname(cookie_file_path), exist_ok=True) with open(cookie_file_path, "w") as cookie_file: json.dump(data, cookie_file, indent=4, cls=EnhancedJSONEncoder) # pylint: disable=broad-except except Exception as e: logger.error( "Failed when tried to write to cache file: {} with exception: {}", opts.cookie_file_path, e)
def test_invalid_json(self): node_json = {"a": "foo", "b": "bazz", "node_type": "garbage"} # Should throw error, none of the keys are right, node_type is wrong with self.assertRaises(TypeError): model_loader.load_model(NodeModel, node_json)