Skip to content

Commit

Permalink
Allow mapping event types to groups using regexes
Browse files Browse the repository at this point in the history
Up until now, in order to associate an event type with an event group,
we needed to spell out events full name in settings file under
appropriate event group category and level.

Some of the providers have hundreds of event types, which makes
filling all this information in tedious and error prone. Not to
mention that settings file is now one giant pile of event types.

In order to make process of registering event types scale a bit
better, this commit adds support for registering a class of event
types that match specified regular expressions. Simple example:

    :ems:
      :ems_dummy:
        :event_handling:
          :event_groups:
            :addition:
              :critical:
              - dummy_event01_add
              - dummy_event02_add
              :detail:
              - dummy_event03_add
              - dummy_event04_add
              ...
              - dummy_event70_add
              - dm_event_create

This can now be written as

    :ems:
      :ems_dummy:
        :event_handling:
          :event_groups:
            :addition:
              :critical:
              - dummy_event01_add
              - dummy_event02_add
              :detail:
              - dm_event_create
              - !ruby/regexp /^dummy_event[0-9]{2}_add$/

We took a great deal of care not to break existing code, so non-regex
event type mappings take precedence over regular expression matches.
For example, in our sample above, dummy_event_02_add gets assigned
critical level despite also matching detail regex.

Note that if sets of event types that are matched by regular
expressions are not disjoint, then there will be multiple valid event
type mappings. In this case, event types that match more than one
group and/or level get assigned an arbitrary one.
  • Loading branch information
Tadej Borovšak committed Aug 7, 2018
1 parent 382ef25 commit d35dd63
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 27 deletions.
18 changes: 13 additions & 5 deletions app/models/event_stream.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,19 @@ def self.event_groups

def self.group_and_level(event_type)
level = :detail # the level is detail as default
group, _ = event_groups.find do |_k, value|
GROUP_LEVELS.detect { |lvl| value[lvl]&.include?(event_type) }.tap do |level_found|
level = level_found if level_found
end
end
egroups = event_groups

group = egroups.find do |_, value|
GROUP_LEVELS
.find { |lvl| value[lvl]&.select { |typ| typ.is_a?(String) }&.include?(event_type) }
.tap { |level_found| level = level_found || level }
end&.first

group ||= egroups.find do |_, value|
GROUP_LEVELS
.find { |lvl| value[lvl]&.select { |typ| typ.is_a?(Regexp) }&.find { |regex| regex === event_type } }
.tap { |level_found| level = level_found || level }
end&.first

group ||= :other
return group, level
Expand Down
89 changes: 67 additions & 22 deletions spec/models/ems_event_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,6 @@
let(:provider_critical_event) { 'SomeCriticalEvent' }
let(:provider_detail_event) { 'SomeDetailEvent' }
let(:provider_warning_event) { 'SomeWarningEvent' }
let(:provider_event) { 'SomeSpecialProviderEvent' }

it 'returns a list of expected groups' do
event_group_names = [
Expand All @@ -296,30 +295,11 @@
expect(described_class.event_groups.keys).to match_array(event_group_names)
expect(described_class.event_groups[:addition]).to include(:name => 'Creation/Addition')
expect(described_class.event_groups[:addition][:critical]).to include('CloneTaskEvent')
expect(described_class.event_groups[:addition][:critical]).not_to include(provider_event)
end

it 'returns the provider event if configured' do
stub_settings_merge(
:ems => {
:some_provider => {
:event_handling => {
:event_groups => {
:addition => {
:critical => [provider_event]
}
}
}
}
}
)

expect(described_class.event_groups[:addition][:critical]).to include('CloneTaskEvent')
expect(described_class.event_groups[:addition][:critical]).to include(provider_event)
expect(described_class.event_groups[:addition][:critical]).not_to include('BogueEvent')
end

it 'returns the group, level and group name of an unknown event' do
group, level = described_class.group_and_level(provider_event)
group, level = described_class.group_and_level('BogusEvent')
expect(group).to eq(:other)
expect(level).to eq(:detail)
expect(described_class.group_name(group)).to eq('Other')
Expand All @@ -345,5 +325,70 @@
expect(level).to eq(:detail)
expect(described_class.group_name(group)).to eq('Power Activity')
end

context 'with provider events' do
before(:each) do
stub_settings_merge(
:ems => {
:some_provider => {
:event_handling => {
:event_groups => {
:addition => {
:warning => [provider_regex],
:critical => [provider_event]
}
}
}
}
}
)
end

let(:provider_event) { 'SomeSpecialProviderEvent' }
let(:provider_regex) { /Some.+Event/ }

it 'returns the provider event if configured' do
expect(described_class.event_groups[:addition][:critical]).to include('CloneTaskEvent')
expect(described_class.event_groups[:addition][:critical]).to include(provider_event)
expect(described_class.event_groups[:addition][:warning]).to include(provider_regex)
end

# Make sure explicitly named event types take precedence over regex
it 'returns the group, level and group name of a warning event' do
group, level = described_class.group_and_level(provider_warning_event)
expect(group).to eq(:power)
expect(level).to eq(:warning)
expect(described_class.group_name(group)).to eq('Power Activity')
end

it 'returns the group, level and group name of a critical event' do
group, level = described_class.group_and_level(provider_critical_event)
expect(group).to eq(:power)
expect(level).to eq(:critical)
expect(described_class.group_name(group)).to eq('Power Activity')
end

it 'returns the group, level and group name of a detail event' do
group, level = described_class.group_and_level(provider_detail_event)
expect(group).to eq(:power)
expect(level).to eq(:detail)
expect(described_class.group_name(group)).to eq('Power Activity')
end
# End make sure explicitly named event types take precedence over regex

it 'returns the group, level and group name of a regex-matched event' do
group, level = described_class.group_and_level('SomeMatchingEvent')
expect(group).to eq(:addition)
expect(level).to eq(:warning)
expect(described_class.group_name(group)).to eq('Creation/Addition')
end

it 'returns the group, level and group name of an unknown event' do
group, level = described_class.group_and_level('BogusEvent')
expect(group).to eq(:other)
expect(level).to eq(:detail)
expect(described_class.group_name(group)).to eq('Other')
end
end
end
end

0 comments on commit d35dd63

Please sign in to comment.