Class: UmlautBorrowDirect::ControllerImplementation

Inherits:
UmlautController
  • Object
show all
Defined in:
app/controllers/umlaut_borrow_direct/controller_implementation.rb

Direct Known Subclasses

BorrowDirectController

Defined Under Namespace

Classes: UserReportableError

Constant Summary collapse

Successful =

Status codes used in ServiceResponses of type bd_request_status

"successful"
InProgress =
"in_progress"
ValidationError =

user input error

"validation_error"
Error =

system error

"error"

Instance Method Summary collapse

Instance Method Details

#submit_requestObject

Will http GET to here as /borrow_direct/:service_id/:request_id (really should be POST, but Shibboleth and other SSO protection have a problem with that, bah. The fact that we are immediately redirecting should keep it from being as big a deal.)

Will return a 500 if service_id or service_response_id can’t be found



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
# File 'app/controllers/umlaut_borrow_direct/controller_implementation.rb', line 24

def submit_request    
  # mark the DispatchedService as InProgress again -- we do this
  # mainly so standard Umlaut will catch if it times out with no
  # request confirmation update, and mark it as errored appropriately. 
  @request.dispatched(@service, DispatchedService::InProgress)

  # add a bd_request_status object as a place to mark that we are in progress
  # specifically with placing a request, and blanking out any previous
  # errors from existing one. 
  set_status_response(
    :status => InProgress,
    :error_user_message => ""
  )

  # We need to have a barcode to make a request. Custom sub-class must
  # supply. 

  # We're gonna kick off the actual request submission in a bg thread,
  # cause it's so damn slow. Yeah, if the process dies in the middle, we might
  # lose it. Umlaut will notice after a timeout and display error. 
  # Saving the @bg_thread only so in testing we can wait on it. 
  @bg_thread = Thread.new(@request, @service, @request.referent.isbn) do |request, service, isbn|
    begin
      ActiveRecord::Base.forbid_implicit_checkout_for_thread!

      requester = BorrowDirect::RequestItem.new(self.patron_barcode, service.library_symbol)
      requester.timeout = @service.http_timeout

      # remove hyphens, BD likes it better. 
      normalized_isbn = isbn.gsub('-', '') if isbn

      request_number = requester.make_request!(params[:pickup_location], :isbn => normalized_isbn)

      ActiveRecord::Base.connection_pool.with_connection do
        service.bd_api_log(isbn, "RequestItem", "SUCCESS", requester.last_request_time)

        request.dispatched(service, DispatchedService::Successful)
        set_status_response({:status => Successful, :request_number => request_number }, request)
      end

    rescue StandardError => e
      # If it was an AR error in the first place, forget trying to record
      # it. 
      if e.kind_of?(ActiveRecord::ActiveRecordError)
        Rails.logger.fatal("BorrowDirect: Error placing request, and we could not log to database (#{e}):  #{e.class} #{e.message}. Backtrace:\n  #{Umlaut::Util.clean_backtrace(e).join("\n  ")}\n")

        # Nothing will do anything with this since we aren't waiting on
        # the thread, but oh well. 
        raise e
      end

      ActiveRecord::Base.connection_pool.with_connection do
        Rails.logger.error("BorrowDirect: Error placing request:  #{e.class} #{e.message}. Backtrace:\n  #{Umlaut::Util.clean_backtrace(e).join("\n  ")}\n")

        request.dispatched(service, DispatchedService::FailedFatal, e)

        status_response_data = {:status => Error}
        status_response_data[:error_user_message] = e.message if e.kind_of? UserReportableError

        set_status_response(status_response_data, request)

        if service
          service.bd_api_log(isbn, "RequestItem", e, (requester.last_request_time if requester))
        end


        # In testing, we kinda wanna re-raise this guy
        raise e if defined?(VCR::Errors::UnhandledHTTPRequestError) && e.kind_of?(VCR::Errors::UnhandledHTTPRequestError)
      end
    end
  end

  redirect_back_to_source
end