From 690c0df9629a2d78407af086cff3d388990bff9e Mon Sep 17 00:00:00 2001
From: Nikolay Stanchev <ns17@it-innovation.soton.ac.uk>
Date: Thu, 28 Jun 2018 11:07:28 +0100
Subject: [PATCH] Documented the CRUD API for the serice function endpoint
 configuration data

---
 docs/clmc-service.md                       | 215 +++++++++++++++++++--
 src/service/clmcservice/whoamiapi/tests.py |   3 +-
 src/service/clmcservice/whoamiapi/views.py |   4 +-
 3 files changed, 206 insertions(+), 16 deletions(-)

diff --git a/docs/clmc-service.md b/docs/clmc-service.md
index c8ff020..6b767d9 100644
--- a/docs/clmc-service.md
+++ b/docs/clmc-service.md
@@ -32,10 +32,10 @@
 #### Description
 
 This document describes the CLMC service and its API endpoints. The CLMC service is implemented in the *Python* framework called **Pyramid**.
-It offers different API endpoints to configure and control the aggregator, which is an essential part in the process of measuring the end-to-end performance.
-All source code, tests and configuration files of the service can be found in the **src/clmc-webservice** folder.
+It offers different API endpoints to configure and control the aggregator as well as a CRUD API for service function endpoints configuration data.
+All source code, tests and configuration files of the service can be found in the **src/service** folder.
 
-#### API Endpoints
+#### Aggregator API Endpoints
 
 * **GET** ***/aggregator/config***
 
@@ -179,13 +179,202 @@ All source code, tests and configuration files of the service can be found in th
         * The functionality of a request with a **restart** action is the same as the functionlity of a **stop** action
         followed by a **start** action.
         
-#### Installing and running the CLMC service (development mode)
+#### CRUD API for service function endpoint configurations
+
+* **GET** ***/whoami/endpoints***
+
+    This API method retrieves all service function endpoint configurations in a JSON format.
+    
+    * Response:
+        
+        Returns a JSON-formatted response - a list of JSON objects, each object representing a service function endpoint configuration.
+        
+    * Response Body Example:
+
+        - No service function endpoint configurations found.
+        ```json
+        []
+        ```
+        
+        - Multiple service function endpoint configurations found.
+        ```json
+        [
+          {
+           "location": "location_1",
+           "sfc": "sfc_1",
+           "sfc_i": "sfc_i_1",
+           "sf": "sf_1",
+           "sf_i": "sf_i_1",
+           "sf_endpoint": "sf_endpoint_1",
+           "sr": "sr_1"
+            },
+          {
+           "location": "location_2",
+           "sfc": "sfc_2",
+           "sfc_i": "sfc_i_2",
+           "sf": "sf_2",
+           "sf_i": "sf_i_2",
+           "sf_endpoint": "sf_endpoint_2",
+           "sr": "sr_2"
+            }
+        ]
+        ```
+
+* **GET** ***/whoami/endpoints/instance?sr={sr_id}&sf_i={sf_instance_id}&sf_endpoint={sf_endpoint_id}***
+
+    This API method retrieves the uniquely defined service function endpoint configuration associated with the given URL parameters - sr, sf_i and sf_endpoint.
+    
+    * Response:
+        
+        Returns a JSON-formatted response - a JSON object representing the service function endpoint configuration if it exists.
+        
+        Returns an 404 Not Found error if there is no service function endpoint configuration associated with the given URL parameters.
+        
+        Returns a 400 Bad Request error if the url parameters are invalid.
+        
+    * Response Body Example:
+        
+        - Request made to /whoami/endpoints/instance?sr=sr_1&sf_i=sf_i_1&sf_endpoint=sf_endpoint_1
+        ```json
+        {
+          "location": "location_1",
+          "sfc": "sfc_1",
+          "sfc_i": "sfc_i_1",
+          "sf": "sf_1",
+          "sf_i": "sf_i_1",
+          "sf_endpoint": "sf_endpoint_1",
+          "sr": "sr_1"
+           }
+        ```
+
+* **POST** ***/whoami/endpoints***
+
+    This API method creates a new service function endpoint configuration.
+    
+    * Request:
+        
+        Expects a JSON-formatted request body with the new service function endpoint configuration.
+        
+    * Request Body Example: 
+
+    ```json
+        {
+          "location": "location_1",
+          "sfc": "sfc_1",
+          "sfc_i": "sfc_i_1",
+          "sf": "sf_1",
+          "sf_i": "sf_i_1",
+          "sf_endpoint": "sf_endpoint_1",
+          "sr": "sr_1"
+           }
+     ```
+
+    * Response
+        
+        Returns a JSON-formatted response - a JSON object representing the service function endpoint configuration that was created.
+        
+        Returns a 400 Bad Request error if the request body is invalid.
+        
+        Returns a 409 Conflict error if there exists another service function endpoint configuration with the same 'sr', 'sf_i' and 'sf_endpoint' values.
+        
+    * Response Body Example: 
+
+    ```json
+        {
+          "location": "location_1",
+          "sfc": "sfc_1",
+          "sfc_i": "sfc_i_1",
+          "sf": "sf_1",
+          "sf_i": "sf_i_1",
+          "sf_endpoint": "sf_endpoint_1",
+          "sr": "sr_1"
+           }
+     ```
+
+* **PUT** ***/whoami/endpoints/instance?sr={sr_id}&sf_i={sf_instance_id}&sf_endpoint={sf_endpoint_id}***
+
+    This API method replaces the uniquely defined service function endpoint configuration associated with the given URL parameters - sr, sf_i and sf_endpoint with a new service
+    function endpoint configuration given in the request body (JSON format). It can also be used for updating.
+    
+    * Request:
+        
+        Expects a JSON-formatted request body with the new service function endpoint configuration.
+        
+    * Request Body Example: 
+
+    ```json
+        {
+          "location": "location_2",
+          "sfc": "sfc_1",
+          "sfc_i": "sfc_i_1",
+          "sf": "sf_1",
+          "sf_i": "sf_i_1",
+          "sf_endpoint": "sf_endpoint_1",
+          "sr": "sr_1"
+           }
+     ```
+
+    * Response
+        
+        Returns a JSON-formatted response - a JSON object representing the new service function endpoint configuration that was created (updated).
+        
+        Returns a 400 Bad Request error if the request body is invalid.
+        
+        Returns a 400 Bad Request error if the url parameters are invalid.
+        
+        Returns an 404 Not Found error if there is no service function endpoint configuration associated with the given URL parameters.
+        
+        Returns a 409 Conflict error if there exists another service function endpoint configuration with the same 'sr', 'sf_i' and 'sf_endpoint' values as the ones in the request body.
+        
+    * Response Body Example: 
+
+        - Request made to /whoami/endpoints/instance?sr=sr_1&sf_i=sf_i_1&sf_endpoint=sf_endpoint_1
+        ```json
+            {
+              "location": "location_2",
+              "sfc": "sfc_1",
+              "sfc_i": "sfc_i_1",
+              "sf": "sf_1",
+              "sf_i": "sf_i_1",
+              "sf_endpoint": "sf_endpoint_1",
+              "sr": "sr_1"
+               }
+         ```
+
+* **DELETE** ***/whoami/endpoints/instance?sr={sr_id}&sf_i={sf_instance_id}&sf_endpoint={sf_endpoint_id}***
+
+    This API method deletes the uniquely defined service function endpoint configuration associated with the given URL parameters - sr, sf_i and sf_endpoint.
+    
+    * Response:
+        
+        Returns the JSON representation of the deleted object.
+        
+        Returns an 404 Not Found error if there is no service function endpoint configuration associated with the given URL parameters.
+        
+        Returns a 400 Bad Request error if the url parameters are invalid.
+        
+    * Response Body Example:
+    
+        - Request made to /whoami/endpoints/instance?sr=sr_1&sf_i=sf_i_1&sf_endpoint=sf_endpoint_1
+        ```json
+         {
+          "location": "location_1",
+          "sfc": "sfc_1",
+          "sfc_i": "sfc_i_1",
+          "sf": "sf_1",
+          "sf_i": "sf_i_1",
+          "sf_endpoint": "sf_endpoint_1",
+          "sr": "sr_1"
+           }
+        ```
+
+#### Installing and running the CLMC service
 
 Before installing the CLMC service and its dependencies, it is recommended to use a python virtual environment. To easily
 manage virtual environments, **virtualenvwrapper** can be used.
 
 ```
-pip install virtualenvwrapper
+pip3 install virtualenvwrapper
 ```
 
 To create a virtual environment use the **mkvirtualenv** command:
@@ -202,15 +391,15 @@ workon CLMC
 
 Now, any installed libraries will be installed relative to this environment only. 
 
-The easiest way to install and use the CLMC service locally is to use **pip**. Navigate to the clmc-webservice folder:
+The easiest way to install and use the CLMC service locally is to use **pip**. Navigate to the clmc-service folder:
 ```
-cd src/clmc-webservice
+cd src/service
 ```
 
 Test the CLMC service using **tox** along with the ***tox.ini*** configuration file. If tox is not installed run:
 
 ```
-pip install tox
+pip3 install tox
 ```
 
 After it is installed, simply use the **tox** command:
@@ -219,16 +408,16 @@ After it is installed, simply use the **tox** command:
 tox
 ```
 
-Then install the service in development mode.
+Then install the service.
 
 ```
-pip install -e .
+pip3 install .
 ```
 
-Finally, start the service on localhost by using pyramid's **pserve**:
+Finally, start the service on localhost by using pyramid's **pserve** command line utility:
 
 ```
-pserve development.ini --reload
+pserve production.ini
 ```
 
-You should now be able to make requests to the CLMC service on http://localhost:9080/aggregator/config and http://localhost:9080/aggregator/control.
+You should now be able to make requests to the CLMC service on the various API endpoints.
diff --git a/src/service/clmcservice/whoamiapi/tests.py b/src/service/clmcservice/whoamiapi/tests.py
index 4bf8960..e35b5b9 100644
--- a/src/service/clmcservice/whoamiapi/tests.py
+++ b/src/service/clmcservice/whoamiapi/tests.py
@@ -249,6 +249,7 @@ class TestWhoamiAPI(object):
         self._validation_of_url_parameters_test("delete")
 
         sf_e = ServiceFunctionEndpoint(location="DC1", sfc="sfc1", sfc_i="sfc_i1", sf="sf1", sf_i="sf_i1", sf_endpoint="sf_endpoint1", sr="sr1")
+        to_delete = sf_e.json
         ServiceFunctionEndpoint.add(sf_e)  # adds the new instance of the model to the database
 
         assert ServiceFunctionEndpoint.exists("sf_i1", "sf_endpoint1", "sr1")
@@ -258,7 +259,7 @@ class TestWhoamiAPI(object):
         request.params["sf_i"] = "sf_i1"
         request.params["sr"] = "sr1"
         response = WhoamiAPI(request).delete()
-        assert response == {}, "DELETE must return an empty body if successful"
+        assert response == to_delete, "DELETE must return an empty body if successful"
 
         assert not ServiceFunctionEndpoint.exists("sf_i1", "sf_endpoint1", "sr1"), "Resource must be deleted after the delete API method has been called."
 
diff --git a/src/service/clmcservice/whoamiapi/views.py b/src/service/clmcservice/whoamiapi/views.py
index 6ac5c15..d4e6501 100644
--- a/src/service/clmcservice/whoamiapi/views.py
+++ b/src/service/clmcservice/whoamiapi/views.py
@@ -140,9 +140,9 @@ class WhoamiAPI(object):
         if sf_endpoint is None:
             raise HTTPNotFound("A service function endpoint with the given parameters doesn't exist.")
         else:
+            deleted = sf_endpoint.json
             ServiceFunctionEndpoint.delete(sf_endpoint)
-            self.request.response.status = 204
-            return {}
+            return deleted
 
     def _get_sf_endpoint_from_url_string(self):
         """
-- 
GitLab