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:
JamesGibo 2021-03-03 14:22:23 +00:00
parent 5e81ac2fcc
commit b587028a74
3 changed files with 20 additions and 7 deletions

View File

@ -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

View File

@ -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)

View File

@ -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