Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Service retirement values from dialog #16799

Merged
merged 4 commits into from
Sep 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 3 additions & 17 deletions app/models/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class Service < ApplicationRecord
virtual_has_one :reconfigure_dialog

before_validation :set_tenant_from_group
before_create :apply_dialog_settings
before_create :update_attributes_from_dialog

delegate :provision_dialog, :to => :miq_request, :allow_nil => true
delegate :user, :to => :miq_request, :allow_nil => true
Expand Down Expand Up @@ -468,21 +468,7 @@ def remove_from_service(parent_service)
def configuration_script
end

private

def apply_dialog_settings
dialog_options = options[:dialog] || {}

%w(dialog_service_name dialog_service_description).each do |field_name|
send(field_name, dialog_options[field_name]) if dialog_options.key?(field_name)
end
end

def dialog_service_name(value)
self.name = value if value.present?
end

def dialog_service_description(value)
self.description = value if value.present?
private def update_attributes_from_dialog
Service::DialogProperties.parse(options[:dialog], evm_owner).each { |key, value| self[key] = value }
end
end
21 changes: 21 additions & 0 deletions app/models/service/dialog_properties.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Service
class DialogProperties
require_nested :Retirement

def initialize(options, user)
@options = options || {}
@user = user
end

def self.parse(options, user)
new(options, user).parse
end

def parse
Service::DialogProperties::Retirement.parse(@options, @user).tap do |attributes|
attributes[:name] = @options['dialog_service_name'] if @options['dialog_service_name'].present?
attributes[:description] = @options['dialog_service_description'] if @options['dialog_service_description'].present?
end
end
end
end
101 changes: 101 additions & 0 deletions app/models/service/dialog_properties/retirement.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
class Service
class DialogProperties
class Retirement
RETIREMENT_WARN_FIELD_NAMES = %w(warn_on warn_in_days warn_in_hours warn_offset_days warn_offset_hours).freeze

def initialize(options, user)
@attributes = {}
@options = options || {}
@user = user
end

def self.parse(options, user)
new(options, user).parse
end

def parse
@attributes.tap { parse_options }
end

private

def parse_options
if @options['dialog_service_retires_on'].present?
field_name = 'dialog_service_retires_on'
self.retire_on_date = time_parse(@options[field_name])
elsif @options['dialog_service_retires_in_hours'].present?
field_name = 'dialog_service_retires_in_hours'
retires_in_duration(@options[field_name], :hours)
elsif @options['dialog_service_retires_in_days'].present?
field_name = 'dialog_service_retires_in_days'
retires_in_duration(@options[field_name], :days)
end
rescue StandardError
$log.error("Error parsing dialog retirement property [#{field_name}] with value [#{@options[field_name].inspect}]. Error: #{$!}")
end

def retires_in_duration(value, modifier)
self.retire_on_date = time_now + offset_set(value, modifier)
end

def offset_set(value, modifier)
value.to_i.send(modifier).tap do |offset|
raise "Offset cannot be a zero or negative value" if offset.zero? || offset.negative?
end
end

def retire_on_date=(value)
@attributes[:retires_on] = value
retirement_warning
end

def retirement_warning
warn_value = parse_retirement_warn
@attributes[:retirement_warn] = warn_value if warn_value
end

def parse_retirement_warn
warn_key, value = retirement_warn_properties

case warn_key
when 'warn_on'
time_parse(value)
when 'warn_in_days'
time_now + offset_set(value, :days)
when 'warn_in_hours'
time_now + offset_set(value, :hours)
when 'warn_offset_days'
@attributes[:retires_on] - offset_set(value, :days)
when 'warn_offset_hours'
@attributes[:retires_on] - offset_set(value, :hours)
end
end

def retirement_warn_properties
warn_name = RETIREMENT_WARN_FIELD_NAMES.detect do |field_name|
@options["dialog_service_retirement_#{field_name}"].present?
end

return warn_name, @options["dialog_service_retirement_#{warn_name}"] if warn_name
end

def time_parse(value)
with_user_timezone do
Time.zone.parse(value).utc.tap do |time|
raise "Retirement date cannot be set in the past" if time < time_now
end
end
end

def time_now
with_user_timezone { Time.zone.now.utc }
end

def with_user_timezone
user = @user || User.current_user

user ? user.with_my_timezone { yield } : yield
end
end
end
end
30 changes: 13 additions & 17 deletions app/models/service_template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -195,22 +195,21 @@ def create_service(service_task, parent_svc = nil)

nh['initiator'] = service_task.options[:initiator] if service_task.options[:initiator]

svc = Service.create(nh)
svc.service_template = self

service_resources.each do |sr|
nh = sr.attributes.dup
%w(id created_at updated_at service_template_id).each { |key| nh.delete(key) }
svc.add_resource(sr.resource, nh) unless sr.resource.nil?
end
Service.create(nh) do |svc|
svc.service_template = self
set_ownership(svc, service_task.get_user)

service_resources.each do |sr|
nh = sr.attributes.dup
%w(id created_at updated_at service_template_id).each { |key| nh.delete(key) }
svc.add_resource(sr.resource, nh) unless sr.resource.nil?
end

if parent_svc
service_resource = ServiceResource.find_by(:id => service_task.options[:service_resource_id])
parent_svc.add_resource!(svc, service_resource)
if parent_svc
service_resource = ServiceResource.find_by(:id => service_task.options[:service_resource_id])
parent_svc.add_resource!(svc, service_resource)
end
end

svc.save
svc
end

def composite?
Expand Down Expand Up @@ -239,8 +238,6 @@ def create_tasks_for_service(service_task, parent_svc)
end
svc = create_service(service_task, parent_svc)

set_ownership(svc, service_task.get_user)

service_task.destination = svc

create_subtasks(service_task, svc)
Expand Down Expand Up @@ -293,7 +290,6 @@ def set_ownership(service, user)
else
$log.info("Setting Service Owning User to Name=#{user.name}, ID=#{user.id}")
end
service.save
end

def self.default_provisioning_entry_point(service_type)
Expand Down
145 changes: 145 additions & 0 deletions spec/models/service/dialog_properties/retirement_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
describe Service::DialogProperties::Retirement do
let(:time) { Time.new(2018, 7, 21, 12, 20, 0, 0) }

it 'with a nil parameter' do
options = nil
expect(described_class.parse(options, nil)).to eq({})
end

it 'with an empty hash' do
options = {}
expect(described_class.parse(options, nil)).to eq({})
end

context 'when setting retirement date' do
describe 'retires_on' do
it 'with invalid time' do
options = {'dialog_service_retires_on' => 'xyz'}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to be_nil
expect(parsed_results[:retirement_warn]).to be_nil
end

it 'with valid time' do
Timecop.freeze(time) do
options = {'dialog_service_retires_on' => time.to_s}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to eq(time)
expect(parsed_results[:retirement_warn]).to be_nil
end
end

it 'with an invalid date that has already past' do
Timecop.freeze(time) do
options = {'dialog_service_retires_on' => "2000-01-01"}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to be_nil
expect(parsed_results[:retirement_warn]).to be_nil
end
end
end

describe 'retires_in_hours' do
it 'with invalid time' do
options = {'dialog_service_retires_in_hours' => 'xyz'}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to be_nil
expect(parsed_results[:retirement_warn]).to be_nil
end

it 'with valid time' do
Timecop.freeze(time) do
options = {'dialog_service_retires_in_hours' => 5}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to eq(time + 5.hours)
expect(parsed_results[:retirement_warn]).to be_nil
end
end
end

describe 'retires_in_days' do
it 'with invalid time' do
options = {'dialog_service_retires_in_days' => 'xyz'}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to be_nil
expect(parsed_results[:retirement_warn]).to be_nil
end

it 'with valid time' do
Timecop.freeze(time) do
options = {'dialog_service_retires_in_days' => 5}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to eq(time + 5.days)
expect(parsed_results[:retirement_warn]).to be_nil
end
end
end
end

context 'when setting retirement warn date' do
it 'with retirement_warn_on' do
user = FactoryGirl.create(:user)
expect(user).to receive(:with_my_timezone).exactly(3).times.and_yield

Timecop.freeze(time) do
options = {'dialog_service_retires_in_days' => 5,
'dialog_service_retirement_warn_on' => (time + 1.day).to_s}
parsed_results = described_class.parse(options, user)

expect(parsed_results[:retires_on]).to eq(time + 5.days)
expect(parsed_results[:retirement_warn]).to eq(time + 1.day)
end
end

it 'with retirement_warn_in_days' do
Timecop.freeze(time) do
options = {'dialog_service_retires_in_days' => 5,
'dialog_service_retirement_warn_in_days' => 1}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to eq(time + 5.days)
expect(parsed_results[:retirement_warn]).to eq(time + 1.day)
end
end

it 'with retirement_warn_offset_days' do
Timecop.freeze(time) do
options = {'dialog_service_retires_in_days' => 5,
'dialog_service_retirement_warn_offset_days' => 4}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to eq(time + 5.days)
expect(parsed_results[:retirement_warn]).to eq(time + 1.day)
end
end

it 'with retirement_warn_in_hours' do
Timecop.freeze(time) do
options = {'dialog_service_retires_in_hours' => 5,
'dialog_service_retirement_warn_in_hours' => 1}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to eq(time + 5.hours)
expect(parsed_results[:retirement_warn]).to eq(time + 1.hour)
end
end

it 'with retirement_warn_offset_hours' do
Timecop.freeze(time) do
options = {'dialog_service_retires_in_hours' => 5,
'dialog_service_retirement_warn_offset_hours' => 4}
parsed_results = described_class.parse(options, nil)

expect(parsed_results[:retires_on]).to eq(time + 5.hours)
expect(parsed_results[:retirement_warn]).to eq(time + 1.hour)
end
end
end
end
40 changes: 40 additions & 0 deletions spec/models/service/dialog_properties_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
describe Service::DialogProperties do
it 'with a nil parameter and nil user' do
options = nil
expect(described_class.parse(options, nil)).to eq({})
end

it 'with an empty hash parameter and nil user' do
options = {}
expect(described_class.parse(options, nil)).to eq({})
end

it `will call the Retirement class` do
expect(Service::DialogProperties::Retirement).to receive(:parse).with({}, nil).and_return({})
described_class.parse(nil, nil)
end

describe 'name' do
it 'with an empty name' do
options = {'dialog_service_name' => ' '}
expect(described_class.parse(options, nil)).to eq({})
end

it 'with option name' do
options = {'dialog_service_name' => 'name from dialog'}
expect(described_class.parse(options, nil)).to eq(:name => 'name from dialog')
end
end

describe 'description' do
it 'with an empty description' do
options = {'dialog_service_description' => ' '}
expect(described_class.parse(options, nil)).to eq({})
end

it 'with option description' do
options = {'dialog_service_description' => 'test description from dialog'}
expect(described_class.parse(options, nil)).to eq(:description => 'test description from dialog')
end
end
end
Loading