Skip to content

Commit cb4e75e

Browse files
Mirko ZitkovichMirko Zitkovich
authored andcommitted
feat: Enhance FlexNetSim API with new features and docs
- Added networks: Cost239, EuroCore, GermanNet, UKNet. - Implemented K routes parameter (default 3, max 6). - Added ExactFit algorithm. - Created /help endpoint for API documentation. - Updated README.md with /help endpoint and parameter details. - Renamed 'bitrate' to "fixed-grid", added 'flex-rate' option.
1 parent 0c0a1b0 commit cb4e75e

File tree

16 files changed

+53521
-2162
lines changed

16 files changed

+53521
-2162
lines changed

.github/workflows/gke-cd.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ name: Deploy FNS API to Cloud Run (Separated Jobs)
33
on:
44
push:
55
branches:
6-
- feature/*
6+
- master
77
pull_request:
88
branches:
9-
- feature/*
9+
- master
1010

1111
jobs:
1212
build-and-push-image:

README.md

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
# Flex Net Sim Backend API
22

3-
Flask-based backend API for integrating the FlexNetSim C++ library, powering the web application deployed at [www.in-progress.com](www.in-progress.com). While unofficial, it serves as a bridge between the simulation engine and the web interface.
3+
Flask-based backend API for integrating the FlexNetSim C++ library, powering the web application.
44

55
## Prerequisites
66

77
* Python 3.9 or higher
88
* g++ (GNU C++ Compiler)
99
* Docker (for containerization)
10-
* Google Cloud SDK (for deployment to GKE) -> In progress.
11-
* A Google Cloud Project with Google Kubernetes Engine (GKE) and Google Container Registry (GCR) enabled -> In progress.
10+
* Google Cloud SDK (for deployment to Cloud Run)
11+
* A Google Cloud Project with Cloud Run API enabled.
1212

1313
## Getting Started (Local Development)
1414

1515
1. **Clone the repository:**
1616
```bash
17-
git clone [repository-url]
17+
git clone <repository-url> # Replace <repository-url> with your repository URL
1818
cd flask-simulation-backend
1919
```
2020

@@ -36,14 +36,34 @@ Flask-based backend API for integrating the FlexNetSim C++ library, powering the
3636
```
3737
The backend will be accessible at `http://127.0.0.1:5000`.
3838

39-
5. **Send simulation requests using `curl` or a frontend application:**
40-
Example `curl` request with minimal parameters (defaults applied):
41-
```bash
42-
curl -X POST -H "Content-Type: application/json" -d '{"algorithm": "FirstFit", "networkType": 1, "bitrate": "bitrate"}' [http://127.0.0.1:5000/run_simulation](http://127.0.0.1:5000/run_simulation)
43-
```
39+
## API Endpoints
4440

45-
Example `curl` request with all parameters specified
46-
```bash
41+
### `/run_simulation` (POST)
42+
43+
This endpoint runs a FlexNetSim simulation based on the parameters provided in the JSON request body.
44+
45+
**Request Body Parameters:**
46+
47+
| Parameter | Type | Description | Allowed Values | Default Value | Constraints |
48+
| :---------------- | :--------------- | :----------------------------------------------------------------------------- | :---------------------------- | :------------ | :-------------------- |
49+
| `algorithm` | `string` | Routing and spectrum assignment algorithm to use. | `FirstFit`, `ExactFit` | `FirstFit` | |
50+
| `networkType` | `integer` | Type of optical network. | `1` | `1` | Only `1` (EON) available |
51+
| `goal_connections`| `integer` | Target number of connection requests for the simulation. | | `100000` | Must be integer > 0 |
52+
| `confidence` | `number (float)` | Confidence level for the simulation results. | | `0.05` | Must be > 0 |
53+
| `lambda_param` | `number (float)` | Arrival rate (lambda) of connection requests. | | `1.0` | Must be > 0 |
54+
| `mu` | `number (float)` | Service rate (mu) of connection requests. | | `10.0` | Must be > 0 |
55+
| `network` | `string` | Network topology to simulate. | `NSFNet`, `Cost239`, `EuroCore`, `GermanNet`, `UKNet` | `NSFNet` | |
56+
| `bitrate` | `string` | Type of bitrate allocation. | `fixed-rate`, `flex-rate` | `bitrate` | |
57+
| `K` | `integer` | Number of paths to compute. | | `3` | |
58+
59+
**Example `curl` request with minimal parameters (defaults applied):**
60+
61+
```bash
62+
curl -X POST -H "Content-Type: application/json" -d '{"algorithm": "FirstFit", "networkType": 1, "bitrate": "bitrate"}' http://127.0.0.1:5000/run_simulation
63+
```
64+
65+
**Example `curl`request with all parameters specified:**
66+
```bash
4767
curl -X POST -H "Content-Type: application/json" \
4868
-d '{
4969
"algorithm": "FirstFit",
@@ -56,7 +76,27 @@ Flask-based backend API for integrating the FlexNetSim C++ library, powering the
5676
"bitrate": "bitrate" -> (filename in the ./bitrates folder)
5777
}' \
5878
http://127.0.0.1:5000/run_simulation
79+
```
80+
81+
**Response**:
82+
- 200 OK: Simulation executed successfully. The response body will be a JSON object with the following structure:
83+
```JSON
84+
{
85+
"output": "string", // Simulation output results
86+
"error": "string" // Empty string if no errors
87+
}
5988
```
89+
- 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.
90+
- 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.
91+
92+
### `/help` (GET)
93+
94+
This endpoint provides detailed information about the `/run_simulation` endpoint, including the expected request structure, parameters, allowed values, and response formats.
95+
96+
**Request**:
97+
```bash
98+
curl http://127.0.0.1:5000/help
99+
```
60100
61101
## Dockerization
62102

backend.py

Lines changed: 114 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ def run_simulation():
6262
lambda_param = data.get("lambda", 1)
6363
mu = data.get("mu", 10)
6464
network = data.get("network", "NSFNet")
65-
bitrate = data.get("bitrate", "bitrate")
65+
bitrate = data.get("bitrate", "fixed-rate")
66+
K = data.get("K", 3)
6667

6768
# Construct command for subprocess
6869
command = [
@@ -74,7 +75,8 @@ def run_simulation():
7475
str(lambda_param),
7576
str(mu),
7677
str(network),
77-
str(bitrate)
78+
str(bitrate),
79+
str(K)
7880
]
7981
logger.debug(f"Running simulation with command: {' '.join(command)}") # Debug log for command
8082

@@ -92,6 +94,116 @@ def run_simulation():
9294
logger.exception("Unexpected error during run_simulation:")
9395
return jsonify({"error": "An unexpected error occurred. Contact developer.", "details": str(e)}), 500
9496

97+
@app.route("/help", methods=["GET"])
98+
def simulation_help():
99+
"""Returns information about the /run_simulation endpoint, including request structure and parameter details."""
100+
schema = {
101+
"endpoint": "/run_simulation",
102+
"method": "POST",
103+
"request_body_format": "application/json",
104+
"description": "Runs a network simulation with provided parameters.",
105+
"request_parameters": [
106+
{
107+
"name": "algorithm",
108+
"type": "string",
109+
"description": "Routing and spectrum assignment algorithm to use.",
110+
"allowed_values": ["FirstFit", "ExactFit"],
111+
"default": "FirstFit",
112+
"required": False
113+
},
114+
{
115+
"name": "networkType",
116+
"type": "integer",
117+
"description": "Type of optical network.",
118+
"allowed_values": [1],
119+
"value_meanings": {"1": "EON (Elastic Optical Network)"},
120+
"note": "Only EON (networkType: 1) is currently available in this playground. SDM (2) and BDM (3) are not yet implemented.",
121+
"default": 1,
122+
"required": False
123+
},
124+
{
125+
"name": "goal_connections",
126+
"type": "integer",
127+
"description": "Target number of connection requests for the simulation.",
128+
"constraints": "Must be an integer greater than 0.",
129+
"default": 100000,
130+
"required": False
131+
},
132+
{
133+
"name": "confidence",
134+
"type": "number (float)",
135+
"description": "Confidence level for the simulation results.",
136+
"constraints": "Must be a number greater than 0.",
137+
"default": 0.05,
138+
"required": False
139+
},
140+
{
141+
"name": "lambda_param",
142+
"type": "number (float)",
143+
"description": "Arrival rate (lambda) of connection requests.",
144+
"constraints": "Must be a number greater than 0.",
145+
"default": 1.0,
146+
"required": False
147+
},
148+
{
149+
"name": "mu",
150+
"type": "number (float)",
151+
"description": "Service rate (mu) of connection requests.",
152+
"constraints": "Must be a number greater than 0.",
153+
"default": 10.0,
154+
"required": False
155+
},
156+
{
157+
"name": "network",
158+
"type": "string",
159+
"description": "Network topology to simulate.",
160+
"allowed_values": ["NSFNet", "Cost239", "EuroCore", "GermanNet", "UKNet"],
161+
"default": "NSFNet",
162+
"required": False
163+
},
164+
{
165+
"name": "bitrate",
166+
"type": "string",
167+
"description": "Type of bitrate allocation.",
168+
"allowed_values": ["fixed-rate", "flex-rate"],
169+
"default": "fixed-rate",
170+
"required": False
171+
},
172+
{
173+
"name": "K",
174+
"type": "integer",
175+
"description": "Number of paths to considers.",
176+
"default": 3,
177+
"required": False
178+
},
179+
],
180+
"response_body_format": "application/json",
181+
"response_structure": {
182+
"output": "string",
183+
"error": "string (empty if no error)"
184+
},
185+
"example_request": {
186+
"algorithm": "FirstFit",
187+
"networkType": 1,
188+
"goal_connections": 10000,
189+
"confidence": 0.05,
190+
"lambda_param": 120,
191+
"mu": 1,
192+
"network": "NSFNet",
193+
"bitrate": "flex-rate",
194+
"K": 3
195+
},
196+
"example_response_success": {
197+
"output": "Simulation output will be a string containing simulation results.",
198+
"error": ""
199+
},
200+
"example_response_error": {
201+
"error": "Simulation execution failed",
202+
"details": "Detailed error message from the simulation or backend."
203+
}
204+
}
205+
return jsonify(schema), 200
206+
95207
# --- Run Setup on Application Start ---
96208
with app.app_context(): # Context needed to call route function outside request
97209
compile_success = compile_simulation() # Call compile directly at startup
File renamed without changes.

bitrates/flex-rate.json

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
{
2+
"10": [
3+
{
4+
"16QAM": {
5+
"slots": 1,
6+
"reach": 560
7+
},
8+
9+
"8QAM": {
10+
"slots": 1,
11+
"reach": 1360
12+
},
13+
14+
"QPSK": {
15+
"slots": 1,
16+
"reach": 2720
17+
},
18+
19+
"BPSK": {
20+
"slots": 1,
21+
"reach": 5520
22+
}
23+
}
24+
],
25+
"40": [
26+
{
27+
"16QAM": {
28+
"slots": 1,
29+
"reach": 560
30+
},
31+
32+
"8QAM": {
33+
"slots": 2,
34+
"reach": 1360
35+
},
36+
37+
"QPSK": {
38+
"slots": 2,
39+
"reach": 2720
40+
},
41+
42+
"BPSK": {
43+
"slots": 4,
44+
"reach": 5520
45+
}
46+
}
47+
],
48+
"100": [
49+
{
50+
"16QAM": {
51+
"slots": 2,
52+
"reach": 560
53+
},
54+
55+
"8QAM": {
56+
"slots": 3,
57+
"reach": 1360
58+
},
59+
60+
"QPSK": {
61+
"slots": 4,
62+
"reach": 2720
63+
},
64+
65+
"BPSK": {
66+
"slots": 8,
67+
"reach": 5520
68+
}
69+
}
70+
],
71+
"400": [
72+
{
73+
"16QAM": {
74+
"slots": 8,
75+
"reach": 560
76+
},
77+
78+
"8QAM": {
79+
"slots": 11,
80+
"reach": 1360
81+
},
82+
83+
"QPSK": {
84+
"slots": 16,
85+
"reach": 2720
86+
},
87+
88+
"BPSK": {
89+
"slots": 32,
90+
"reach": 5520
91+
}
92+
}
93+
],
94+
"1000": [
95+
{
96+
"16QAM": {
97+
"slots": 20,
98+
"reach": 560
99+
},
100+
101+
"8QAM": {
102+
"slots": 27,
103+
"reach": 1360
104+
},
105+
106+
"QPSK": {
107+
"slots": 40,
108+
"reach": 2720
109+
},
110+
111+
"BPSK": {
112+
"slots": 80,
113+
"reach": 5520
114+
}
115+
}
116+
]
117+
}

0 commit comments

Comments
 (0)