require 'ecoportal/api/v1/job/status' require 'ecoportal/api/v1/job/awaiter' module Ecoportal module API class V1 class Job attr_reader :client, :person_class # @param client [Common::Client] a `Common::Client` object that holds the configuration of the api connection. # @return [People] an instance object ready to make people api requests. def initialize(client, person_class:) @client = client @person_class = person_class @created = false end # Allows to preserve the learned througoutput def new self.class.new(client, person_class: person_class).tap do |out| out.awaiter = @awaiter end end def created? @created end # @return [Ecoportal::API::Common::Response] the results of the batch job def batch(recover: false) raise_if_already_launched! unless recover @operation ||= Common::BatchOperation.new( "/people", person_class, logger: client.logger ) yield operation unless recover total = operation.count job_id = create(operation, recover: recover) stat = awaiter( job_id: job_id, total: total ).await_completion! job_result(job_id, operation) if stat&.complete?(total) end def status(job_id) response = client.get("/people/job/#{CGI.escape(job_id)}/status") body = response && body_data(response.body) msg = "Status error (#{response.status}) - " msg << "Errors: #{body}" raise msg unless response.success? Status.new(*body.values_at(*%w[id complete errored progress])) end protected attr_writer :awaiter def awaiter(job_id:, total:, preserve: true) return @awaiter = Awaiter.new(self, job_id: job_id, total: total) unless preserve && @awaiter @awaiter = @awaiter.new(job_id: job_id, total: total) end private attr_reader :operation def operations @operations ||= {} end def job_operation(job_id) operations[job_id] end def raise_if_already_launched! return unless created? msg = "Missusage: job was already created." msg << " Can't call batch more than once" raise msg end # @return [Ecoportal::API::Common::Response] the results of the batch job def job_result(job_id, operation) client.get("/people/job/#{CGI.escape(job_id)}").tap do |response| operation.process_response(response) end end # @return [String] the `id` of the created batch job def create(operation, recover: false) raise_if_already_launched! unless recover job_id = nil client.post("/people/job", data: operation.as_json).tap do |response| job_id = body_data(response.body)["id"] if response.success? next if job_id msg = "Could not create job - Error (#{response.status}): " msg << body_data(response.body).to_s raise msg end if job_id @created = true operations[job_id] = operation end job_id end # Hook for other api versions to obtain the raw data of a response # @note this was introduced to allow `v2` to reuse this class def body_data(body) body end end end end end