evaluator - adding RCA action
Change-Id: I6f957587ac69eacc5ce71c0b72bc0610a1370f66
This commit is contained in:
parent
9cb5557d24
commit
97caf84d0f
@ -40,6 +40,7 @@ class EdgeProperties(object):
|
||||
class EdgeLabels(object):
|
||||
ON = 'on'
|
||||
CONTAINS = 'contains'
|
||||
CAUSES = 'causes'
|
||||
|
||||
|
||||
class SyncMode(object):
|
||||
|
@ -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,
|
||||
|
@ -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 = {}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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, {})
|
||||
|
@ -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):
|
||||
|
@ -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)
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user