port_repo.rb

  1# frozen_string_literal: true
  2
  3require "em_promise"
  4require "delegate"
  5require "ruby-bandwidth-iris"
  6require "lazy_object"
  7
  8require_relative "db_port"
  9
 10class PortRepo
 11	def initialize(output, dry_run: false)
 12		@output = output
 13		@dry_run = dry_run
 14		@step_repo = PortingStepRepo.new(output: output)
 15	end
 16
 17	def list
 18		raise NotImplementedError, "subclass must implement"
 19	end
 20
 21	def process
 22		list.then { |ports|
 23			EMPromise.all(ports.map(&method(:tick)))
 24		}
 25	end
 26
 27	class Bandwidth < self
 28		class PortWithBackend < SimpleDelegator
 29			def backend_sgx
 30				CONFIG[:sgx]
 31			end
 32
 33			def id
 34				self[:order_id]
 35			end
 36
 37			def customer_id
 38				self[:customer_order_id]
 39			end
 40
 41			def tel
 42				self[:billing_telephone_number]
 43			end
 44
 45			def updated_at
 46				self[:last_modified_date]
 47			end
 48		end
 49
 50		def list
 51			(BandwidthIris::PortIn.list(
 52				page: 1,
 53				size: 50,
 54				start_date: Date.today - 1,
 55				end_date: Date.today
 56			) || []).map(&PortWithBackend.method(:new))
 57		end
 58	end
 59
 60	class Db < self
 61		def initialize(
 62			output,
 63			dry_run: false,
 64			db: LazyObject.new { DB },
 65			filters: {}
 66		)
 67			super(output, dry_run: dry_run)
 68			@db = db
 69			@filters = filters
 70		end
 71
 72		def list(**kwargs)
 73			rows(**@filters.merge(kwargs)).then { |r|
 74				r.map { |row|
 75					DbPort.from(**row.transform_keys(&:to_sym))
 76				}
 77			}
 78		end
 79
 80	protected
 81
 82		def rows(
 83			max_results: 50,
 84			offset: 0,
 85			start_date: Date.today - 1,
 86			end_date: Date.today + 1,
 87			customer_id: nil
 88		)
 89			conditions = ["actual_foc_date >= $1", "actual_foc_date <= $2"]
 90			params = [start_date, end_date]
 91
 92			if customer_id
 93				conditions << "customer_id = $#{params.length + 1}"
 94				params << customer_id
 95			end
 96
 97			@db.exec_defer(<<~SQL, params + [max_results, offset])
 98				SELECT * FROM ports
 99				WHERE #{conditions.join(' AND ')}
100				LIMIT $#{params.length + 1}
101				OFFSET $#{params.length + 2}
102			SQL
103		end
104	end
105
106	class Fake < Bandwidth
107		FakePort = Struct.new(
108			:id,
109			:processing_status,
110			:actual_foc_date,
111			:updated_at,
112			:customer_id,
113			:tel,
114			:backend_sgx
115		)
116
117		def list
118			minutes = 1.0 / (24 * 60)
119
120			[
121				# This should be ignored
122				FakePort.new(
123					"T01", "SUBMITTED", nil, DateTime.now - 1,
124					"ignored", "9998887777", "testroute"
125				),
126				FakePort.new(
127					"T02", "COMPLETE", DateTime.now - (60 * minutes),
128					DateTime.now - (55 * minutes), "0001", "2223334444", "testroute"
129				)
130			]
131		end
132	end
133
134protected
135
136	def tick(port)
137		@step_repo.find(port).then { |step|
138			@output.info(port.id, :class, step.class)
139			if @dry_run
140				@output.info("DRY", :dry, "Not taking action")
141			else
142				step.perform_next_step
143			end
144		}
145	end
146end