From b587028a74e2350edb256b132913ec9d17b66791 Mon Sep 17 00:00:00 2001 From: JamesGibo Date: Wed, 3 Mar 2021 14:22:23 +0000 Subject: [PATCH] Support latest event formats and prevent race condition MariaDB defaults to autocommit true, meaning it will ignore 'for update' database locks which may lead to race conditions. If no 'created_at' trait was supplied with the event the an unhandled exception would be raised. To fix if no 'created_at' or 'launched_at' trait is supplied an Ignored Event exception is raised which results in a HTTP 202 response ratehr than 500. Also added support for 'launched_at' trait, whcih is now used by ceilometer rather than 'created_at' when creating a VM. Make api work Python < 3.7, when datetime.fromisoformat was added Change-Id: Iecabc18176c14ed87570e9876e4fb455b6feb391 --- atmosphere/api/ingress.py | 6 ++++-- atmosphere/api/usage.py | 6 +++--- atmosphere/models.py | 15 +++++++++++++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/atmosphere/api/ingress.py b/atmosphere/api/ingress.py index a369d84..30809b6 100644 --- a/atmosphere/api/ingress.py +++ b/atmosphere/api/ingress.py @@ -48,7 +48,9 @@ def event(): try: models.Resource.get_or_create(event_data) - except (exceptions.EventTooOld, exceptions.IgnoredEvent): - return '', 202 + except exceptions.EventTooOld: + return 'Event Too Old', 202 + except exceptions.IgnoredEvent: + return 'Ignored Event', 202 return '', 204 diff --git a/atmosphere/api/usage.py b/atmosphere/api/usage.py index 103815a..df89c92 100644 --- a/atmosphere/api/usage.py +++ b/atmosphere/api/usage.py @@ -15,7 +15,7 @@ """Usage API.""" import os -from datetime import datetime +import dateutil.parser from flask import abort from flask import Blueprint @@ -65,8 +65,8 @@ def list_resources(): project_id = request.args['project_id'] try: - start = datetime.fromisoformat(request.args['start']) - end = datetime.fromisoformat(request.args['end']) + start = dateutil.parser.isoparse(request.args['start']) + end = dateutil.parser.isoparse(request.args['end']) except (KeyError, ValueError): abort(400) diff --git a/atmosphere/models.py b/atmosphere/models.py index ffca1dc..9cfe581 100644 --- a/atmosphere/models.py +++ b/atmosphere/models.py @@ -31,7 +31,11 @@ from sqlalchemy import or_ from atmosphere import exceptions -db = SQLAlchemy() +session_options = { + 'autocommit': False +} + +db = SQLAlchemy(session_options=session_options) migrate = Migrate() @@ -180,7 +184,8 @@ class Resource(db.Model, GetOrCreateMixin): # No existing period, start our first period. if len(resource.periods) == 0: resource.periods.append(Period( - started_at=event['traits']['created_at'], + started_at=event['traits'].get('created_at') or + event['traits'].get('launched_at'), spec=spec )) @@ -246,6 +251,12 @@ class Instance(Resource): if vm_state_is_deleted and no_deleted_at: return True + # Check if event is missing both created_at and launched_at traits + no_created_at = ('created_at' not in event['traits']) + no_launched_at = ('launched_at' not in event['traits']) + if no_created_at and no_launched_at: + return True + return False