diff options
Diffstat (limited to 'chef/lib/chef/solr_query')
-rw-r--r-- | chef/lib/chef/solr_query/lucene.treetop | 150 | ||||
-rw-r--r-- | chef/lib/chef/solr_query/lucene_nodes.rb | 285 | ||||
-rw-r--r-- | chef/lib/chef/solr_query/query_transform.rb | 65 | ||||
-rw-r--r-- | chef/lib/chef/solr_query/solr_http_request.rb | 132 |
4 files changed, 0 insertions, 632 deletions
diff --git a/chef/lib/chef/solr_query/lucene.treetop b/chef/lib/chef/solr_query/lucene.treetop deleted file mode 100644 index 99d3e1f709..0000000000 --- a/chef/lib/chef/solr_query/lucene.treetop +++ /dev/null @@ -1,150 +0,0 @@ -# -# Author:: Seth Falcon (<seth@opscode.com>) -# Copyright:: Copyright (c) 2010-2011 Opscode, Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -grammar Lucene - - rule body - (expression / space)* <Body> - end - - rule expression - operation / group / field / field_range / term / string - end - - rule term - keyword valid_letter+ <Term> / !keyword !"?" valid_letter <Term> - end - - rule field - field_name ":" (term/string/group) <Field> - end - - rule field_range - field_name ":" "[" range_value " TO " range_value "]" <InclFieldRange> - / - field_name ":" "{" range_value " TO " range_value "}" <ExclFieldRange> - end - - rule field_name - !keyword valid_letter+ <FieldName> - end - - rule range_value - valid_letter+ <RangeValue> / "*" <RangeValue> - end - - rule group - space? '(' body ')' space? <Group> - end - - rule operation - binary_op / unary_op / fuzzy_op / boost_op - end - - rule unary_op - not_op / required_op / prohibited_op - end - - rule binary_op - (group / field / field_range / term) space? boolean_operator space+ body <BinaryOp> - end - - rule boolean_operator - and_operator / or_operator - end - - rule and_operator - 'AND' <AndOperator> / '&&' <AndOperator> - end - - rule or_operator - 'OR' <OrOperator> / '||' <OrOperator> - end - - rule not_op - not_operator space (group / field / field_range / term / string) <UnaryOp> - / - bang_operator space? (group / field / field_range / term / string) <UnaryOp> - end - - rule not_operator - 'NOT' <NotOperator> - end - - rule bang_operator - '!' <NotOperator> - end - - rule required_op - !valid_letter required_operator (term/string) <UnaryOp> - / - required_operator (term/string) <UnaryOp> - end - - rule required_operator - '+' <RequiredOperator> - end - - rule prohibited_op - !valid_letter prohibited_operator (field/field_range/term/string) <UnaryOp> - end - - rule prohibited_operator - '-' <ProhibitedOperator> - end - - rule boost_op - (term/string) '^' fuzzy_param <BoostOp> - end - - rule fuzzy_op - (term/string) '~' fuzzy_param? (space / !valid_letter) <FuzzyOp> - end - - rule fuzzy_param - [0-9] '.'? [0-9] <FuzzyParam> / [0-9]+ <FuzzyParam> - end - - rule string - '"' term (space term)* '"' <Phrase> - end - - rule keyword - 'AND' / 'OR' / 'NOT' - end - - rule valid_letter - start_letter+ ([a-zA-Z0-9@*?_.-] / '\\' special_char)* - end - - rule start_letter - [a-zA-Z0-9@._*] / '\\' special_char - end - - rule end_letter - [a-zA-Z0-9*?_.] / '\\' special_char - end - - rule special_char - [-+&|!(){}\[\]^"~*?:\\] - end - - rule space - [\s]+ - end -end diff --git a/chef/lib/chef/solr_query/lucene_nodes.rb b/chef/lib/chef/solr_query/lucene_nodes.rb deleted file mode 100644 index c2d7777365..0000000000 --- a/chef/lib/chef/solr_query/lucene_nodes.rb +++ /dev/null @@ -1,285 +0,0 @@ -# -# Author:: Seth Falcon (<seth@opscode.com>) -# Copyright:: Copyright (c) 2010-2011 Opscode, Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'treetop' - -module Lucene - SEP = "__=__" - - class Term < Treetop::Runtime::SyntaxNode - def to_array - "T:#{self.text_value}" - end - - def transform - self.text_value - end - end - - class Field < Treetop::Runtime::SyntaxNode - def to_array - field = self.elements[0].text_value - term = self.elements[1].to_array - "(F:#{field} #{term})" - end - - def transform - field = self.elements[0].text_value - term = self.elements[1] - if term.is_a? Phrase - str = term.transform - # remove quotes - str = str[1 ... (str.length - 1)] - "content:\"#{field}#{SEP}#{str}\"" - else - "content:#{field}#{SEP}#{term.transform}" - end - end - end - - class FieldRange < Treetop::Runtime::SyntaxNode - - def to_array - field = self.elements[0].text_value - range_start = self.elements[1].to_array - range_end = self.elements[2].to_array - "(FR:#{field} #{left}#{range_start}#{right} #{left}#{range_end}#{right})" - end - - def transform - field = self.elements[0].text_value - range_start = self.elements[1].transform - range_end = self.elements[2].transform - # FIXME: handle special cases for missing start/end - if ("*" == range_start && "*" == range_end) - "content:#{field}#{SEP}*" - elsif "*" == range_end - "content:#{left}#{field}#{SEP}#{range_start} TO #{field}#{SEP}\\ufff0#{right}" - elsif "*" == range_start - "content:#{left}#{field}#{SEP} TO #{field}#{SEP}#{range_end}#{right}" - else - "content:#{left}#{field}#{SEP}#{range_start} TO #{field}#{SEP}#{range_end}#{right}" - end - end - - end - - class InclFieldRange < FieldRange - def left - "[" - end - def right - "]" - end - end - - class ExclFieldRange < FieldRange - def left - "{" - end - def right - "}" - end - end - - class RangeValue < Treetop::Runtime::SyntaxNode - def to_array - self.text_value - end - - def transform - to_array - end - end - - class FieldName < Treetop::Runtime::SyntaxNode - def to_array - self.text_value - end - - def transform - to_array - end - end - - - class Body < Treetop::Runtime::SyntaxNode - def to_array - self.elements.map { |x| x.to_array }.join(" ") - end - - def transform - self.elements.map { |x| x.transform }.join(" ") - end - end - - class Group < Treetop::Runtime::SyntaxNode - def to_array - "(" + self.elements[0].to_array + ")" - end - - def transform - "(" + self.elements[0].transform + ")" - end - end - - class BinaryOp < Treetop::Runtime::SyntaxNode - def to_array - op = self.elements[1].to_array - a = self.elements[0].to_array - b = self.elements[2].to_array - "(#{op} #{a} #{b})" - end - - def transform - op = self.elements[1].transform - a = self.elements[0].transform - b = self.elements[2].transform - "#{a} #{op} #{b}" - end - end - - class AndOperator < Treetop::Runtime::SyntaxNode - def to_array - "OP:AND" - end - - def transform - "AND" - end - end - - class OrOperator < Treetop::Runtime::SyntaxNode - def to_array - "OP:OR" - end - - def transform - "OR" - end - end - - class FuzzyOp < Treetop::Runtime::SyntaxNode - def to_array - a = self.elements[0].to_array - param = self.elements[1] - if param - "(OP:~ #{a} #{param.to_array})" - else - "(OP:~ #{a})" - end - end - - def transform - a = self.elements[0].transform - param = self.elements[1] - if param - "#{a}~#{param.transform}" - else - "#{a}~" - end - end - end - - class BoostOp < Treetop::Runtime::SyntaxNode - def to_array - a = self.elements[0].to_array - param = self.elements[1] - "(OP:^ #{a} #{param.to_array})" - end - - def transform - a = self.elements[0].transform - param = self.elements[1] - "#{a}^#{param.transform}" - end - end - - class FuzzyParam < Treetop::Runtime::SyntaxNode - def to_array - self.text_value - end - - def transform - self.text_value - end - end - - class UnaryOp < Treetop::Runtime::SyntaxNode - def to_array - op = self.elements[0].to_array - a = self.elements[1].to_array - "(#{op} #{a})" - end - - def transform - op = self.elements[0].transform - a = self.elements[1].transform - spc = case op - when "+", "-" - "" - else - " " - end - "#{op}#{spc}#{a}" - end - - end - - class NotOperator < Treetop::Runtime::SyntaxNode - def to_array - "OP:NOT" - end - - def transform - "NOT" - end - - end - - class RequiredOperator < Treetop::Runtime::SyntaxNode - def to_array - "OP:+" - end - - def transform - "+" - end - - end - - class ProhibitedOperator < Treetop::Runtime::SyntaxNode - def to_array - "OP:-" - end - - def transform - "-" - end - end - - class Phrase < Treetop::Runtime::SyntaxNode - def to_array - "STR:#{self.text_value}" - end - - def transform - "#{self.text_value}" - end - end -end diff --git a/chef/lib/chef/solr_query/query_transform.rb b/chef/lib/chef/solr_query/query_transform.rb deleted file mode 100644 index 529f9de482..0000000000 --- a/chef/lib/chef/solr_query/query_transform.rb +++ /dev/null @@ -1,65 +0,0 @@ -# -# Author:: Seth Falcon (<seth@opscode.com>) -# Copyright:: Copyright (c) 2010-2011 Opscode, Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -require 'treetop' -require 'chef/solr_query/lucene_nodes' - -class Chef - class Exceptions - class QueryParseError < StandardError - end - end -end - -class Chef - class SolrQuery - class QueryTransform - @@base_path = File.expand_path(File.dirname(__FILE__)) - Treetop.load(File.join(@@base_path, 'lucene.treetop')) - @@parser = LuceneParser.new - - def self.parse(data) - tree = @@parser.parse(data) - msg = "Parse error at offset: #{@@parser.index}\n" - msg += "Reason: #{@@parser.failure_reason}" - raise Chef::Exceptions::QueryParseError, msg if tree.nil? - self.clean_tree(tree) - tree.to_array - end - - def self.transform(data) - return "*:*" if data == "*:*" - tree = @@parser.parse(data) - msg = "Parse error at offset: #{@@parser.index}\n" - msg += "Reason: #{@@parser.failure_reason}" - raise Chef::Exceptions::QueryParseError, msg if tree.nil? - self.clean_tree(tree) - tree.transform - end - - private - - def self.clean_tree(root_node) - return if root_node.elements.nil? - root_node.elements.delete_if do |node| - node.class.name == "Treetop::Runtime::SyntaxNode" - end - root_node.elements.each { |node| self.clean_tree(node) } - end - end - end -end diff --git a/chef/lib/chef/solr_query/solr_http_request.rb b/chef/lib/chef/solr_query/solr_http_request.rb deleted file mode 100644 index e7ce1d5675..0000000000 --- a/chef/lib/chef/solr_query/solr_http_request.rb +++ /dev/null @@ -1,132 +0,0 @@ -# -# Author:: Adam Jacob (<adam@opscode.com>) -# Author:: Daniel DeLeo (<dan@opscode.com>) -# Copyright:: Copyright (c) 2009-2011 Opscode, Inc. -# License:: Apache License, Version 2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -require 'net/http' -require 'uri' -require 'chef/json_compat' -require 'chef/config' - -class Chef - class SolrQuery - class SolrHTTPRequest - CLASS_FOR_METHOD = {:GET => Net::HTTP::Get, :POST => Net::HTTP::Post} - - TEXT_XML = {"Content-Type" => "text/xml"} - - def self.solr_url=(solr_url) - @solr_url = solr_url - @http_client = nil - @url_prefix = nil - end - - def self.solr_url - @solr_url || Chef::Config[:solr_url] - end - - def self.http_client - @http_client ||= begin - uri = URI.parse(solr_url) - http_client = Net::HTTP.new(uri.host, uri.port) - http_client.use_ssl = true if uri.port == 443 - http_client - end - end - - def self.url_prefix - @url_prefix ||= begin - uri = URI.parse(solr_url) - if uri.path == "" - "/solr" - else - uri.path.gsub(%r{/$}, '') - end - end - end - - def self.select(params={}) - url = "#{url_prefix}/select?#{url_join(params)}" - Chef::Log.debug("Sending #{url} to Solr") - request = new(:GET, url) - json_response = request.run("Search Query to Solr '#{solr_url}#{url}'") - Chef::JSONCompat.from_json(json_response) - end - - def self.update(doc) - url = "#{url_prefix}/update" - Chef::Log.debug("POSTing document to SOLR:\n#{doc}") - request = new(:POST, url, TEXT_XML) { |req| req.body = doc.to_s } - request.run("POST to Solr '#{solr_url}#{url}', data: #{doc}") - end - - def self.url_join(params_hash={}) - params = params_hash.inject("") do |param_str, params| - param_str << "#{params[0]}=#{escape(params[1])}&" - end - params.chop! # trailing & - params - end - - def self.escape(s) - s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) { - '%'+$1.unpack('H2'*$1.size).join('%').upcase - }.tr(' ', '+') - end - - def initialize(method, url, headers=nil) - args = headers ? [url, headers] : url - @request = CLASS_FOR_METHOD[method].new(*args) - yield @request if block_given? - end - - def http_client - self.class.http_client - end - - def solr_url - self.class.solr_url - end - - def run(description="HTTP Request to Solr") - response = http_client.request(@request) - request_failed!(response, description) unless response.kind_of?(Net::HTTPSuccess) - response.body - rescue NoMethodError => e - # http://redmine.ruby-lang.org/issues/show/2708 - # http://redmine.ruby-lang.org/issues/show/2758 - if e.to_s =~ /#{Regexp.escape(%q|undefined method 'closed?' for nil:NilClass|)}/ - Chef::Log.fatal("#{description} failed. Chef::Exceptions::SolrConnectionError exception: Errno::ECONNREFUSED (net/http undefined method closed?) attempting to contact #{solr_url}") - Chef::Log.debug("Rescued error in http connect, treating it as Errno::ECONNREFUSED to hide bug in net/http") - Chef::Log.debug(e.backtrace.join("\n")) - raise Chef::Exceptions::SolrConnectionError, "Errno::ECONNREFUSED: Connection refused attempting to contact #{solr_url}" - else - raise - end - end - - def request_failed!(response, description='HTTP call') - Chef::Log.fatal("#{description} failed (#{response.class} #{response.code} #{response.message})") - response.error! - rescue Timeout::Error, Errno::EINVAL, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT => e - Chef::Log.debug(e.backtrace.join("\n")) - raise Chef::Exceptions::SolrConnectionError, "#{e.class.name}: #{e.to_s}" - end - - end - end -end |