# OrderService running on port 8088 from flask import Flask, jsonify, request, Response import logging from opentelemetry import trace from opentelemetry.instrumentation.logging import LoggingInstrumentor from opentelemetry.instrumentation.wsgi import collect_request_attributes from opentelemetry.instrumentation.flask import FlaskInstrumentor from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter from opentelemetry.instrumentation.requests import RequestsInstrumentor from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import ( ConsoleSpanExporter, SimpleSpanProcessor, ) from Error import Error from requests import delete, get, post, put import flask, os, pkg_resources, socket, random, requests, json logger = logging.getLogger(__name__) READ_ERROR_RATE_THRESHOLD = 0 UPDATE_ERROR_RATE_THRESHOLD = 0 DELETE_ERROR_RATE_THRESHOLD = 0 app = Flask(__name__) OTLP = os.getenv("OTLP") if os.getenv("OTLP") is not None else "localhost" DATABASE = os.getenv("DATABASE") if os.getenv("DATABASE") is not None else "localhost" LOGS = os.getenv("LOGS") if os.getenv("LOGS") is not None else "localhost" trace.set_tracer_provider( TracerProvider( resource=Resource.create( { "service.name": "order", "service.instance.id": str(id(app)), "telemetry.sdk.name": "opentelemetry", "telemetry.sdk.language": "python", "telemetry.sdk.version": pkg_resources.get_distribution("opentelemetry-sdk").version, "host.hostname": socket.gethostname(), } ) ) ) tracerProvider = trace.get_tracer_provider() tracer = tracerProvider.get_tracer(__name__) tracerProvider.add_span_processor( SimpleSpanProcessor(ConsoleSpanExporter()) ) otlp_exporter = OTLPSpanExporter(endpoint="{}:55680".format(OTLP), insecure=True) tracerProvider.add_span_processor( SimpleSpanProcessor(otlp_exporter) ) LoggingInstrumentor().instrument(set_logging_format=True) FlaskInstrumentor().instrument_app(app) RequestsInstrumentor().instrument(tracer_provider=tracerProvider) @app.errorhandler(Error) def handle_invalid_usage(error): response = jsonify(error.to_dict()) response.status_code = error.status_code return response @app.route("/update_order", methods=["POST", "PUT"]) def update_order(): errorRate = random.randint(0,99) if errorRate < UPDATE_ERROR_RATE_THRESHOLD: logs('Order', 'Update operation failed - Service Unavailable: 503') logger.error('Order - Update operation failed - Service Unavailable: 503') raise Error('Update Order Failed - Service Unavailable', status_code=503) else: with tracer.start_as_current_span("update_order"): rawData = request.form failedItems = [] for itemId in rawData.keys(): qty = sum([val for val in rawData.getlist(itemId, type=int)]) if qty >= 0: databaseResponse = post( "http://{}:80/add_item_to_cart".format(DATABASE), data={"ItemId": itemId, "Qty": qty}) else: databaseResponse = post( "http://{}:80/remove_item_from_cart".format(DATABASE), data={"ItemId": itemId, "Qty": -qty}) if databaseResponse.status_code != 200: failedItems.append(itemId) if len(failedItems)>0: response = jsonify( {"failed_items": failedItems} ) response.status_code = 206 response.status = "{} {}".format( response.status_code, "Update order response contains failed items." ) return response else: logs('Order', 'Update operations successful') logger.info('Order - Update operations successful') return jsonify({"failed_items": []}) @app.route("/get_order") def get_order(): errorRate = random.randint(0,99) if errorRate < READ_ERROR_RATE_THRESHOLD: logs('Order', 'Read operation failed - Service Unavailable: 503') logger.error('Order - Read operation failed - Service Unavailable: 503') raise Error('getOrder Failed - Service Unavailable', status_code=503) else: with tracer.start_as_current_span("get_order"): databaseResponse = get( "http://{}:80/get_cart".format(DATABASE)) assert databaseResponse.status_code == 200 logs('Order', 'Read operation successful') logger.info('Order - Read operation successful') return databaseResponse.json() @app.route("/clear_order", methods=["DELETE"]) def clear_order(): errorRate = random.randint(0,99) if errorRate < DELETE_ERROR_RATE_THRESHOLD: logs('Order', 'Update operation failed - Service Unavailable: 503') logger.error('Order - Update operation failed - Service Unavailable: 503') raise Error('clearOrder Failed - Service Unavailable', status_code=503) else: with tracer.start_as_current_span("clear_order"): databaseResponse = put( "http://{}:80/cart_empty".format(DATABASE), ) assert databaseResponse.status_code == 200 logs('Order', 'Delete operation successful') logger.info('Order - Delete operation successful') return "success" @app.route("/pay_order", methods=["POST", "GET"]) def pay_order(): with tracer.start_as_current_span("pay_order"): databaseResponse = delete( "http://{}:80/cart_sold".format(DATABASE), ) assert databaseResponse.status_code == 200 logs('Order', 'Update operation successful') logger.info('Order - Update operation successful') return "success" def logs(serv=None, mes=None): create_log_data = {'service': serv, 'message': mes} url = "http://{}:80/logs".format(LOGS) response = requests.post( url, data=json.dumps(create_log_data), headers={'Content-Type': 'application/json'} ) assert response.status_code == 200 return "success" if __name__ == "__main__": app.run(port=5000, host="0.0.0.0")