Commit 502efc7

mo khan <mo.khan@gmail.com>
2020-05-20 17:22:13
Extract Http class to log requests and apply retries
1 parent 0ee86d6
lib/scim/kit/v2/configuration.rb
@@ -40,7 +40,8 @@ module Scim
         attr_accessor :resource_types
         attr_accessor :schemas
 
-        def initialize
+        def initialize(http: Scim::Kit::Http.new)
+          @http = http
           @resource_types = {}
           @schemas = {}
 
@@ -48,12 +49,11 @@ module Scim
         end
 
         def load_from(base_url)
+          base_url = "#{base_url}/"
           uri = URI.join(base_url, 'ServiceProviderConfig')
-          response = client.get(uri, headers: {
-                                  'Accept' => 'application/scim+json',
-                                  'Content-Type' => 'application/scim+json'
-                                })
-          self.service_provider_configuration = ServiceProviderConfiguration.parse(response.body)
+          json = http.get(uri)
+
+          self.service_provider_configuration = ServiceProviderConfiguration.parse(json, json)
 
           load_items(base_url, 'Schemas', Schema, schemas)
           load_items(base_url, 'ResourceTypes', ResourceType, resource_types)
@@ -61,25 +61,15 @@ module Scim
 
         private
 
+        attr_reader :http
+
         def load_items(base_url, path, type, items)
-          response = client.get(URI.join(base_url, path), headers: headers)
-          hashes = JSON.parse(response.body, symbolize_names: true)
+          hashes = http.get(URI.join(base_url, path))
           hashes.each do |hash|
             item = type.from(hash)
             items[item.id] = item
           end
         end
-
-        def client
-          @client ||= Net::Hippie::Client.new
-        end
-
-        def headers
-          {
-            'Accept' => 'application/scim+json',
-            'Content-Type' => 'application/scim+json'
-          }
-        end
       end
     end
   end
lib/scim/kit/http.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+module Scim
+  module Kit
+    class Http
+      attr_reader :driver, :retries
+
+      def initialize(driver: Http.default_driver, retries: 3)
+        @driver = driver
+        @retries = retries
+      end
+
+      def get(uri)
+        driver.with_retry(retries: retries) do |client|
+          response = client.get(uri)
+          ok?(response) ? JSON.parse(response.body, symbolize_names: true) : {}
+        end
+      rescue *Net::Hippie::CONNECTION_ERRORS => error
+        Scim::Kit.logger.error(error)
+        {}
+      end
+
+      def self.default_driver
+        @default_driver ||= Net::Hippie::Client.new(headers: headers).tap do |http|
+          http.logger = Scim::Kit.logger
+          http.open_timeout = 1
+          http.read_timeout = 5
+          http.follow_redirects = 3
+        end
+      end
+
+      def self.headers
+        {
+          'Accept' => 'application/scim+json',
+          'Content-Type' => 'application/scim+json',
+          'User-Agent' => "scim/kit #{Scim::Kit::VERSION}"
+        }
+      end
+
+      private
+
+      def ok?(response)
+        response.is_a?(Net::HTTPSuccess)
+      end
+    end
+  end
+end
lib/scim/kit.rb
@@ -10,6 +10,7 @@ require 'tilt'
 require 'tilt/jbuilder'
 
 require 'scim/kit/dynamic_attributes'
+require 'scim/kit/http'
 require 'scim/kit/templatable'
 require 'scim/kit/template'
 require 'scim/kit/v2'
Gemfile.lock
@@ -3,7 +3,7 @@ PATH
   specs:
     scim-kit (0.5.0)
       activemodel (>= 5.2.0)
-      net-hippie (~> 0.2)
+      net-hippie (~> 0.3)
       parslet (~> 1.8)
       tilt (~> 2.0)
       tilt-jbuilder (~> 0.7)
scim-kit.gemspec
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
   spec.metadata['yard.run'] = 'yri'
 
   spec.add_dependency 'activemodel', '>= 5.2.0'
-  spec.add_dependency 'net-hippie', '~> 0.2'
+  spec.add_dependency 'net-hippie', '~> 0.3'
   spec.add_dependency 'parslet', '~> 1.8'
   spec.add_dependency 'tilt', '~> 2.0'
   spec.add_dependency 'tilt-jbuilder', '~> 0.7'