From 45564ce45da6fe1cb01138beff4f5aa40c055565 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Fri, 6 Jun 2014 12:05:08 -0300 Subject: [PATCH] nailing down the layered implementation scheme --- quincy/api.py | 63 ++++++++++++++++++++++++++++++++++++++--------- quincy/v1_api.py | 4 +-- quincy/v1_impl.py | 33 +++++++++++++++++++++++++ quincy/v2_api.py | 20 +++++++++++++++ quincy/v2_impl.py | 20 +++++++++++++++ requirements.txt | 1 + tox.ini | 8 +++--- 7 files changed, 131 insertions(+), 18 deletions(-) create mode 100644 quincy/v1_impl.py create mode 100644 quincy/v2_api.py create mode 100644 quincy/v2_impl.py diff --git a/quincy/api.py b/quincy/api.py index 59f63c4..6dc8dda 100644 --- a/quincy/api.py +++ b/quincy/api.py @@ -14,23 +14,64 @@ # limitations under the License. import falcon +import simport + import v1_api +import v2_api -class V1TestImplementation(object): - def get_events(self, resp): - return [] +class NotImplemented(Exception): + pass -versions = {1: v1_api.Schema, - 2: v2_api.Schema} +def _load_implementations(impl_map, versions, config): + for version in versions: + target = config.get('v%d_impl' % version) + klass = simport.load(target) + impl_map[version] = klass() -enabled_versions = [1, 2] -api = falcon.API() +def _initialize(self, enabled_versions, implementation_map): + # The de facto set of supported versions. + versions = {1: v1_api.Schema, + 2: v2_api.Schema} -routes = [] -for version in enabled_version: - klass = versions[version] - routes.append(version, klass(api)) + api = falcon.API() + + routes = [] + for version in enabled_version: + klass = versions[version] + impl = implementation_map.get(version) + if not impl: + raise NotImplemented("No implementation available for Quincy" + " version %d" % version) + routes.append(klass(api, impl)) + + # TODO(sandy): We need to create the /v1 + # ... + # /vN + # resources here too. + + +if __name__ == '__main__': + # There may have been prior versions + # but they could be deprecated and dropped. + # Only the versions specified here define + # the currently supported StackTach.v3 API. + enabled_versions = [1, 2] + + # The default implementation is internal and works with + # a fake/static set of data. + local_config = {'v1_impl': 'v1_impl.Impl', + 'v2_impl': 'v2_impl.Impl'} + + impl_map = {} + _load_implementations(impl_map, enabled_versions, local_config) + + # TODO(sandy): Overlay the impl_map with the implementations + # specified in the config file. + # config = ... + # _load_implementations(impl_map, enabled_versions, config) + + _initialize(enabled_versions, impl_map) diff --git a/quincy/v1_api.py b/quincy/v1_api.py index 3ee6d63..2ee2e3e 100644 --- a/quincy/v1_api.py +++ b/quincy/v1_api.py @@ -32,9 +32,9 @@ class Schema(object): def _v(self): return "/v%d" % self.version - def __init__(self, version, api): + def __init__(self, version, api, impl): self.api = api - self.impl = Impl() + self.impl = impl self.event_collection = EventCollection(impl) self.event_item = EventItem(impl) self.version = version diff --git a/quincy/v1_impl.py b/quincy/v1_impl.py new file mode 100644 index 0000000..fbdb628 --- /dev/null +++ b/quincy/v1_impl.py @@ -0,0 +1,33 @@ +# Copyright (c) 2014 Dark Secret Software 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 datetime +import uuid + + +class Event(object): + def __init__(self, request_id, name): + self.when = datetime.datetime.utcnow() + self.name = name + self.request_id = request_id + self.message_id = str(uuid.uuid4()) + + +class Impl(object): + def get_events(self, resp): + rid = str(uuid.uuid4()) + return [Event(rid, "scheduler.run_instance.start"), + Event(rid, "scheduler.run_instanace.scheduled"), + Event(rid, "scheduler.run_instance.end")] diff --git a/quincy/v2_api.py b/quincy/v2_api.py new file mode 100644 index 0000000..0b25c67 --- /dev/null +++ b/quincy/v2_api.py @@ -0,0 +1,20 @@ +# Copyright (c) 2014 Dark Secret Software 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 v1_api + + +class Schema(v1_api.Schema): + pass diff --git a/quincy/v2_impl.py b/quincy/v2_impl.py new file mode 100644 index 0000000..206f00e --- /dev/null +++ b/quincy/v2_impl.py @@ -0,0 +1,20 @@ +# Copyright (c) 2014 Dark Secret Software 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 v1_impl + + +class Impl(v1_impl.Impl): + pass diff --git a/requirements.txt b/requirements.txt index b3e647d..657218c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ falcon +json simport >= 0.0.dev0 diff --git a/tox.ini b/tox.ini index ca0ec80..e869052 100644 --- a/tox.ini +++ b/tox.ini @@ -3,13 +3,11 @@ envlist = py26,py27 [testenv] deps = + falcon + json coverage nose mock - notigen - notification_utils - pyrax - python-dateutil simport -commands = nosetests -d -v --with-coverage --cover-inclusive --cover-package shoebox [] +commands = nosetests -d -v --with-coverage --cover-inclusive --cover-package quincy []