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:
@@ -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."
|
||||
|
@@ -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.')
|
||||
|
@@ -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()
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user