TrivialBackendSgxRepo#get should return a promise

Stephen Paul Weber created

Every repo find/get should return a promise, and also we plan to do IO
in here soon.

Change summary

lib/admin_actions/number_change.rb | 13 ++++---
lib/bwmsgsv2_repo.rb               | 49 ++++++++++++++++---------------
lib/customer.rb                    |  4 +-
lib/customer_info.rb               |  3 +
lib/customer_repo.rb               | 10 +++---
lib/parent_code_repo.rb            |  2 
lib/trivial_backend_sgx_repo.rb    | 18 ++++++-----
sgx_jmp.rb                         | 16 ++-------
test/test_backend_sgx.rb           |  3 +
test/test_customer_repo.rb         |  2 
test/test_helper.rb                | 17 +++++++++++
test/test_low_balance.rb           |  1 
test/test_registration.rb          |  6 +-
13 files changed, 81 insertions(+), 63 deletions(-)

Detailed changes

lib/admin_actions/number_change.rb 🔗

@@ -68,12 +68,13 @@ class AdminAction
 		end
 
 		def forward
-			sgx = TrivialBackendSgxRepo.new.get(customer_id)
-			EMPromise.all([
-				REDIS.rename("catapult_fwd-#{old_tel}", "catapult_fwd-#{new_tel}"),
-				sgx.register!(new_tel),
-				should_delete? && first_time? ? disconnect_number : nil
-			]).then { self }
+			TrivialBackendSgxRepo.new.get(customer_id).then do |sgx|
+				EMPromise.all([
+					REDIS.rename("catapult_fwd-#{old_tel}", "catapult_fwd-#{new_tel}"),
+					sgx.register!(new_tel),
+					should_delete? && first_time? ? disconnect_number : nil
+				]).then { self }
+			end
 		end
 
 		def to_reverse

lib/bwmsgsv2_repo.rb 🔗

@@ -22,35 +22,38 @@ class Bwmsgsv2Repo
 	end
 
 	def get(customer_id, tel: nil)
-		sgx = @trivial_repo.get(customer_id, tel: tel)
-		fetch_raw(sgx).then do |(((ogm_url, fwd_time, fwd), flags), reg)|
-			sgx.with(
-				ogm_url: ogm_url,
-				fwd: CustomerFwd.for(uri: fwd, timeout: fwd_time),
-				transcription_enabled: !flags[VOICEMAIL_TRANSCRIPTION_DISABLED],
-				registered?: reg
-			)
-		end
+		@trivial_repo.get(customer_id, tel: tel)
+			.then { |sgx| EMPromise.all([fetch_raw(sgx), sgx]) }
+			.then do |((((ogm_url, fwd_time, fwd), flags), reg), sgx)|
+				sgx.with(
+					ogm_url: ogm_url,
+					fwd: CustomerFwd.for(uri: fwd, timeout: fwd_time),
+					transcription_enabled: !flags[VOICEMAIL_TRANSCRIPTION_DISABLED],
+					registered?: reg
+				)
+			end
 	end
 
 	def put_transcription_enabled(customer_id, enabled)
-		sgx = @trivial_repo.get(customer_id)
-		REDIS.setbit(
-			"catapult_settings_flags-#{sgx.from_jid}",
-			Bwmsgsv2Repo::VOICEMAIL_TRANSCRIPTION_DISABLED,
-			enabled ? 0 : 1
-		)
+		@trivial_repo.get(customer_id).then do |sgx|
+			REDIS.setbit(
+				"catapult_settings_flags-#{sgx.from_jid}",
+				Bwmsgsv2Repo::VOICEMAIL_TRANSCRIPTION_DISABLED,
+				enabled ? 0 : 1
+			)
+		end
 	end
 
 	def put_fwd(customer_id, tel, customer_fwd)
-		sgx = @trivial_repo.get(customer_id)
-		EMPromise.all([
-			set_or_delete("catapult_fwd-#{tel}", customer_fwd.uri),
-			set_or_delete(
-				"catapult_fwd_timeout-#{sgx.from_jid}",
-				customer_fwd.timeout.to_i
-			)
-		])
+		@trivial_repo.get(customer_id).then do |sgx|
+			EMPromise.all([
+				set_or_delete("catapult_fwd-#{tel}", customer_fwd.uri),
+				set_or_delete(
+					"catapult_fwd_timeout-#{sgx.from_jid}",
+					customer_fwd.timeout.to_i
+				)
+			])
+		end
 	end
 
 protected

lib/customer.rb 🔗

@@ -56,11 +56,11 @@ class Customer
 	def initialize(
 		customer_id,
 		jid,
+		sgx:,
 		plan: CustomerPlan.new(customer_id),
 		balance: BigDecimal(0),
 		tndetails: {},
-		feature_flags: [],
-		sgx: TrivialBackendSgxRepo.new.get(customer_id)
+		feature_flags: []
 	)
 		@plan = plan
 		@usage = CustomerUsage.new(customer_id)

lib/customer_info.rb 🔗

@@ -129,7 +129,8 @@ class AdminInfo
 			info: CustomerInfo.for(customer),
 			call_info: call_info(customer, call_attempt_repo),
 			trust_level: trust_level_repo.find(customer).then(&:to_s),
-			backend_jid: backend_repo.get(customer.customer_id).from_jid.to_s,
+			backend_jid: backend_repo.get(customer.customer_id)
+				.then(&:from_jid).then(&:to_s),
 			subaccounts: Subaccount.get_subaccounts(customer.billing_customer_id)
 		).then(&method(:new))
 	end

lib/customer_repo.rb 🔗

@@ -96,13 +96,13 @@ class CustomerRepo
 		@braintree.customer.create.then do |result|
 			raise "Braintree customer create failed" unless result.success?
 
-			cid = result.customer.id
+			c = result.customer.id
 			@redis.msetnx(
-				"jmp_customer_id-#{jid}", cid, "jmp_customer_jid-#{cid}", jid
+				"jmp_customer_id-#{jid}", c, "jmp_customer_jid-#{c}", jid
 			).then do |redis_result|
 				raise "Saving new customer to redis failed" unless redis_result == 1
 
-				Customer.created(cid, jid, sgx: new_sgx(cid), repo: self)
+				mksgx(c).then { |sgx| Customer.created(c, jid, sgx: sgx, repo: self) }
 			end
 		end
 	end
@@ -156,8 +156,8 @@ class CustomerRepo
 
 protected
 
-	def new_sgx(customer_id)
-		TrivialBackendSgxRepo.new.get(customer_id).with(registered?: false)
+	def mksgx(cid)
+		TrivialBackendSgxRepo.new.get(cid).then { |s| s.with(registered?: false) }
 	end
 
 	def mget(*keys)

lib/parent_code_repo.rb 🔗

@@ -46,7 +46,7 @@ class ParentCodeRepo
 	def trust_level_guard(parent_id)
 		return unless parent_id
 
-		@trust_level_repo.find(Customer.new(parent_id, "")).then { |tl|
+		@trust_level_repo.find(Customer.new(parent_id, "", sgx: nil)).then { |tl|
 			existing_subaccounts(parent_id).then { |c| [tl, c] }
 		}.then do |(tl, number_of_subaccounts)|
 			unless tl.create_subaccount?(number_of_subaccounts)

lib/trivial_backend_sgx_repo.rb 🔗

@@ -17,14 +17,16 @@ class TrivialBackendSgxRepo
 	end
 
 	def get(customer_id, tel: nil)
-		BackendSgx.new(
-			jid: @jid, creds: @creds,
-			from_jid: Blather::JID.new("customer_#{customer_id}", @component_jid),
-			ogm_url: NotLoaded.new(:ogm_url),
-			fwd: NotLoaded.new(:fwd_timeout),
-			transcription_enabled: NotLoaded.new(:transcription_enabled),
-			registered?: tel ? ibr_for(tel) : NotLoaded.new(:registered?)
-		).with(@with)
+		EMPromise.resolve(nil).then do
+			BackendSgx.new(
+				jid: @jid, creds: @creds,
+				from_jid: Blather::JID.new("customer_#{customer_id}", @component_jid),
+				ogm_url: NotLoaded.new(:ogm_url),
+				fwd: NotLoaded.new(:fwd_timeout),
+				transcription_enabled: NotLoaded.new(:transcription_enabled),
+				registered?: tel ? ibr_for(tel) : NotLoaded.new(:registered?)
+			).with(@with)
+		end
 	end
 
 protected

sgx_jmp.rb 🔗

@@ -507,18 +507,10 @@ Command.new(
 			"./ns:userId", ns: "https://ns.cheogram.com/google-play"
 		)&.first&.content
 	end
-	if Command.execution.iq.from.stripped.to_s == CONFIG[:web_register][:from]
-		Customer.new(
-			"__web_register", Command.execution.iq.from.stripped,
-			sgx: TrivialBackendSgxRepo.new.get("__web_register")
-				.with(registered?: false)
-		)
-	else
-		Command.customer.catch_only(CustomerRepo::NotFound) {
-			Sentry.add_breadcrumb(Sentry::Breadcrumb.new(message: "Customer.create"))
-			Command.execution.customer_repo.create(Command.execution.iq.from.stripped)
-		}
-	end.then { |customer|
+	Command.customer.catch_only(CustomerRepo::NotFound) {
+		Sentry.add_breadcrumb(Sentry::Breadcrumb.new(message: "Customer.create"))
+		Command.execution.customer_repo.create(Command.execution.iq.from.stripped)
+	}.then { |customer|
 		Sentry.add_breadcrumb(Sentry::Breadcrumb.new(message: "Registration.for"))
 		Registration.for(customer, google_play_userid, TEL_SELECTIONS).then(&:write)
 	}.then {

test/test_backend_sgx.rb 🔗

@@ -53,8 +53,9 @@ class BackendSgxTest < Minitest::Test
 				assert_equal "+15555550000", ibr.phone
 			end]
 		)
-		sgx = TrivialBackendSgxRepo.new.get("test")
+		sgx = TrivialBackendSgxRepo.new.get("test").sync
 		sgx.register!("+15555550000")
 		BackendSgx::IQ_MANAGER.verify
 	end
+	em :test_register!
 end

test/test_customer_repo.rb 🔗

@@ -259,7 +259,7 @@ class CustomerRepoTest < Minitest::Test
 			["test", true]
 		)
 		@repo.put_transcription_enabled(
-			Customer.new("test", "test@exmple.com"),
+			Customer.new("test", "test@exmple.com", sgx: nil),
 			true
 		)
 		assert_mock @repo.sgx_repo

test/test_helper.rb 🔗

@@ -43,6 +43,22 @@ require "tel_selections"
 $VERBOSE = nil
 Sentry.init
 
+def mksgx(customer_id="bogus", **kwargs)
+	kwargs.delete(:sgx) || BackendSgx.new(
+		jid: Blather::JID.new(CONFIG[:sgx]),
+		creds: CONFIG[:creds],
+		from_jid: ProxiedJID.proxy(
+			"customer_#{customer_id}",
+			CONFIG[:component][:jid]
+		).__getobj__,
+		ogm_url: NotLoaded.new("ogm_url"),
+		fwd: NotLoaded.new("fwd"),
+		transcription_enabled: NotLoaded.new("transcription_enabled"),
+		registered?: NotLoaded.new("registered?"),
+		**kwargs
+	)
+end
+
 def customer(
 	customer_id="test",
 	plan_name: nil,
@@ -54,6 +70,7 @@ def customer(
 	Customer.extract(
 		customer_id,
 		jid,
+		sgx: kwargs.delete(:sgx) || mksgx(customer_id),
 		plan_name: plan_name,
 		expires_at: expires_at,
 		auto_top_up_amount: auto_top_up_amount,

test/test_low_balance.rb 🔗

@@ -7,6 +7,7 @@ ExpiringLock::REDIS = Minitest::Mock.new
 CustomerPlan::REDIS = Minitest::Mock.new
 CustomerFinancials::REDIS = Minitest::Mock.new
 LowBalance::AutoTopUp::REDIS = Minitest::Mock.new
+LowBalance::DB = Minitest::Mock.new
 
 class LowBalanceTest < Minitest::Test
 	def test_for_locked

test/test_registration.rb 🔗

@@ -1181,7 +1181,7 @@ class RegistrationTest < Minitest::Test
 		Transaction::DB = Minitest::Mock.new
 
 		def setup
-			@sgx = Minitest::Mock.new(TrivialBackendSgxRepo.new.get("test"))
+			@sgx = Minitest::Mock.new(mksgx)
 			iq = Blather::Stanza::Iq::Command.new
 			iq.from = "test\\40example.com@cheogram.com"
 			@finish = Registration::Finish.new(
@@ -1639,9 +1639,9 @@ class RegistrationTest < Minitest::Test
 		Registration::FinishOnboarding::Snikket::IQ_MANAGER = Minitest::Mock.new
 
 		def setup
-			@sgx = Minitest::Mock.new(TrivialBackendSgxRepo.new.get("test"))
+			@sgx = Minitest::Mock.new(mksgx)
 			@snikket = Registration::FinishOnboarding::Snikket.new(
-				customer,
+				customer(sgx: @sgx),
 				"+15555550000",
 				db: FakeDB.new
 			)