diff --git a/Dockerfile b/Dockerfile index c21d1f7..4610384 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,9 @@ -FROM centos/python-36-centos7 +FROM python:3.6-slim + +RUN apt-get update && apt-get install -y ca-certificates \ + && update-ca-certificates \ + && python3 -m ensurepip --default-pip \ + && pip install --upgrade pip setuptools wheel COPY requirements.txt /tmp/requirements.txt RUN pip install -r /tmp/requirements.txt @@ -6,11 +11,7 @@ RUN pip install -r /tmp/requirements.txt WORKDIR /mediator COPY server /mediator -USER root - RUN useradd mediator && chown -R mediator /mediator - USER mediator -# CMD ["python", "Server.py"] -CMD ["gunicorn", "--timeout=180", "--workers=20", "--bind=0.0.0.0:8081", "--access-logfile=-", "Server:app"] +CMD ["gunicorn", "--timeout=180", "--workers=20", "--bind=0.0.0.0:8081", "--access-logfile=-", "Server:app"] \ No newline at end of file diff --git a/README.md b/README.md index 945b4f0..55d3312 100644 --- a/README.md +++ b/README.md @@ -1,72 +1,85 @@ # The CONTROL-CORE Mediator for Closed-Loop Neuromodulation Control Systems -The CONTROL-CORE Mediator is built with is Python-3.7. It is the core component that makes the distributed executions a reality in the CONTROL-CORE framework. The Mediator enables distributed execution of the CONTROL-CORE studies. As a containerized architecture, Mediator is easy to install, together with a Kong API Gateway-based authentication mechanism. The Mediator uses simple REST calls and file-sharing mechanisms for the distributed execution of the studies. +The CONTROL-CORE Mediator is built with Python-3.7. It is the core component that makes distributed executions a reality in the CONTROL-CORE framework. The Mediator enables distributed execution of the CONTROL-CORE studies. As a containerized architecture, Mediator is easy to install, together with a Kong API Gateway-based authentication mechanism. The Mediator uses simple REST calls and file-sharing mechanisms for the distributed execution of the studies. +--- - -# Building Mediator Container +## Building Mediator Container Log in to the server which you like to configure as the Mediator. -If it is a remote AWS server, use ssh as below, assuming x.x.x.x to be the IP address of your server. -```` +If it is a remote AWS server, use ssh as below, assuming `x.x.x.x` to be the IP address of your server. + +```bash $ ssh -i "controlcore.pem" ubuntu@x.x.x.x -```` -Perform Git clone if this is the first time you are configuring the Server -```` +``` + +Perform Git clone if this is the first time you are configuring the Server. + +```bash $ git clone git@github.com:ControlCore-Project/Mediator.git -```` +``` First, build the Docker Container of the Mediator. -```` + +```bash $ cd Mediator -```` +``` Get the latest version if the clone was old. -```` -$ git pull +```bash +$ git pull $ sudo docker build -t mediator . -```` +``` + +--- + +## Running CONTROL-CORE Mediator with Kong as Containers -# Running CONTROL-CORE Mediator with Kong as containers +If you are already running Mediator, make sure to stop and clear the existing Mediator container as it may conflict with the port. If there is a Kong gateway running in default ports, stop and clear it too. The same goes for the Kong Database. -If you are already running Mediator, make sure to stop and clear existing Mediator container as it is likely conflict with the port. If there is Kong gateway running in default ports, stop and clear it too. Same goes with Koing Database. -```` +```bash $ sudo docker stop mediator $ sudo docker rm mediator $ sudo docker stop kong $ sudo docker rm kong $ sudo docker stop kong-database $ sudo docker rm kong-database -```` +``` + +Start and configure PostgreSQL container for Kong API. -Start and configure Cassandra container for Kong API. -```` +```bash $ sudo docker run -d --name kong-database \ - -p 9042:9042 \ - cassandra:3 + -p 5432:5432 \ + -e POSTGRES_USER=kong \ + -e POSTGRES_PASSWORD=kong \ + -e POSTGRES_DB=kong \ + postgres:latest +``` -Wait a minute or two for Cassandra to start. +Wait a minute or two for PostgreSQL to start. +```bash $ sudo docker run --rm \ --link kong-database:kong-database \ - -e "KONG_DATABASE=cassandra" \ + -e "KONG_DATABASE=postgres" \ -e "KONG_PG_HOST=kong-database" \ -e "KONG_PG_USER=kong" \ -e "KONG_PG_PASSWORD=kong" \ - -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \ - kong kong migrations bootstrap -```` + kong/kong-gateway:latest kong migrations bootstrap +``` -Start Kong -```` +Start Kong. + +```bash $ sudo docker run -d --name kong \ --link kong-database:kong-database \ - -e "KONG_DATABASE=cassandra" \ + -e "KONG_DATABASE=postgres" \ -e "KONG_PG_HOST=kong-database" \ + -e "KONG_PG_USER=kong" \ -e "KONG_PG_PASSWORD=kong" \ - -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \ -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \ -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \ -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \ @@ -76,49 +89,59 @@ $ sudo docker run -d --name kong \ -p 8443:8443 \ -p 8001:8001 \ -p 8444:8444 \ - kong -```` + kong/kong-gateway:latest +``` + +Start Mediator container. -Start Mediator container -```` +```bash $ nohup sudo docker run --name mediator -p 8090:8081 mediator > controlcore.out & -```` +``` -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. -```` +Delete if there is a previously configured Kong service. If not, skip this step. First, find the ID-VALUE for the route with a GET command before deleting the route and service. + +```bash $ curl -X GET "http://localhost:8001/services/mediator/routes" -```` -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): -```` -$ curl -X DELETE "http://localhost:8001/services/mediator/routes/ID-VALUE" +``` + +Use the ID output from above to issue the delete command below (issue this only if you have a previous conflicting service definition in Kong. Otherwise, skip this step): +```bash +$ curl -X DELETE "http://localhost:8001/services/mediator/routes/ID-VALUE" $ curl -X DELETE "http://localhost:8001/services/mediator/" -```` +``` Define Kong Service and Route. -First, configure a Kong service, replacing the variable "private-ip" with the private IP address of your server below. -```` +First, configure a Kong service, replacing the variable `private-ip` with the private IP address of your server below. + +```bash $ curl -i -X POST --url http://localhost:8001/services/ --data 'name=mediator' --data 'url=http://private-ip:8090' -```` -Then configure the route to the service -```` +``` + +Then configure the route to the service. + +```bash $ curl -i -X POST --url http://localhost:8001/services/mediator/routes --data 'paths=/' -```` +``` -Now, controlcore.org is routed through the Kong APIs. +Now, `controlcore.org` is routed through the Kong APIs. -# Configuring Secondary Kong (Only if the API Key generation is handled publicly) -*This section assumes the API key generation is managed externally, exposing Kong's admin APIs securely to the public. Otherwise, the secondary Kong is not necessary and the API Keys can be configured directly, skipping this step, and adapting accordingly.* +--- -Start Secondary Kong that functions as an Admin Kong -``` +## Configuring Secondary Kong (Only if the API Key generation is handled publicly) + +*This section assumes the API key generation is managed externally, exposing Kong's admin APIs securely to the public. Otherwise, the secondary Kong is not necessary, and the API Keys can be configured directly, skipping this step, and adapting accordingly.* + +Start Secondary Kong that functions as an Admin Kong. + +```bash $ docker run -d --name kongadmin \ --link kong-database:kong-database \ - -e "KONG_DATABASE=cassandra" \ + -e "KONG_DATABASE=postgres" \ -e "KONG_PG_HOST=kong-database" \ + -e "KONG_PG_USER=kong" \ -e "KONG_PG_PASSWORD=kong" \ - -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \ -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \ -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \ -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \ @@ -128,112 +151,131 @@ $ docker run -d --name kongadmin \ -p 9443:8443 \ -p 9001:8001 \ -p 9444:8444 \ - kong -```` + kong/kong-gateway:latest +``` -Configure API definitions +Configure API definitions. -Run the service_config.sh script, after replacing the variable "private-ip" with the private IP address of your server. -```` +Run the `service_config.sh` script, after replacing the variable `private-ip` with the private IP address of your server. + +```bash $ bash service_config.sh -```` -Define the Consumer Creation API: +``` +Define the Consumer Creation API: -Step 1: Create a service for consumers, replacing the variable "private-ip" with the private IP address of your server below: +**Step 1:** Create a service for consumers, replacing the variable `private-ip` with the private IP address of your server below: -```` +```bash $ curl -i -X POST --url http://localhost:9001/services/ --data 'name=consumers' --data 'url=http://private-ip:8001/consumers' -```` +``` -Step 2: Create a route: +**Step 2:** Create a route: -```` +```bash $ curl -i -X POST --url http://localhost:9001/services/consumers/routes --data 'paths=/consumers' -```` +``` + +**Step 3:** Create a consumer "testuser" from O2S2Parc: -Step 3: Create a consumer "testuser" from O2S2Parc: +Using Python client: -Using Python client -```` +```bash $ pip3 install requests -```` +``` -Change the value of global variable "tenant" to your preferred string such as your OSPARC ID. +Change the value of the global variable `tenant` to your preferred string such as your OSPARC ID. -Then run the APIKeyGen.py, after replacing the value www.project-url.org with the actual URL of your project (i.e., the URL where Mediator is deployed). If the APIKeyGen.py is run locally, replace it with localhost instead. +Then run the `APIKeyGen.py`, after replacing the value `www.project-url.org` with the actual URL of your project (i.e., the URL where Mediator is deployed). If the `APIKeyGen.py` is run locally, replace it with `localhost` instead. Take note of the API Key output. -```` -python3 APIKeyGen.py -```` -Or using curl, assuming www.project-url.org to be the web URL where the Mediator is hosted. +```bash +$ python3 APIKeyGen.py +``` + +Or using curl, assuming `www.project-url.org` to be the web URL where the Mediator is hosted. -format: -```` +Format: + +```bash $ curl -d "username=SOME_ID&custom_id=SOME_CUSTOM_ID" www.project-url.org:8002/consumers/ -```` -sample: -```` +``` + +Sample: + +```bash $ curl -d "username=testuser&custom_id=testuser" www.project-url.org:8002/consumers/ -```` +``` -Step 4: Create a key: +**Step 4:** Create a key: -format: -```` +Format: + +```bash $ curl -X POST www.project-url.org:8002/consumers/{consumer}/key-auth -```` +``` -sample: -```` +Sample: + +```bash $ curl -X POST www.project-url.org:8002/consumers/testuser/key-auth -```` +``` -Step 5: Test with the newly created key. +**Step 5:** Test with the newly created key. +``` http://www.project-url.org/homepage?apikey=xxxxxxxxxx +``` + +--- +## Troubleshooting the Mediator -# Troubleshooting the Mediator +Connect to the Server VM. -Connect to the Server VM -```` +```bash $ ssh -i "controlcore.pem" ubuntu@x.x.x.x -```` +``` + Check the Server logs. -```` + +```bash $ tail -f controlcore.out -```` +``` + or -```` + +```bash $ sudo docker logs mediator -f -```` -Find the Mediator docker container -```` +``` + +Find the Mediator docker container. + +```bash $ sudo docker ps -```` -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -dfdd3b3d3308 mediator "python Server.py" 38 minutes ago Up 38 minutes 0.0.0.0:80->80/tcp mediator +``` -Access the container -```` -$ sudo docker exec -it dfdd /bin/bash -```` +Access the container. + +```bash +$ sudo docker exec -it /bin/bash +``` -# Start the containers if they are stopped on their own. +--- -```` +## Start the containers if they are stopped on their own. + +```bash $ sudo docker start kong-database -kong-database $ sudo docker start kong -kong $ sudo docker start mediator -mediator -```` -# Citing the CONTROL-CORE Mediator +``` + +--- + +## Citing the CONTROL-CORE Mediator If you use the CONTROL-CORE Mediator in your research, please cite the below paper: -* 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 +* 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 diff --git a/requirements.txt b/requirements.txt index 7dd84d5..d0e254d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -Flask==0.12.2 +Flask>=1.1.0 gunicorn==19.7.1 filelock \ No newline at end of file