Skip to content
Snippets Groups Projects
Commit 1a4c69c3 authored by Nikolay Stanchev's avatar Nikolay Stanchev
Browse files

Updates initial version of config API

parent 6793cc30
No related branches found
No related tags found
No related merge requests found
...@@ -57,7 +57,7 @@ class TestSFCConfigAPI(object): ...@@ -57,7 +57,7 @@ class TestSFCConfigAPI(object):
response = SFCConfigAPI(request).get_all() response = SFCConfigAPI(request).get_all()
assert response == [], "Initially there mustn't be any service function chains in the database." assert response == [], "Initially there mustn't be any service function chains in the database."
sfc = ServiceFunctionChain(sfc="sfc1", sfc_i="sfc_i1", chain={"nginx": ["minio"]}) sfc = ServiceFunctionChain(sfc="sfc1", chain={"nginx": ["minio"]})
expected_response_data = [sfc.json] expected_response_data = [sfc.json]
ServiceFunctionChain.add(sfc) # adds the new instance of the model to the database ServiceFunctionChain.add(sfc) # adds the new instance of the model to the database
...@@ -65,10 +65,10 @@ class TestSFCConfigAPI(object): ...@@ -65,10 +65,10 @@ class TestSFCConfigAPI(object):
response = SFCConfigAPI(request).get_all() response = SFCConfigAPI(request).get_all()
assert response == expected_response_data, "Incorrect response data with 1 service function chain." assert response == expected_response_data, "Incorrect response data with 1 service function chain."
sfc = ServiceFunctionChain(sfc="sfc2", sfc_i="sfc_i1", chain={"nginx": ["minio"]}) sfc = ServiceFunctionChain(sfc="sfc2", chain={"nginx": ["minio"]})
expected_response_data.append(sfc.json) expected_response_data.append(sfc.json)
ServiceFunctionChain.add(sfc) ServiceFunctionChain.add(sfc)
sfc = ServiceFunctionChain(sfc="sfc2", sfc_i="sfc_i2", chain={"nginx": ["minio"]}) sfc = ServiceFunctionChain(sfc="sfc3", chain={"nginx": ["minio"]})
expected_response_data.append(sfc.json) expected_response_data.append(sfc.json)
ServiceFunctionChain.add(sfc) ServiceFunctionChain.add(sfc)
...@@ -78,7 +78,7 @@ class TestSFCConfigAPI(object): ...@@ -78,7 +78,7 @@ class TestSFCConfigAPI(object):
def test_get_one(self): def test_get_one(self):
""" """
Tests the GET one method of the config API for service function chains - returns an instance of a service function chain from the database. Tests the GET one method of the config API for service function chains - returns a service function chain from the database.
""" """
request = testing.DummyRequest() request = testing.DummyRequest()
...@@ -87,19 +87,17 @@ class TestSFCConfigAPI(object): ...@@ -87,19 +87,17 @@ class TestSFCConfigAPI(object):
self._validation_of_url_parameters_test("get_one") self._validation_of_url_parameters_test("get_one")
sfc = ServiceFunctionChain(sfc="sfc1", sfc_i="sfc_i1", chain={"nginx": ["minio"]}) sfc = ServiceFunctionChain(sfc="sfc1", chain={"nginx": ["minio"]})
expected_response_data = sfc.json expected_response_data = sfc.json
ServiceFunctionChain.add(sfc) # adds the new instance of the model to the database ServiceFunctionChain.add(sfc) # adds the new instance of the model to the database
request = testing.DummyRequest() request = testing.DummyRequest()
request.params["sfc"] = "sfc1" request.params["sfc"] = "sfc1"
request.params["sfc_i"] = "sfc_i1"
response = SFCConfigAPI(request).get_one() response = SFCConfigAPI(request).get_one()
assert response == expected_response_data, "Invalid data returned in the response of GET instance" assert response == expected_response_data, "Invalid data returned in the response of GET instance"
request = testing.DummyRequest() request = testing.DummyRequest()
request.params["sfc"] = "sfc2" request.params["sfc"] = "sfc2"
request.params["sfc_i"] = "sfc_i2"
error_raised = False error_raised = False
try: try:
SFCConfigAPI(request).get_one() SFCConfigAPI(request).get_one()
...@@ -109,20 +107,20 @@ class TestSFCConfigAPI(object): ...@@ -109,20 +107,20 @@ class TestSFCConfigAPI(object):
def test_post(self): def test_post(self):
""" """
Tests the POST method of the config API for service function chains - creates an instance of a service function chain in the database. Tests the POST method of the config API for service function chains - creates a service function chain in the database.
""" """
request = testing.DummyRequest() request = testing.DummyRequest()
response = SFCConfigAPI(request).get_all() response = SFCConfigAPI(request).get_all()
assert response == [], "Initially there mustn't be any service function chains in the database." assert response == [], "Initially there mustn't be any service function chains in the database."
resource = dict(sfc="sfc1", sfc_i="sfc_i1", chain={"nginx": ["minio"]}) resource = dict(sfc="sfc1", chain={"nginx": ["minio"]})
json_data = dumps(resource) json_data = dumps(resource)
request = testing.DummyRequest() request = testing.DummyRequest()
request.body = json_data.encode(request.charset) request.body = json_data.encode(request.charset)
response = SFCConfigAPI(request).post() response = SFCConfigAPI(request).post()
assert response == resource, "POST request must return the created resource" assert response == resource, "POST request must return the created resource"
assert ServiceFunctionChain.exists("sfc1", "sfc_i1"), "POST request must have created the resource" assert ServiceFunctionChain.exists("sfc1"), "POST request must have created the resource"
resource["chain"] = {} resource["chain"] = {}
json_data = dumps(resource) json_data = dumps(resource)
...@@ -136,11 +134,11 @@ class TestSFCConfigAPI(object): ...@@ -136,11 +134,11 @@ class TestSFCConfigAPI(object):
assert error_raised, "An error must be raised when trying to create a resource which breaks the unique constraint" assert error_raised, "An error must be raised when trying to create a resource which breaks the unique constraint"
@pytest.mark.parametrize("body, valid", [ @pytest.mark.parametrize("body, valid", [
('{"sfc": "sfc1", "sfc_i": "sfc_i1", "chain":{"nginx":["minio"]}}', True), ('{"sfc": "sfc1", "chain":{"nginx":["minio"]}}', True),
('{"sfc": "sfc2", "sfc_i": "sfc_i2", "chain":{}}', True), ('{"sfc": "sfc2", "chain":{}}', True),
('{"sfc": "sfc1", "sfc_i": "sfc_i1", "chain":[]}', False), ('{"sfc": "sfc1", "chain":[]}', False),
('{}', False), ('{}', False),
('{"sfc": "sfc3", "sfc_i": "sfc_i3"', False), ('{"sfc": "sfc3"}', False),
('{"sf": "sfc2", "sf_i": "sfc_i2", "chain":{}', False), ('{"sf": "sfc2", "sf_i": "sfc_i2", "chain":{}', False),
('{invalid json}', False), ('{invalid json}', False),
]) ])
...@@ -163,7 +161,7 @@ class TestSFCConfigAPI(object): ...@@ -163,7 +161,7 @@ class TestSFCConfigAPI(object):
def test_put(self): def test_put(self):
""" """
Tests the PUT method of the Config API for service function chains - overwrites an instance of a service function chain from the database. Tests the PUT method of the Config API for service function chains - overwrites a service function chain from the database.
""" """
request = testing.DummyRequest() request = testing.DummyRequest()
...@@ -172,11 +170,10 @@ class TestSFCConfigAPI(object): ...@@ -172,11 +170,10 @@ class TestSFCConfigAPI(object):
self._validation_of_url_parameters_test("put") self._validation_of_url_parameters_test("put")
resource = dict(sfc="sfc1", sfc_i="sfc_i1", chain={"nginx": ["minio"]}) resource = dict(sfc="sfc1", chain={"nginx": ["minio"]})
body = dumps(resource) body = dumps(resource)
request = testing.DummyRequest() request = testing.DummyRequest()
request.params["sfc"] = "sfc1" request.params["sfc"] = "sfc1"
request.params["sfc_i"] = "sfc_i1"
request.body = body.encode(request.charset) request.body = body.encode(request.charset)
error_raised = False error_raised = False
try: try:
...@@ -185,38 +182,35 @@ class TestSFCConfigAPI(object): ...@@ -185,38 +182,35 @@ class TestSFCConfigAPI(object):
error_raised = True error_raised = True
assert error_raised, "Not found error must be raised in case of a non existing service function chain" assert error_raised, "Not found error must be raised in case of a non existing service function chain"
sfc = ServiceFunctionChain(sfc="sfc1", sfc_i="sfc_i1", chain={"nginx": ["minio"]}) sfc = ServiceFunctionChain(sfc="sfc1", chain={"nginx": ["minio"]})
ServiceFunctionChain.add(sfc) # adds the new instance of the model to the database ServiceFunctionChain.add(sfc) # adds the new instance of the model to the database
resource = dict(sfc="sfc1", sfc_i="sfc_i1", chain={}) resource = dict(sfc="sfc1", chain={})
body = dumps(resource) body = dumps(resource)
request = testing.DummyRequest() request = testing.DummyRequest()
request.params["sfc"] = "sfc1" request.params["sfc"] = "sfc1"
request.params["sfc_i"] = "sfc_i1"
request.body = body.encode(request.charset) request.body = body.encode(request.charset)
response = SFCConfigAPI(request).put() response = SFCConfigAPI(request).put()
assert response == resource, "PUT request must return the updated resource" assert response == resource, "PUT request must return the updated resource"
assert ServiceFunctionChain.get("sfc1", "sfc_i1").json["chain"] == {} assert ServiceFunctionChain.get("sfc1").json["chain"] == {}
resource = dict(sfc="sfc2", sfc_i="sfc_i2", chain={"nginx": ["minio"]}) resource = dict(sfc="sfc2", chain={"nginx": ["minio"]})
body = dumps(resource) body = dumps(resource)
request = testing.DummyRequest() request = testing.DummyRequest()
request.params["sfc"] = "sfc1" request.params["sfc"] = "sfc1"
request.params["sfc_i"] = "sfc_i1"
request.body = body.encode(request.charset) request.body = body.encode(request.charset)
response = SFCConfigAPI(request).put() response = SFCConfigAPI(request).put()
assert response == resource, "PUT request must return the updated resource" assert response == resource, "PUT request must return the updated resource"
assert not ServiceFunctionChain.exists("sfc1", "sfc_i1"), "Resource has not been updated" assert not ServiceFunctionChain.exists("sfc1"), "Resource has not been updated"
assert ServiceFunctionChain.exists("sfc2", "sfc_i2"), "Resource has not been updated" assert ServiceFunctionChain.exists("sfc2"), "Resource has not been updated"
sfc = ServiceFunctionChain(sfc="sfc1", sfc_i="sfc_i1", chain={"nginx": ["minio"]}) sfc = ServiceFunctionChain(sfc="sfc1", chain={"nginx": ["minio"]})
ServiceFunctionChain.add(sfc) # adds the new instance of the model to the database ServiceFunctionChain.add(sfc) # adds the new instance of the model to the database
resource = dict(sfc="sfc2", sfc_i="sfc_i2", chain={"nginx": ["minio"]}) resource = dict(sfc="sfc2", chain={"nginx": ["minio"]})
body = dumps(resource) body = dumps(resource)
request = testing.DummyRequest() request = testing.DummyRequest()
request.params["sfc"] = "sfc1" request.params["sfc"] = "sfc1"
request.params["sfc_i"] = "sfc_i1"
request.body = body.encode(request.charset) request.body = body.encode(request.charset)
error_raised = False error_raised = False
try: try:
...@@ -226,11 +220,11 @@ class TestSFCConfigAPI(object): ...@@ -226,11 +220,11 @@ class TestSFCConfigAPI(object):
assert error_raised, "PUT request breaks unique constraint" assert error_raised, "PUT request breaks unique constraint"
@pytest.mark.parametrize("body, valid", [ @pytest.mark.parametrize("body, valid", [
('{"sfc": "sfc1", "sfc_i": "sfc_i1", "chain":{"nginx":["minio"]}}', True), ('{"sfc": "sfc1", "chain":{"nginx":["minio"]}}', True),
('{"sfc": "sfc2", "sfc_i": "sfc_i2", "chain":{}}', True), ('{"sfc": "sfc2", "chain":{}}', True),
('{"sfc": "sfc1", "sfc_i": "sfc_i1", "chain":[]}', False), ('{"sfc": "sfc1", "chain":[]}', False),
('{}', False), ('{}', False),
('{"sfc": "sfc3", "sfc_i": "sfc_i3"', False), ('{"sfc": "sfc3"}', False),
('{"sf": "sfc2", "sf_i": "sfc_i2", "chain":{}', False), ('{"sf": "sfc2", "sf_i": "sfc_i2", "chain":{}', False),
('{invalid json}', False), ('{invalid json}', False),
]) ])
...@@ -242,12 +236,11 @@ class TestSFCConfigAPI(object): ...@@ -242,12 +236,11 @@ class TestSFCConfigAPI(object):
:param valid: True if body is valid, False otherwise :param valid: True if body is valid, False otherwise
""" """
sfc = ServiceFunctionChain(sfc="sfc1", sfc_i="sfc_i1", chain={"nginx": ["minio"]}) sfc = ServiceFunctionChain(sfc="sfc1", chain={"nginx": ["minio"]})
ServiceFunctionChain.add(sfc) # adds the new instance of the model to the database ServiceFunctionChain.add(sfc) # adds the new instance of the model to the database
request = testing.DummyRequest() request = testing.DummyRequest()
request.params["sfc"] = "sfc1" request.params["sfc"] = "sfc1"
request.params["sfc_i"] = "sfc_i1"
request.body = body.encode(request.charset) request.body = body.encode(request.charset)
error_raised = False error_raised = False
try: try:
...@@ -258,7 +251,7 @@ class TestSFCConfigAPI(object): ...@@ -258,7 +251,7 @@ class TestSFCConfigAPI(object):
def test_delete(self): def test_delete(self):
""" """
Tests the DELETE method of the config API for service function chains - deletes an instance of a service function chain from the database. Tests the DELETE method of the config API for service function chains - deletes a service function chain from the database.
""" """
request = testing.DummyRequest() request = testing.DummyRequest()
...@@ -267,23 +260,21 @@ class TestSFCConfigAPI(object): ...@@ -267,23 +260,21 @@ class TestSFCConfigAPI(object):
self._validation_of_url_parameters_test("delete") self._validation_of_url_parameters_test("delete")
sfc = ServiceFunctionChain(sfc="sfc1", sfc_i="sfc_i1", chain={"nginx": ["minio"]}) sfc = ServiceFunctionChain(sfc="sfc1", chain={"nginx": ["minio"]})
to_delete = sfc.json to_delete = sfc.json
ServiceFunctionChain.add(sfc) # adds the new instance of the model to the database ServiceFunctionChain.add(sfc) # adds the new instance of the model to the database
assert ServiceFunctionChain.exists("sfc1", "sfc_i1") assert ServiceFunctionChain.exists("sfc1")
request = testing.DummyRequest() request = testing.DummyRequest()
request.params["sfc"] = "sfc1" request.params["sfc"] = "sfc1"
request.params["sfc_i"] = "sfc_i1"
response = SFCConfigAPI(request).delete() response = SFCConfigAPI(request).delete()
assert response == to_delete, "DELETE must return the deleted object if successful" assert response == to_delete, "DELETE must return the deleted object if successful"
assert not ServiceFunctionChain.exists("sfc1", "sfc_i1"), "Resource must be deleted after the delete API method has been called." assert not ServiceFunctionChain.exists("sfc1"), "Resource must be deleted after the delete API method has been called."
request = testing.DummyRequest() request = testing.DummyRequest()
request.params["sfc"] = "sfc1" request.params["sfc"] = "sfc1"
request.params["sfc_i"] = "sfc_i1"
error_raised = False error_raised = False
try: try:
SFCConfigAPI(request).delete() SFCConfigAPI(request).delete()
...@@ -308,7 +299,7 @@ class TestSFCConfigAPI(object): ...@@ -308,7 +299,7 @@ class TestSFCConfigAPI(object):
assert error_raised, "Error must be raised in case of no URL parameters" assert error_raised, "Error must be raised in case of no URL parameters"
request = testing.DummyRequest() request = testing.DummyRequest()
request.params["sfc"] = "sfc1" request.params["sfc_i"] = "sfc1" # argument should be sfc
try: try:
getattr(SFCConfigAPI(request), method).__call__() getattr(SFCConfigAPI(request), method).__call__()
except HTTPBadRequest: except HTTPBadRequest:
...@@ -317,7 +308,6 @@ class TestSFCConfigAPI(object): ...@@ -317,7 +308,6 @@ class TestSFCConfigAPI(object):
request = testing.DummyRequest() request = testing.DummyRequest()
request.params["sf"] = "sfc1" # argument should be sfc request.params["sf"] = "sfc1" # argument should be sfc
request.params["sfc_i"] = "sfc_i1"
try: try:
getattr(SFCConfigAPI(request), method).__call__() getattr(SFCConfigAPI(request), method).__call__()
except HTTPBadRequest: except HTTPBadRequest:
......
...@@ -40,29 +40,15 @@ def validate_sfchain_body(body): ...@@ -40,29 +40,15 @@ def validate_sfchain_body(body):
except: except:
raise AssertionError("Service function chain must be represented by a JSON object.") raise AssertionError("Service function chain must be represented by a JSON object.")
# the database table has one more column which is a UID integer assert len(body) == len(ServiceFunctionChain.__table__.columns), "Service function chain JSON object mustn't contain a different number of attributes than the number of required ones."
assert len(body) == len(ServiceFunctionChain.__table__.columns) - 1, "Service function chain JSON object mustn't contain a different number of attributes than the number of required ones."
# validate that all required attributes are given in the body # validate that all required attributes are given in the body
for attribute in ServiceFunctionChain.required_columns(): for attribute in ServiceFunctionChain.__table__.columns:
assert attribute in body, "Required attribute not found in the request content." assert attribute.name in body, "Required attribute not found in the request content."
assert type(body["chain"]) == dict, "The chain attribute of a service function chain must be a graph representing the relations between service functions." assert type(body["chain"]) == dict, "The chain attribute of a service function chain must be a graph representing the relations between service functions."
return body for sf in body["chain"]:
assert type(body["chain"][sf]) == list, "A list must be used to represent each dependency between service functions"
def validate_sfchain_params(params): return body
"""
Validates the request parameters to retrieve an service function chain resource from the database.
:param params: the parameters dictionary to validate
:return: the validated parameters
:raise AssertionError: for invalid parameters
"""
constrained_cols = ServiceFunctionChain.constrained_columns()
assert len(params) == len(constrained_cols), "Incorrect url query parameters."
return params
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
from pyramid.httpexceptions import HTTPBadRequest, HTTPConflict, HTTPNotFound from pyramid.httpexceptions import HTTPBadRequest, HTTPConflict, HTTPNotFound
from pyramid.view import view_defaults, view_config from pyramid.view import view_defaults, view_config
from clmcservice.models import ServiceFunctionChain from clmcservice.models import ServiceFunctionChain
from clmcservice.configapi.utilities import validate_sfchain_body, validate_sfchain_params from clmcservice.configapi.utilities import validate_sfchain_body
@view_defaults(renderer='json') @view_defaults(renderer='json')
...@@ -59,7 +59,7 @@ class SFCConfigAPI(object): ...@@ -59,7 +59,7 @@ class SFCConfigAPI(object):
""" """
GET API call for a single resources. GET API call for a single resources.
:return: One service function chain instance retrieved from the database by querying the uniquely constrained columns. :return: One service function chain instance retrieved from the database by querying the sfc ID
:raises HTTPBadRequest: if the request parameters are invalid(invalid url query string) :raises HTTPBadRequest: if the request parameters are invalid(invalid url query string)
:raises HTTPNotFound: if a resource with the given parameters doesn't exist in the database :raises HTTPNotFound: if a resource with the given parameters doesn't exist in the database
""" """
...@@ -101,7 +101,7 @@ class SFCConfigAPI(object): ...@@ -101,7 +101,7 @@ class SFCConfigAPI(object):
sf_chain = self._get_sf_chain_from_url_string() sf_chain = self._get_sf_chain_from_url_string()
if sf_chain is None: if sf_chain is None:
raise HTTPNotFound("A service function chain with the given parameters doesn't exist.") raise HTTPNotFound("A service function chain with the given ID doesn't exist.")
else: else:
try: try:
body = self.request.body.decode(self.request.charset) body = self.request.body.decode(self.request.charset)
...@@ -111,14 +111,14 @@ class SFCConfigAPI(object): ...@@ -111,14 +111,14 @@ class SFCConfigAPI(object):
new_resource = validated_body new_resource = validated_body
old_resource = sf_chain.json old_resource = sf_chain.json
updating = new_resource["sfc"] == old_resource["sfc"] and new_resource["sfc_i"] == old_resource["sfc_i"] updating = new_resource["sfc"] == old_resource["sfc"]
if updating: if updating:
ServiceFunctionChain.delete(sf_chain) ServiceFunctionChain.delete(sf_chain)
new_sf_chain = ServiceFunctionChain(**validated_body) new_sf_chain = ServiceFunctionChain(**validated_body)
ServiceFunctionChain.add(new_sf_chain) ServiceFunctionChain.add(new_sf_chain)
else: else:
resource_exists = ServiceFunctionChain.exists(new_resource["sfc"], new_resource["sfc_i"]) resource_exists = ServiceFunctionChain.exists(new_resource["sfc"])
if resource_exists: if resource_exists:
raise HTTPConflict("Service function chain with this data already exists.") # error 409 in case of resource conflict raise HTTPConflict("Service function chain with this data already exists.") # error 409 in case of resource conflict
...@@ -139,7 +139,7 @@ class SFCConfigAPI(object): ...@@ -139,7 +139,7 @@ class SFCConfigAPI(object):
sf_chain = self._get_sf_chain_from_url_string() sf_chain = self._get_sf_chain_from_url_string()
if sf_chain is None: if sf_chain is None:
raise HTTPNotFound("A service function chain with the given parameters doesn't exist.") raise HTTPNotFound("A service function chain with the given ID doesn't exist.")
else: else:
deleted = sf_chain.json deleted = sf_chain.json
ServiceFunctionChain.delete(sf_chain) ServiceFunctionChain.delete(sf_chain)
...@@ -152,17 +152,10 @@ class SFCConfigAPI(object): ...@@ -152,17 +152,10 @@ class SFCConfigAPI(object):
:return: An instance of a service function chain or None if not existing :return: An instance of a service function chain or None if not existing
""" """
params = {} if "sfc" not in self.request.params:
for attribute in ServiceFunctionChain.constrained_columns(): raise HTTPBadRequest("Request format is incorrect: URL argument 'sfc' not found")
if attribute in self.request.params:
params[attribute] = self.request.params.get(attribute)
try:
params = validate_sfchain_params(params)
except AssertionError as e:
raise HTTPBadRequest("Request format is incorrect: {0}".format(e.args))
sf_chain = ServiceFunctionChain.get(**params) sf_chain = ServiceFunctionChain.get(sfc=self.request.params["sfc"])
return sf_chain return sf_chain
def _validate_and_create(self): def _validate_and_create(self):
...@@ -182,7 +175,7 @@ class SFCConfigAPI(object): ...@@ -182,7 +175,7 @@ class SFCConfigAPI(object):
resource = validated_body resource = validated_body
resource_exists = ServiceFunctionChain.exists(resource["sfc"], resource["sfc_i"]) resource_exists = ServiceFunctionChain.exists(resource["sfc"])
if resource_exists: if resource_exists:
raise HTTPConflict("Service function chain with this data already exists.") # error 409 in case of resource conflict raise HTTPConflict("Service function chain with this data already exists.") # error 409 in case of resource conflict
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
// Created for Project : FLAME // Created for Project : FLAME
""" """
from sqlalchemy import Column, String, Integer, UniqueConstraint, and_ from sqlalchemy import Column, String, and_
from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.dialects.postgresql import JSONB
from clmcservice.models.meta import Base from clmcservice.models.meta import Base
...@@ -34,12 +34,7 @@ class ServiceFunctionChain(Base): ...@@ -34,12 +34,7 @@ class ServiceFunctionChain(Base):
__tablename__ = 'sfchain' # table name in the PostgreSQL database __tablename__ = 'sfchain' # table name in the PostgreSQL database
__table_args__ = (UniqueConstraint('sfc', 'sfc_i'),) # defines a unique constraint across 2 columns - sfc, sfc_i sfc = Column(String, nullable=False, primary_key=True) # service function chain label
uid = Column(Integer, primary_key=True, autoincrement=True, nullable=False) # a primary key integer field (auto incremented)
sfc = Column(String, nullable=False) # service function chain label
sfc_i = Column(String, nullable=False) # service function chain instance identifier
chain = Column(JSONB, nullable=False) # the service function chain graph represented by a python dictionary (JSON object essentially) chain = Column(JSONB, nullable=False) # the service function chain graph represented by a python dictionary (JSON object essentially)
@property @property
...@@ -51,7 +46,6 @@ class ServiceFunctionChain(Base): ...@@ -51,7 +46,6 @@ class ServiceFunctionChain(Base):
""" """
fields = {c.name: getattr(self, c.name) for c in self.__table__.columns} fields = {c.name: getattr(self, c.name) for c in self.__table__.columns}
fields.pop("uid")
return fields return fields
...@@ -62,38 +56,28 @@ class ServiceFunctionChain(Base): ...@@ -62,38 +56,28 @@ class ServiceFunctionChain(Base):
:return: a generator object :return: a generator object
""" """
return tuple(column.name for column in ServiceFunctionChain.__table__.columns if column.name != "uid") return tuple(column.name for column in ServiceFunctionChain.__table__.columns)
@staticmethod
def constrained_columns():
"""
:return: the columns that are uniquely identifying an instance of this model.
"""
return tuple(column.name for column in ServiceFunctionChain.__table_args__[0].columns)
@staticmethod @staticmethod
def get(sfc, sfc_i): def get(sfc):
""" """
Gets the instance matching the unique constraint or None if not existing. Gets the instance matching the sfc argument
:param sfc: service function chain id :param sfc: service function chain id
:param sfc_i: service function chain instance id
:return: the first object from the result set that matches the unique constraint or None :return: the first object from the result set that matches the sfc argument (must be only one)
""" """
return ServiceFunctionChain.query().filter(and_(ServiceFunctionChain.sfc == sfc, ServiceFunctionChain.sfc_i == sfc_i)).first() return ServiceFunctionChain.query().filter(and_(ServiceFunctionChain.sfc == sfc)).first()
@staticmethod @staticmethod
def exists(sfc, sfc_i): def exists(sfc):
""" """
Checks if an instance matching the unique constraint exists. Checks if an instance matching the sfc exists.
:param sfc: service function chain id :param sfc: service function chain id
:param sfc_i: service function chain instance id
:return: True if exists, False otherwise :return: True if exists, False otherwise
""" """
return ServiceFunctionChain.get(sfc, sfc_i) is not None return ServiceFunctionChain.get(sfc) is not None
...@@ -51,12 +51,12 @@ requires = [ ...@@ -51,12 +51,12 @@ requires = [
'psycopg2', 'psycopg2',
'influxdb', 'influxdb',
'neo4j-driver', 'neo4j-driver',
'py2neo', 'py2neo'
'pytest',
] ]
tests_require = [ tests_require = [
'pytest-cov', 'pytest',
'pytest-cov'
] ]
setup( setup(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment