Move mistral demo-app to mistral-extra
Change-Id: I1790309fddb66a6c1fc91b479399a6eb88f189fa
This commit is contained in:
parent
709ee551ea
commit
5e749d114d
|
@ -1,3 +1,4 @@
|
|||
git+https://github.com/stackforge/python-mistralclient.git
|
||||
pbr>=0.5.21,<1.0
|
||||
eventlet>=0.13.0
|
||||
pyyaml
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# 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 pecan
|
||||
|
||||
|
||||
app = {
|
||||
'root': 'demo_app.api.controllers.root.RootController',
|
||||
'modules': ['demo_app.api'],
|
||||
'debug': True,
|
||||
}
|
||||
|
||||
|
||||
def get_pecan_config():
|
||||
# Set up the pecan configuration
|
||||
return pecan.configuration.conf_from_dict(app)
|
||||
|
||||
|
||||
def setup_app(config=None):
|
||||
if not config:
|
||||
config = get_pecan_config()
|
||||
|
||||
app_conf = dict(config)
|
||||
|
||||
return pecan.make_app(
|
||||
app_conf.pop('root'),
|
||||
logging=getattr(config, 'logging', {}),
|
||||
**app_conf
|
||||
)
|
|
@ -0,0 +1,60 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# 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 mock
|
||||
import pkg_resources as pkg
|
||||
|
||||
from mistralclient.api import client
|
||||
|
||||
from simple_app import version
|
||||
|
||||
MISTRAL_URL = "http://localhost:8989/v1"
|
||||
client.Client.authenticate = mock.MagicMock(return_value=(MISTRAL_URL,
|
||||
"", "", ""))
|
||||
CLIENT = client.Client(mistral_url=MISTRAL_URL,
|
||||
project_name="mistral_demo")
|
||||
|
||||
|
||||
WB_NAME = "myWorkbook"
|
||||
TARGET_TASK = "task4"
|
||||
|
||||
|
||||
def upload_workbook():
|
||||
try:
|
||||
CLIENT.workbooks.get(WB_NAME)
|
||||
except:
|
||||
CLIENT.workbooks.create(WB_NAME,
|
||||
description="My test workbook",
|
||||
tags=["test"])
|
||||
print("Uploading workbook definition...\n")
|
||||
definition = get_workbook_definition()
|
||||
CLIENT.workbooks.upload_definition(WB_NAME, definition)
|
||||
print definition
|
||||
print("\nUploaded.")
|
||||
|
||||
|
||||
def get_workbook_definition():
|
||||
return open(pkg.resource_filename(version.version_info.package,
|
||||
"demo.yaml")).read()
|
||||
|
||||
|
||||
def start_execution():
|
||||
import threading
|
||||
t = threading.Thread(target=CLIENT.executions.create,
|
||||
kwargs={'workbook_name': WB_NAME,
|
||||
'target_task': TARGET_TASK})
|
||||
t.start()
|
||||
return "accepted"
|
|
@ -0,0 +1,54 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# 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 logging
|
||||
from wsme import types as wtypes
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
API_STATUS = wtypes.Enum(str, 'SUPPORTED', 'CURRENT', 'DEPRECATED')
|
||||
|
||||
|
||||
class Resource(wtypes.Base):
|
||||
"""REST API Resource."""
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, d):
|
||||
# TODO: take care of nested resources
|
||||
obj = cls()
|
||||
|
||||
for key, val in d.items():
|
||||
if hasattr(obj, key):
|
||||
setattr(obj, key, val)
|
||||
|
||||
return obj
|
||||
|
||||
def __str__(self):
|
||||
"""WSME based implementation of __str__."""
|
||||
|
||||
res = "%s [" % type(self).__name__
|
||||
|
||||
first = True
|
||||
for attr in self._wsme_attributes:
|
||||
if not first:
|
||||
res += ', '
|
||||
else:
|
||||
first = False
|
||||
|
||||
res += "%s='%s'" % (attr.name, getattr(self, attr.name))
|
||||
|
||||
return res + "]"
|
|
@ -0,0 +1,69 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# 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 logging
|
||||
import pecan
|
||||
from pecan import rest
|
||||
from wsme import types as wtypes
|
||||
import wsmeext.pecan as wsme_pecan
|
||||
|
||||
from simple_app.api.controllers import resource
|
||||
from simple_app.api.controllers import tasks
|
||||
from simple_app.api import client
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
API_STATUS = wtypes.Enum(str, 'SUPPORTED', 'CURRENT', 'DEPRECATED')
|
||||
|
||||
|
||||
class Link(resource.Resource):
|
||||
"""Web link."""
|
||||
|
||||
href = wtypes.text
|
||||
target = wtypes.text
|
||||
|
||||
|
||||
class APIVersion(resource.Resource):
|
||||
"""API Version."""
|
||||
|
||||
id = wtypes.text
|
||||
status = API_STATUS
|
||||
link = Link
|
||||
|
||||
|
||||
class StartController(rest.RestController):
|
||||
@wsme_pecan.wsexpose(wtypes.text)
|
||||
def get(self):
|
||||
print("Start execution for: %s" % client.TARGET_TASK)
|
||||
|
||||
return client.start_execution()
|
||||
|
||||
|
||||
class RootController(object):
|
||||
|
||||
tasks = tasks.Controller()
|
||||
start = StartController()
|
||||
|
||||
@wsme_pecan.wsexpose([APIVersion])
|
||||
def index(self):
|
||||
LOG.debug("Fetching API versions.")
|
||||
|
||||
host_url = '%s/%s' % (pecan.request.host_url, 'v1')
|
||||
api_v1 = APIVersion(id='v1.0',
|
||||
status='CURRENT',
|
||||
link=Link(href=host_url, target='v1'))
|
||||
|
||||
return [api_v1]
|
|
@ -0,0 +1,70 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# 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 logging
|
||||
from pecan import abort
|
||||
from pecan import rest
|
||||
import pecan
|
||||
from wsme import types as wtypes
|
||||
import wsmeext.pecan as wsme_pecan
|
||||
|
||||
from simple_app import tasks
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Controller(rest.RestController):
|
||||
"""API root controller"""
|
||||
|
||||
@wsme_pecan.wsexpose(wtypes.text)
|
||||
def get_all(self):
|
||||
LOG.debug("Fetch items.")
|
||||
|
||||
values = {
|
||||
'tasks': [
|
||||
'task1',
|
||||
'task2',
|
||||
'task3',
|
||||
'task4'
|
||||
]
|
||||
}
|
||||
|
||||
if not values:
|
||||
abort(404)
|
||||
else:
|
||||
return values
|
||||
|
||||
@wsme_pecan.wsexpose(wtypes.text, wtypes.text)
|
||||
def get(self, name):
|
||||
print("Task '%s' is starting" % name)
|
||||
|
||||
value = "Task %s accepted" % name
|
||||
tasks.start_task(**self.get_mistral_headers())
|
||||
return value
|
||||
|
||||
def get_mistral_headers(self):
|
||||
headers = pecan.request.headers
|
||||
try:
|
||||
needed_headers = {
|
||||
'workbook_name': headers['Mistral-Workbook-Name'],
|
||||
'execution_id': headers['Mistral-Execution-Id'],
|
||||
'task_id': headers['Mistral-Task-Id']
|
||||
}
|
||||
return needed_headers
|
||||
except KeyError:
|
||||
raise RuntimeError("Could not find http headers for "
|
||||
"defining mistral task")
|
|
@ -0,0 +1,80 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# 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.
|
||||
|
||||
"""Script to start Demo API service."""
|
||||
|
||||
import eventlet
|
||||
|
||||
import logging
|
||||
import os
|
||||
from requests import exceptions
|
||||
import sys
|
||||
import threading
|
||||
from time import sleep
|
||||
from wsgiref import simple_server
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from simple_app import config
|
||||
from simple_app.api import app
|
||||
from simple_app.api import client
|
||||
|
||||
|
||||
eventlet.monkey_patch(
|
||||
os=True, select=True, socket=True, thread=True, time=True)
|
||||
|
||||
logging.basicConfig(level=logging.WARN)
|
||||
LOG = logging.getLogger(__name__)
|
||||
CLIENT = client.CLIENT
|
||||
|
||||
|
||||
def upload_wb_and_start():
|
||||
sleep(5)
|
||||
|
||||
try:
|
||||
client.upload_workbook()
|
||||
except exceptions.ConnectionError:
|
||||
LOG.error("Error. Mistral service probably is not working now")
|
||||
sys.exit(1)
|
||||
|
||||
print("Start execution for: %s" % client.TARGET_TASK)
|
||||
|
||||
client.start_execution()
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
config.parse_args()
|
||||
|
||||
host = cfg.CONF.api.host
|
||||
port = cfg.CONF.api.port
|
||||
|
||||
server = simple_server.make_server(host, port, app.setup_app())
|
||||
|
||||
LOG.info("Demo app API is serving on http://%s:%s (PID=%s)" %
|
||||
(host, port, os.getpid()))
|
||||
|
||||
server.serve_forever()
|
||||
except RuntimeError, e:
|
||||
sys.stderr.write("ERROR: %s\n" % e)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
upload_thread = threading.Thread(target=upload_wb_and_start)
|
||||
upload_thread.run()
|
||||
main()
|
|
@ -0,0 +1,36 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# 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.
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from simple_app import version
|
||||
|
||||
|
||||
api_opts = [
|
||||
cfg.StrOpt('host', default='0.0.0.0', help='Simple-app API server host'),
|
||||
cfg.IntOpt('port', default=8988, help='Simple-app API server port')
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(api_opts, group='api')
|
||||
|
||||
|
||||
def parse_args(args=None, usage=None, default_config_files=None):
|
||||
CONF(args=args,
|
||||
project='mistral-demo',
|
||||
version=version,
|
||||
usage=usage,
|
||||
default_config_files=default_config_files)
|
|
@ -0,0 +1,57 @@
|
|||
Services:
|
||||
MyRest:
|
||||
type: REST_API
|
||||
parameters:
|
||||
baseUrl: http://localhost:8988
|
||||
actions:
|
||||
task1:
|
||||
parameters:
|
||||
url: /tasks/task1
|
||||
method: GET
|
||||
task-parameters:
|
||||
|
||||
task2:
|
||||
parameters:
|
||||
url: /tasks/task2
|
||||
method: GET
|
||||
task-parameters:
|
||||
|
||||
task3:
|
||||
parameters:
|
||||
url: /tasks/task3
|
||||
method: GET
|
||||
task-parameters:
|
||||
|
||||
task4:
|
||||
parameters:
|
||||
url: /tasks/task4
|
||||
method: GET
|
||||
task-parameters:
|
||||
|
||||
Workflow:
|
||||
tasks:
|
||||
task1:
|
||||
action: MyRest:task1
|
||||
parameters:
|
||||
|
||||
task2:
|
||||
requires: [task1]
|
||||
action: MyRest:task2
|
||||
parameters:
|
||||
|
||||
task3:
|
||||
requires: [task1]
|
||||
action: MyRest:task3
|
||||
parameters:
|
||||
|
||||
task4:
|
||||
requires: [task2, task3]
|
||||
action: MyRest:task4
|
||||
parameters:
|
||||
|
||||
events:
|
||||
task4:
|
||||
type: periodic
|
||||
tasks: task4
|
||||
parameters:
|
||||
cron-pattern: "*/1 * * * *"
|
|
@ -0,0 +1,37 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# 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.
|
||||
|
||||
from time import sleep
|
||||
import threading
|
||||
|
||||
from simple_app.api import client
|
||||
|
||||
|
||||
CLIENT = client.CLIENT
|
||||
|
||||
|
||||
def start_task(**kwargs):
|
||||
thread = threading.Thread(target=finish_task, kwargs=kwargs)
|
||||
thread.start()
|
||||
|
||||
|
||||
def finish_task(task_id, execution_id, workbook_name):
|
||||
# simulate working
|
||||
sleep(8)
|
||||
|
||||
task = CLIENT.tasks.update(workbook_name, execution_id,
|
||||
task_id, "SUCCESS")
|
||||
print("Task %s - SUCCESS" % task.name)
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# 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.
|
||||
|
||||
from pbr import version
|
||||
|
||||
version_info = version.VersionInfo('simple_app')
|
||||
version_string = version_info.version_string
|
Loading…
Reference in New Issue