From 2b21f4a05658be444afb5cd37ffd0f22c75ba3b8 Mon Sep 17 00:00:00 2001 From: Alexander Tivelkov Date: Thu, 18 Jul 2013 16:27:24 +0400 Subject: [PATCH] lastStatus introduced Added an API call to fetch the latest status of Session's services regardless of deployments Change-Id: I4f766510227af9ae12042bc14aa4c16693843f44 --- muranoapi/api/v1/deployments.py | 8 +++----- muranoapi/api/v1/environments.py | 25 ++++++++++++++++++++++++- muranoapi/api/v1/router.py | 4 ++++ muranoapi/common/utils.py | 16 ++++++++++++++++ 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/muranoapi/api/v1/deployments.py b/muranoapi/api/v1/deployments.py index 4205beaf1..afd699097 100644 --- a/muranoapi/api/v1/deployments.py +++ b/muranoapi/api/v1/deployments.py @@ -11,6 +11,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +from muranoapi.common.utils import build_entity_map from muranoapi.openstack.common import wsgi from muranoapi.db.models import Deployment, Status, Environment @@ -48,11 +49,8 @@ class Controller(object): if 'services' in environment: for service in environment['services']: if service['id'] in service_id_set: - entity_ids.append(service['id']) - if 'units' in service: - unit_ids = [u['id'] for u in service['units'] - if 'id' in u] - entity_ids = entity_ids + unit_ids + id_map = build_entity_map(service) + entity_ids = entity_ids + id_map.keys() if entity_ids: query = query.filter(Status.entity_id.in_(entity_ids)) else: diff --git a/muranoapi/api/v1/environments.py b/muranoapi/api/v1/environments.py index 2e3a52a65..7f1f64677 100644 --- a/muranoapi/api/v1/environments.py +++ b/muranoapi/api/v1/environments.py @@ -13,10 +13,12 @@ # under the License. import eventlet +from muranoapi.common.utils import build_entity_map +from sqlalchemy import desc from webob import exc from muranoapi.common import config from muranoapi.db.session import get_session -from muranoapi.db.models import Environment +from muranoapi.db.models import Environment, Status from muranoapi.db.services.core_services import CoreServices from muranoapi.db.services.environments import EnvironmentServices from muranoapi.openstack.common import wsgi @@ -113,6 +115,27 @@ class Controller(object): EnvironmentServices.delete(environment_id, request.context.auth_token) + def last(self, request, environment_id): + session_id = None + if hasattr(request, 'context') and request.context.session: + session_id = request.context.session + services = CoreServices.get_data(environment_id, '/services', + session_id) + db_session = get_session() + result = {} + for service in services: + service_id = service['id'] + entity_ids = build_entity_map(service).keys() + last_status = db_session.query(Status). \ + filter(Status.entity_id.in_(entity_ids)). \ + order_by(desc(Status.created)). \ + first() + if last_status: + result[service_id] = last_status.to_dict() + else: + result[service_id] = None + return {'lastStatuses': result} + def create_resource(): return wsgi.Resource(Controller()) diff --git a/muranoapi/api/v1/router.py b/muranoapi/api/v1/router.py index 00c6e2cde..d71c43e11 100644 --- a/muranoapi/api/v1/router.py +++ b/muranoapi/api/v1/router.py @@ -82,6 +82,10 @@ class API(wsgi.Router): controller=environments_resource, action='delete', conditions={'method': ['DELETE']}) + mapper.connect('/environments/{environment_id}/lastStatus', + controller=environments_resource, + action='last', + conditions={'method': ['GET']}) deployments_resource = deployments.create_resource() mapper.connect('/environments/{environment_id}/deployments', diff --git a/muranoapi/common/utils.py b/muranoapi/common/utils.py index 902965590..59724115d 100644 --- a/muranoapi/common/utils.py +++ b/muranoapi/common/utils.py @@ -136,6 +136,22 @@ def auto_id(value): return value +def build_entity_map(value): + def build_entity_map_recursive(value, id_map): + if isinstance(value, types.DictionaryType): + if 'id' in value: + id_map[value['id']] = value + for k, v in value.iteritems(): + build_entity_map_recursive(v, id_map) + if isinstance(value, types.ListType): + for item in value: + build_entity_map_recursive(item, id_map) + + id_map = {} + build_entity_map_recursive(value, id_map) + return id_map + + def retry(ExceptionToCheck, tries=4, delay=3, backoff=2): """Retry calling the decorated function using an exponential backoff.