Fix missing fields in API response

Previously, if some fields are not set during object creation in
database, they are not shown in API response, which will cause some
issues for python-qinlingclient. For those missing fields, qinling
client will make an extra API request which is not efficient.

Change-Id: If6d95b6fe11b56183cf05291daaed233ad347cb0
This commit is contained in:
Lingxian Kong 2018-04-30 12:25:33 +12:00
parent 68b261d83d
commit 0e8d91c30b
7 changed files with 23 additions and 27 deletions

View File

@ -64,7 +64,7 @@ class ExecutionsController(rest.RestController):
db_model = executions.create_execution(self.engine_client, params)
return resources.Execution.from_dict(db_model.to_dict())
return resources.Execution.from_db_obj(db_model)
@rest_utils.wrap_wsme_controller_exception
@wsme_pecan.wsexpose(resources.Executions, wtypes.text, bool, wtypes.text,
@ -95,7 +95,7 @@ class ExecutionsController(rest.RestController):
LOG.info("Get all %ss. filters=%s", self.type, filters)
db_execs = db_api.get_executions(insecure=all_projects, **filters)
executions = [resources.Execution.from_dict(db_model.to_dict())
executions = [resources.Execution.from_db_obj(db_model)
for db_model in db_execs]
return resources.Executions(executions=executions)
@ -107,7 +107,7 @@ class ExecutionsController(rest.RestController):
execution_db = db_api.get_execution(id)
return resources.Execution.from_dict(execution_db.to_dict())
return resources.Execution.from_db_obj(execution_db)
@rest_utils.wrap_wsme_controller_exception
@wsme_pecan.wsexpose(None, types.uuid, status_code=204)

View File

@ -111,7 +111,7 @@ class FunctionsController(rest.RestController):
if not download:
pecan.override_template('json')
return resources.Function.from_dict(func_db.to_dict()).to_dict()
return resources.Function.from_db_obj(func_db).to_dict()
else:
LOG.info("Downloading function %s", id)
source = func_db.code['source']
@ -230,7 +230,7 @@ class FunctionsController(rest.RestController):
raise e
pecan.response.status = 201
return resources.Function.from_dict(func_db.to_dict()).to_dict()
return resources.Function.from_db_obj(func_db).to_dict()
@rest_utils.wrap_wsme_controller_exception
@wsme_pecan.wsexpose(resources.Functions, bool, wtypes.text)
@ -252,7 +252,7 @@ class FunctionsController(rest.RestController):
)
LOG.info("Get all functions. filters=%s", filters)
db_functions = db_api.get_functions(insecure=all_projects, **filters)
functions = [resources.Function.from_dict(db_model.to_dict())
functions = [resources.Function.from_db_obj(db_model)
for db_model in db_functions]
return resources.Functions(functions=functions)
@ -422,7 +422,7 @@ class FunctionsController(rest.RestController):
self.storage_provider.delete(ctx.projectid, id, pre_md5sum)
pecan.response.status = 200
return resources.Function.from_dict(func_db.to_dict()).to_dict()
return resources.Function.from_db_obj(func_db).to_dict()
@rest_utils.wrap_wsme_controller_exception
@wsme_pecan.wsexpose(

View File

@ -135,7 +135,7 @@ class FunctionVersionsController(rest.RestController):
version = self._create_function_version(ctx.project_id, function_id,
**values)
return resources.FunctionVersion.from_dict(version.to_dict())
return resources.FunctionVersion.from_db_obj(version)
@rest_utils.wrap_wsme_controller_exception
@wsme_pecan.wsexpose(resources.FunctionVersions, types.uuid)
@ -148,7 +148,7 @@ class FunctionVersionsController(rest.RestController):
func_db = db_api.get_function(function_id)
db_versions = func_db.versions
versions = [resources.FunctionVersion.from_dict(v.to_dict())
versions = [resources.FunctionVersion.from_db_obj(v)
for v in db_versions]
return resources.FunctionVersions(function_versions=versions)
@ -170,8 +170,7 @@ class FunctionVersionsController(rest.RestController):
LOG.info("Getting version %s for function %s.", version,
function_id)
pecan.override_template('json')
return resources.FunctionVersion.from_dict(
version_db.to_dict()).to_dict()
return resources.FunctionVersion.from_db_obj(version_db).to_dict()
LOG.info("Downloading version %s for function %s.", version,
function_id)

View File

@ -81,7 +81,7 @@ class JobsController(rest.RestController):
}
db_job = db_api.create_job(values)
return resources.Job.from_dict(db_job.to_dict())
return resources.Job.from_db_obj(db_job)
@rest_utils.wrap_wsme_controller_exception
@wsme_pecan.wsexpose(None, types.uuid, status_code=204)
@ -95,7 +95,7 @@ class JobsController(rest.RestController):
LOG.info("Get resource.", resource={'type': self.type, 'id': id})
job_db = db_api.get_job(id)
return resources.Job.from_dict(job_db.to_dict())
return resources.Job.from_db_obj(job_db)
@rest_utils.wrap_wsme_controller_exception
@wsme_pecan.wsexpose(resources.Jobs, bool, wtypes.text)
@ -111,7 +111,7 @@ class JobsController(rest.RestController):
)
LOG.info("Get all %ss. filters=%s", self.type, filters)
db_jobs = db_api.get_jobs(insecure=all_projects, **filters)
jobs = [resources.Job.from_dict(db_model.to_dict())
jobs = [resources.Job.from_db_obj(db_model)
for db_model in db_jobs]
return resources.Jobs(jobs=jobs)
@ -177,4 +177,4 @@ class JobsController(rest.RestController):
).get_next(datetime.datetime)
updated_job = db_api.update_job(id, values)
return resources.Job.from_dict(updated_job.to_dict())
return resources.Job.from_db_obj(updated_job)

View File

@ -45,6 +45,10 @@ class Resource(wtypes.Base):
return obj
@classmethod
def from_db_obj(cls, db_obj):
return cls.from_dict(db_obj.to_dict())
def __str__(self):
"""WSME based implementation of __str__."""

View File

@ -47,14 +47,14 @@ class RuntimesController(rest.RestController):
runtime_db = db_api.get_runtime(id)
return resources.Runtime.from_dict(runtime_db.to_dict())
return resources.Runtime.from_db_obj(runtime_db)
@rest_utils.wrap_wsme_controller_exception
@wsme_pecan.wsexpose(resources.Runtimes)
def get_all(self):
LOG.info("Get all %ss.", self.type)
runtimes = [resources.Runtime.from_dict(db_model.to_dict())
runtimes = [resources.Runtime.from_db_obj(db_model)
for db_model in db_api.get_runtimes()]
return resources.Runtimes(runtimes=runtimes)
@ -82,7 +82,7 @@ class RuntimesController(rest.RestController):
db_model = db_api.create_runtime(params)
self.engine_client.create_runtime(db_model.id)
return resources.Runtime.from_dict(db_model.to_dict())
return resources.Runtime.from_db_obj(db_model)
@rest_utils.wrap_wsme_controller_exception
@wsme_pecan.wsexpose(None, types.uuid, status_code=204)
@ -161,4 +161,4 @@ class RuntimesController(rest.RestController):
runtime_db = db_api.update_runtime(id, values)
return resources.Runtime.from_dict(runtime_db.to_dict())
return resources.Runtime.from_db_obj(runtime_db)

View File

@ -15,7 +15,6 @@
from oslo_db.sqlalchemy import models as oslo_models
import sqlalchemy as sa
from sqlalchemy.ext import declarative
from sqlalchemy.orm import attributes
from qinling import context
from qinling.utils import common
@ -65,14 +64,8 @@ class _QinlingModelBase(oslo_models.ModelBase, oslo_models.TimestampMixin):
"""sqlalchemy based automatic to_dict method."""
d = {}
# If a column is unloaded at this point, it is
# probably deferred. We do not want to access it
# here and thereby cause it to load.
unloaded = attributes.instance_state(self).unloaded
for col in self.__table__.columns:
if col.name not in unloaded and hasattr(self, col.name):
d[col.name] = getattr(self, col.name)
d[col.name] = getattr(self, col.name)
common.datetime_to_str(d, 'created_at')
common.datetime_to_str(d, 'updated_at')