lib/odata4/service.rb in odata4-0.8.0 vs lib/odata4/service.rb in odata4-0.8.1
- old
+ new
@@ -1,5 +1,8 @@
+require 'odata4/service/request'
+require 'odata4/service/response'
+
module OData4
# Encapsulates the basic details and functionality needed to interact with an
# OData4 service.
class Service
# The OData4 Service's URL
@@ -12,10 +15,11 @@
METADATA_TIMEOUTS = [20, 60]
MIME_TYPES = {
atom: 'application/atom+xml',
json: 'application/json',
+ xml: 'application/xml',
plain: 'text/plain'
}
# Opens the service based on the requested URL and adds the service to
# {OData4::Registry}
@@ -131,61 +135,17 @@
"#<#{self.class.name}:#{self.object_id} name='#{name}' service_url='#{self.service_url}'>"
end
# Execute a request against the service
#
- # @param url_chunk [to_s] string to append to service url
- # @param additional_options [Hash] options to pass to Typhoeus
- # @return [Typhoeus::Response]
- def execute(url_chunk, additional_options = {})
- accept = content_type(additional_options.delete(:format) || :auto)
- accept_header = {'Accept' => accept }
-
- request_options = options[:typhoeus]
- .merge({ method: :get })
- .merge(additional_options)
-
- # Don't overwrite Accept header if already present
- unless request_options[:headers]['Accept']
- request_options[:headers] = request_options[:headers].merge(accept_header)
- end
-
- request = ::Typhoeus::Request.new(
- URI.join("#{service_url}/", URI.escape(url_chunk)),
- request_options
- )
- logger.info "Requesting #{URI.unescape(request.url)}..."
- request.run
-
- response = request.response
- logger.debug(response.headers)
- logger.debug(response.body)
-
- validate_response(response)
- response
+ # @param url_chunk [to_s] string to append to service URL
+ # @param options [Hash] additional request options
+ # @return [OData4::Service::Response]
+ def execute(url_chunk, options = {})
+ Request.new(self, url_chunk, options).execute
end
- # Find a specific node in the given result set
- #
- # @param results [Typhoeus::Response]
- # @return [Nokogiri::XML::Element]
- def find_node(results, node_name)
- document = ::Nokogiri::XML(results.body)
- document.remove_namespaces!
- document.xpath("//#{node_name}").first
- end
-
- # Find entity entries in a result set
- #
- # @param results [Typhoeus::Response]
- # @return [Nokogiri::XML::NodeSet]
- def find_entities(results)
- document = ::Nokogiri::XML(results.body)
- document.remove_namespaces!
- document.xpath('//entry')
- end
-
# Get the property type for an entity from metadata.
#
# @param entity_name [to_s] the fully qualified entity name
# @param property_name [to_s] the property name needed
# @return [String] the name of the property's type
@@ -254,58 +214,30 @@
private
def default_options
{
typhoeus: {
- headers: { 'OData4-Version' => '4.0' },
+ headers: { 'OData-Version' => '4.0' },
timeout: HTTP_TIMEOUT
},
strict: true # strict property validation
}
end
- def content_type(format)
- if format == :auto
- MIME_TYPES.values.join(',')
- elsif MIME_TYPES.has_key? format
- MIME_TYPES[format]
- else
- raise ArgumentError, "Unknown format '#{format}'"
- end
- end
-
def read_metadata
- response = nil
# From file, good for debugging
if options[:metadata_file]
data = File.read(options[:metadata_file])
::Nokogiri::XML(data).remove_namespaces!
else # From a URL
+ response = nil
METADATA_TIMEOUTS.each do |timeout|
- response = ::Typhoeus::Request.get(URI.escape(metadata_url),
- options[:typhoeus].merge(timeout: timeout))
+ response = execute(metadata_url, timeout: timeout)
break unless response.timed_out?
end
raise "Metadata Timeout" if response.timed_out?
- validate_response(response)
::Nokogiri::XML(response.body).remove_namespaces!
end
- end
-
- def validate_response(response)
- raise "Bad Request. #{error_message(response)}" if response.code == 400
- raise "Access Denied" if response.code == 401
- raise "Forbidden" if response.code == 403
- raise "Not Found" if [0,404].include?(response.code)
- raise "Method Not Allowed" if response.code == 405
- raise "Not Acceptable" if response.code == 406
- raise "Request Entity Too Large" if response.code == 413
- raise "Internal Server Error" if response.code == 500
- raise "Service Unavailable" if response.code == 503
- end
-
- def error_message(response)
- OData4::Query::Result.new(nil, response).error_message
end
def register_custom_types
complex_types.each do |name, type|
::OData4::PropertyRegistry.add(name, type.property_class)