-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcomponent.rb
More file actions
165 lines (141 loc) · 4.82 KB
/
component.rb
File metadata and controls
165 lines (141 loc) · 4.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
module OpenComponents
# Wrapper object for a component fetched from an OC registry.
class Component
REGISTRY_TIMEOUT_MESSAGE = 'The registry took too long to respond.'.freeze #:nodoc:
BLANK = ''.freeze #:nodoc:
# Public: Gets/sets the String name of the component.
attr_accessor :name
# Public: Gets/sets the desired String version of the component.
attr_accessor :version
# Public: Gets/sets a Hash of params to send in the component request.
attr_accessor :params
# Public: Gets/sets a Hash of headers to send in the component request.
attr_accessor :headers
# Public: Gets the String URL of the requested component.
attr_reader :href
# Public: Gets the String version of the component as served by the
# registry.
attr_reader :registry_version
# Public: Gets the String type of the component as served by the
# registry.
attr_reader :type
# Public: Gets the String render mode of the component as served by the
# registry. Generally either `rendered` or `unrendered`.
attr_reader :render_mode
# Public: Initializes a new Component subclass.
#
# name - The String name of the component to request.
#
# Options
# params - A Hash of parameters to send in the component request (default: {}).
# version - The String version of the component to request (default: '').
# headers - A Hash of HTTP request headers to include in the request (default: {}).
def initialize(name, params: {}, version: nil, headers: {})
@name = name
@params = params
@version = version || BLANK
@headers = headers
end
# Public: Returns the String value of `requestVersion` from a component
# response, `nil` if not present.
def request_version
@request_version == BLANK ? nil : @request_version
end
# Public: Resets all component attributes from a registry response to `nil`.
#
# Examples
#
# component.flush!
# # => #<OpenComponents::RenderedComponent: ... >
#
# Returns the reset Component.
def flush!
flush_variables_whitelist.each do |var|
instance_variable_set(var, nil)
end
self
end
# Public: Resets all component attributes and reloads them from a registry
# response.
#
# Examples
#
# component.reload!
# # => #<OpenComponents::RenderedComponent: ... >
#
# Returns the reloaded Component.
def reload!
flush!
load
end
private
# Internal: Executes a component request and sets attributes common to all
# component render modes. Public-facing `#load` methods exist on Component
# subclasses.
#
# Returns the Component.
def load
@href = response_data['href']
@registry_version = response_data['version']
@request_version = response_data['requestVersion']
@type = response_data['type']
@render_mode = response_data['renderMode']
self
end
# Internal: Builds the URL to send a component request to.
#
# Returns the String URL to request a component from.
def uri
URI(File.join(OpenComponents.config.registry, name, version)).tap do |u|
u.query = URI.encode_www_form(params)
end
end
# Internal: Executes a component request against the configured registry.
#
# Returns a response body String.
# Raises OpenComponents::ComponentNotFound if the registry responds with a
# 404.
# Raises OpenComponents::RegistryTimeout if the request times out.
def response
_response = Net::HTTP.start(
uri.host,
uri.port,
read_timeout: OpenComponents.config.timeout,
open_timeout: OpenComponents.config.timeout
) { |http| http.request request }
case _response
when Net::HTTPNotFound
fail ComponentNotFound, "Component #{name} not found."
when Net::HTTPRequestTimeOut
fail_with_timeout
end
_response
rescue Timeout::Error
fail_with_timeout
end
# Internal: Helper method for building the component request. Includes
# all params and headers.
def request
Net::HTTP::Get.new(uri).tap do |r|
headers.each { |k, v| r[k] = v }
end
end
# Internal: Helper method for converting and memoizing registry response
# data.
#
# Returns a Hash of registry response data.
def response_data
@_response_data ||= JSON.parse(response.body)
end
def fail_with_timeout
fail RegistryTimeout, REGISTRY_TIMEOUT_MESSAGE
end
# Internal: Whitelists instance variable names allowed to be reset when
# calling `#flush!`.
#
# Returns an Array of instance variable Symbols allowed to be reset.
def flush_variables_whitelist
instance_variables - [:@name, :@version, :@params, :@headers]
end
end
end