Class: Chef::Expander::Solrizer
- Inherits:
-
Object
- Object
- Chef::Expander::Solrizer
- Includes:
- Loggable
- Defined in:
- lib/chef/expander/solrizer.rb
Constant Summary collapse
- ADD =
"add"
- DELETE =
"delete"
- SKIP =
"skip"
- ITEM =
"item"
- ID =
"id"
- TYPE =
"type"
- DATABASE =
"database"
- ENQUEUED_AT =
"enqueued_at"
- DATA_BAG_ITEM =
"data_bag_item"
- DATA_BAG =
"data_bag"
- X_CHEF_id_CHEF_X =
'X_CHEF_id_CHEF_X'
- X_CHEF_database_CHEF_X =
'X_CHEF_database_CHEF_X'
- X_CHEF_type_CHEF_X =
'X_CHEF_type_CHEF_X'
- CONTENT_TYPE_XML =
{"Content-Type" => "text/xml"}
- START_XML =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- ADD_DOC =
"<add><doc>"
- DELETE_DOC =
"<delete>"
- ID_OPEN =
"<id>"
- ID_CLOSE =
"</id>"
- END_ADD_DOC =
"</doc></add>\n"
- END_DELETE =
"</delete>\n"
- START_CONTENT =
'<field name="content">'
- CLOSE_FIELD =
"</field>"
- FLD_CHEF_ID_FMT =
'<field name="X_CHEF_id_CHEF_X">%s</field>'
- FLD_CHEF_DB_FMT =
'<field name="X_CHEF_database_CHEF_X">%s</field>'
- FLD_CHEF_TY_FMT =
'<field name="X_CHEF_type_CHEF_X">%s</field>'
- FLD_DATA_BAG =
'<field name="data_bag">%s</field>'
- KEYVAL_FMT =
"%s__=__%s "
Constants included from Loggable
Instance Attribute Summary collapse
-
#action ⇒ Object
readonly
Returns the value of attribute action.
-
#chef_object ⇒ Object
readonly
Returns the value of attribute chef_object.
-
#database ⇒ Object
readonly
Returns the value of attribute database.
-
#enqueued_at ⇒ Object
readonly
Returns the value of attribute enqueued_at.
-
#indexer_payload ⇒ Object
readonly
Returns the value of attribute indexer_payload.
-
#obj_id ⇒ Object
readonly
Returns the value of attribute obj_id.
-
#obj_type ⇒ Object
readonly
Returns the value of attribute obj_type.
Class Method Summary collapse
- .clear_http_requests ⇒ Object
- .http_request_completed(instance) ⇒ Object
- .http_request_started(instance) ⇒ Object
- .http_requests_active? ⇒ Boolean
Instance Method Summary collapse
- #add ⇒ Object
- #completed ⇒ Object
- #delete ⇒ Object
- #eql?(other) ⇒ Boolean
- #extract_object_fields ⇒ Object
- #flattened_object ⇒ Object
- #hash ⇒ Object
- #http_request_started ⇒ Object
- #indexed_object ⇒ Object
-
#initialize(object_command_json, &on_completion_block) ⇒ Solrizer
constructor
A new instance of Solrizer.
- #parse(serialized_object) ⇒ Object
-
#pointyize_add ⇒ Object
Takes a flattened hash where the values are arrays and converts it into a dignified XML document suitable for POST to Solr.
-
#pointyize_delete ⇒ Object
Takes a succinct document id, like 2342, and turns it into something even more compact, like ā<?xml version="1.0" encoding="UTF-8"?>n<delete><id>2342</id></delete>nā.
- #post_to_solr(document, &logger_block) ⇒ Object
- #run ⇒ Object
- #solr_url ⇒ Object
- #transit_time ⇒ Object
Methods included from Loggable
Constructor Details
#initialize(object_command_json, &on_completion_block) ⇒ Solrizer
Returns a new instance of Solrizer.
85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/chef/expander/solrizer.rb', line 85 def initialize(object_command_json, &on_completion_block) @start_time = Time.now.to_f @on_completion_block = on_completion_block if = parse(object_command_json) @action = ["action"] @indexer_payload = ["payload"] extract_object_fields if @indexer_payload else @action = SKIP end end |
Instance Attribute Details
#action ⇒ Object (readonly)
Returns the value of attribute action.
71 72 73 |
# File 'lib/chef/expander/solrizer.rb', line 71 def action @action end |
#chef_object ⇒ Object (readonly)
Returns the value of attribute chef_object.
75 76 77 |
# File 'lib/chef/expander/solrizer.rb', line 75 def chef_object @chef_object end |
#database ⇒ Object (readonly)
Returns the value of attribute database.
81 82 83 |
# File 'lib/chef/expander/solrizer.rb', line 81 def database @database end |
#enqueued_at ⇒ Object (readonly)
Returns the value of attribute enqueued_at.
83 84 85 |
# File 'lib/chef/expander/solrizer.rb', line 83 def enqueued_at @enqueued_at end |
#indexer_payload ⇒ Object (readonly)
Returns the value of attribute indexer_payload.
73 74 75 |
# File 'lib/chef/expander/solrizer.rb', line 73 def indexer_payload @indexer_payload end |
#obj_id ⇒ Object (readonly)
Returns the value of attribute obj_id.
77 78 79 |
# File 'lib/chef/expander/solrizer.rb', line 77 def obj_id @obj_id end |
#obj_type ⇒ Object (readonly)
Returns the value of attribute obj_type.
79 80 81 |
# File 'lib/chef/expander/solrizer.rb', line 79 def obj_type @obj_type end |
Class Method Details
.clear_http_requests ⇒ Object
46 47 48 |
# File 'lib/chef/expander/solrizer.rb', line 46 def self.clear_http_requests @active_http_requests.clear end |
.http_request_completed(instance) ⇒ Object
38 39 40 |
# File 'lib/chef/expander/solrizer.rb', line 38 def self.http_request_completed(instance) @active_http_requests.delete(instance) end |
.http_request_started(instance) ⇒ Object
34 35 36 |
# File 'lib/chef/expander/solrizer.rb', line 34 def self.http_request_started(instance) @active_http_requests << instance end |
.http_requests_active? ⇒ Boolean
42 43 44 |
# File 'lib/chef/expander/solrizer.rb', line 42 def self.http_requests_active? !@active_http_requests.empty? end |
Instance Method Details
#add ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/chef/expander/solrizer.rb', line 128 def add post_to_solr(pointyize_add) do ["indexed #{indexed_object}", "transit,xml,solr-post |", [transit_time, @xml_time, @solr_post_time].join(","), "|" ].join(" ") end rescue Exception => e log.error { "#{e.class.name}: #{e.}\n#{e.backtrace.join("\n")}"} end |
#completed ⇒ Object
243 244 245 246 247 |
# File 'lib/chef/expander/solrizer.rb', line 243 def completed @solr_post_time = Time.now.to_f - @start_time self.class.http_request_completed(self) @on_completion_block.call end |
#delete ⇒ Object
140 141 142 143 144 |
# File 'lib/chef/expander/solrizer.rb', line 140 def delete post_to_solr(pointyize_delete) { "deleted #{indexed_object} transit-time[#{transit_time}s]"} rescue Exception => e log.error { "#{e.class.name}: #{e.}\n#{e.backtrace.join("\n")}"} end |
#eql?(other) ⇒ Boolean
265 266 267 |
# File 'lib/chef/expander/solrizer.rb', line 265 def eql?(other) other.hash == hash end |
#extract_object_fields ⇒ Object
98 99 100 101 102 103 104 105 |
# File 'lib/chef/expander/solrizer.rb', line 98 def extract_object_fields @chef_object = @indexer_payload[ITEM] @database = @indexer_payload[DATABASE] @obj_id = @indexer_payload[ID] @obj_type = @indexer_payload[TYPE] @enqueued_at = @indexer_payload[ENQUEUED_AT] @data_bag = @obj_type == DATA_BAG_ITEM ? @chef_object[DATA_BAG] : nil end |
#flattened_object ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/chef/expander/solrizer.rb', line 146 def flattened_object flattened_object = Flattener.new(@chef_object).flattened_item flattened_object[X_CHEF_id_CHEF_X] = [@obj_id] flattened_object[X_CHEF_database_CHEF_X] = [@database] flattened_object[X_CHEF_type_CHEF_X] = [@obj_type] log.debug {"adding flattened object to Solr: #{flattened_object.inspect}"} flattened_object end |
#hash ⇒ Object
269 270 271 |
# File 'lib/chef/expander/solrizer.rb', line 269 def hash "#{action}#{indexed_object}#@enqueued_at#{self.class.name}".hash end |
#http_request_started ⇒ Object
261 262 263 |
# File 'lib/chef/expander/solrizer.rb', line 261 def http_request_started self.class.http_request_started(self) end |
#indexed_object ⇒ Object
257 258 259 |
# File 'lib/chef/expander/solrizer.rb', line 257 def indexed_object "#{@obj_type}[#{@obj_id}] database[#{@database}]" end |
#parse(serialized_object) ⇒ Object
107 108 109 110 111 |
# File 'lib/chef/expander/solrizer.rb', line 107 def parse(serialized_object) Yajl::Parser.parse(serialized_object) rescue Yajl::ParseError log.error { "cannot index object because it is invalid JSON: #{serialized_object}" } end |
#pointyize_add ⇒ Object
Takes a flattened hash where the values are arrays and converts it into a dignified XML document suitable for POST to Solr. The general structure of the output document is like this:
<?xml version="1.0" encoding="UTF-8"?>
<add>
<doc>
<field name="content">
key__=__value
key__=__another_value
other_key__=__yet another value
</field>
</doc>
</add>
The document as generated has minimal newlines and formatting, however.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/chef/expander/solrizer.rb', line 189 def pointyize_add xml = "" xml << START_XML << ADD_DOC xml << (FLD_CHEF_ID_FMT % @obj_id) xml << (FLD_CHEF_DB_FMT % @database) xml << (FLD_CHEF_TY_FMT % @obj_type) xml << START_CONTENT content = "" flattened_object.each do |field, values| values.each do |v| content << (KEYVAL_FMT % [field, v]) end end xml << content.fast_xs xml << CLOSE_FIELD # ends content xml << (FLD_DATA_BAG % @data_bag.fast_xs) if @data_bag xml << END_ADD_DOC @xml_time = Time.now.to_f - @start_time xml end |
#pointyize_delete ⇒ Object
Takes a succinct document id, like 2342, and turns it into something even more compact, like
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<delete><id>2342</id></delete>\n"
213 214 215 216 217 218 219 220 221 222 |
# File 'lib/chef/expander/solrizer.rb', line 213 def pointyize_delete xml = "" xml << START_XML xml << DELETE_DOC xml << ID_OPEN xml << @obj_id.to_s xml << ID_CLOSE xml << END_DELETE xml end |
#post_to_solr(document, &logger_block) ⇒ Object
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/chef/expander/solrizer.rb', line 224 def post_to_solr(document, &logger_block) log.debug("POSTing document to SOLR:\n#{document}") http_req = EventMachine::HttpRequest.new(solr_url).post(:body => document, :timeout => 1200, :head => CONTENT_TYPE_XML) http_request_started http_req.callback do completed if http_req.response_header.status == 200 log.info(&logger_block) else log.error { "Failed to post to solr: #{indexed_object}" } end end http_req.errback do completed log.error { "Failed to post to solr (connection error): #{indexed_object}" } end end |
#run ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/chef/expander/solrizer.rb', line 113 def run case @action when ADD add when DELETE delete when SKIP completed log.info { "not indexing this item because of malformed JSON"} else completed log.error { "cannot index object becuase it has an invalid action #{@action}" } end end |
#solr_url ⇒ Object
253 254 255 |
# File 'lib/chef/expander/solrizer.rb', line 253 def solr_url "#{Expander.config.solr_url}/update" end |
#transit_time ⇒ Object
249 250 251 |
# File 'lib/chef/expander/solrizer.rb', line 249 def transit_time Time.now.utc.to_i - @enqueued_at end |