diff --git a/.github/workflows/README_DEV.md b/.github/workflows/README_DEV.md new file mode 100644 index 0000000..81a5df2 --- /dev/null +++ b/.github/workflows/README_DEV.md @@ -0,0 +1,113 @@ +# Flex Net Sim Backend API - Development and Deployment Instructions + +This document is for developers who want to set up, develop, and deploy the Flex Net Sim Backend API. + +## Prerequisites + +* Python 3.9 or higher +* g++ (GNU C++ Compiler) +* Docker (for containerization) +* Google Cloud SDK (for deployment to Google Cloud Run) +* A Google Cloud Project with Cloud Run API enabled. + +## Getting Started (Local Development) + +1. **Clone the repository:** + ```bash + git clone [https://github.com/MirkoZETA/FlexNetSim-API.git](https://github.com/MirkoZETA/FlexNetSim-API.git) + cd flask-simulation-backend + ``` + +2. **Create a Python virtual environment (recommended):** + ```bash + python3 -m venv .venv + ``` + + On Linux/macOS: + ```bash + source .venv/bin/activate + ``` + + On Windows + ```bash + .venv\Scripts\activate + ``` +3. **Install Python dependencies:** + ```bash + pip install -r requirements.txt + ``` + +4. **Run the Flask backend:** + ```bash + flask --app backend run + ``` + The backend will be accessible at `http://127.0.0.1:5000`. + +5. **Test**: + ```bash + curl http://127.0.0.1:5000/help + ``` + or + ```bash + curl -X POST -H "Content-Type: application/json" -d '{}' http://127.0.0.1:5000/run_simulation + ``` + +### Dockerization + +To build the Docker image: + +```bash +docker build -t fns-api . +``` + +## GCloud Deployment Configuration + +As a prerequisite is mandatory to apply the following steps to the GCloud project for the docker image build and upload to artifacts, and also service account creation and IAM policy binding: + +[GCloud Configuration Video Tutorial](https://www.youtube.com/watch?v=KQUKDiBz3IA) + +This video will guide you through the necessary configurations in the Google Cloud Console to prepare your project for Cloud Run deployments using GitHub Actions. + +**Key Reminders from the Video & for Successful Deployment:** + +* **Keep Track of Docker Image Name, Project ID:** Note these down during the video configuration, as you will need them in subsequent steps and for your GitHub Actions workflow. +* **Service Account Email:** Ensure you create a Service Account as shown in the video and securely download and store the JSON key file. You'll also need to note the Service Account's email address. + +**Post-Configuration Steps (using `gcloud` and `cloud-run`):** + +1. Activate necessary apis: + + * `gcloud services enable run.googleapis.com` + +2. Create cloud run service: + * Navigate to the Cloud Run section in your Google Cloud Console. + * Create a **Service**. + * Select *Use an inline editor to create a function*. + * Set a name, in this case *fns-api-cloud-run* will be used. + * Note down the Endpoint URL, because it will the defaul url for the API. + * Select the authetification preferences. + * Create. + +3. Update access of service accounts to cloud run resources: + + ```bash + gcloud projects add-iam-policy-binding "" --member="serviceAccount:" --role="roles/run.admin" + ``` + + and + + ```bash + gcloud iam service-accounts add-iam-policy-binding "-compute@developer.gserviceaccount.com" --member="serviceAccount:" --role="roles/iam.serviceAccountActor" + ``` + +4. **Test the Deployed API (using `curl`):** + + Use the `curl` command with the `ENDPOINT-URL` you obtained from the previous steps to test your deployed API. Replace `YOUR-ENDPOINT-URL` with the actual `ENDPOINT-URL`. + + ```bash + curl -X POST -H "Content-Type: application/json" -d '{"algorithm": "FirstFit", "networkType": 1, "bitrate": "fixed-rate"}' /run_simulation + ``` + + Remember that depending on the authetification preferences you might need to authetificate to send request to the Endpoint just created. + +**Remember**: These GCloud configurations, along with the repository's `gke-cd.yml` GitHub Actions workflow and correctly configured GitHub secrets, are essential for successful automated deployment of your FlexNetSim-API application to Google Cloud Run. \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d8995f4 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,44 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added +- Switch to Flex Net Sim v0.8.2. +- Enchanced previous algorithms. +- New algorithm BestFit. +- Point README docs to oficial documentation. +- New domain. + +## [0.2.0] - 2025-02-19 + +### Added + +- This API hopefully serves as playground to all new users of Flex Net Sim C++ simulation library. +- The current version utilizes Flex Net Sim v0.8.1. +- `/run_simulation` endpoint for simulation includes parameters such as: + - `algorithm`: FirstFit, ExactFit. + - `networkType`: Only 1 (EON) available for now. + - `goalConnections`: 1 to 10,000,000. + - `confidence`: significance level (alpha) greater than zero. + - `lambdaParam`: Arrival rate (lambda) of connection requests. + - `mu`: departure rate of connection requests. + - `network`: name of the netowrk to simulate, `Cost239`, `EuroCore`, `GermanNet`, `UKNet`, `NSFNet`. + - `bitrate`: fixed-rate or flex-rate. + - `K`: Number of paths to consider during allocation, max 6. +- `/help` endpoint provides detailed information about the `/run_simulation` endpoint. +- API allocated in cloud run. +- Documentation README for the process of develop/deployment located in [workflows](https://github.com/MirkoZETA/FlexNetSim-API/tree/master/.github/workflows/README_DEV.md). + +## [0.1.0] - 2025-02-18 + +### Added + +- It was a mess! + +[0.2.0]: https://github.com/MirkoZETA/FlexNetSim-API/releases/tag/v0.0.2 +[0.1.0]: https://github.com/MirkoZETA/FlexNetSim-API/releases/tag/v0.0.1 diff --git a/README.md b/README.md index 19acd13..2cc28dc 100644 --- a/README.md +++ b/README.md @@ -1,167 +1,79 @@ # Flex Net Sim Backend API -Flask-based backend API for integrating the FlexNetSim C++ library, powering the web application. +Welcome to the Flex Net Sim Backend API repository. -## Prerequisites +This is the **publicly accessible backend API** for the [Flex Net Sim](https://gitlab.com/DaniloBorquez/flex-net-sim) project. -* Python 3.9 or higher -* g++ (GNU C++ Compiler) -* Docker (for containerization) -* Google Cloud SDK (for deployment to Cloud Run) -* A Google Cloud Project with Cloud Run API enabled. +This API provides a **hands-on demonstration**, enabling users to quickly execute pre-configured network simulations and gain an initial understanding of Flex Net Sim's capabilities. -## Getting Started (Local Development) +Through simple POST requests, initiated via command-line tools or the [playground page](www.in-progress.com), users can experiment with a defined set of parameters and algorithms. This allows for exploration of fundamental network simulation concepts using Flex Net Sim. -1. **Clone the repository:** - ```bash - git clone https://github.com/MirkoZETA/FlexNetSim-API.git - cd flask-simulation-backend - ``` +It is important to note that **this API is intentionally designed as a limited demonstration platform**. It serves as a **simplified method of accessing** and showcasing the **basic functionalities** of Flex Net Sim. **It is not intended for complex simulations or for algorithm customization.** Algorithm customization is a core strength of Flex Net Sim, and this advanced capability is exclusively unlocked when working directly with **the library**. -2. **Create a Python virtual environment (recommended):** - ```bash - python3 -m venv .venv - source .venv/bin/activate # On Linux/macOS - .venv\Scripts\activate # On Windows - ``` +The purpose of this API is to introduce users to Flex Net Sim and encourage exploration of **the full library** for advanced simulation tasks. **The full library** offers significantly greater power, flexibility, and customization potential. -3. **Install Python dependencies:** - ```bash - pip install -r requirements.txt - ``` +For users interested in progressing beyond this introductory API, comprehensive resources and documentation are available at the official [Flex Net Sim documentation](https://flex-net-sim-fork.readthedocs.io/stable/). -4. **Run the Flask backend:** - ```bash - flask --app backend run - ``` - The backend will be accessible at `http://127.0.0.1:5000`. +For **Development and Deployment Instructions** of this API (the playground itself), please refer to [README_DEV.md](README_DEV.md). ## API Endpoints ### `/run_simulation` (POST) -This endpoint runs a FlexNetSim simulation based on the parameters provided in the JSON request body. +This endpoint runs a Flex Net Sim simulation based on the parameters provided in the JSON request body. **Request Body Parameters:** -| Parameter | Type | Description | Allowed Values | Default Value | Constraints | -| :---------------- | :--------------- | :----------------------------------------------------------------------------- | :---------------------------- | :------------ | :-------------------- | -| `algorithm` | `string` | Routing and spectrum assignment algorithm to use. | `FirstFit`, `ExactFit` | `FirstFit` | | -| `networkType` | `integer` | Type of optical network. | `1` | `1` | Only `1` (EON) available | -| `goal_connections`| `integer` | Target number of connection requests for the simulation. | | `100000` | Must be integer > 0 | -| `confidence` | `number (float)` | Confidence level for the simulation results. | | `0.05` | Must be > 0 | -| `lambda_param` | `number (float)` | Arrival rate (lambda) of connection requests. | | `1.0` | Must be > 0 | -| `mu` | `number (float)` | Service rate (mu) of connection requests. | | `10.0` | Must be > 0 | -| `network` | `string` | Network topology to simulate. | `NSFNet`, `Cost239`, `EuroCore`, `GermanNet`, `UKNet` | `NSFNet` | | -| `bitrate` | `string` | Type of bitrate allocation. | `fixed-rate`, `flex-rate` | `bitrate` | | -| `K` | `integer` | Number of paths to compute. | | `3` | | +| Parameter | Type | Description | Allowed Values | Default Value | Constraints | +| :---------------- | :-------------- | :----------------------------------------------------- | :---------------------------- | :------------ | :-------------------- | +| `algorithm` | `string` | Routing and spectrum assignment algorithm to use. | `FirstFit`, `ExactFit` | `FirstFit` | | +| `networkType` | `integer` | Type of optical network. | `1` | `1` | Only `1` (EON) available | +| `goalConnections`| `integer` | Target number of connection requests for the simulation.| | `100000` | Must be integer > 0 | +| `confidence` | `number (float)`| Confidence level for the simulation results. | | `0.05` | Must be > 0 | +| `lambdaParam` | `number (float)` | Arrival rate (lambda) of connection requests. | | `1.0` | Must be > 0 | +| `mu` | `number (float)`| Service rate (mu) of connection requests. | | `10.0` | Must be > 0 | +| `network` | `string` | Network topology to simulate. | `NSFNet`, `Cost239`, `EuroCore`, `GermanNet`, `UKNet` | `NSFNet` | | +| `bitrate` | `string` | Type of bitrate allocation. | `fixed-rate`, `flex-rate` | `bitrate` | | +| `K` | `integer` | Number of paths to consider. | | `3` | | -**Example `curl` request with minimal parameters (defaults applied):** +**Example `curl` request with no parameters (defaults applied):** ```bash -curl -X POST -H "Content-Type: application/json" -d '{"algorithm": "FirstFit", "networkType": 1, "bitrate": "bitrate"}' http://127.0.0.1:5000/run_simulation +curl -X POST -H "Content-Type: application/json" -d '{}' https://fns-api-cloud-run-787143541358.us-central1.run.app/run_simulation ``` **Example `curl`request with all parameters specified:** + ```bash - curl -X POST -H "Content-Type: application/json" \ - -d '{ - "algorithm": "FirstFit", - "networkType": 1, -> (Only EONs available for the moment) - "goal_connections": 10000000, - "confidence": 0.05, - "lambda": 120, - "mu": 1, - "network": "NSFNet", - "bitrate": "bitrate" -> (filename in the ./bitrates folder) - }' \ - http://127.0.0.1:5000/run_simulation - ``` +curl -X POST -H "Content-Type: application/json" \ +-d '{ "algorithm": "FirstFit", + "networkType": 1, + "goalConnections": 1000000, + "confidence": 0.05, + "lambdaParam": 120, + "mu": 1, + "network": "NSFNet", + "bitrate": "fixed-rate" + }' \ + https://fns-api-cloud-run-787143541358.us-central1.run.app/run_simulation +``` **Response**: - - 200 OK: Simulation executed successfully. The response body will be a JSON object with the following structure: + - `200` OK: Simulation executed successfully. The response body will be a JSON object with the following structure: ```JSON { - "output": "string", // Simulation output results - "error": "string" // Empty string if no errors + "output": "string", + "error": "string" } ``` -- 400 Bad Request: Indicates an error in the request, such as missing or invalid parameters. The response body will be a JSON object with an `"error"` field describing the issue. -- 500 Internal Server Error: Indicates a server-side error, either during compilation or simulation execution. The response body will be a JSON object with `"error"` and "details" fields providing more information about the error. + - `400` Bad Request: Indicates an error in the request, such as missing or invalid parameters. The response body will be a JSON object with an `error` field describing the issue. + - `500` Internal Server Error: Indicates a server-side error, either during compilation or simulation execution. The response body will be a JSON object with `error` and "details" fields providing more information about the error. ### `/help` (GET) -This endpoint provides detailed information about the `/run_simulation` endpoint, including the expected request structure, parameters, allowed values, and response formats. +This endpoint provides detailed information about the `/run_simulation` endpoint, including the expected request structure, parameters, and response formats. **Request**: ```bash -curl http://127.0.0.1:5000/help -``` - -## Dockerization - -To build the Docker image: - -```bash -docker build -t fns-api . -``` -To run: -```bash -docker run -p 8080:8080 fns-api -``` -To stop: -```bash -docker stop fns-api -``` - -## GCloud Deployment Configuration - -As a prerequisite is mandatory to apply the following steps to the GCloud project for the docker image build and upload to artifacts, and also service account creation and IAM policy binding: - -[GCloud Configuration Video Tutorial](https://www.youtube.com/watch?v=KQUKDiBz3IA) - -This video will guide you through the necessary configurations in the Google Cloud Console to prepare your project for Cloud Run deployments using GitHub Actions. - -**Key Reminders from the Video & for Successful Deployment:** - -* **Keep Track of Docker Image Name, Project ID:** Note these down during the video configuration, as you will need them in subsequent steps and for your GitHub Actions workflow. -* **Service Account Email:** Ensure you create a Service Account as shown in the video and securely download and store the JSON key file. You'll also need to note the Service Account's email address. - -**Post-Configuration Steps (using `gcloud` and `cloud-run`):** - -1. Activate necessary apis: - - * `gcloud services enable run.googleapis.com` - -2. Create cloud run service: - * Navigate to the Cloud Run section in your Google Cloud Console. - * Create a **Service**. - * Select *Use an inline editor to create a function*. - * Set a name, in this case *fns-api-cloud-run* will be used. - * Note down the Endpoint URL, because it will the defaul url for the API. - * Select the authetification preferences. - * Create. - -3. Update access of service accounts to cloud run resources: - - ```bash - gcloud projects add-iam-policy-binding "" --member="serviceAccount:" --role="roles/run.admin" - ``` - - and - - ```bash - gcloud iam service-accounts add-iam-policy-binding "-compute@developer.gserviceaccount.com" --member="serviceAccount:" --role="roles/iam.serviceAccountActor" - ``` - -4. **Test the Deployed API (using `curl`):** - - Use the `curl` command with the `ENDPOINT-URL` you obtained from the previous steps to test your deployed API. Replace `YOUR-ENDPOINT-URL` with the actual `ENDPOINT-URL`. - - ```bash - curl -X POST -H "Content-Type: application/json" -d '{"algorithm": "FirstFit", "networkType": 1, "bitrate": "bitrate"}' /run_simulation - ``` - - Remember that depending on the authetification preferences you might need to authetificate to send request to the Endpoint just created. - -**Remember**: These GCloud configurations, along with the repository's `gke-cd.yml` GitHub Actions workflow and correctly configured GitHub secrets, are essential for successful automated deployment of your FlexNetSim-API application to Google Cloud Run. \ No newline at end of file +curl https://fns-api-cloud-run-787143541358.us-central1.run.app/help +``` \ No newline at end of file diff --git a/backend.py b/backend.py index 69f45af..695672b 100644 --- a/backend.py +++ b/backend.py @@ -3,214 +3,159 @@ import subprocess import os import logging # Import the logging module -from flask_cors import CORS # Import Flask-CORS (if you use it) +import json # --- Flask Setup --- app = Flask(__name__) -CORS(app, resources={r"/run_simulation": {"origins": 'http://localhost:5000'}}) # <-- UNCOMMENT and SET ORIGIN +#CORS(app, resources={r"/run_simulation": {"origins": 'http://localhost:5000'}}) # <-- UNCOMMENT and SET ORIGIN # --- Setup and Compilation --- SIMULATION_EXECUTABLE = "./src/simulation.out" -COMPILE_ERROR = None # Global variable to store compilation errors +COMPILE_ERROR = None # --- Logging Setup --- -logging.basicConfig(level=logging.INFO, # Set the minimum level to INFO (or DEBUG for more verbosity) +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') -logger = logging.getLogger(__name__) # Get a logger instance for this module +logger = logging.getLogger(__name__) # --- Compilation --- def compile_simulation(): - """Compiles the simulation at startup. Logs compilation details.""" - global COMPILE_ERROR - - # If file exists, delete it. - if os.path.exists(SIMULATION_EXECUTABLE): - logger.info(f"{SIMULATION_EXECUTABLE} already exists, deleting.") # Use logger.info instead of print - os.remove(SIMULATION_EXECUTABLE) - - logger.info("Compiling simulation...") # Use logger.info - compile_result = subprocess.run(["g++", "-O3", "-o", SIMULATION_EXECUTABLE, "./src/main.cpp"], capture_output=True, text=True) - if compile_result.returncode != 0: - COMPILE_ERROR = {"error": "Compilation failed", "details": compile_result.stderr} - logger.error(f"Compilation failed: {COMPILE_ERROR['error']} - Details: {COMPILE_ERROR['details']}") # Use logger.error for errors - return False - logger.info("Simulation compiled successfully.") # Use logger.info - return True + """Compiles the simulation at startup. Logs compilation details.""" + global COMPILE_ERROR + + # If file exists, delete it. + if os.path.exists(SIMULATION_EXECUTABLE): + logger.info(f"{SIMULATION_EXECUTABLE} already exists, deleting.") + os.remove(SIMULATION_EXECUTABLE) + + logger.info("Compiling simulation...") + compile_result = subprocess.run(["g++", "-O3", "-o", SIMULATION_EXECUTABLE, "./src/main.cpp"], capture_output=True, text=True) + + if compile_result.returncode != 0: + COMPILE_ERROR = {"error": "Compilation failed", "details": compile_result.stderr} + logger.error(f"Compilation failed: {COMPILE_ERROR['error']} - Details: {COMPILE_ERROR['details']}") # Use logger.error for errors + return False + + logger.info("Simulation compiled successfully.") + return True # --- Run Simulation Endpoint --- @app.route("/run_simulation", methods=["POST"]) -@app.route("/run_simulation", methods=["POST"]) def run_simulation(): - """Runs the simulation with parameters provided in the request.""" - global COMPILE_ERROR - if COMPILE_ERROR: - return jsonify(COMPILE_ERROR), 500 # Return compilation error if it exists from startup - - if not os.path.exists(SIMULATION_EXECUTABLE): # Double check if executable exists - return jsonify({"error": "Simulation executable not found. Contact developer."}), 400 - - try: - data = request.get_json() - if not data: - return jsonify({"error": "Missing JSON parameters in request body."}), 400 - - # Parameters, use default values if not provided - algorithm = data.get("algorithm", "FirstFit") - networkType = data.get("networkType", 1) - goal_connections = data.get("goal_connections", 100000) - confidence = data.get("confidence", 0.05) - lambda_param = data.get("lambda", 1) - mu = data.get("mu", 10) - network = data.get("network", "NSFNet") - bitrate = data.get("bitrate", "fixed-rate") - K = data.get("K", 3) - - # Construct command for subprocess - command = [ - f"./{SIMULATION_EXECUTABLE}", - str(algorithm), - str(networkType), - str(goal_connections), - str(confidence), - str(lambda_param), - str(mu), - str(network), - str(bitrate), - str(K) - ] - logger.debug(f"Running simulation with command: {' '.join(command)}") # Debug log for command - - process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - output, error = process.communicate() - - if process.returncode != 0: - logger.error(f"Simulation execution failed. Return code: {process.returncode}, Details: {error.strip()}") # Error log for simulation failure - return jsonify({"error": "Simulation execution failed", "details": error.strip()}), 500 - - # Return output in a structured JSON format - return jsonify({"output": output.strip(), "error": error.strip()}), 200 - - except Exception as e: - logger.exception("Unexpected error during run_simulation:") - return jsonify({"error": "An unexpected error occurred. Contact developer.", "details": str(e)}), 500 + """Runs the simulation with parameters provided in the request.""" + global COMPILE_ERROR + if COMPILE_ERROR: + return jsonify(COMPILE_ERROR), 500 + + if not os.path.exists(SIMULATION_EXECUTABLE): + return jsonify({"error": "Simulation executable not found. Contact developer."}), 400 + + try: + data = request.get_json() + # if not data: + # return jsonify({"error": "Missing JSON parameters in request body."}), 400 + + # Parameters, use default values if not provided + algorithm = data.get("algorithm", "FirstFit") + networkType = data.get("networkType", 1) + goalConnections = data.get("goalConnections", 100000) + confidence = data.get("confidence", 0.05) + lambdaParam = data.get("lambdaParam", 1) + mu = data.get("mu", 10) + network = data.get("network", "NSFNet") + bitrate = data.get("bitrate", "fixed-rate") + K = data.get("K", 3) + + # Construct command for subprocess + command = [ + f"./{SIMULATION_EXECUTABLE}", + str(algorithm), + str(networkType), + str(goalConnections), + str(confidence), + str(lambdaParam), + str(mu), + str(network), + str(bitrate), + str(K) + ] + logger.debug(f"Running simulation with command: {' '.join(command)}") + + process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + output, error = process.communicate() + + # Error log for simulation failure + if process.returncode != 0: + logger.error(f"Simulation execution failed. Return code: {process.returncode}, Details: {error.strip()}") + return jsonify({"error": "Simulation execution failed", "details": error.strip()}), 500 + + # Return output in a structured JSON format + return jsonify({"output": output.strip(), "error": error.strip()}), 200 + + except Exception as e: + logger.exception("Unexpected error during run_simulation:") + return jsonify({"error": "An unexpected error occurred. Contact developer.", "details": str(e)}), 500 @app.route("/help", methods=["GET"]) def simulation_help(): - """Returns information about the /run_simulation endpoint, including request structure and parameter details.""" - schema = { - "endpoint": "/run_simulation", - "method": "POST", - "request_body_format": "application/json", - "description": "Runs a network simulation with provided parameters.", - "request_parameters": [ - { - "name": "algorithm", - "type": "string", - "description": "Routing and spectrum assignment algorithm to use.", - "allowed_values": ["FirstFit", "ExactFit"], - "default": "FirstFit", - "required": False - }, - { - "name": "networkType", - "type": "integer", - "description": "Type of optical network.", - "allowed_values": [1], - "value_meanings": {"1": "EON (Elastic Optical Network)"}, - "note": "Only EON (networkType: 1) is currently available in this playground. SDM (2) and BDM (3) are not yet implemented.", - "default": 1, - "required": False - }, - { - "name": "goal_connections", - "type": "integer", - "description": "Target number of connection requests for the simulation.", - "constraints": "Must be an integer greater than 0.", - "default": 100000, - "required": False - }, - { - "name": "confidence", - "type": "number (float)", - "description": "Confidence level for the simulation results.", - "constraints": "Must be a number greater than 0.", - "default": 0.05, - "required": False - }, - { - "name": "lambda_param", - "type": "number (float)", - "description": "Arrival rate (lambda) of connection requests.", - "constraints": "Must be a number greater than 0.", - "default": 1.0, - "required": False - }, - { - "name": "mu", - "type": "number (float)", - "description": "Service rate (mu) of connection requests.", - "constraints": "Must be a number greater than 0.", - "default": 10.0, - "required": False - }, - { - "name": "network", - "type": "string", - "description": "Network topology to simulate.", - "allowed_values": ["NSFNet", "Cost239", "EuroCore", "GermanNet", "UKNet"], - "default": "NSFNet", - "required": False - }, - { - "name": "bitrate", - "type": "string", - "description": "Type of bitrate allocation.", - "allowed_values": ["fixed-rate", "flex-rate"], - "default": "fixed-rate", - "required": False - }, - { - "name": "K", - "type": "integer", - "description": "Number of paths to considers.", - "default": 3, - "required": False - }, - ], - "response_body_format": "application/json", - "response_structure": { - "output": "string", - "error": "string (empty if no error)" - }, - "example_request": { - "algorithm": "FirstFit", - "networkType": 1, - "goal_connections": 10000, - "confidence": 0.05, - "lambda_param": 120, - "mu": 1, - "network": "NSFNet", - "bitrate": "flex-rate", - "K": 3 - }, - "example_response_success": { - "output": "Simulation output will be a string containing simulation results.", - "error": "" - }, - "example_response_error": { - "error": "Simulation execution failed", - "details": "Detailed error message from the simulation or backend." - } + """Returns human-readable API documentation in plain text format.""" + + help_message = """\ + API Endpoint: /run_simulation + Method: POST + Description: Runs a network simulation with provided parameters. + + Request Parameters (all optional, defaults shown): + - algorithm: string (default: "FirstFit") + - networkType: integer (default: 1) + - goalConnections: integer (default: 100000) + - confidence: float (default: 0.05) + - lambdaParam: float (default: 1.0) + - mu: float (default: 10.0) + - network: string (default: "NSFNet") + - bitrate: string (default: "fixed-rate") + - K: integer (default: 3) + + Example Request: + curl -X POST -H "Content-Type: application/json" \\ + -d '{ "algorithm": "FirstFit", + "networkType": 1, + "goalConnections": 1000000, + "confidence": 0.05, + "lambdaParam": 120, + "mu": 1, + "network": "NSFNet", + "bitrate": "fixed-rate" + }' \\ + https://fns-api-cloud-run-787143541358.us-central1.run.app/run_simulation + + Example Response (Success): + { + error: "", + output: ...output from simulation... } - return jsonify(schema), 200 + + Example Response (Failure): + + { + error: "Simulation execution failed...", + details: "Error details..." + } + """ + + return app.response_class( + response=help_message, + status=200, + mimetype="text/plain" + ) # --- Run Setup on Application Start --- -with app.app_context(): # Context needed to call route function outside request - compile_success = compile_simulation() # Call compile directly at startup +with app.app_context(): + compile_success = compile_simulation() # Call compile directly at startup if __name__ == "__main__": - if not compile_success: - print("Application start aborted due to compilation error. Please check /setup endpoint.") - else: - print("Starting Flask application...") - app.run(debug=True, host="0.0.0.0") # Enable debug for development \ No newline at end of file + if not compile_success: + print("Application start aborted due to compilation error. Contact developers!") + else: + print("Starting Flask application...") + app.run(host="0.0.0.0") \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 18ebecf..f163f4d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,2 @@ flask -flask-cors gunicorn \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 73a3c51..f237114 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -100,18 +100,32 @@ END_ALLOC_FUNCTION int main(int argc, char *argv[]) { - if (argc < 10) - { - std::cerr << "Uso: " << argv[0] << " " << std::endl; + if (argc < 10) { + std::cerr << "Uso: " << argv[0] << " " << std::endl; return 1; } int networkType = std::stoi(argv[2]); + if (networkType != 1) { + std::cerr << "At the moment only networkType 1 is supported" << std::endl; + return 1; + } + int goalConnections = std::stoi(argv[3]); + if (goalConnections > 10000000) { + std::cerr << "goalConnections must be less than 10,000,000" << std::endl; + return 1; + } + float confidence = std::stof(argv[4]); float lambda = std::stof(argv[5]); + float mu = std::stof(argv[6]); K = std::stoi(argv[9]); + if (K > 6) { + std::cerr << "Max K is 6" << std::endl; + return 1; + } std::string networkName = argv[7]; std::string bitrate = argv[8]; @@ -121,9 +135,6 @@ int main(int argc, char *argv[]) std::string("./bitrates/" + bitrate + ".json"), networkType); - // Print folders: - std::cout << "Network: " << networkName << std::endl; - char algoritmo = argv[1][0]; switch (algoritmo) {