Change for synchronous Mistral actions from CLI

This patch allows the Mistral actions to be run synchronously from
the Mistral CLI.

When a Mistral action is run synchronously using the Mistral CLI
'run-action' command, it does not complete successfully. This is due
to the Mistral API server handling requests on a single thread.

The 'run-action' command performs a REST POST call to the
ActionExecution RestController in the API server. That in turn calls
back into the python-mistralclient which then performs another REST
call back to the appropriate REST controller to actually run the
action requested. That call hangs since the requests are handled on
a single thread because the first POST has not completed yet.
Eventually the RPC call between the engine and the executor servers
times out, and the 'run-action' command fails.

This patch changes the Mistral API server so that requests are
handled in separate threads.

Added a new functional test to the tempest test package to test
synchronous action execution of a mistral action from within
mistral.

Change-Id: I8e06d3ef6aab4b2009a8fff4aa4d1acc118eee3f
Implements: blueprint mistral-mistral-actions
This commit is contained in:
Daryl Mowrer 2016-02-19 12:40:30 -06:00
parent 812f1803a6
commit 984cec8547
2 changed files with 29 additions and 1 deletions

View File

@ -25,6 +25,7 @@ eventlet.monkey_patch(
time=True)
import os
import six
import time
# If ../mistral/__init__.py exists, add ../ to Python search path, so that
@ -38,7 +39,14 @@ if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'mistral', '__init__.py')):
from oslo_config import cfg
from oslo_log import log as logging
import oslo_messaging as messaging
if six.PY3 is True:
import socketserver
else:
import SocketServer as socketserver
from wsgiref import simple_server
from wsgiref.simple_server import WSGIServer
from mistral.api import app
from mistral import config
@ -128,6 +136,10 @@ def launch_engine(transport):
server.wait()
class ThreadingWSGIServer(socketserver.ThreadingMixIn, WSGIServer):
pass
def launch_api(transport):
host = cfg.CONF.api.host
port = cfg.CONF.api.port
@ -135,7 +147,8 @@ def launch_api(transport):
server = simple_server.make_server(
host,
port,
app.setup_app()
app.setup_app(),
ThreadingWSGIServer
)
LOG.info("Mistral API is serving on http://%s:%s (PID=%s)" %

View File

@ -1167,3 +1167,18 @@ class ActionExecutionTestsV2(base.TestCase):
'action_executions',
'nonexist'
)
@test.attr(type='sanity')
def test_create_action_execution_sync(self):
token = self.client.auth_provider.get_token()
resp, body = self.client.create_action_execution(
{
'name': 'std.http',
'input': '{{"url": "http://localhost:8989/v2/workflows",\
"headers": {{"X-Auth-Token": "{}"}}}}'.format(token)
}
)
self.assertEqual(201, resp.status)
output = json.loads(body['output'])
self.assertEqual(200, output['result']['status'])