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
This commit is contained in:
@@ -48,7 +48,9 @@ def event():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
models.Resource.get_or_create(event_data)
|
models.Resource.get_or_create(event_data)
|
||||||
except (exceptions.EventTooOld, exceptions.IgnoredEvent):
|
except exceptions.EventTooOld:
|
||||||
return '', 202
|
return 'Event Too Old', 202
|
||||||
|
except exceptions.IgnoredEvent:
|
||||||
|
return 'Ignored Event', 202
|
||||||
|
|
||||||
return '', 204
|
return '', 204
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
"""Usage API."""
|
"""Usage API."""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from datetime import datetime
|
import dateutil.parser
|
||||||
|
|
||||||
from flask import abort
|
from flask import abort
|
||||||
from flask import Blueprint
|
from flask import Blueprint
|
||||||
@@ -65,8 +65,8 @@ def list_resources():
|
|||||||
project_id = request.args['project_id']
|
project_id = request.args['project_id']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
start = datetime.fromisoformat(request.args['start'])
|
start = dateutil.parser.isoparse(request.args['start'])
|
||||||
end = datetime.fromisoformat(request.args['end'])
|
end = dateutil.parser.isoparse(request.args['end'])
|
||||||
except (KeyError, ValueError):
|
except (KeyError, ValueError):
|
||||||
abort(400)
|
abort(400)
|
||||||
|
|
||||||
|
@@ -31,7 +31,11 @@ from sqlalchemy import or_
|
|||||||
|
|
||||||
from atmosphere import exceptions
|
from atmosphere import exceptions
|
||||||
|
|
||||||
db = SQLAlchemy()
|
session_options = {
|
||||||
|
'autocommit': False
|
||||||
|
}
|
||||||
|
|
||||||
|
db = SQLAlchemy(session_options=session_options)
|
||||||
migrate = Migrate()
|
migrate = Migrate()
|
||||||
|
|
||||||
|
|
||||||
@@ -180,7 +184,8 @@ class Resource(db.Model, GetOrCreateMixin):
|
|||||||
# No existing period, start our first period.
|
# No existing period, start our first period.
|
||||||
if len(resource.periods) == 0:
|
if len(resource.periods) == 0:
|
||||||
resource.periods.append(Period(
|
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
|
spec=spec
|
||||||
))
|
))
|
||||||
|
|
||||||
@@ -246,6 +251,12 @@ class Instance(Resource):
|
|||||||
if vm_state_is_deleted and no_deleted_at:
|
if vm_state_is_deleted and no_deleted_at:
|
||||||
return True
|
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
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user