Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supporting multiple item records in Item controller APi #1508

Merged
merged 6 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 83 additions & 69 deletions app/controllers/api/v01/bibs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,86 +13,100 @@ class Api::V01::BibsController < Api::V01::GeneralController
# Find or create a teacher set in the MLN db and its associated books.
def create_or_update_teacher_sets
api_response = []
parse_request_body(request).each do |req_body|
begin
http_status = 200
LogWrapper.log('DEBUG', {'message' => 'create_or_update_teacher_sets.start',
'method' => 'bibs_controller.create_or_update_teacher_sets'})
# Raise validations if input params missing
validate_input_params(req_body, true)
begin
parse_request_body(request).each do |req_body|
begin
http_status = 200
LogWrapper.log("DEBUG", { "message" => "create_or_update_teacher_sets.start",
"method" => "bibs_controller.create_or_update_teacher_sets" })
# Raise validations if input params missing
validate_input_params(req_body, true)

# create/update teacher-set data from bib request_body.
teacher_set = TeacherSet.create_or_update_teacher_set(req_body)
response = SYS_SUCCESS.call('TeacherSet successlly created', { teacher_set: bib_response(teacher_set) }.to_json, "Bib id: #{req_body['id']}")
ts_id = teacher_set.id
rescue InvalidInputException => e
http_status = 400
message = e.message
response = SYS_FAILURE.call(e.code, e.message, e.detailed_msg, "Bib id: #{req_body['id']}")
rescue SuppressedBibRecordException, BibRecordNotFoundException => e
http_status = 404
message = e.message
response = SYS_FAILURE.call(e.code, e.message, e.detailed_msg, "Bib id: #{req_body['id']}")
rescue DBException, ElasticsearchException => e
http_status = 500
message = e.message
response = SYS_FAILURE.call(e.code, e.message, e.detailed_msg, "Bib id: #{req_body['id']}")
rescue StandardError => e
http_status = 500
message = e.message
response = SYS_FAILURE.call(UNEXPECTED_EXCEPTION[:code], UNEXPECTED_EXCEPTION[:msg], nil, "Bib id: #{req_body['id']}")
AdminMailer.failed_bibs_controller_api_request(req_body, "Error while creating/updating the teacherset: #{e.message[0..200]}...",
action_name, teacher_set).deliver
end
LogWrapper.log('INFO', {'message' => "message: #{message}, http_status: #{http_status}",
'method' => __method__, 'bib_id' => req_body['id'], 'teacher_set_id' => ts_id,
'suppressed' => req_body["suppressed"]})
# create/update teacher-set data from bib request_body.
teacher_set = TeacherSet.create_or_update_teacher_set(req_body)
response = SYS_SUCCESS.call("TeacherSet successlly created", { teacher_set: bib_response(teacher_set) }.to_json, "Bib id: #{req_body["id"]}")
ts_id = teacher_set.id
rescue InvalidInputException => e
http_status = 400
message = e.message
response = SYS_FAILURE.call(e.code, e.message, e.detailed_msg, "Bib id: #{req_body["id"]}")
rescue SuppressedBibRecordException, BibRecordNotFoundException => e
http_status = 404
message = e.message
response = SYS_FAILURE.call(e.code, e.message, e.detailed_msg, "Bib id: #{req_body["id"]}")
rescue DBException, ElasticsearchException => e
http_status = 500
message = e.message
response = SYS_FAILURE.call(e.code, e.message, e.detailed_msg, "Bib id: #{req_body["id"]}")
rescue StandardError => e
http_status = 500
message = e.message
response = SYS_FAILURE.call(UNEXPECTED_EXCEPTION[:code], UNEXPECTED_EXCEPTION[:msg], nil, "Bib id: #{req_body["id"]}")
AdminMailer.failed_bibs_controller_api_request(req_body, "Error while creating/updating the teacherset: #{e.message[0..200]}...",
action_name, teacher_set).deliver
end
LogWrapper.log("INFO", { "message" => "message: #{message}, http_status: #{http_status}",
"method" => __method__, "bib_id" => req_body["id"], "teacher_set_id" => ts_id,
"suppressed" => req_body["suppressed"] })

api_response << { status: http_status, response: response }
api_response << { status: http_status, response: response }
end
rescue InvalidInputException => e
http_status = 400
message = e.message
http_response = SYS_FAILURE.call(e.code, e.message, e.detailed_msg)
api_response << { status: http_status, response: http_response }
end
api_http_status = api_response.pluck(:status).include?(500) ? 500 : 200

api_http_status = api_response.pluck(:status).include?(500) ? 500 : 200
render status: api_http_status, json: api_response
end

def delete_teacher_sets
api_response = []
parse_request_body(request).each do |req_body|
begin
http_status = 200
bib_id = req_body['id']
begin
parse_request_body(request).each do |req_body|
begin
http_status = 200
bib_id = req_body["id"]

# Raise validations if input params missing
validate_input_params(req_body)
# Delete teacher-set from db and elastic-search.
teacher_set = TeacherSet.delete_teacher_set(bib_id)
response = SYS_SUCCESS.call('TeacherSet successlly deleted', { teacher_set: bib_response(teacher_set) }.to_json, "Bib id: #{req_body['id']}")
ts_id = teacher_set.id

rescue InvalidInputException => e
http_status = 400
message = e.message
response = SYS_FAILURE.call(e.code, message, e.detailed_msg, "Bib id: #{req_body['id']}")
rescue BibRecordNotFoundException => e
http_status = 404
message = e.message
response = SYS_FAILURE.call(e.code, message, e.detailed_msg, "Bib id: #{req_body['id']}")
rescue DBException, ElasticsearchException => e
http_status = 500
message = e.message
response = SYS_FAILURE.call(e.code, message, e.detailed_msg, "Bib id: #{req_body['id']}")
rescue StandardError => e
http_status = 500
message = e.message
response = SYS_FAILURE.call(UNEXPECTED_EXCEPTION[:code], UNEXPECTED_EXCEPTION[:msg], nil, "Bib id: #{req_body['id']}")
AdminMailer.failed_bibs_controller_api_request(req_body, "Error while deleting the teacherset: #{e.message[0..200]}...",
action_name, teacher_set).deliver
LogWrapper.log('INFO', {message: "message: #{message}, http_status: #{http_status}",
method: __method__, bib_id: req_body['id'], teacher_set_id: ts_id,
suppressed: req_body["suppressed"]})
# Raise validations if input params missing
validate_input_params(req_body)
# Delete teacher-set from db and elastic-search.
teacher_set = TeacherSet.delete_teacher_set(bib_id)
response = SYS_SUCCESS.call("TeacherSet successlly deleted", { teacher_set: bib_response(teacher_set) }.to_json, "Bib id: #{req_body["id"]}")
ts_id = teacher_set.id
rescue InvalidInputException => e
http_status = 400
message = e.message
response = SYS_FAILURE.call(e.code, message, e.detailed_msg, "Bib id: #{req_body["id"]}")
rescue BibRecordNotFoundException => e
http_status = 404
message = e.message
response = SYS_FAILURE.call(e.code, message, e.detailed_msg, "Bib id: #{req_body["id"]}")
rescue DBException, ElasticsearchException => e
http_status = 500
message = e.message
response = SYS_FAILURE.call(e.code, message, e.detailed_msg, "Bib id: #{req_body["id"]}")
rescue StandardError => e
http_status = 500
message = e.message
response = SYS_FAILURE.call(UNEXPECTED_EXCEPTION[:code], UNEXPECTED_EXCEPTION[:msg], nil, "Bib id: #{req_body["id"]}")
AdminMailer.failed_bibs_controller_api_request(req_body, "Error while deleting the teacherset: #{e.message[0..200]}...",
action_name, teacher_set).deliver
LogWrapper.log("INFO", { message: "message: #{message}, http_status: #{http_status}",
method: __method__, bib_id: req_body["id"], teacher_set_id: ts_id,
suppressed: req_body["suppressed"] })
end
api_response << { status: http_status, response: response }
end
api_response << { status: http_status, response: response }
rescue InvalidInputException => e
http_status = 400
message = e.message
http_response = SYS_FAILURE.call(e.code, e.message, e.detailed_msg)
api_response << { status: http_status, response: http_response }
end
api_http_status = api_response.pluck(:status).include?(500) ? 500 : 200
api_http_status = api_response.pluck(:status).include?(500) ? 500 : 200
render status: api_http_status, json: api_response
end
end
103 changes: 59 additions & 44 deletions app/controllers/api/v01/items_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

class Api::V01::ItemsController < Api::V01::GeneralController
include LogWrapper
include MlnHelper
include MlnResponse

before_action :set_request_body
before_action :validate_source_of_request
Expand All @@ -17,61 +19,74 @@ class Api::V01::ItemsController < Api::V01::GeneralController
# On error finding local data, writes a message to the error log, but returns a success to the calling lambda.
# On error communicating with the Bib Service, returns a failure to the calling lambda (triggering a re-try).
def update_availability
api_response = []
begin
LogWrapper.log('DEBUG', {'message' => 'update_availability.start','method' => "#{controller_name}.#{action_name}",
"requestBody" => @request_body })
error_code_and_message = validate_request
if error_code_and_message.any?
# don't send an alert email for now
# AdminMailer.failed_items_controller_api_request(error_code_and_message).deliver
render_error(error_code_and_message)
end
return if error_code_and_message.any?
parse_request_body(request).each do |req_body|
begin
LogWrapper.log("DEBUG", { "message" => "update_availability.start", "method" => "#{controller_name}.#{action_name}",
"requestBody" => req_body })
error_code_and_message = validate_request
if error_code_and_message.any?
end
t_set_bnumber, nypl_source = parse_item_bib_id_and_nypl_source(req_body)
http_status = 200
unless t_set_bnumber.present?
http_status = 404
message = "BIB id is empty."
http_response = SYS_FAILURE.call(http_status, message, "Item id: #{req_body["id"]}")
api_response << { status: http_status, response: http_response }
end

t_set_bnumber, nypl_source = parse_item_bib_id_and_nypl_source(@request_body)
unless nypl_source.present?
http_status = 400
message = "NYPL source is empty."
http_response = SYS_FAILURE.call(http_status, message, "Item id: #{req_body["id"]}")
api_response << { status: http_status, response: http_response }
end

unless t_set_bnumber.present?
render_error([404, "BIB id is empty."])
return
end
unless nypl_source.present?
render_error([404, "NYPL source is empty."])
return
teacher_set = TeacherSet.find_by_bnumber("b#{t_set_bnumber}")
unless teacher_set.present?
http_status = 404
message = "BIB id not found in MLN DB. Bib id b#{t_set_bnumber},"
http_response = SYS_FAILURE.call(http_status, message, "Item id: #{req_body["id"]}")
end
if teacher_set.present? && t_set_bnumber.present?
teacher_set.update_available_and_total_count(t_set_bnumber)
http_response = { message: "OK" }
message = "Items availability successfully updated. Bnumber: #{t_set_bnumber}"
end
rescue InvalidInputException => e
http_status = 400
message = e.message
response = SYS_FAILURE.call(e.code, e.message, e.detailed_msg, "Item id: #{req_body["id"]}")
rescue StandardError => e
http_status = 500
http_response = "Error while getting item records via API: #{e.message[0..200]}, Bnumber: #{t_set_bnumber}"
AdminMailer.failed_items_controller_api_request(http_response).deliver
api_response << { status: http_status, response: http_response }
end
LogWrapper.log("INFO", { "message" => "message: #{message}, http_status: #{http_status}",
"method" => __method__, "item_id" => req_body["id"] })
api_response << { status: http_status, response: http_response }
end
teacher_set = TeacherSet.find_by_bnumber("b#{t_set_bnumber}")
unless teacher_set.present?
# I added 500 for testing only, needs to remove
render_error([500, "BIB id not found in MLN DB. BibId b#{t_set_bnumber}"])
return
end

begin
response = teacher_set.update_available_and_total_count(t_set_bnumber)
http_status = response[:bibs_resp]['statusCode']
http_response = {message: response[:bibs_resp]['message'] || 'OK'}
rescue => e
error_message = "Error while getting item records via API: #{e.message[0..200]}, Bnumber: #{t_set_bnumber}"
AdminMailer.failed_items_controller_api_request(error_message).deliver
render_error([500, error_message])
return
end
rescue => e
render_error([500, "Error occured: #{e.message[0..200]}, Bnumber: #{t_set_bnumber}"])
return
rescue InvalidInputException => e
http_status = 400
message = e.message
http_response = SYS_FAILURE.call(e.code, e.message, e.detailed_msg)
api_response << { status: http_status, response: http_response }
end
LogWrapper.log('INFO','message' => "Items availability successfully updated. Bnumber: #{t_set_bnumber}")
api_response_builder(http_status, http_response.to_json)
# HTTP status code 200 was specifically added for the consumer app to ensure proper handling of API responses.
api_http_status = api_response.pluck(:status).include?(500) ? 500 : 200
render status: api_http_status, json: api_response
end #method ends

# All records are inside @request_body.
# Reads item JSON, Parses out the item t_set_bnumber and nypl_source
def parse_item_bib_id_and_nypl_source(request_body)
t_set_bnumber = nil
nypl_source = nil
request_body.each do |item|
t_set_bnumber = item['bibIds'][0]
nypl_source = item['nyplSource']
end
t_set_bnumber = request_body["bibIds"][0]
nypl_source = request_body["nyplSource"]
return t_set_bnumber, nypl_source
end
end
Loading