Add resource params to reflect WSME 0.8 fixes

Before, WSME would ignore fields that didn't exist in the resource, but
with the version 0.8.0 WSME will raise HTTP 400 (BadRequest) when one
attempt to create a resource with nonexistent fields.

Change-Id: Ie13038ff8a2f4988fa3dc97bdfbd5daf3d35a5f6
Closes-Bug: #1488873
This commit is contained in:
Lingxian Kong
2015-08-26 17:23:29 +08:00
parent 5b86095951
commit eb4f86998c
4 changed files with 46 additions and 22 deletions

View File

@@ -17,12 +17,12 @@
import json
from oslo_log import log as logging
import pecan
from pecan import rest
from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from mistral.api.controllers import resource
from mistral.api.controllers.v2 import types
from mistral.db.v2 import api as db_api
from mistral.engine import rpc
from mistral import exceptions as exc
@@ -55,6 +55,9 @@ class ActionExecution(resource.Resource):
created_at = wtypes.text
updated_at = wtypes.text
# Add this param to make Mistral API work with WSME 0.8.0 or higher version
params = types.jsontype
@classmethod
def from_dict(cls, d):
e = cls()
@@ -63,7 +66,7 @@ class ActionExecution(resource.Resource):
if hasattr(e, key):
# Nonetype check for dictionary must be explicit.
if val is not None and (
key == 'input' or key == 'output'):
key == 'input' or key == 'output' or key == 'params'):
val = json.dumps(val)
setattr(e, key, val)
@@ -86,7 +89,8 @@ class ActionExecution(resource.Resource):
input='{"first_name": "John", "last_name": "Doe"}',
output='{"some_output": "Hello, John Doe!"}',
created_at='1970-01-01T00:00:00.000000',
updated_at='1970-01-01T00:00:00.000000'
updated_at='1970-01-01T00:00:00.000000',
params={'save_result': True}
)
@@ -156,12 +160,13 @@ class ActionExecutionsController(rest.RestController):
body=ActionExecution, status_code=201)
def post(self, action_execution):
"""Create new action_execution."""
body = json.loads(pecan.request.body)
LOG.info("Create action_execution [action_execution=%s]" % body)
LOG.info("Create action_execution [action_execution=%s]" %
action_execution)
action_input = action_execution.input or None
description = action_execution.description or None
params = action_execution.params or {}
name = action_execution.name
if action_input:
try:
@@ -175,9 +180,6 @@ class ActionExecutionsController(rest.RestController):
"error: %s" % (action_execution.input, e)
)
name = action_execution.name
params = body.get('params', {})
if not name:
raise exc.InputException(
"Please provide at least action name to run action."

View File

@@ -17,6 +17,7 @@ import json
from oslo_log import log as logging
from pecan import rest
import wsme
from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
@@ -54,6 +55,9 @@ class Task(resource.Resource):
created_at = wtypes.text
updated_at = wtypes.text
# Add this param to make Mistral API work with WSME 0.8.0 or higher version
reset = wsme.wsattr(bool, mandatory=True)
@classmethod
def from_dict(cls, d):
e = cls()
@@ -79,7 +83,8 @@ class Task(resource.Resource):
published='{key: value}',
processed=True,
created_at='1970-01-01T00:00:00.000000',
updated_at='1970-01-01T00:00:00.000000'
updated_at='1970-01-01T00:00:00.000000',
reset=True
)
@@ -134,8 +139,8 @@ class TasksController(rest.RestController):
return _get_task_resources_with_results()
@rest_utils.wrap_wsme_controller_exception
@wsme_pecan.wsexpose(Task, wtypes.text, bool, body=Task)
def put(self, id, reset, task):
@wsme_pecan.wsexpose(Task, wtypes.text, body=Task)
def put(self, id, task):
"""Update the specified task execution.
:param id: Task execution ID.
@@ -146,6 +151,7 @@ class TasksController(rest.RestController):
task_ex = db_api.get_task_execution(id)
task_spec = spec_parser.get_task_spec(task_ex.spec)
task_name = task.name or None
reset = task.reset
if task_name and task_name != task_ex.name:
raise exc.WorkflowException('Task name does not match.')

View File

@@ -11,6 +11,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
from oslo_utils import uuidutils
import six
@@ -39,9 +40,7 @@ class ListType(wtypes.UserType):
@staticmethod
def frombasetype(value):
if value is None:
return None
return ListType.validate(value)
return ListType.validate(value) if value is not None else None
class UniqueListType(ListType):
@@ -64,9 +63,7 @@ class UniqueListType(ListType):
@staticmethod
def frombasetype(value):
if value is None:
return None
return UniqueListType.validate(value)
return UniqueListType.validate(value) if value is not None else None
class UuidType(wtypes.UserType):
@@ -89,11 +86,30 @@ class UuidType(wtypes.UserType):
@staticmethod
def frombasetype(value):
if value is None:
return None
return UuidType.validate(value)
return UuidType.validate(value) if value is not None else None
class JsonType(wtypes.UserType):
"""A simple JSON type."""
basetype = wtypes.text
name = 'json'
@staticmethod
def validate(value):
try:
json.dumps(value)
except TypeError:
raise exc.InputException('%s is not JSON serializable' % value)
else:
return value
@staticmethod
def frombasetype(value):
return JsonType.validate(value) if value is not None else None
uuid = UuidType()
list = ListType()
uniquelist = UniqueListType()
jsontype = JsonType()

View File

@@ -193,7 +193,7 @@ class TestTasksController(base.FunctionalTest):
self.assertEqual(resp.status_int, 400)
self.assertIn('faultstring', resp.json)
self.assertIn('Missing argument', resp.json['faultstring'])
self.assertIn('Mandatory field missing', resp.json['faultstring'])
@mock.patch.object(db_api, 'get_workflow_execution', MOCK_WF_EX)
@mock.patch.object(db_api, 'get_task_execution', MOCK_RERUN_ITEMS_TASKS)