Module: SkullIsland::Helpers::Resource

Included in:
Resource
Defined in:
lib/skull_island/helpers/resource.rb

Overview

Simple helper methods for Resources

Instance Method Summary collapse

Instance Method Details

#<=>(other) ⇒ Object



229
230
231
232
233
234
235
236
237
238
239
# File 'lib/skull_island/helpers/resource.rb', line 229

def <=>(other)
  if id < other.id
    -1
  elsif id > other.id
    1
  elsif id == other.id
    0
  else
    raise Exceptions::InvalidArguments
  end
end

#datetime_from_params(params, actual_key) ⇒ Object



7
8
9
10
11
12
13
14
15
# File 'lib/skull_island/helpers/resource.rb', line 7

def datetime_from_params(params, actual_key)
  DateTime.new(
    params["#{actual_key}(1i)"].to_i,
    params["#{actual_key}(2i)"].to_i,
    params["#{actual_key}(3i)"].to_i,
    params["#{actual_key}(4i)"].to_i,
    params["#{actual_key}(5i)"].to_i
  )
end

#delayed_set(property, data, key) ⇒ Object

rubocop:disable Style/GuardClause



18
19
20
21
22
23
24
25
26
27
28
# File 'lib/skull_island/helpers/resource.rb', line 18

def delayed_set(property, data, key)
  # rubocop:disable Security/Eval
  if data[key]
    value = data[key].is_a?(String) ? eval(Erubi::Engine.new(data[key]).src) : data[key]
    send(
      "#{property}=".to_sym,
      value.is_a?(String) && value.start_with?('{"') ? eval(value) : value
    )
  end
  # rubocop:enable Security/Eval
end

#destroyObject



154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/skull_island/helpers/resource.rb', line 154

def destroy
  raise Exceptions::ImmutableModification if immutable?

  unless new?
    @api_client.delete(relative_uri.to_s)
    @api_client.invalidate_cache_for(relative_uri.to_s)
    @lazy = false
    @tainted = true
    @entity.delete('id')
  end
  true
end

#digestObject

rubocop:enable Style/GuardClause



31
32
33
34
35
# File 'lib/skull_island/helpers/resource.rb', line 31

def digest
  Digest::MD5.hexdigest(
    digest_properties.sort.map { |prp| "#{prp}=#{send(prp.to_sym) || ''}" }.compact.join(':')
  )
end

#digest_propertiesObject



37
38
39
40
# File 'lib/skull_island/helpers/resource.rb', line 37

def digest_properties
  props = properties.keys.reject { |k| %i[created_at updated_at].include? k }
  supports_meta? ? props + [:project] : props
end

#find_by_digestObject

Tests for an existing version of this resource based on its properties rather than its ‘id`



43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/skull_island/helpers/resource.rb', line 43

def find_by_digest
  result = self.class.where(:digest, digest) # matching digest means the equivalent resource
  if result.size == 1
    entity_data = @api_client.cache(result.first.relative_uri.to_s) do |client|
      client.get(result.first.relative_uri.to_s)
    end
    @entity = entity_data
    @lazy = false
    @tainted = false
    true
  else
    false
  end
end

#fresh?Boolean

Returns:

  • (Boolean)


58
59
60
# File 'lib/skull_island/helpers/resource.rb', line 58

def fresh?
  !tainted?
end

#host_regexObject



62
63
64
# File 'lib/skull_island/helpers/resource.rb', line 62

def host_regex
  /^(([\w]|[\w][\w\-]*[\w])\.)*([\w]|[\w][\w\-]*[\w])$/
end

#idObject



70
71
72
# File 'lib/skull_island/helpers/resource.rb', line 70

def id
  @entity[id_property.to_s]
end

#id_propertyObject



66
67
68
# File 'lib/skull_island/helpers/resource.rb', line 66

def id_property
  self.class.properties.select { |_, opts| opts[:id_property] }.keys.first || 'id'
end

#immutable?Boolean

Returns:

  • (Boolean)


74
75
76
# File 'lib/skull_island/helpers/resource.rb', line 74

def immutable?
  self.class.immutable?
end

#import_update_or_skip(verbose: false, test: false, index:) ⇒ Object

rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/PerceivedComplexity



80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/skull_island/helpers/resource.rb', line 80

def import_update_or_skip(verbose: false, test: false, index:)
  if find_by_digest
    puts "[INFO] Skipping #{self.class} index #{index} (#{id})" if verbose
  elsif test
    puts "[INFO] Would have saved #{self.class} index #{index}"
  elsif modified_existing?
    puts "[INFO] Modified #{self.class} index #{index} (#{id})" if verbose
  elsif save
    puts "[INFO] Created #{self.class} index #{index} (#{id})" if verbose
  else
    puts "[ERR] Failed to save #{self.class} index #{index}"
  end
end

#lookup(type, value) ⇒ Object

rubocop:enable Metrics/CyclomaticComplexity rubocop:enable Metrics/PerceivedComplexity



96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/skull_island/helpers/resource.rb', line 96

def lookup(type, value)
  case type
  when :consumer
    { 'id' => Resources::Consumer.find(:username, value).id }
  when :route
    { 'id' => Resources::Route.find(:name, value).id }
  when :service
    { 'id' => Resources::Service.find(:name, value).id }
  when :upstream
    { 'id' => Resources::Upstream.find(:name, value).id }
  else
    raise Exceptions::InvalidArguments, "#{type} is not a valid lookup type"
  end
end

#model_nameObject

ActiveRecord ActiveModel::Name compatibility method



112
113
114
# File 'lib/skull_island/helpers/resource.rb', line 112

def model_name
  self.class
end

#new?Boolean

Returns:

  • (Boolean)


116
117
118
# File 'lib/skull_island/helpers/resource.rb', line 116

def new?
  !@entity.key?(id_property.to_s)
end

#persisted?Boolean

ActiveRecord ActiveModel::Model compatibility method

Returns:

  • (Boolean)


121
122
123
# File 'lib/skull_island/helpers/resource.rb', line 121

def persisted?
  !new?
end

#postprocess_created_at(value) ⇒ Object



125
126
127
# File 'lib/skull_island/helpers/resource.rb', line 125

def postprocess_created_at(value)
  Time.at(value).utc.to_datetime
end

#postprocess_updated_at(value) ⇒ Object



129
130
131
# File 'lib/skull_island/helpers/resource.rb', line 129

def postprocess_updated_at(value)
  Time.at(value).utc.to_datetime
end

#propertiesObject



133
134
135
# File 'lib/skull_island/helpers/resource.rb', line 133

def properties
  self.class.properties
end

#prune_for_save(data) ⇒ Object



241
242
243
244
245
246
247
248
# File 'lib/skull_island/helpers/resource.rb', line 241

def prune_for_save(data)
  data.reject do |k, v|
    k.to_sym == id_property ||
      !properties[k.to_sym] ||
      properties[k.to_sym][:read_only] ||
      v.nil?
  end
end

#reloadObject



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/skull_island/helpers/resource.rb', line 167

def reload
  if new?
    # Can't reload a new resource
    false
  else
    @api_client.invalidate_cache_for(relative_uri.to_s)
    entity_data = @api_client.cache(relative_uri.to_s) do |client|
      client.get(relative_uri.to_s)
    end
    @entity = entity_data
    @lazy = false
    @tainted = false
    true
  end
end

#required_propertiesObject



137
138
139
# File 'lib/skull_island/helpers/resource.rb', line 137

def required_properties
  properties.select { |_key, value| value[:required] }
end

#saveObject



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/skull_island/helpers/resource.rb', line 183

def save
  saveable_data = prune_for_save(@entity)
  validate_required_properties(saveable_data)

  if new?
    @entity  = @api_client.post(save_uri.to_s, saveable_data)
    @lazy    = true
  else
    @api_client.invalidate_cache_for(relative_uri.to_s)
    @entity = @api_client.patch(relative_uri, saveable_data)
  end
  @api_client.invalidate_cache_for(self.class.relative_uri.to_s) # clear any collection class
  @tainted = false
  true
end

#save_uriObject



199
200
201
# File 'lib/skull_island/helpers/resource.rb', line 199

def save_uri
  self.class.relative_uri
end

#supports_meta?Boolean

Returns:

  • (Boolean)


203
204
205
# File 'lib/skull_island/helpers/resource.rb', line 203

def supports_meta?
  false
end

#tainted?Boolean

Returns:

  • (Boolean)


141
142
143
# File 'lib/skull_island/helpers/resource.rb', line 141

def tainted?
  @tainted ? true : false
end

#to_paramObject

ActiveRecord ActiveModel::Conversion compatibility method



146
147
148
# File 'lib/skull_island/helpers/resource.rb', line 146

def to_param
  new? ? nil : id.to_s
end

#to_sObject



150
151
152
# File 'lib/skull_island/helpers/resource.rb', line 150

def to_s
  to_param.to_s
end

#update(params) ⇒ Object

ActiveRecord ActiveModel compatibility method



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/skull_island/helpers/resource.rb', line 208

def update(params)
  new_params = {}
  # need to convert multi-part datetime params
  params.each do |key, value|
    if /([^(]+)\(1i/.match?(key)
      actual_key = key.match(/([^(]+)\(/)[1]
      new_params[actual_key] = datetime_from_params(params, actual_key)
    else
      new_params[key] = value
    end
  end

  new_params.each do |key, value|
    setter_key = "#{key}=".to_sym
    raise Exceptions::InvalidProperty unless respond_to?(setter_key)

    send(setter_key, value)
  end
  save
end