Skip to content

Commit 4a20177

Browse files
authored
Merge pull request #3 from amit-62/dev
FRI Updated
2 parents 9f8ec59 + 9c8e23a commit 4a20177

7 files changed

Lines changed: 232 additions & 0 deletions

File tree

fri/Dockerfile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM centos/python-36-centos7
2+
COPY requirements.txt /tmp/requirements.txt
3+
RUN pip install -r /tmp/requirements.txt
4+
WORKDIR /fri
5+
COPY server /fri
6+
USER root
7+
RUN useradd fri && chown -R fri /fri
8+
USER fri
9+
CMD ["gunicorn", "--timeout=180", "--workers=4", "--bind=0.0.0.0:8080", "--access-logfile=-", "main:app"]

fri/README.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# The Control-Core FRI for Closed-Loop Neuromodulation Control Systems
2+
3+
The Control-Core File Receiving Interface (FRI) is built with is Python-3.10. It is the core component that makes the distributed executions a reality in the Control-Core framework.
4+
5+
6+
# Building FRI Container
7+
8+
Connect to the Server VM, assuming x.x.x.x to be the IP address of your server.
9+
````
10+
$ ssh -i "controlcore.pem" ubuntu@x.x.x.x
11+
````
12+
Perform Git clone if this is the first time you are configuring the Server
13+
````
14+
$ git clone git@github.com/ControlCore-Project/concore.git
15+
````
16+
17+
First build the Docker Container of the FRI.
18+
````
19+
$ git pull
20+
21+
$ sudo docker build -t fri .
22+
````
23+
24+
# Running Control-Core FRI with Kong as containers
25+
26+
If you are already running FRI, make sure to stop and clear existing FRI container as it is likely conflict with the port. If there is Kong gateway running in default ports, stop and clear it too.
27+
````
28+
$ docker stop fri
29+
$ docker rm fri
30+
$ docker stop kong
31+
$ docker rm kong
32+
````
33+
34+
Start and configure Cassandra container for Kong API.
35+
````
36+
$ docker run -d --name kong-database \
37+
-p 9042:9042 \
38+
cassandra:3
39+
40+
41+
$ docker run --rm \
42+
--link kong-database:kong-database \
43+
-e "KONG_DATABASE=cassandra" \
44+
-e "KONG_PG_HOST=kong-database" \
45+
-e "KONG_PG_USER=kong" \
46+
-e "KONG_PG_PASSWORD=kong" \
47+
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
48+
kong kong migrations bootstrap
49+
````
50+
51+
Start Kong
52+
````
53+
$ docker run -d --name kong \
54+
--link kong-database:kong-database \
55+
-e "KONG_DATABASE=cassandra" \
56+
-e "KONG_PG_HOST=kong-database" \
57+
-e "KONG_PG_PASSWORD=kong" \
58+
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
59+
-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
60+
-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
61+
-e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
62+
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
63+
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \
64+
-p 80:8000 \
65+
-p 8443:8443 \
66+
-p 8001:8001 \
67+
-p 8444:8444 \
68+
kong
69+
````
70+
71+
Start FRI container
72+
````
73+
$ nohup sudo docker run --name fri -p 8090:8081 fri > controlcore.out &
74+
````
75+
76+
Delete if there is a previously configured Kong service. If not, skip this step. First you need to find the ID-VALUE for the route with a GET command before deleting the route and service.
77+
````
78+
$ curl -X GET "http://localhost:8001/services/fri/routes"
79+
````
80+
Use the ID output from above to issue the delete command as below (issue this only if you have a previous conflicting service definiton in kong. Otherwise, skip this step):
81+
````
82+
$ curl -X DELETE "http://localhost:8001/services/fri/routes/ID-VALUE"
83+
84+
$ curl -X DELETE "http://localhost:8001/services/fri/"
85+
````
86+
87+
Define Kong Service and Route.
88+
89+
First Configure a Kong service, replacing the variable "private-ip" with the private IP address of your server below.
90+
````
91+
$ curl -i -X POST --url http://localhost:8001/services/ --data 'name=fri' --data 'url=http://private-ip:8090'
92+
````
93+
Then configure route to the service
94+
````
95+
$ curl -i -X POST --url http://localhost:8001/services/fri/routes --data 'paths=/'
96+
````
97+
98+
Now, controlcore.org is routed through the Kong APIs.
99+
100+
101+
# Troubleshooting the FRI
102+
103+
Connect to the Server VM
104+
````
105+
$ ssh -i "controlcore.pem" ubuntu@x.x.x.x
106+
````
107+
Check the Server logs.
108+
````
109+
$ tail -f controlcore.out
110+
````
111+
or
112+
````
113+
$ sudo docker logs fri -f
114+
````
115+
Find the FRI docker container
116+
````
117+
$ sudo docker ps
118+
````
119+
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
120+
dfdd3b3d3308 fri "python main.py" 38 minutes ago Up 38 minutes 0.0.0.0:80->80/tcp fri
121+
122+
Access the container
123+
````
124+
$ sudo docker exec -it dfdd /bin/bash
125+
````
126+
127+
128+
129+
# Citing the CONTROL-CORE FRI
130+
131+
If you use the CONTROL-CORE FRI in your research, please cite the below paper:
132+
133+
* Kathiravelu, P., Arnold, M., Fleischer, J., Yao, Y., Awasthi, S., Goel, A. K., Branen, A., Sarikhani, P., Kumar, G., Kothare, M. V., and Mahmoudi, B. **CONTROL-CORE: A Framework for Simulation and Design of Closed-Loop Peripheral Neuromodulation Control Systems**. In IEEE Access. March 2022. https://doi.org/10.1109/ACCESS.2022.3161471

fri/example.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
print("amit")

fri/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Flask
2+
gunicorn==20.1.0

fri/server/main.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from flask import Flask, request, jsonify, render_template
2+
from werkzeug.utils import secure_filename
3+
import os
4+
5+
6+
UPLOAD_FOLDER = "./uploaded_files"
7+
8+
if not os.path.exists(UPLOAD_FOLDER):
9+
os.makedirs(UPLOAD_FOLDER)
10+
11+
app = Flask(__name__)
12+
app.secret_key = "secret key"
13+
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
14+
15+
16+
@app.route('/multiple-files-upload', methods=['POST'])
17+
def upload_file():
18+
if 'files[]' not in request.files:
19+
resp = jsonify({'message' : 'No file in the request'})
20+
resp.status_code = 400
21+
return resp
22+
23+
files = request.files.getlist('files[]')
24+
25+
errors = {}
26+
success = False
27+
28+
for file in files:
29+
if file:
30+
filename = secure_filename(file.filename)
31+
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
32+
success = True
33+
34+
if success and errors:
35+
errors['message'] = 'File(s) successfully uploaded'
36+
resp = jsonify(errors)
37+
resp.status_code = 500
38+
return resp
39+
if success:
40+
resp = jsonify({'message' : 'Files successfully uploaded'})
41+
resp.status_code = 201
42+
return resp
43+
else:
44+
resp = jsonify(errors)
45+
resp.status_code = 500
46+
return resp
47+
48+
if __name__ == "__main__":
49+
app.run(host="0.0.0.0")

fri/service_config.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/bin/bash
2+
3+
SERVICES=('upload_file' 'execute')
4+
for service in "${SERVICES[@]}"
5+
do
6+
name="name="$service
7+
path="paths=/"$service
8+
service_path="url=http://private-ip:8090/"$service
9+
route_path="http://localhost:8001/services/"$service"/routes"
10+
plugin_path="http://localhost:8001/services/"$service"/plugins"
11+
echo "Name is, $name"
12+
echo "Path is, $path"
13+
echo "Service path is, $service_path"
14+
echo "Route path is, $route_path"
15+
echo "Plugin path is, $plugin_path"
16+
echo "Creating Service, $service..."
17+
curl -i -X POST --url http://localhost:8001/services/ --data $name --data $service_path
18+
echo "Creating route for $service..."
19+
curl -i -X POST --url $route_path --data $path
20+
echo "Creating apikey-based authentication for $service..."
21+
curl -X POST $plugin_path --data "name=key-auth" --data "config.key_names=apikey"
22+
done

fri/test.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import requests
2+
import os
3+
4+
url = "http://127.0.0.1:5000/multiple-files-upload"
5+
6+
path = os.path.abspath("example.py")
7+
8+
payload={}
9+
files=[
10+
('files[]',('example.py',open( path,'rb'),'application/octet-stream'))
11+
]
12+
headers = {}
13+
14+
response = requests.request("POST", url, headers=headers, data=payload, files=files)
15+
16+
print(response.text)

0 commit comments

Comments
 (0)