Skip to content

Commit

Permalink
add placement SSM
Browse files Browse the repository at this point in the history
  • Loading branch information
hadik3r committed Oct 27, 2017
1 parent 7747615 commit fd7f68b
Show file tree
Hide file tree
Showing 30 changed files with 2,095 additions and 1 deletion.
45 changes: 45 additions & 0 deletions son-ssm-examples/Gerneral_placement/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Copyright (c) 2015 SONATA-NFV
# ALL RIGHTS RESERVED.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
# nor the names of its contributors may be used to endorse or promote
# products derived from this software without specific prior written
# permission.
# This work has been performed in the framework of the SONATA project,
# funded by the European Commission under Grant number 671517 through
# the Horizon 2020 and 5G-PPP programmes. The authors would like to
# acknowledge the contributions of their colleagues of the SONATA
# partner consortium (www.sonata-nfv.eu).

FROM python:3.4-slim
MAINTAINER SONATA

# configrurations
ENV mongo_host mongo
ENV mongo_port 27017
ENV broker_host amqp://guest:guest@broker:5672/%2F
ENV broker_exchange son-kernel

ADD son-ssm-examples/General_placement /placement
ADD son-mano-framework/son-mano-base /son-mano-base
ADD son-sm-template /son-sm-template
ADD utils/delayedstart.sh /delayedstart.sh

WORKDIR /son-mano-base
Run python setup.py install

WORKDIR /son-sm-template
RUN python setup.py install

WORKDIR /placement
RUN python setup.py develop

CMD ["placement"]
45 changes: 45 additions & 0 deletions son-ssm-examples/Gerneral_placement/Dockerfile~
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Copyright (c) 2015 SONATA-NFV
# ALL RIGHTS RESERVED.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
# nor the names of its contributors may be used to endorse or promote
# products derived from this software without specific prior written
# permission.
# This work has been performed in the framework of the SONATA project,
# funded by the European Commission under Grant number 671517 through
# the Horizon 2020 and 5G-PPP programmes. The authors would like to
# acknowledge the contributions of their colleagues of the SONATA
# partner consortium (www.sonata-nfv.eu).

FROM python:3.4-slim
MAINTAINER SONATA

# configrurations
ENV mongo_host mongo
ENV mongo_port 27017
ENV broker_host amqp://guest:guest@broker:5672/%2F
ENV broker_exchange son-kernel

ADD son-ssm-examples/placement /placement
ADD son-mano-framework/son-mano-base /son-mano-base
ADD son-sm-template /son-sm-template
ADD utils/delayedstart.sh /delayedstart.sh

WORKDIR /son-mano-base
Run python setup.py install

WORKDIR /son-sm-template
RUN python setup.py install

WORKDIR /placement
RUN python setup.py develop

CMD ["placement"]
2 changes: 2 additions & 0 deletions son-ssm-examples/Gerneral_placement/MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Include the license file
include ../../LICENSE
58 changes: 58 additions & 0 deletions son-ssm-examples/Gerneral_placement/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Placement SSM Example (in progress)
An example of placement SSM taking care of service placement.

## Requires
* Docker
* Python3.4
* RabbitMQ

## Implementation
* Implemented in Python 3.4
* Dependencies: amqp-storm
* The main implementation can be found in: `son-ssm-examples/placement/placement.py`

## How to run it

* To run the placement SSM locally, you need:
* a running RabbitMQ broker (see general README.md of [son-mano framework repository](https://github.com/sonata-nfv/son-mano-framework) for info on how to do this)
* a running Service Specific Registry (SMR) connected to the broker (see general README.md of [SMR repository](https://github.com/sonata-nfv/son-mano-framework) for info on how to do this)

* Run the placement SSM (in a Docker container):
* (do in `son-sm/`)
* `docker build -t sonssmservice1placement1 -f son-ssm-examples/placement/Dockerfile .`
* `docker run -it --rm --link broker:broker --name sonssmservice1placement1 sonssmservice1placement1`

* Or: Run the placement SSM (directly in your terminal not in a Docker container):
* (In `son-sm/son-sm-template/`)
* `python3.4 setup.py install`
* (In `son-sm/son-ssm-examples/placement/`)
* `python3.4 setup.py develop`
* (In `son-sm/`)
* `python3.4 son-ssm-examples/placement/placement/placement.py`

## How to test it
* Do the following; each in a separate terminal.
1. Run the SMR container
2. Run the placement container
3. In son-sm/son-ssm-examples/placement/test run python3.4 placementtrigger.py

* The expected results are as follows:

* In the SMR terminal:

```
DEBUG:son-mano-specific-manager-registry:registration request received for: sonssmservice1placement1
INFO:son-mano-specific-manager-registry:sonssmservice1placement1 status: Placement decision was sent: {'placement': ['from_ssm']}
```

* In placement terminal:

```
INFO:son-sm-base:Starting sonssmservice1placement1 ...
INFO:son-sm-base:sonssmservice1placement1 registered with uuid:d88f37a2-6ca4-47cb-a103-833f5fc29fb9
DEBUG:ssm-placement-1:Received registration ok event.
INFO:ssm-placement-1:Subscribed to placement.ssm.1234
WARNING:amqpstorm.channel:Received Basic.Cancel on consumer_tag: q.specific.manager.registry.ssm.registration.2e50cc94-abc8-4663-b1dc-91c12c6a10fa
INFO:ssm-placement-1:Placement request received: {cpu: '20', location: DE, memory: '30'}
INFO:ssm-placement-1:Placement decision was sent: {'placement': ['from_ssm']}
```
Empty file.
8 changes: 8 additions & 0 deletions son-ssm-examples/Gerneral_placement/placement/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from placement import placement


def main():
placement.main()

if __name__ == '__main__':
main()
185 changes: 185 additions & 0 deletions son-ssm-examples/Gerneral_placement/placement/placement.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
"""
Copyright (c) 2015 SONATA-NFV
ALL RIGHTS RESERVED.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
This work has been performed in the framework of the SONATA project,
funded by the European Commission under Grant number 671517 through
the Horizon 2020 and 5G-PPP programmes. The authors would like to
acknowledge the contributions of their colleagues of the SONATA
partner consortium (www.sonata-nfv.eu).
"""

import logging
import yaml
from sonsmbase.smbase import sonSMbase

logging.basicConfig(level=logging.INFO)
LOG = logging.getLogger("ssm-placement-1")
LOG.setLevel(logging.DEBUG)
logging.getLogger("son-mano-base:messaging").setLevel(logging.INFO)


class PlacementSSM(sonSMbase):

def __init__(self):

"""
:param specific_manager_type: specifies the type of specific manager that could be either fsm or ssm.
:param service_name: the name of the service that this specific manager belongs to.
:param function_name: the name of the function that this specific manager belongs to, will be null in SSM case
:param specific_manager_name: the actual name of specific manager (e.g., scaling, placement)
:param id_number: the specific manager id number which is used to distinguish between multiple SSM/FSM
that are created for the same objective (e.g., scaling with algorithm 1 and 2)
:param version: version
:param description: description
"""
self.specific_manager_type = 'ssm'
self.service_name = 'service1'
self.specific_manager_name = 'placement'
self.id_number = '1'
self.version = 'v0.1'
self.description = "Placement SSM"

super(self.__class__, self).__init__(specific_manager_type= self.specific_manager_type,
service_name= self.service_name,
specific_manager_name = self.specific_manager_name,
id_number = self.id_number,
version = self.version,
description = self.description)


def on_registration_ok(self):

LOG.debug("Received registration ok event.")

# For testing, here we set the service uuid.
# In the actual scenario this should be set by SLM and SMR during the SSM instantiation.
self.sfuuid = '1234'

# Register to placement topic.
topic = 'placement.ssm.' + self.sfuuid

self.manoconn.register_async_endpoint(self.on_place,topic= topic)

LOG.info("Subscribed to {0}".format(topic))

def on_place(self, ch, method, properties, payload):
"""
This method organises the placement calculation, and
provides the response for the SLM.
"""

LOG.info("Placement started")
message = yaml.load(payload)
topology = message['topology']
nsd = message['nsd']
functions = message['vnfds']
nap = message['nap']

mapping = self.placement_alg(nsd, functions, topology, nap)

if mapping is None:
LOG.info("The mapping calculation has failed.")
message = {}
message['error'] = 'Unable to perform placement.'
message['status'] = 'ERROR'

else:
LOG.info("The mapping calculation has succeeded.")
message = {}
message['error'] = None
message['status'] = "COMPLETED"
message['mapping'] = mapping

is_dict = isinstance(message, dict)
LOG.info("Type Dict: " + str(is_dict))

payload = yaml.dump(message)
self.manoconn.notify('placement.ssm.' + self.sfuuid,
payload,
correlation_id=properties.correlation_id)

return

def placement_alg(self, nsd, functions, topology, nap):
"""
This is the default placement algorithm that is used if the SLM
is responsible to perform the placement
"""
LOG.info("Mapping algorithm started.")
mapping = {}

ingress = nap['ingress'][0]['location']
egress = nap['egress'][0]['location']

for vnfd in functions:
needed_cpu = vnfd['virtual_deployment_units'][0]['resource_requirements']['cpu']['vcpus']
needed_mem = vnfd['virtual_deployment_units'][0]['resource_requirements']['memory']['size']


#needed_sto = vnfd['virtual_deployment_units'][0]['resource_requirements']['storage']['size']


if vnfd['name'] == 'vnfd1':

for vim in topology:

if vim['vim_city'] == ingress:
cpu_req = needed_cpu <= (vim['core_total'] - vim['core_used'])
mem_req = needed_mem <= (vim['memory_total'] - vim['memory_used'])


if cpu_req and mem_req:
print('VNF ' + vnfd['name'] + ' mapped on VIM ' + vim['vim_uuid'])
mapping[vnfd['name']] = {}
mapping[vnfd['name']]['vim'] = vim['vim_uuid']
vim['core_used'] = vim['core_used'] + needed_cpu
vim['memory_used'] = vim['memory_used'] + needed_mem
break

if vnfd['name'] == 'vnfd2':

for vim in topology:

if vim['vim_city'] == egress:
cpu_req = needed_cpu <= (vim['core_total'] - vim['core_used'])
mem_req = needed_mem <= (vim['memory_total'] - vim['memory_used'])

if cpu_req and mem_req:
print('VNF ' + vnfd['name'] + ' mapped on VIM ' + vim['vim_uuid'])
mapping[vnfd['name']] = {}
mapping[vnfd['name']]['vim'] = vim['vim_uuid']
vim['core_used'] = vim['core_used'] + needed_cpu
vim['memory_used'] = vim['memory_used'] + needed_mem
break


# Check if all VNFs have been mapped
if len(mapping.keys()) == len(functions):
LOG.info("Mapping succeeded: " + str(mapping))
return mapping
else:
return None

def main():
PlacementSSM()

if __name__ == '__main__':
main()
Loading

0 comments on commit fd7f68b

Please sign in to comment.