def save_supplier_to_blockchain(supplier): """save the given supplier on the blockchain by calling the ledger service """ try: call_ledger_api( "post", "/ledger/suppliers", { "uuid": supplier.uuid, "short_id": "", "name": supplier.name, "passwd": supplier.password, "url": "" }) except APIError as error: raise APIError("Failed to save supplier to blockchain. " + str(error))
def save_part_to_blockchain(part): """save the given part on the blockchain by calling the ledger service """ try: call_ledger_api("post", "/ledger/parts", { "uuid": part.uuid, "name": part.name, "checksum": "", "version": part.version, "src_uri": part.url, "licensing": part.licensing, "label": "", "description": part.description }) except APIError as error: raise APIError("Failed to save part to blockchain. " + str(error))
def register_app_with_blockchain(): """call the conductor service to register this app (sparts catalog) on the supply chain network """ print("Registering app with blockchain...") data = { "name": "Software Parts Catalog", "label": "Software Parts Catalog", "uuid": "9fb84fa0-1716-4367-7012-61370e23028f", "api_address": "http://catalog.open.windriver.com", "app_type": "website", "description": "Software Parts Catalog" } try: return call_conductor_api("post", "/apps/register", data) except APIError as error: raise APIError("Failed to register app with blockchain. " + str(error))
def call_api_service(method, url, data): """call the API service at url with given HTTP method and parameters """ if app.config["BYPASS_API_CALLS"]: return {} try: print("Calling [" + method + "] " + url) print("with " + str(data)) if method == "get": response = requests.get(url, params=data, \ timeout=app.config["DEFAULT_API_TIMEOUT"]) elif method == "post": response = requests.post(url, data=json.dumps(data), \ headers={'Content-type': 'application/json'}, \ timeout=app.config["DEFAULT_API_TIMEOUT"]) else: raise APIError("Bad method passed to function `call_api()`. Got `" + method \ + "`; expected 'get' or 'post'.") if response.status_code != 200: raise APIError("The call to " + url + " resulted in HTTP status " \ + str(response.status_code)) try: json_response = response.json() except: raise APIError("Failed to parse the JSON data in the response of API service at " \ + url + ". The response was `" + str(response.content) + "`.") if "status" in json_response and json_response["status"] != "success": raise APIError("API service at '" + url + "' returned status '" \ + str(json_response["status"]) + "', with the following details: " \ + str(json_response)) return json_response except ReadTimeout: raise APIError("Connection to " + url + " timed out.") except ConnectionError: raise APIError("API service at " + url + " refused connection.") except Exception as error: raise APIError("Failed to call the API service at " + url + ". " + str(error))
def register_app_with_blockchain(): """call the conductor service to register this app (sparts catalog) on the supply chain network """ data = { "uuid": "9fb84fa0-1716-4367-7012-61370e23028f", "api_url": "http://open.windriver.com:5000", "type": "website", "label": "Sparts Catalog" } if app.config["BYPASS_API_CALLS"]: return try: response = requests.post(API_SERVER + "/app/register", data=json.dumps(data), \ headers={'Content-type': 'application/json'}, timeout=app.config["DEFAULT_API_TIMEOUT"]) except ReadTimeout: raise APIError("Failed to register app with blockchain. Conductor service timed out") except ConnectionError: raise APIError("Failed to register app with blockchain. " \ + "The conductor service refused connection or is not running.") if response.status_code != 200: raise APIError("Failed to register app with blockchain. Server responded with " \ + "HTTP " + str(response.status_code)) try: result = response.json() except: raise APIError("Failed to register app with blockchain. Invalid JSON return data " \ + "'" + str(response.content)) + "'" if "status" not in result: raise APIError("Failed to register app with blockchain. Invalid JSON return data " \ + ": Missing required field 'status'.") if result["status"] != "success": raise APIError("Failed to register app with blockchain. Server returned status '" \ + str(result["status"]) + "'.")
def call_blockchain_api(method, url, data={}): """ call the blockchain ledger service with the given method (post or get), url, and data. """ if app.config["BYPASS_API_CALLS"]: return {} bc_server_ip, bc_server_port = get_ledger_api_address() request_url = "http://" + bc_server_ip + ":" + str(bc_server_port) + "/api/sparts" + url print("[" + method + "] " + request_url) result = None try: if method == "get": result = requests.get(request_url, params=data, timeout=app.config["DEFAULT_API_TIMEOUT"]) elif method == "post": result = requests.post(request_url, data=json.dumps(data), \ headers={'Content-type': 'application/json'}, timeout=app.config["DEFAULT_API_TIMEOUT"]) else: raise APIError("Bad method passed to function 'call_blockchain_api") except ReadTimeout: raise APIError("Blockchain ledger service timed out.") except ConnectionError: raise APIError("Blockchain ledger service refused connection.") if result.status_code != 200: raise APIError("The blockchain API server responeded with HTTP " + \ str(result.status_code) + ".") # hack to bypass invalid JSON value when blockchain is empty if result.content == "[{[]}]": return [] json_result = None try: json_result = result.json() except: raise APIError("Failed to parse the following JSON data in the response of the blockchain" \ +" API server.<br><br><pre>" + str(result.content) + "</pre>") if "status" in json_result: # raise APIError("Invalid JSON in the response of the ledger service at " + url \ # + "Missing required field 'status'") if json_result["status"] == "failed": if "error_message" in json_result: raise APIError("Leger service call to '" + url + "' failed. " \ + "The API server provided the following reason: '" \ + json_result["error_message"] + "'.") else: raise APIError("Leger service call to '" + url + "' failed." + \ "No error_message was provided by the server.") if json_result["status"] != "success": raise APIError("Leger service call to '" + url + "' returned 'status' = '" \ + json_result["status"] + "'.") return json_result