evaluator - adding RCA action

Change-Id: I6f957587ac69eacc5ce71c0b72bc0610a1370f66
This commit is contained in:
Liat Har-Tal 2016-03-09 07:16:12 +00:00
parent 9cb5557d24
commit 97caf84d0f
9 changed files with 166 additions and 29 deletions

View File

@ -40,6 +40,7 @@ class EdgeProperties(object):
class EdgeLabels(object):
ON = 'on'
CONTAINS = 'contains'
CAUSES = 'causes'
class SyncMode(object):

View File

@ -129,7 +129,7 @@ class Processor(processor.ProcessorBase):
LOG.info("Delete event arrived on invalid resource: %s",
deleted_vertex)
def update_relationship(self, updated_vertex, neighbors):
def update_relationship(self, entity_vertex, neighbors):
LOG.debug("Update relationship in entity graph: %s", neighbors)
for neighbor in neighbors:
@ -254,14 +254,18 @@ class Processor(processor.ProcessorBase):
def _calculate_aggregated_state(self, vertex, action):
LOG.debug("calculate event state")
if action in [EventAction.UPDATE_ENTITY, EventAction.DELETE_ENTITY,
if action in [EventAction.UPDATE_ENTITY,
EventAction.DELETE_ENTITY,
EventAction.CREATE_ENTITY]:
graph_vertex = self.entity_graph.get_vertex(vertex.vertex_id)
elif action == EventAction.END_MESSAGE:
elif action in [EventAction.END_MESSAGE,
EventAction.UPDATE_RELATIONSHIP,
EventAction.DELETE_RELATIONSHIP]:
return None
else:
LOG.info('not recognized action: %s for vertex: %s',
action, vertex)
return None
state = self._get_updated_property(vertex, graph_vertex, VProps.STATE)
vitrage_state = self._get_updated_property(vertex,

View File

@ -16,6 +16,7 @@ import copy
from oslo_log import log as logging
from oslo_utils import importutils
from vitrage.common.constants import EdgeProperties as EProps
from vitrage.common.constants import EntityType
from vitrage.common.constants import SynchronizerProperties as SyncProps
from vitrage.common.constants import SyncMode
@ -42,7 +43,7 @@ class ActionExecutor(object):
def __init__(self, event_queue):
self.event_queue = event_queue
self.action_recipes = self._register_action_recipes()
self.action_recipes = ActionExecutor._register_action_recipes()
self.action_step_defs = {
ADD_VERTEX: self.add_vertex,
@ -70,9 +71,7 @@ class ActionExecutor(object):
def update_vertex(self, params):
event = copy.deepcopy(params)
event[SyncProps.SYNC_MODE] = SyncMode.UPDATE
event[SyncProps.SYNC_TYPE] = EntityType.VITRAGE
event[SyncProps.SAMPLE_DATE] = str(datetime_utils.utcnow())
ActionExecutor._add_default_properties(event)
event[EVALUATOR_EVENT_TYPE] = UPDATE_VERTEX
self.event_queue.put(event)
@ -81,15 +80,33 @@ class ActionExecutor(object):
pass
def add_edge(self, params):
pass
event = copy.deepcopy(params)
ActionExecutor._add_default_properties(event)
event[EVALUATOR_EVENT_TYPE] = ADD_EDGE
self.event_queue.put(event)
def remove_edge(self, params):
pass
event = copy.deepcopy(params)
ActionExecutor._add_default_properties(event)
event[EVALUATOR_EVENT_TYPE] = REMOVE_EDGE
self.event_queue.put(event)
def notify(self, params):
pass
def _register_action_recipes(self):
@staticmethod
def _add_default_properties(event):
event[SyncProps.SYNC_MODE] = SyncMode.UPDATE
event[SyncProps.SYNC_TYPE] = EntityType.VITRAGE
event[EProps.UPDATE_TIMESTAMP] = str(datetime_utils.utcnow())
@staticmethod
def _register_action_recipes():
recipes = {}

View File

@ -13,12 +13,16 @@
# under the License.
from oslo_log import log as logging
from vitrage.common.constants import EdgeProperties as EProps
from vitrage.common.constants import EventAction
from vitrage.common.constants import SynchronizerProperties as SyncProps
from vitrage.common.constants import VertexProperties as VProps
from vitrage.common.exception import VitrageTransformerError
from vitrage.evaluator.actions.recipes.action_steps import ADD_EDGE
from vitrage.evaluator.actions.recipes.action_steps import REMOVE_EDGE
from vitrage.evaluator.actions.recipes.action_steps import UPDATE_VERTEX
from vitrage.evaluator.actions.recipes.base import EVALUATOR_EVENT_TYPE
from vitrage.evaluator.template_fields import TemplateFields
import vitrage.graph.utils as graph_utils
from vitrage.graph import Vertex
from vitrage.synchronizer.plugins import transformer_base
@ -39,13 +43,26 @@ class EvaluatorEventTransformer(transformer_base.TransformerBase):
properties = {
VProps.VITRAGE_STATE: event[VProps.VITRAGE_STATE],
VProps.UPDATE_TIMESTAMP: event[SyncProps.SAMPLE_DATE]
VProps.UPDATE_TIMESTAMP: event[VProps.UPDATE_TIMESTAMP]
}
return Vertex(event[VProps.VITRAGE_ID], properties)
return None
def _create_neighbors(self, event):
event_type = event[EVALUATOR_EVENT_TYPE]
if event_type in [ADD_EDGE, REMOVE_EDGE]:
relation_edge = graph_utils.create_edge(
source_id=event[TemplateFields.SOURCE],
target_id=event[TemplateFields.TARGET],
relationship_type=event[EProps.RELATIONSHIP_NAME],
update_timestamp=event[EProps.UPDATE_TIMESTAMP])
return [transformer_base.Neighbor(None, relation_edge)]
return []
def _extract_action_type(self, event):
@ -54,6 +71,10 @@ class EvaluatorEventTransformer(transformer_base.TransformerBase):
if event_type == UPDATE_VERTEX:
return EventAction.UPDATE_ENTITY
if event_type == ADD_EDGE:
return EventAction.UPDATE_RELATIONSHIP
if event_type == REMOVE_EDGE:
return EventAction.DELETE_RELATIONSHIP
raise VitrageTransformerError(
'Invalid Evaluator event type: (%s)' % event_type)

View File

@ -11,18 +11,40 @@
# 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 vitrage.common.constants import EdgeLabels
from vitrage.common.constants import EdgeProperties
from vitrage.evaluator.actions.recipes.action_steps import ADD_EDGE
from vitrage.evaluator.actions.recipes.action_steps import REMOVE_EDGE
from vitrage.evaluator.actions.recipes import base
from vitrage.evaluator.actions.recipes.base import ActionStepWrapper
from vitrage.evaluator.template_fields import TemplateFields as TFields
class AddCausalRelationship(base.Recipe):
@staticmethod
def get_do_recipe(params):
# Add edge
pass
def get_do_recipe(action_spec):
edge_params = AddCausalRelationship._get_edge_params(
action_spec.targets)
add_edge_step = ActionStepWrapper(ADD_EDGE, edge_params)
return [add_edge_step]
@staticmethod
def get_undo_recipe(params):
# Remove edge
pass
def get_undo_recipe(action_spec):
edge_params = AddCausalRelationship._get_edge_params(
action_spec.targets)
remove_edge_step = ActionStepWrapper(REMOVE_EDGE, edge_params)
return [remove_edge_step]
@staticmethod
def _get_edge_params(params):
return {
TFields.SOURCE: params[TFields.SOURCE],
TFields.TARGET: params[TFields.TARGET],
EdgeProperties.RELATIONSHIP_NAME: EdgeLabels.CAUSES
}

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from vitrage.common.constants import VertexProperties as VProps
from vitrage.evaluator.actions.recipes.action_steps import NOTIFY
from vitrage.evaluator.actions.recipes.action_steps import UPDATE_VERTEX
from vitrage.evaluator.actions.recipes import base
from vitrage.evaluator.actions.recipes.base import ActionStepWrapper
@ -27,9 +28,9 @@ class SetState(base.Recipe):
action_spec.targets[TFields.TARGET],
action_spec.properties[TFields.STATE])
# TODO(lhartal): add notify step
notify_step = SetState._get_notify_step()
return [update_vertex_step]
return [update_vertex_step, notify_step]
@staticmethod
def get_undo_recipe(action_spec):
@ -38,9 +39,9 @@ class SetState(base.Recipe):
action_spec.targets[TFields.TARGET],
None)
# TODO(lhartal): add notify step
notify_step = SetState._get_notify_step()
return [update_vertex_step]
return [update_vertex_step, notify_step]
@staticmethod
def _get_update_vertex_step(target_id, vitrage_state):
@ -53,3 +54,9 @@ class SetState(base.Recipe):
update_vertex_params)
return update_vertex_step
@staticmethod
def _get_notify_step():
# TODO(lhartal): add params
return ActionStepWrapper(NOTIFY, {})

View File

@ -38,9 +38,8 @@ Neighbor = namedtuple('Neighbor', ['vertex', 'edge'])
TIMESTAMP_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
AVAILABLE = 'available'
Neighbor = namedtuple('Neighbor', ['vertex', 'edge'])
AVAILABLE = 'available'
def extract_field_value(entity_event, key_names):

View File

@ -0,0 +1,65 @@
# Copyright 2016 - Nokia
#
# 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_log import log as logging
from vitrage.common.constants import EdgeLabels
from vitrage.common.constants import EdgeProperties
from vitrage.evaluator.actions.base import ActionType
from vitrage.evaluator.actions.recipes.action_steps import ADD_EDGE
from vitrage.evaluator.actions.recipes.add_causal_relationship import \
AddCausalRelationship
from vitrage.evaluator.template import ActionSpecs
from vitrage.evaluator.template_fields import TemplateFields as TField
from vitrage.tests import base
LOG = logging.getLogger(__name__)
class AddCausalRelationshipTest(base.BaseTest):
def test_get_do_recipe(self):
# Test Setup
target_vertex_id = 'RESOURCE:nova.host:test_target'
source_vertex_id = 'RESOURCE:nova.host:test_source'
targets = {
TField.TARGET: target_vertex_id,
TField.SOURCE: source_vertex_id
}
action_spec = ActionSpecs(ActionType.ADD_CAUSAL_RELATIONSHIP,
targets,
{})
add_causal_relation_action = AddCausalRelationship()
# Test Action
action_steps = add_causal_relation_action.get_do_recipe(action_spec)
# Test Assertions
self.assertEqual(1, len(action_steps))
self.assertEqual(ADD_EDGE, action_steps[0].type)
add_edge_step_params = action_steps[0].params
self.assertEqual(3, len(add_edge_step_params))
source = add_edge_step_params.get(TField.SOURCE)
self.assertEqual(source_vertex_id, source)
target = add_edge_step_params.get(TField.TARGET)
self.assertEqual(target_vertex_id, target)
relation_name = add_edge_step_params[EdgeProperties.RELATIONSHIP_NAME]
self.assertEqual(EdgeLabels.CAUSES, relation_name)

View File

@ -15,6 +15,7 @@
from oslo_log import log as logging
from vitrage.common.constants import VertexProperties as VProps
from vitrage.evaluator.actions.base import ActionType
from vitrage.evaluator.actions.recipes.action_steps import UPDATE_VERTEX
from vitrage.evaluator.actions.recipes.set_state import SetState
from vitrage.evaluator.template import ActionSpecs
@ -31,17 +32,17 @@ class SetStateRecipeTest(base.BaseTest):
# Test Setup
target_vertex_id = 'RESOURCE:nova.host:test1'
targets = {'target': target_vertex_id}
props = {'state': 'SUBOPTIMAL'}
targets = {TFields.TARGET: target_vertex_id}
props = {TFields.STATE: 'SUBOPTIMAL'}
action_spec = ActionSpecs('set_state', targets, props)
action_spec = ActionSpecs(ActionType.SET_STATE, targets, props)
set_state_action = SetState()
# Test Action
action_steps = set_state_action.get_do_recipe(action_spec)
# Test Assertions
self.assertEqual(1, len(action_steps))
self.assertEqual(2, len(action_steps))
self.assertEqual(UPDATE_VERTEX, action_steps[0].type)
update_vertex_step_params = action_steps[0].params