Class: Rox::Core::StateSender

Inherits:
Object
  • Object
show all
Includes:
Helpers::ApiKey
Defined in:
lib/rox/core/network/state_sender.rb

Constant Summary

Constants included from Helpers::ApiKey

Helpers::ApiKey::MONGO_API_KEY_PATTERN, Helpers::ApiKey::UUID_API_KEY_PATTERN

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Helpers::ApiKey

#is_cbp?, #validate_api_key

Constructor Details

#initialize(sdk_settings, device_properties, flag_repository, custom_property_repository) ⇒ StateSender

Returns a new instance of StateSender.



18
19
20
21
22
23
24
25
# File 'lib/rox/core/network/state_sender.rb', line 18

def initialize(sdk_settings, device_properties, flag_repository, custom_property_repository)
  @sdk_settings = sdk_settings
  @device_properties = device_properties
  @flag_repository = flag_repository
  @custom_property_repository = custom_property_repository
  @request = Request.new
  @debouncer = Debouncer.new(1, proc { send })
end

Class Method Details

.md5_signature(serialized_feature_flags, serialized_custom_properties, device_properties, dev_mode_secret) ⇒ Object



80
81
82
83
84
85
86
# File 'lib/rox/core/network/state_sender.rb', line 80

def self.md5_signature(serialized_feature_flags, serialized_custom_properties, device_properties, dev_mode_secret)
  values = state_payload(serialized_feature_flags, serialized_custom_properties, device_properties,
                         dev_mode_secret).values

  hash = Digest::MD5.hexdigest(values.join('|'))
  hash.upcase
end

.seralize_flag_repository(flag_repository) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
# File 'lib/rox/core/network/state_sender.rb', line 100

def self.seralize_flag_repository(flag_repository)
  flags = []
  flag_repository.all_flags.sort_by(&:name).each do |f|
    flags << {
      name: f.name,
      defaultValue: f.default_value,
      options: f.options
    }
  end
  flags
end

.seralize_flag_repository_with_values(flag_repository) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/rox/core/network/state_sender.rb', line 112

def self.seralize_flag_repository_with_values(flag_repository)
  flags = []
  flag_repository.all_flags.sort_by(&:name).each do |f|
    flags <<  {
      name: f.name,
      enabled: f.enabled?,
      defaultValue: f.default_value,
      options: f.options
    }
  end
  flags
end

.serialize_custom_properties_repository(custom_property_repository) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
# File 'lib/rox/core/network/state_sender.rb', line 125

def self.serialize_custom_properties_repository(custom_property_repository)
  properties = []
  custom_property_repository.all_custom_properties.sort_by(&:name).each do |p|
    properties << {
      name: p.name,
      type: p.type.type,
      externalType: p.type.external_type
    }
  end
  properties
end

.serialize_custom_properties_repository_with_values(custom_property_repository) ⇒ Object



137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/rox/core/network/state_sender.rb', line 137

def self.serialize_custom_properties_repository_with_values(custom_property_repository)
  properties = []
  custom_property_repository.all_custom_properties.sort_by(&:name).each do |p|
    properties << {
      name: p.name,
      value: p.value(nil),
      type: p.type.type,
      externalType: p.type.external_type
    }
  end
  properties
end

.state_payload(seralized_flag_repository, serialized_custom_property_repository, device_properties, dev_mode_secret) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
# File 'lib/rox/core/network/state_sender.rb', line 88

def self.state_payload(seralized_flag_repository, serialized_custom_property_repository, device_properties, dev_mode_secret)
  values = {}
  # be careful adding here properties, md5 signature uses all props
  # to add more payload data, please change the md5_signature to use only the relevant properties (the current ones creating the payload)
  values[PropertyType::APP_KEY.name] = device_properties.all_properties[PropertyType::APP_KEY.name]
  values[PropertyType::PLATFORM.name] = device_properties.all_properties[PropertyType::PLATFORM.name]
  values.merge!({ feature_flags: seralized_flag_repository })
  values.merge!({ custom_properties: serialized_custom_property_repository })
  values['devModeSecret'] = dev_mode_secret
  values
end

Instance Method Details

#delayed_sendObject



27
28
29
# File 'lib/rox/core/network/state_sender.rb', line 27

def delayed_send
  @debouncer.call
end

#dump_stateObject



61
62
63
64
65
66
# File 'lib/rox/core/network/state_sender.rb', line 61

def dump_state
  serialized_feature_flags = StateSender.seralize_flag_repository_with_values(@flag_repository)
  serialized_custom_properties = StateSender.serialize_custom_properties_repository_with_values(@custom_property_repository)
  StateSender.state_payload(serialized_feature_flags, serialized_custom_properties, @device_properties,
                            @sdk_settings.dev_mode_secret)
end

#get_state_from_CDN(rollout_key, md5_signature) ⇒ Object



68
69
70
71
72
# File 'lib/rox/core/network/state_sender.rb', line 68

def get_state_from_CDN(rollout_key, md5_signature)
  url_for_state_cdn =
    RequestData.new("#{Rox::Core::Environment.state_cdn_path}/#{rollout_key}/#{md5_signature}", {})
  @request.send_get(url_for_state_cdn)
end

#sendObject



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/rox/core/network/state_sender.rb', line 31

def send
  rollout_key = @device_properties.rollout_key
  serialized_feature_flags = seralize_flag_repository
  serialized_custom_properties = serialize_custom_properties_repository

  state_payload = StateSender.state_payload(serialized_feature_flags, serialized_custom_properties,
                                            @device_properties, @sdk_settings.dev_mode_secret)
  md5_signature = StateSender.md5_signature(serialized_feature_flags, serialized_custom_properties,
                                            @device_properties, @sdk_settings.dev_mode_secret)

  unless @device_properties.rox_options.self_managed?
    response = get_state_from_CDN(rollout_key, md5_signature)
    if response.success?
      Rox::Core::Logging.logger.debug('Successfully fetched state from CDN')
      return response, nil
    else
      Rox::Core::Logging.logger.debug('Failed to fetch state from CDN. Sending state to API...')
    end
  end

  response = send_state_to_API(rollout_key, md5_signature, state_payload)
  message = if response.success?
              'Successfully sent state to API.'
            else
              'Failed to send state to API.'
            end
  Rox::Core::Logging.logger.debug(message)
  return response, state_payload
end

#send_state_to_API(rollout_key, md5_signature, state_payload) ⇒ Object



74
75
76
77
78
# File 'lib/rox/core/network/state_sender.rb', line 74

def send_state_to_API(rollout_key, md5_signature, state_payload)
  @request.send_post(
    "#{Rox::Core::Environment.state_api_path}/#{rollout_key}/#{md5_signature}", state_payload
  )
end