Decoupling magnum service from periodic task
Liberty tech-debt-bug Magnum service was initially utilizing periodic task within magnum conductor. This commit lays out independent periodic framework for magnum service, by decoupling from periodic task. Change-Id: Ie0e725b75069309a9fa783f77c1a454f9dae549e Partial-Bug: 1500998changes/99/246599/4
parent
cb5c74e285
commit
d024bc60c4
|
@ -22,6 +22,7 @@ from oslo_service import service
|
|||
from magnum.common import rpc
|
||||
from magnum.objects import base as objects_base
|
||||
from magnum.service import periodic
|
||||
from magnum.servicegroup import magnum_service_periodic as servicegroup
|
||||
|
||||
|
||||
# NOTE(paulczar):
|
||||
|
@ -69,8 +70,10 @@ class Service(service.Service):
|
|||
self.binary = binary
|
||||
|
||||
def start(self):
|
||||
# NOTE(suro-patz): The parent class has created a threadgroup, already
|
||||
if CONF.periodic_enable:
|
||||
self.tg = periodic.setup(CONF, self.binary)
|
||||
periodic.setup(CONF, self.tg)
|
||||
servicegroup.setup(CONF, self.binary, self.tg)
|
||||
self._server.start()
|
||||
|
||||
def wait(self):
|
||||
|
|
|
@ -18,7 +18,6 @@ import six
|
|||
|
||||
from oslo_log import log
|
||||
from oslo_service import periodic_task
|
||||
from oslo_service import threadgroup
|
||||
|
||||
from magnum.common import clients
|
||||
from magnum.common import context
|
||||
|
@ -61,33 +60,10 @@ class MagnumPeriodicTasks(periodic_task.PeriodicTasks):
|
|||
|
||||
'''
|
||||
|
||||
def __init__(self, conf, binary):
|
||||
self.magnum_service_ref = None
|
||||
self.host = conf.host
|
||||
self.binary = binary
|
||||
def __init__(self, conf):
|
||||
super(MagnumPeriodicTasks, self).__init__(conf)
|
||||
self.notifier = rpc.get_notifier()
|
||||
|
||||
@periodic_task.periodic_task(run_immediately=True)
|
||||
@set_context
|
||||
def update_magnum_service(self, ctx):
|
||||
LOG.debug('Update magnum_service')
|
||||
if self.magnum_service_ref:
|
||||
self.magnum_service_ref.report_state_up(ctx)
|
||||
else:
|
||||
self.magnum_service_ref = \
|
||||
objects.MagnumService.get_by_host_and_binary(
|
||||
ctx, self.host, self.binary)
|
||||
if self.magnum_service_ref is None:
|
||||
magnum_service_dict = {
|
||||
'host': self.host,
|
||||
'binary': self.binary
|
||||
}
|
||||
self.magnum_service_ref = objects.MagnumService(
|
||||
ctx, **magnum_service_dict)
|
||||
self.magnum_service_ref.create(ctx)
|
||||
self.magnum_service_ref.report_state_up(ctx)
|
||||
|
||||
@periodic_task.periodic_task(run_immediately=True)
|
||||
@set_context
|
||||
def sync_bay_status(self, ctx):
|
||||
|
@ -210,11 +186,9 @@ class MagnumPeriodicTasks(periodic_task.PeriodicTasks):
|
|||
message)
|
||||
|
||||
|
||||
def setup(conf, binary):
|
||||
tg = threadgroup.ThreadGroup()
|
||||
pt = MagnumPeriodicTasks(conf, binary)
|
||||
def setup(conf, tg):
|
||||
pt = MagnumPeriodicTasks(conf)
|
||||
tg.add_dynamic_timer(
|
||||
pt.run_periodic_tasks,
|
||||
periodic_interval_max=conf.periodic_interval_max,
|
||||
context=None)
|
||||
return tg
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
# Copyright 2015 - Yahoo! 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.
|
||||
|
||||
"""Magnum Service Layer"""
|
||||
|
||||
from oslo_log import log
|
||||
from oslo_service import periodic_task
|
||||
|
||||
from magnum import objects
|
||||
from magnum.service import periodic
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class MagnumServicePeriodicTasks(periodic_task.PeriodicTasks):
|
||||
'''Magnum periodic Task class
|
||||
|
||||
Any periodic task job need to be added into this class
|
||||
'''
|
||||
|
||||
def __init__(self, conf, binary):
|
||||
self.magnum_service_ref = None
|
||||
self.host = conf.host
|
||||
self.binary = binary
|
||||
super(MagnumServicePeriodicTasks, self).__init__(conf)
|
||||
|
||||
@periodic_task.periodic_task(run_immediately=True)
|
||||
@periodic.set_context
|
||||
def update_magnum_service(self, ctx):
|
||||
LOG.debug('Update magnum_service')
|
||||
if self.magnum_service_ref is None:
|
||||
self.magnum_service_ref = \
|
||||
objects.MagnumService.get_by_host_and_binary(
|
||||
ctx, self.host, self.binary)
|
||||
if self.magnum_service_ref is None:
|
||||
magnum_service_dict = {
|
||||
'host': self.host,
|
||||
'binary': self.binary
|
||||
}
|
||||
self.magnum_service_ref = objects.MagnumService(
|
||||
ctx, **magnum_service_dict)
|
||||
self.magnum_service_ref.create(ctx)
|
||||
self.magnum_service_ref.report_state_up(ctx)
|
||||
|
||||
|
||||
def setup(conf, binary, tg):
|
||||
pt = MagnumServicePeriodicTasks(conf, binary)
|
||||
tg.add_dynamic_timer(
|
||||
pt.run_periodic_tasks,
|
||||
periodic_interval_max=conf.periodic_interval_max,
|
||||
context=None)
|
|
@ -51,14 +51,6 @@ class PeriodicTestCase(base.TestCase):
|
|||
self.bay3 = objects.Bay(ctx, **bay3)
|
||||
self.bay4 = objects.Bay(ctx, **bay4)
|
||||
|
||||
mock_magnum_service_refresh = mock.Mock()
|
||||
|
||||
class FakeMS(object):
|
||||
report_state_up = mock_magnum_service_refresh
|
||||
|
||||
self.fake_ms = FakeMS()
|
||||
self.fake_ms_refresh = mock_magnum_service_refresh
|
||||
|
||||
@mock.patch.object(objects.Bay, 'list')
|
||||
@mock.patch('magnum.common.clients.OpenStackClients')
|
||||
@mock.patch.object(dbapi.Connection, 'destroy_bay')
|
||||
|
@ -79,8 +71,7 @@ class PeriodicTestCase(base.TestCase):
|
|||
mock_keystone_client.client.project_id = "fake_project"
|
||||
mock_osc.keystone.return_value = mock_keystone_client
|
||||
|
||||
periodic.MagnumPeriodicTasks(CONF,
|
||||
'fake-conductor').sync_bay_status(None)
|
||||
periodic.MagnumPeriodicTasks(CONF).sync_bay_status(None)
|
||||
|
||||
self.assertEqual(bay_status.CREATE_COMPLETE, self.bay1.status)
|
||||
self.assertEqual('fake_reason_11', self.bay1.status_reason)
|
||||
|
@ -102,8 +93,7 @@ class PeriodicTestCase(base.TestCase):
|
|||
mock_osc = mock_oscc.return_value
|
||||
mock_osc.heat.return_value = mock_heat_client
|
||||
mock_bay_list.return_value = [self.bay1, self.bay2, self.bay3]
|
||||
periodic.MagnumPeriodicTasks(CONF,
|
||||
'fake-conductor').sync_bay_status(None)
|
||||
periodic.MagnumPeriodicTasks(CONF).sync_bay_status(None)
|
||||
|
||||
self.assertEqual(bay_status.CREATE_IN_PROGRESS, self.bay1.status)
|
||||
self.assertEqual(bay_status.DELETE_IN_PROGRESS, self.bay2.status)
|
||||
|
@ -126,8 +116,7 @@ class PeriodicTestCase(base.TestCase):
|
|||
mock_keystone_client.client.project_id = "fake_project"
|
||||
mock_osc.keystone.return_value = mock_keystone_client
|
||||
|
||||
periodic.MagnumPeriodicTasks(CONF,
|
||||
'fake-conductor').sync_bay_status(None)
|
||||
periodic.MagnumPeriodicTasks(CONF).sync_bay_status(None)
|
||||
|
||||
self.assertEqual(bay_status.CREATE_FAILED, self.bay1.status)
|
||||
self.assertEqual('Stack with id 11 not found in Heat.',
|
||||
|
@ -137,46 +126,6 @@ class PeriodicTestCase(base.TestCase):
|
|||
self.assertEqual('Stack with id 33 not found in Heat.',
|
||||
self.bay3.status_reason)
|
||||
|
||||
@mock.patch.object(objects.MagnumService, 'get_by_host_and_binary')
|
||||
@mock.patch.object(objects.MagnumService, 'create')
|
||||
@mock.patch.object(objects.MagnumService, 'report_state_up')
|
||||
def test_update_magnum_service_firsttime(self,
|
||||
mock_ms_refresh,
|
||||
mock_ms_create,
|
||||
mock_ms_get
|
||||
):
|
||||
periodic_a = periodic.MagnumPeriodicTasks(CONF, 'fake-conductor')
|
||||
mock_ms_get.return_value = None
|
||||
|
||||
periodic_a.update_magnum_service(None)
|
||||
|
||||
mock_ms_get.assert_called_once_with(mock.ANY, periodic_a.host,
|
||||
periodic_a.binary)
|
||||
mock_ms_create.assert_called_once_with(mock.ANY)
|
||||
mock_ms_refresh.assert_called_once_with(mock.ANY)
|
||||
|
||||
@mock.patch.object(objects.MagnumService, 'get_by_host_and_binary')
|
||||
@mock.patch.object(objects.MagnumService, 'create')
|
||||
def test_update_magnum_service_on_restart(self,
|
||||
mock_ms_create,
|
||||
mock_ms_get):
|
||||
periodic_a = periodic.MagnumPeriodicTasks(CONF, 'fake-conductor')
|
||||
mock_ms_get.return_value = self.fake_ms
|
||||
|
||||
periodic_a.update_magnum_service(None)
|
||||
|
||||
mock_ms_get.assert_called_once_with(mock.ANY, periodic_a.host,
|
||||
periodic_a.binary)
|
||||
self.fake_ms_refresh.assert_called_once_with(mock.ANY)
|
||||
|
||||
def test_update_magnum_service_regular(self):
|
||||
periodic_a = periodic.MagnumPeriodicTasks(CONF, 'fake-conductor')
|
||||
periodic_a.magnum_service_ref = self.fake_ms
|
||||
|
||||
periodic_a.update_magnum_service(None)
|
||||
|
||||
self.fake_ms_refresh.assert_called_once_with(mock.ANY)
|
||||
|
||||
@mock.patch('magnum.conductor.monitors.create_monitor')
|
||||
@mock.patch('magnum.objects.Bay.list')
|
||||
@mock.patch('magnum.common.rpc.get_notifier')
|
||||
|
@ -195,8 +144,7 @@ class PeriodicTestCase(base.TestCase):
|
|||
monitor.get_metric_unit.return_value = '%'
|
||||
mock_create_monitor.return_value = monitor
|
||||
|
||||
periodic.MagnumPeriodicTasks(
|
||||
CONF, 'fake-conductor')._send_bay_metrics(self.context)
|
||||
periodic.MagnumPeriodicTasks(CONF)._send_bay_metrics(self.context)
|
||||
|
||||
expected_event_type = 'magnum.bay.metrics.update'
|
||||
expected_metrics = [
|
||||
|
@ -239,8 +187,7 @@ class PeriodicTestCase(base.TestCase):
|
|||
"error on computing metric")
|
||||
mock_create_monitor.return_value = monitor
|
||||
|
||||
periodic.MagnumPeriodicTasks(
|
||||
CONF, 'fake-conductor')._send_bay_metrics(self.context)
|
||||
periodic.MagnumPeriodicTasks(CONF)._send_bay_metrics(self.context)
|
||||
|
||||
expected_event_type = 'magnum.bay.metrics.update'
|
||||
expected_msg = {
|
||||
|
@ -268,8 +215,7 @@ class PeriodicTestCase(base.TestCase):
|
|||
monitor.pull_data.side_effect = Exception("error on pulling data")
|
||||
mock_create_monitor.return_value = monitor
|
||||
|
||||
periodic.MagnumPeriodicTasks(
|
||||
CONF, 'fake-conductor')._send_bay_metrics(self.context)
|
||||
periodic.MagnumPeriodicTasks(CONF)._send_bay_metrics(self.context)
|
||||
|
||||
self.assertEqual(1, mock_create_monitor.call_count)
|
||||
self.assertEqual(0, notifier.info.call_count)
|
||||
|
@ -287,8 +233,7 @@ class PeriodicTestCase(base.TestCase):
|
|||
mock_bay_list.return_value = [self.bay4]
|
||||
mock_create_monitor.return_value = None
|
||||
|
||||
periodic.MagnumPeriodicTasks(
|
||||
CONF, 'fake-conductor')._send_bay_metrics(self.context)
|
||||
periodic.MagnumPeriodicTasks(CONF)._send_bay_metrics(self.context)
|
||||
|
||||
self.assertEqual(1, mock_create_monitor.call_count)
|
||||
self.assertEqual(0, notifier.info.call_count)
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
# Copyright 2015 - Yahoo! 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
|
||||
|
||||
from magnum.common.rpc_service import CONF
|
||||
from magnum import objects
|
||||
from magnum.servicegroup import magnum_service_periodic as periodic
|
||||
from magnum.tests import base
|
||||
|
||||
|
||||
class MagnumServicePeriodicTestCase(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(MagnumServicePeriodicTestCase, self).setUp()
|
||||
mock_magnum_service_refresh = mock.Mock()
|
||||
|
||||
class FakeMS(object):
|
||||
report_state_up = mock_magnum_service_refresh
|
||||
|
||||
self.fake_ms = FakeMS()
|
||||
self.fake_ms_refresh = mock_magnum_service_refresh
|
||||
|
||||
@mock.patch.object(objects.MagnumService, 'get_by_host_and_binary')
|
||||
@mock.patch.object(objects.MagnumService, 'create')
|
||||
@mock.patch.object(objects.MagnumService, 'report_state_up')
|
||||
def test_update_magnum_service_firsttime(self,
|
||||
mock_ms_refresh,
|
||||
mock_ms_create,
|
||||
mock_ms_get
|
||||
):
|
||||
p_task = periodic.MagnumServicePeriodicTasks(CONF,
|
||||
'fake-conductor')
|
||||
mock_ms_get.return_value = None
|
||||
|
||||
p_task.update_magnum_service(None)
|
||||
|
||||
mock_ms_get.assert_called_once_with(mock.ANY, p_task.host,
|
||||
p_task.binary)
|
||||
mock_ms_create.assert_called_once_with(mock.ANY)
|
||||
mock_ms_refresh.assert_called_once_with(mock.ANY)
|
||||
|
||||
@mock.patch.object(objects.MagnumService, 'get_by_host_and_binary')
|
||||
@mock.patch.object(objects.MagnumService, 'create')
|
||||
def test_update_magnum_service_on_restart(self,
|
||||
mock_ms_create,
|
||||
mock_ms_get):
|
||||
p_task = periodic.MagnumServicePeriodicTasks(CONF,
|
||||
'fake-conductor')
|
||||
mock_ms_get.return_value = self.fake_ms
|
||||
|
||||
p_task.update_magnum_service(None)
|
||||
|
||||
mock_ms_get.assert_called_once_with(mock.ANY, p_task.host,
|
||||
p_task.binary)
|
||||
self.fake_ms_refresh.assert_called_once_with(mock.ANY)
|
||||
|
||||
def test_update_magnum_service_regular(self):
|
||||
p_task = periodic.MagnumServicePeriodicTasks(CONF,
|
||||
'fake-conductor')
|
||||
p_task.magnum_service_ref = self.fake_ms
|
||||
|
||||
p_task.update_magnum_service(None)
|
||||
|
||||
self.fake_ms_refresh.assert_called_once_with(mock.ANY)
|
Loading…
Reference in New Issue