Composite paste for monasca-log-api

Following commit introduces using composite
paste file to describe application pipelines.
With the help of composite feature it was possible to
define 4 distinct supapplications, each having different
pipeline setup:

* version_app => no keystoneauth, simple data return with error trap
* healthcheck_app => no keystoneauth, simple data return with error trap
* api_v2 => as it was, added error_trap though
* api_v3 => as it was, added error_trap though

Following approach opens up the possibilities of modelling an API
in far more flexible way and removes the need of any hacking inside
the codebase.

Note:
Keeps backward compatibility with older codebase.

Extra:
* removed dirty hack around skipping certain request.path
in keystonemiddleware (now described in paste file)
* removed 404 when issuing ```curl api_host:api_port/```. Request
is redirected down to VersionApp

Depends-On: I0323eacb5cbba8418550e3322189104c35cf4c36
Change-Id: I873e1376665c8cf66c8ee503975324f9b93ddb45
This commit is contained in:
Tomasz Trębski 2017-05-27 23:59:16 +02:00 committed by Witold Bedyk
parent 3e790fe136
commit 5e7ebdd9c5
19 changed files with 361 additions and 301 deletions

View File

@ -182,15 +182,15 @@ function configure_monasca_log_api {
create_log_api_cache_dir
# ensure fresh installation of configuration files
rm -rf $MONASCA_LOG_API_CONF $MONASCA_LOG_API_PASTE_INI $MONASCA_LOG_API_LOGGING_CONF
rm -rf $MONASCA_LOG_API_CONF $MONASCA_LOG_API_PASTE $MONASCA_LOG_API_LOGGING_CONF
if [[ "$MONASCA_LOG_API_CONF_DIR" != "$MONASCA_LOG_API_DIR/etc/monasca" ]]; then
install -m 600 $MONASCA_LOG_API_DIR/etc/monasca/log-api-config.conf $MONASCA_LOG_API_CONF
install -m 600 $MONASCA_LOG_API_DIR/etc/monasca/log-api-config.ini $MONASCA_LOG_API_PASTE_INI
install -m 600 $MONASCA_LOG_API_DIR/etc/monasca/log-api.conf $MONASCA_LOG_API_CONF
install -m 600 $MONASCA_LOG_API_DIR/etc/monasca/log-api-paste.ini $MONASCA_LOG_API_PASTE
install -m 600 $MONASCA_LOG_API_DIR/etc/monasca/log-api-logging.conf $MONASCA_LOG_API_LOGGING_CONF
fi
# configure log-api-config.conf
# configure log-api.conf
iniset "$MONASCA_LOG_API_CONF" DEFAULT log_config_append $MONASCA_LOG_API_LOGGING_CONF
iniset "$MONASCA_LOG_API_CONF" service region $REGION_NAME
iniset "$MONASCA_LOG_API_CONF" log_publisher kafka_url $KAFKA_SERVICE_HOST:$KAFKA_SERVICE_PORT
@ -207,11 +207,10 @@ function configure_monasca_log_api {
iniset "$MONASCA_LOG_API_CONF" keystone_authtoken insecure False
fi
# configure log-api-config.ini
iniset "$MONASCA_LOG_API_PASTE_INI" server:main host $MONASCA_LOG_API_SERVICE_HOST
iniset "$MONASCA_LOG_API_PASTE_INI" server:main port $MONASCA_LOG_API_SERVICE_PORT
iniset "$MONASCA_LOG_API_PASTE_INI" server:main chdir $MONASCA_LOG_API_DIR
iniset "$MONASCA_LOG_API_PASTE_INI" server:main workers $API_WORKERS
# configure log-api-paste.ini
iniset "$MONASCA_LOG_API_PASTE" server:main bind $MONASCA_LOG_API_SERVICE_HOST:$MONASCA_LOG_API_SERVICE_PORT
iniset "$MONASCA_LOG_API_PASTE" server:main chdir $MONASCA_LOG_API_DIR
iniset "$MONASCA_LOG_API_PASTE" server:main workers $API_WORKERS
# WSGI
if [ "$MONASCA_LOG_API_USE_MOD_WSGI" == "True" ]; then
@ -220,7 +219,7 @@ function configure_monasca_log_api {
# link configuration for the gate
ln -sf $MONASCA_LOG_API_CONF $GATE_CONFIGURATION_DIR
ln -sf $MONASCA_LOG_API_PASTE_INI $GATE_CONFIGURATION_DIR
ln -sf $MONASCA_LOG_API_PASTE $GATE_CONFIGURATION_DIR
ln -sf $MONASCA_LOG_API_LOGGING_CONF $GATE_CONFIGURATION_DIR
fi
@ -248,7 +247,7 @@ function configure_monasca_log_api_wsgi {
fi
# copy proxy vhost and wsgi helper files
sudo cp $MONASCA_LOG_API_DIR/monasca_log_api/wsgi/monasca_log_api.py $MONASCA_LOG_API_WSGI_DIR/monasca_log_api
sudo cp $MONASCA_LOG_API_DIR/monasca_log_api/app/wsgi.py $MONASCA_LOG_API_WSGI_DIR/monasca_log_api
sudo cp $PLUGIN_FILES/apache-log-api.template $monasca_log_api_apache_conf
sudo sed -e "
s|%PUBLICPORT%|$monasca_log_api_api_port|g;
@ -272,7 +271,7 @@ function clean_monasca_log_api {
echo_summary "Cleaning monasca-log-api"
sudo rm -f $MONASCA_LOG_API_CONF || true
sudo rm -f $MONASCA_LOG_API_PASTE_INI || true
sudo rm -f $MONASCA_LOG_API_PASTE || true
sudo rm -f $MONASCA_LOG_API_LOGGING_CONF || true
sudo rm -rf $MONASCA_LOG_API_CACHE_DIR || true
sudo rm -rf $MONASCA_LOG_API_CONF_DIR || true
@ -311,7 +310,7 @@ function start_monasca_log_api {
tail_log monasca-log-api /var/log/$APACHE_NAME/monasca-log-api.log
else
local gunicorn="$MONASCA_LOG_API_BIN_DIR/gunicorn"
run_process "monasca-log-api" "$gunicorn -n monasca-log-api -k eventlet --paste $MONASCA_LOG_API_PASTE_INI"
run_process "monasca-log-api" "$gunicorn --paste $MONASCA_LOG_API_PASTE"
fi
echo "Waiting for monasca-log-api to start..."

View File

@ -62,8 +62,8 @@ LIBS_FROM_GIT="${LIBS_FROM_GIT:-""},monasca-common,monasca-statsd"
# configuration bits
MONASCA_LOG_API_CONF_DIR=${MONASCA_LOG_API_CONF_DIR:-/etc/monasca}
MONASCA_LOG_API_CONF=${MONASCA_LOG_API_CONF:-$MONASCA_LOG_API_CONF_DIR/log-api-config.conf}
MONASCA_LOG_API_PASTE_INI=${MONASCA_LOG_API_PASTE_INI:-$MONASCA_LOG_API_CONF_DIR/log-api-config.ini}
MONASCA_LOG_API_CONF=${MONASCA_LOG_API_CONF:-$MONASCA_LOG_API_CONF_DIR/log-api.conf}
MONASCA_LOG_API_PASTE=${MONASCA_LOG_API_PASTE:-$MONASCA_LOG_API_CONF_DIR/log-api-paste.ini}
MONASCA_LOG_API_LOGGING_CONF=${MONASCA_LOG_API_LOGGING_CONF:-$MONASCA_LOG_API_CONF_DIR/log-api-logging.conf}
MONASCA_LOG_API_CACHE_DIR=${MONASCA_LOG_API_CACHE_DIR:-/var/cache/monasca-log-api}

View File

@ -1,45 +0,0 @@
#
# Copyright 2016 FUJITSU LIMITED
#
# 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.
#
[DEFAULT]
name = monasca_log_api
[pipeline:main]
pipeline = request_id auth roles api
[app:api]
paste.app_factory = monasca_log_api.server:launch
[filter:auth]
paste.filter_factory = monasca_log_api.healthcheck.keystone_protocol:filter_factory
[filter:roles]
paste.filter_factory = monasca_log_api.middleware.role_middleware:RoleMiddleware.factory
[filter:request_id]
paste.filter_factory = oslo_middleware.request_id:RequestId.factory
[server:main]
use = egg:gunicorn#main
host = 127.0.0.1
port = 5607
workers = 9
worker-connections = 2000
backlog = 1000
proc_name = monasca_log_api
loglevel = DEBUG
chdir = /opt/monasca-log-api

View File

@ -0,0 +1,81 @@
#
# Copyright 2016-2017 FUJITSU LIMITED
#
# 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.
#
[DEFAULT]
name = main
[composite:main]
use = egg:Paste#urlmap
/: la_version
/healthcheck: la_healthcheck
/v2.0: la_api_v2
/v3.0: la_api_v3
[pipeline:la_version]
pipeline = error_trap versionapp
[pipeline:la_healthcheck]
pipeline = error_trap healthcheckapp
[pipeline:la_api_v2]
pipeline = error_trap request_id auth roles api_v2_app
[pipeline:la_api_v3]
pipeline = error_trap request_id auth roles api_v3_app
[app:versionapp]
paste.app_factory = monasca_log_api.app.api:create_version_app
[app:healthcheckapp]
paste.app_factory = monasca_log_api.app.api:create_healthcheck_app
[app:api_v2_app]
paste.app_factory = monasca_log_api.app.api:create_api_app
set api_version=v2.0
[app:api_v3_app]
paste.app_factory = monasca_log_api.app.api:create_api_app
set api_version=v3.0
[filter:auth]
paste.filter_factory = keystonemiddleware.auth_token:filter_factory
[filter:roles]
paste.filter_factory = monasca_log_api.middleware.role_middleware:RoleMiddleware.factory
[filter:request_id]
paste.filter_factory = oslo_middleware.request_id:RequestId.factory
# NOTE(trebskit) this is optional
# insert this into either pipeline to get some WSGI environment debug output
[filter:debug]
paste.filter_factory = oslo_middleware.debug:Debug.factory
[filter:error_trap]
paste.filter_factory = oslo_middleware.catch_errors:CatchErrors.factory
[server:main]
use = egg:gunicorn#main
bind = 127.0.0.1:5607
workers = 9
worker-connections = 2000
worker-class = eventlet
timeout = 30
backlog = 2048
keepalive = 2
proc_name = monasca-log-api
loglevel = DEBUG

View File

@ -20,12 +20,6 @@
[DEFAULT]
log_config_append=/etc/monasca/log-api-logging.conf
[dispatcher]
logs = monasca_log_api.reference.v2.logs:Logs
logs_v3 = monasca_log_api.reference.v3.logs:Logs
versions = monasca_log_api.reference.versions:Versions
healthchecks = monasca_log_api.reference.healthchecks:HealthChecks
[monitoring]
statsd_host = 127.0.0.1
statsd_port = 8125

View File

@ -64,7 +64,7 @@ class Request(falcon.Request):
:rtype: str
"""
return self.context.tenant
return self.context.project_id
@property
def cross_project_id(self):

View File

154
monasca_log_api/app/api.py Normal file
View File

@ -0,0 +1,154 @@
# Copyright 2017 FUJITSU LIMITED
#
# 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.
"""
Module contains factories to initializes various applications
of monasca-log-api
"""
import six
import falcon
from oslo_config import cfg
from oslo_log import log
from monasca_log_api.api.core import request
from monasca_log_api.reference.common import error_handlers
from monasca_log_api.reference import healthchecks
from monasca_log_api.reference.v2 import logs as v2_logs
from monasca_log_api.reference.v3 import logs as v3_logs
from monasca_log_api.reference import versions
from monasca_log_api import version
LOG = log.getLogger(__name__)
CONF = cfg.CONF
_CONF_LOADED = False
def error_trap(app_name):
"""Decorator trapping any error during application boot time"""
@six.wraps(error_trap)
def _wrapper(func):
@six.wraps(_wrapper)
def _inner_wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception:
LOG.exception('Failed to load application \'%s\'', app_name)
raise
return _inner_wrapper
return _wrapper
def singleton_config(func):
"""Decorator ensuring that configuration is loaded only once."""
@six.wraps(singleton_config)
def _wrapper(global_config, **local_conf):
_load_config()
return func(global_config, **local_conf)
def _load_config():
global _CONF_LOADED
if _CONF_LOADED:
LOG.debug('Configuration has been already loaded')
return
log.set_defaults()
log.register_options(CONF)
CONF(args=[],
# NOTE(trebskit) this disables any oslo.cfg CLI
# opts as gunicorn has some trouble with them
# i.e. gunicorn's argparse clashes with the one
# defined inside oslo.cfg
prog='log-api',
project='monasca',
version=version.version_str,
description='REST-ful API to collect log files')
log.setup(CONF,
product_name='monasca-log-api',
version=version.version_str)
_CONF_LOADED = True
return _wrapper
@error_trap('version')
def create_version_app(global_conf, **local_conf):
"""Creates Version application"""
ctrl = versions.Versions()
controllers = {
'/': ctrl, # redirect http://host:port/ down to Version app
# avoid conflicts with actual pipelines and 404 error
'/version': ctrl, # list all the versions
'/version/{version_id}': ctrl # display details of the version
}
wsgi_app = falcon.API()
for route, ctrl in controllers.items():
wsgi_app.add_route(route, ctrl)
return wsgi_app
@error_trap('healthcheck')
def create_healthcheck_app(global_conf, **local_conf):
"""Creates Healthcheck application"""
ctrl = healthchecks.HealthChecks()
controllers = {
'/': ctrl
}
wsgi_app = falcon.API()
for route, ctrl in controllers.items():
wsgi_app.add_route(route, ctrl)
return wsgi_app
@error_trap('api')
@singleton_config
def create_api_app(global_conf, **local_conf):
"""Creates MainAPI application"""
controllers = {}
api_version = global_conf.get('api_version')
if api_version == 'v2.0':
controllers.update({
'/log/single': v2_logs.Logs()
})
elif api_version == 'v3.0':
controllers.update({
'/logs': v3_logs.Logs()
})
wsgi_app = falcon.API(
request_type=request.Request
)
for route, ctrl in controllers.items():
wsgi_app.add_route(route, ctrl)
error_handlers.register_error_handlers(wsgi_app)
return wsgi_app

View File

@ -0,0 +1,48 @@
# Copyright 2017 FUJITSU LIMITED
#
# 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.
"""
Allows to run monasca-log-api from within local [dev] environment.
Primarily used for development.
"""
import sys
from paste import deploy
from paste import httpserver
from monasca_log_api import version
def get_wsgi_app():
config_dir = 'etc/monasca'
return deploy.loadapp(
'config:%s/log-api-paste.ini' % config_dir,
relative_to='../../',
name='main'
)
def main():
wsgi_app = get_wsgi_app()
server_version = 'log-api/%s' % version.version_str
server = httpserver.serve(application=wsgi_app, host='127.0.0.1',
port=5607, server_version=server_version)
return server
if __name__ == '__main__':
sys.exit(main())

View File

@ -0,0 +1,30 @@
# Copyright 2017 FUJITSU LIMITED
#
# 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.
"""
Use this file for deploying the API under mod_wsgi.
"""
from paste import deploy
def main():
base_dir = '/etc/monasca/'
conf = '%slog-api-paste.ini' % base_dir
app = deploy.loadapp('config:%s' % conf)
return app
if __name__ == '__main__':
application = main()

View File

@ -1,65 +0,0 @@
# Copyright 2016 FUJITSU LIMITED
#
# 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 keystonemiddleware import auth_token
from oslo_log import log
LOG = log.getLogger(__name__)
_SKIP_PATH = '/version', '/healthcheck'
"""Tuple of non-application endpoints"""
class SkippingAuthProtocol(auth_token.AuthProtocol):
"""SkippingAuthProtocol to reach healthcheck endpoint
Because healthcheck endpoints exists as endpoint, it
is hidden behind keystone filter thus a request
needs to authenticated before it is reached.
Note:
SkippingAuthProtocol is lean customization
of :py:class:`keystonemiddleware.auth_token.AuthProtocol`
that disables keystone communication if request
is meant to reach healthcheck
"""
def process_request(self, request):
path = request.path
for p in _SKIP_PATH:
if path.startswith(p):
LOG.debug(
('Request path is %s and it does not require keystone '
'communication'), path)
return None # return NONE to reach actual logic
return super(SkippingAuthProtocol, self).process_request(request)
def filter_factory(global_conf, **local_conf): # pragma: no cover
"""Return factory function for :py:class:`.SkippingAuthProtocol`
:param global_conf: global configuration
:param local_conf: local configuration
:return: factory function
:rtype: function
"""
conf = global_conf.copy()
conf.update(local_conf)
def auth_filter(app):
return SkippingAuthProtocol(app, conf)
return auth_filter

View File

@ -20,10 +20,9 @@ from monasca_log_api.api import headers
from monasca_log_api.api import logs_api
from monasca_log_api.reference.common import log_publisher
from monasca_log_api.reference.v2.common import service
from monasca_log_api import uri_map
_DEPRECATED_INFO = ('%s has been deprecated. Please use %s.'
% (uri_map.V2_LOGS_URI, uri_map.V3_LOGS_URI))
_DEPRECATED_INFO = ('/v2.0/log/single has been deprecated. '
'Please use /v3.0/logs')
class Logs(logs_api.LogsApi):
@ -91,4 +90,4 @@ def _get_v3_link(req):
if six.PY2:
self_uri = self_uri.decode('UTF-8')
base_uri = self_uri.replace(req.relative_uri, '')
return '%s%s' % (base_uri, uri_map.V3_LOGS_URI)
return '%s/v3.0/logs' % base_uri

View File

@ -1,113 +0,0 @@
# Copyright 2015 kornicameister@gmail.com
# Copyright 2016-2017 FUJITSU LIMITED
#
# 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 os
from wsgiref import simple_server
import falcon
from monasca_common.simport import simport
from oslo_config import cfg
from oslo_log import log
import paste.deploy
from monasca_log_api.api.core import request
from monasca_log_api.reference.common import error_handlers
from monasca_log_api import uri_map
LOG = log.getLogger(__name__)
CONF = cfg.CONF
dispatcher_opts = [
cfg.StrOpt('versions',
default=None,
required=True,
help='Versions endpoint'),
cfg.StrOpt('logs',
default=None,
required=True,
help='Logs endpoint'),
cfg.StrOpt('healthchecks',
default=None,
required=True,
help='Healthchecks endpoint'),
cfg.StrOpt('logs_v3',
default=None,
help='Logs')
]
dispatcher_group = cfg.OptGroup(name='dispatcher', title='dispatcher')
CONF.register_group(dispatcher_group)
CONF.register_opts(dispatcher_opts, dispatcher_group)
log.register_options(CONF)
def launch(conf, config_file='/etc/monasca/log-api-config.conf'):
if conf and 'config_file' in conf:
config_file = conf.get('config_file')
log.set_defaults()
CONF(args=[],
project='monasca_log_api',
default_config_files=[config_file])
log.setup(CONF, 'monasca_log_api')
app = falcon.API(request_type=request.Request)
load_versions_resource(app)
load_logs_resource(app)
load_healthcheck_resource(app)
error_handlers.register_error_handlers(app)
LOG.debug('Dispatcher drivers have been added to the routes!')
return app
def load_healthcheck_resource(app):
healthchecks = simport.load(CONF.dispatcher.healthchecks)()
app.add_route(uri_map.HEALTHCHECK_URI, healthchecks)
def load_logs_resource(app):
logs = simport.load(CONF.dispatcher.logs)()
app.add_route(uri_map.V2_LOGS_URI, logs)
logs_v3 = simport.load(CONF.dispatcher.logs_v3)()
app.add_route(uri_map.V3_LOGS_URI, logs_v3)
def load_versions_resource(app):
versions = simport.load(CONF.dispatcher.versions)()
app.add_route("/version", versions)
app.add_route("/version/{version_id}", versions)
def get_wsgi_app(config_base_path=None):
if config_base_path is None:
config_base_path = os.path.join(
os.path.dirname(os.path.realpath(__file__)), '../etc/monasca')
global_conf = {'config_file': (
os.path.join(config_base_path, 'log-api-config.conf'))}
return (
paste.deploy.loadapp(
'config:log-api-config.ini',
relative_to=config_base_path,
global_conf=global_conf
)
)
if __name__ == '__main__':
wsgi_app = get_wsgi_app()
httpd = simple_server.make_server('127.0.0.1', 5607, wsgi_app)
httpd.serve_forever()

View File

@ -1,43 +0,0 @@
# Copyright 2015-2017 FUJITSU LIMITED
#
# 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
from oslotest import base
from monasca_log_api.healthcheck import keystone_protocol
_APP = mock.Mock()
_CONF = {}
class TestKeystoneProtocol(base.BaseTestCase):
def test_should_return_none_if_healthcheck(self):
instance = keystone_protocol.SkippingAuthProtocol(_APP, _CONF)
request = mock.Mock()
request.path = '/healthcheck'
ret_val = instance.process_request(request)
self.assertIsNone(ret_val)
@mock.patch('keystonemiddleware.auth_token.AuthProtocol.process_request')
def test_should_enter_keystone_auth_if_not_healthcheck(self, proc_request):
instance = keystone_protocol.SkippingAuthProtocol(_APP, _CONF)
request = mock.Mock()
request.path = '/v2.0/logs/single'
instance.process_request(request)
self.assertTrue(proc_request.called)

View File

@ -0,0 +1,22 @@
# Copyright 2017 FUJITSU LIMITED
#
# 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 oslotest import base
from monasca_log_api import version
class TestAppVersion(base.BaseTestCase):
def test_should_report_version(self):
self.assertIsNotNone(version.version_str)

View File

@ -1,3 +0,0 @@
V2_LOGS_URI = '/v2.0/log/single'
V3_LOGS_URI = '/v3.0/logs'
HEALTHCHECK_URI = '/healthcheck'

View File

@ -12,9 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
# extremely simple way to setup of monasca-log-api
# with wsgi
import pbr.version
from monasca_log_api import server
application = server.get_wsgi_app(config_base_path='/etc/monasca')
version_info = pbr.version.VersionInfo('monasca-log-api')
version_str = version_info.version_string()

View File

@ -33,7 +33,10 @@ data_files =
[entry_points]
console_scripts =
monasca-log-api = monasca_log_api.server:launch
monasca-log-api = monasca_log_api.app.main:main
wsgi_scripts =
monasca-log-api-wsgi = monasca_log_api.app.wsgi:main
tempest.test_plugins =
monasca_log_api_tests = monasca_log_api_tempest.plugin:MonascaLogApiTempestPlugin

View File

@ -22,6 +22,7 @@ deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands =
find ./ -type f -name '*.pyc' -delete
rm -Rf .testrepository/times.dbm
[testenv:py27]
basepython = python2.7