Added ability to post few services at once

Change-Id: Ie214f0fc9467171b2feb17b2356e834237786bb7
This commit is contained in:
Serg Melikyan 2013-08-15 11:25:39 +04:00
parent c0458ddaa1
commit 98451622fa
7 changed files with 70 additions and 65 deletions

View File

@ -21,5 +21,5 @@ ENV_SCHEMA = {
"id": {"type": "string"}, "id": {"type": "string"},
"name": {"type": "string"} "name": {"type": "string"}
}, },
"required": ["id"] "required": ["id", "name"]
} }

View File

@ -55,7 +55,7 @@ class Controller(object):
@utils.verify_session @utils.verify_session
@normalize_path @normalize_path
def post(self, request, environment_id, path, body): def post(self, request, environment_id, path, body):
log.debug(_('Services:Post <EnvId: {0}, , Path: {2}, ' log.debug(_('Services:Post <EnvId: {0}, Path: {2}, '
'Body: {1}>'.format(environment_id, body, path))) 'Body: {1}>'.format(environment_id, body, path)))
post_data = CoreServices.post_data post_data = CoreServices.post_data
@ -69,7 +69,7 @@ class Controller(object):
@utils.verify_session @utils.verify_session
@normalize_path @normalize_path
def put(self, request, environment_id, path, body): def put(self, request, environment_id, path, body):
log.debug(_('Services:Put <EnvId: {0}, , Path: {2}, ' log.debug(_('Services:Put <EnvId: {0}, Path: {2}, '
'Body: {1}>'.format(environment_id, body, path))) 'Body: {1}>'.format(environment_id, body, path)))
put_data = CoreServices.put_data put_data = CoreServices.put_data

View File

@ -12,12 +12,12 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import eventlet
from jsonschema import validate
from muranoapi.common.uuidutils import generate_uuid
import types
from collections import deque from collections import deque
from functools import wraps from functools import wraps
import eventlet
from jsonschema import validate
import types
from muranoapi.openstack.common import log as logging from muranoapi.openstack.common import log as logging
@ -101,6 +101,18 @@ class TraverseHelper(object):
node = TraverseHelper.get(path, source) node = TraverseHelper.get(path, source)
node.append(value) node.append(value)
@staticmethod
def extend(path, value, source):
"""
Extend list by appending elements from the iterable.
:param path: string with path to desired value
:param value: value
:param source: List
"""
node = TraverseHelper.get(path, source)
node.extend(value)
@staticmethod @staticmethod
def remove(path, source): def remove(path, source):
""" """
@ -125,17 +137,6 @@ class TraverseHelper(object):
raise ValueError('Source object or path is malformed') raise ValueError('Source object or path is malformed')
def auto_id(value):
if isinstance(value, types.DictionaryType):
value['id'] = generate_uuid()
for k, v in value.iteritems():
value[k] = auto_id(v)
if isinstance(value, types.ListType):
for item in value:
auto_id(item)
return value
def build_entity_map(value): def build_entity_map(value):
def build_entity_map_recursive(value, id_map): def build_entity_map_recursive(value, id_map):
if isinstance(value, types.DictionaryType): if isinstance(value, types.DictionaryType):

View File

@ -12,9 +12,10 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from muranoapi.common.utils import TraverseHelper, auto_id from muranoapi.common.utils import TraverseHelper
from muranoapi.db.services.environments import EnvironmentServices from muranoapi.db.services.environments import EnvironmentServices
from muranoapi.openstack.common import timeutils from muranoapi.openstack.common import timeutils
import types
class CoreServices(object): class CoreServices(object):
@ -66,16 +67,12 @@ class CoreServices(object):
if not 'services' in env_description: if not 'services' in env_description:
env_description['services'] = [] env_description['services'] = []
data = auto_id(data)
if path == '/services': if path == '/services':
data['created'] = str(timeutils.utcnow()) if isinstance(data, types.ListType):
data['updated'] = str(timeutils.utcnow()) TraverseHelper.extend(path, data, env_description)
else:
TraverseHelper.insert(path, data, env_description)
for idx, unit in enumerate(data['units']):
unit['name'] = data['name'] + '_instance_' + str(idx)
TraverseHelper.insert(path, data, env_description)
save_description(session_id, env_description) save_description(session_id, env_description)
return data return data

View File

@ -16,9 +16,11 @@ from collections import namedtuple
from jsonschema import validate from jsonschema import validate
from muranoapi.api.v1.schemas import ENV_SCHEMA from muranoapi.api.v1.schemas import ENV_SCHEMA
from muranoapi.common import config from muranoapi.common import config
from muranoapi.common.uuidutils import generate_uuid
from muranoapi.db.models import Session, Environment from muranoapi.db.models import Session, Environment
from muranoapi.db.services.sessions import SessionServices, SessionState from muranoapi.db.services.sessions import SessionServices, SessionState
from muranoapi.db.session import get_session from muranoapi.db.session import get_session
from muranoapi.openstack.common import timeutils
from muranocommon.messaging import MqClient, Message from muranocommon.messaging import MqClient, Message
@ -175,6 +177,37 @@ class EnvironmentServices(object):
unit = get_session() unit = get_session()
session = unit.query(Session).get(session_id) session = unit.query(Session).get(session_id)
EnvironmentServices.normalize(environment)
validate(environment, ENV_SCHEMA) validate(environment, ENV_SCHEMA)
session.description = environment session.description = environment
session.save(unit) session.save(unit)
@staticmethod
def normalize(environment):
if 'id' not in environment:
environment['id'] = generate_uuid()
if 'services' not in environment:
return
for service in environment['services']:
if 'id' not in service:
service['id'] = generate_uuid()
if 'created' not in service:
service['created'] = str(timeutils.utcnow())
if 'updated' not in service:
service['updated'] = str(timeutils.utcnow())
if 'units' not in service:
continue
for idx, unit in enumerate(service['units']):
if 'id' not in unit:
unit['id'] = generate_uuid()
if 'name' not in unit:
unit['name'] = '{srv_name}_instance_{number}'.format(
srv_name=service['name'], number=idx
)

View File

@ -88,6 +88,18 @@ class TraverseHelperTests(unittest.TestCase):
value = TraverseHelper.get('/obj/attr', source) value = TraverseHelper.get('/obj/attr', source)
self.assertListEqual(value, [1, 2, 3, 4]) self.assertListEqual(value, [1, 2, 3, 4])
def test_extending_list_with_list(self):
source = {'attr': [1, 2, 3]}
TraverseHelper.extend('/attr', [4, 5], source)
value = TraverseHelper.get('/attr', source)
self.assertListEqual(value, [1, 2, 3, 4, 5])
def test_nested_extending_list_with_list(self):
source = {'obj': {'attr': [1, 2, 3]}}
TraverseHelper.extend('/obj/attr', [4, 5], source)
value = TraverseHelper.get('/obj/attr', source)
self.assertListEqual(value, [1, 2, 3, 4, 5])
def test_attribute_remove_from_dict(self): def test_attribute_remove_from_dict(self):
source = {'attr1': False, 'attr2': True} source = {'attr1': False, 'attr2': True}
TraverseHelper.remove('/attr1', source) TraverseHelper.remove('/attr1', source)

View File

@ -1,38 +0,0 @@
# Copyright (c) 2013 Mirantis, Inc.
#
# 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.
import unittest2 as unittest
from muranoapi.common.utils import auto_id
class AutoIdTests(unittest.TestCase):
def test_simple_dict(self):
source = {"attr": True}
value = auto_id(source)
self.assertIn('id', value)
def test_nested_lists(self):
source = {"attr": True, "obj": {"attr": False}}
value = auto_id(source)
self.assertIn('id', value)
def test_list_with_ints(self):
source = [0, 1, 2, 3]
value = auto_id(source)
self.assertListEqual(value, source)
def test_list_with_dicts(self):
source = [{"attr": True}, {"attr": False}]
value = auto_id(source)
for item in value:
self.assertIn('id', item)