优化
This commit is contained in:
@@ -7,10 +7,10 @@ spring:
|
||||
baiyue:
|
||||
security-event:
|
||||
event-bridge-url: ${SECURITY_EVENT_BRIDGE_URL:http://event-bridge-overseas:9312}
|
||||
customer-dimension-initialization:
|
||||
fixed-delay-ms: ${CUSTOMER_DIMENSION_INITIALIZATION_FIXED_DELAY_MS:5000}
|
||||
max-attempts: ${CUSTOMER_DIMENSION_INITIALIZATION_MAX_ATTEMPTS:12}
|
||||
security-event:
|
||||
event-bridge-url: ${SECURITY_EVENT_BRIDGE_URL:http://event-bridge-overseas:9312}
|
||||
notification:
|
||||
scheduler-enabled: ${NOTIFICATION_SCHEDULER_ENABLED:false}
|
||||
dispatch-timeout-seconds: ${NOTIFICATION_DISPATCH_TIMEOUT_SECONDS:300}
|
||||
mq-consumer-enabled: ${NOTIFICATION_MQ_CONSUMER_ENABLED:false}
|
||||
|
||||
|
||||
@@ -25,9 +25,8 @@ spring:
|
||||
baiyue:
|
||||
security-event:
|
||||
event-bridge-url: ${SECURITY_EVENT_BRIDGE_URL:http://event-bridge-overseas:9312}
|
||||
customer-dimension-initialization:
|
||||
fixed-delay-ms: ${CUSTOMER_DIMENSION_INITIALIZATION_FIXED_DELAY_MS:5000}
|
||||
max-attempts: ${CUSTOMER_DIMENSION_INITIALIZATION_MAX_ATTEMPTS:12}
|
||||
security-event:
|
||||
event-bridge-url: ${SECURITY_EVENT_BRIDGE_URL:http://event-bridge-overseas:9312}
|
||||
notification:
|
||||
scheduler-enabled: ${NOTIFICATION_SCHEDULER_ENABLED:false}
|
||||
dispatch-timeout-seconds: ${NOTIFICATION_DISPATCH_TIMEOUT_SECONDS:300}
|
||||
@@ -50,3 +49,4 @@ logging:
|
||||
max-history: "${LOGGING_ROLLING_MAX_HISTORY:7}"
|
||||
total-size-cap: "${LOGGING_ROLLING_TOTAL_SIZE_CAP:5GB}"
|
||||
clean-history-on-start: "${LOGGING_ROLLING_CLEAN_HISTORY_ON_START:false}"
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ class MerchantOnboardingServiceTest {
|
||||
@MockBean private CustomerDimensionRuleInitializationService dimensionRuleInitialization;
|
||||
@MockBean private OverseasStorageFeeInitializationService overseasStorageFeeInitialization;
|
||||
@MockBean private SecurityEventOutboxService securityEvents;
|
||||
@MockBean private SecurityEventOutboxService securityEvents;
|
||||
@Resource private MerchantOnboardingService service;
|
||||
@Test
|
||||
void clientRegistrationCreatesOwnerAndAssignsGlobalMerchantOwnerRole() {
|
||||
@@ -55,8 +56,8 @@ class MerchantOnboardingServiceTest {
|
||||
when(roles.selectOne(any())).thenReturn(ownerRole);
|
||||
|
||||
var result = service.register(new MerchantRegistrationRequest(
|
||||
9001L, "注册人", "测试企业", "张三", "13800138000",
|
||||
"owner@example.com", "CN", "深圳市宝安区"));
|
||||
9001L, "注册人", "测试企业", "张三", "13800138000",
|
||||
"owner@example.com", "CN", "深圳市宝安区"));
|
||||
|
||||
ArgumentCaptor<IamTenant> tenant = ArgumentCaptor.forClass(IamTenant.class);
|
||||
ArgumentCaptor<IamUser> user = ArgumentCaptor.forClass(IamUser.class);
|
||||
@@ -67,19 +68,21 @@ class MerchantOnboardingServiceTest {
|
||||
verify(memberships).insert(membership.capture());
|
||||
verify(membershipRoles).insert(roleGrant.capture());
|
||||
verify(dimensionRuleInitialization).initialize(result.tenantId(), 9001L);
|
||||
verify(overseasStorageFeeInitialization).initialize(result.tenantId(), 9001L, "测试企业");
|
||||
verify(overseasStorageFeeInitialization).initialize(result.tenantId(), 9001L, "测试企业");
|
||||
verify(securityEvents).tenantStatus(result.tenantId(), "PROFILE_REQUIRED");
|
||||
verify(securityEvents).userStatus(9001L, result.tenantId(), "MERCHANT", "ACTIVE");
|
||||
verify(securityEvents).permissionChanged(9001L, result.tenantId(), "MERCHANT",
|
||||
"INITIAL_AUTHORIZATION");
|
||||
verify(securityEvents).tenantStatus(result.tenantId(), "PROFILE_REQUIRED");
|
||||
verify(securityEvents).userStatus(9001L, result.tenantId(), "MERCHANT", "ACTIVE");
|
||||
verify(securityEvents).permissionChanged(9001L, result.tenantId(), "MERCHANT",
|
||||
"INITIAL_AUTHORIZATION");
|
||||
|
||||
assertEquals("PROFILE_REQUIRED", result.tenantStatus());
|
||||
assertEquals("PENDING", result.dimensionInitializationStatus());
|
||||
assertEquals("PENDING", tenant.getValue().getDimensionInitializationStatus());
|
||||
assertEquals(result.tenantId(), tenant.getValue().getId());
|
||||
assertEquals("测试企业", tenant.getValue().getLegalName());
|
||||
assertEquals("张三", tenant.getValue().getLegalRepresentative());
|
||||
assertEquals("注册人", tenant.getValue().getContactName());
|
||||
assertEquals("测试企业", tenant.getValue().getLegalName());
|
||||
assertEquals("张三", tenant.getValue().getLegalRepresentative());
|
||||
assertEquals("注册人", tenant.getValue().getContactName());
|
||||
assertEquals(9001L, user.getValue().getAuthUserId());
|
||||
assertEquals("ACTIVE", user.getValue().getStatus());
|
||||
assertEquals(result.tenantId(), membership.getValue().getTenantId());
|
||||
@@ -124,7 +127,7 @@ class MerchantOnboardingServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void clientRegistrationFailsWhenDurableInitializationIntentCannotBePersisted() {
|
||||
void clientRegistrationFailsWhenFourDefaultBoxDimensionsCannotBeInitialized() {
|
||||
IamRole ownerRole = new IamRole();
|
||||
ownerRole.setId(4000100L);
|
||||
ownerRole.setTenantId(0L);
|
||||
@@ -133,14 +136,14 @@ class MerchantOnboardingServiceTest {
|
||||
ownerRole.setStatus("ACTIVE");
|
||||
when(roles.selectOne(any())).thenReturn(ownerRole);
|
||||
org.mockito.Mockito.doThrow(new com.baiyue.common.core.exception.BizException(
|
||||
com.baiyue.common.core.api.ResultCode.SERVICE_UNAVAILABLE, "初始化失败"))
|
||||
com.baiyue.common.core.api.ResultCode.SERVICE_UNAVAILABLE, "初始化失败"))
|
||||
.when(dimensionRuleInitialization).initialize(
|
||||
org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong());
|
||||
|
||||
var failure = assertThrows(com.baiyue.common.core.exception.BizException.class,
|
||||
() -> service.register(new MerchantRegistrationRequest(
|
||||
9001L, "注册人", "测试企业", "张三", "13800138000",
|
||||
"owner@example.com", "CN", "深圳市宝安区")));
|
||||
9001L, "注册人", "测试企业", "张三", "13800138000",
|
||||
"owner@example.com", "CN", "深圳市宝安区")));
|
||||
|
||||
assertEquals(com.baiyue.common.core.api.ResultCode.SERVICE_UNAVAILABLE, failure.getResultCode());
|
||||
}
|
||||
@@ -190,7 +193,7 @@ class MerchantOnboardingServiceTest {
|
||||
when(qualifications.selectCount(any())).thenReturn(0L);
|
||||
when(reviews.selectCount(any())).thenReturn(0L);
|
||||
org.mockito.Mockito.doThrow(new com.baiyue.common.core.exception.BizException(
|
||||
com.baiyue.common.core.api.ResultCode.SERVICE_UNAVAILABLE, "补偿失败"))
|
||||
com.baiyue.common.core.api.ResultCode.SERVICE_UNAVAILABLE, "补偿失败"))
|
||||
.when(dimensionRuleInitialization).compensateRegistration(10001L);
|
||||
|
||||
assertThrows(com.baiyue.common.core.exception.BizException.class,
|
||||
@@ -201,3 +204,4 @@ class MerchantOnboardingServiceTest {
|
||||
verify(tenants, never()).deleteById((java.io.Serializable) any());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -151,22 +151,22 @@ class TenantServiceTest {
|
||||
|
||||
var updated = service.updateMerchant(10001L,
|
||||
new UpdateTenantRequest("New name", "New legal", "Bob", "Alice", "13800138000", "alice@example.com",
|
||||
"专业版", "alice_wechat", "Sales Zhang", 45, "LIMITED_COMPANY", LocalDate.of(2020, 1, 2),
|
||||
new BigDecimal("5000000.00"), "CNY", "深圳市南山区示例路 1 号", "一期重点客户"));
|
||||
"专业版", "alice_wechat", "Sales Zhang", 45, "LIMITED_COMPANY", LocalDate.of(2020, 1, 2),
|
||||
new BigDecimal("5000000.00"), "CNY", "深圳市南山区示例路 1 号", "一期重点客户"));
|
||||
var disabled = service.changeMerchantStatus(10001L, new ChangeTenantStatusRequest("DISABLED"));
|
||||
|
||||
assertEquals("New name", updated.tenantName());
|
||||
assertEquals("Bob", updated.legalRepresentative());
|
||||
assertEquals("alice_wechat", updated.contactWechat());
|
||||
assertEquals("专业版", updated.servicePackage());
|
||||
assertEquals("专业版", updated.servicePackage());
|
||||
assertEquals("Sales Zhang", updated.salesOwnerName());
|
||||
assertEquals(45, updated.paymentTermDays());
|
||||
assertEquals("LIMITED_COMPANY", updated.enterpriseType());
|
||||
assertEquals(LocalDate.of(2020, 1, 2), updated.establishedDate());
|
||||
assertEquals(new BigDecimal("5000000.00"), updated.registeredCapital());
|
||||
assertEquals("CNY", updated.registeredCapitalCurrency());
|
||||
assertEquals("深圳市南山区示例路 1 号", updated.registeredAddress());
|
||||
assertEquals("一期重点客户", updated.internalRemark());
|
||||
assertEquals("深圳市南山区示例路 1 号", updated.registeredAddress());
|
||||
assertEquals("一期重点客户", updated.internalRemark());
|
||||
assertEquals("DISABLED", disabled.status());
|
||||
verify(repository, org.mockito.Mockito.times(2)).saveTenant(tenant);
|
||||
}
|
||||
@@ -178,7 +178,7 @@ class TenantServiceTest {
|
||||
|
||||
BizException exception = assertThrows(BizException.class, () -> service.updateMerchant(10001L,
|
||||
new UpdateTenantRequest("New name", "New legal", "Bob", "Alice", "13900139000", null,
|
||||
"基础版", null, null, 30, null, null, null, "CNY", null, null)));
|
||||
"基础版", null, null, 30, null, null, null, "CNY", null, null)));
|
||||
|
||||
assertEquals(ResultCode.CONFLICT, exception.getResultCode());
|
||||
assertEquals("13800138000", tenant.getContactPhone());
|
||||
@@ -273,7 +273,7 @@ class TenantServiceTest {
|
||||
|
||||
BizException platformFailure = assertThrows(BizException.class, () -> service.updateMerchant(10001L,
|
||||
new UpdateTenantRequest("New name", "New legal", "Bob", "Alice", "13800138000", null,
|
||||
"基础版", null, null, 30, null, null, null, "CNY", null, null)));
|
||||
"基础版", null, null, 30, null, null, null, "CNY", null, null)));
|
||||
BizException merchantFailure = assertThrows(BizException.class, () -> service.update(10001L,
|
||||
new UpdateProfileRequest("New name", "New legal", "Bob", "Alice",
|
||||
"13800138000", "alice@example.com")));
|
||||
@@ -308,32 +308,32 @@ class TenantServiceTest {
|
||||
|
||||
var created = service.register(new RegisterRequest(
|
||||
"Example Merchant", "Example Merchant Ltd", "Bob", "Alice", "13800138000",
|
||||
"alice@example.com", "基础版", "alice_wechat", "Sales Zhang", 30, "LIMITED_COMPANY",
|
||||
LocalDate.of(2020, 1, 2), new BigDecimal("5000000.00"), "CNY", "深圳市南山区", "草稿客户"),
|
||||
"alice@example.com", "基础版", "alice_wechat", "Sales Zhang", 30, "LIMITED_COMPANY",
|
||||
LocalDate.of(2020, 1, 2), new BigDecimal("5000000.00"), "CNY", "深圳市南山区", "草稿客户"),
|
||||
9001L);
|
||||
|
||||
assertEquals("PROFILE_REQUIRED", created.tenant().status());
|
||||
assertEquals("PENDING", created.tenant().dimensionInitializationStatus());
|
||||
assertEquals("Bob", created.tenant().legalRepresentative());
|
||||
assertEquals("基础版", created.tenant().servicePackage());
|
||||
assertEquals("基础版", created.tenant().servicePackage());
|
||||
assertEquals("13800138000", created.administratorUsername());
|
||||
assertEquals("Password1234", created.temporaryPassword());
|
||||
verify(repository).insertTenant(argThat(tenant -> Long.valueOf(9001L).equals(tenant.getCreatedBy())
|
||||
&& Long.valueOf(9001L).equals(tenant.getUpdatedBy())));
|
||||
verify(dimensionRuleInitialization).initialize(created.tenant().id(), 9001L);
|
||||
verify(securityEvents).tenantStatus(created.tenant().id(), "PROFILE_REQUIRED");
|
||||
verify(securityEvents).tenantStatus(created.tenant().id(), "PROFILE_REQUIRED");
|
||||
verify(provisioning).provisionPlatformCreatedTenant(any(), eq(9001L));
|
||||
verify(repository, never()).insertReview(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformRegistrationFailsWhenDurableInitializationIntentCannotBePersisted() {
|
||||
doThrow(new BizException(ResultCode.SERVICE_UNAVAILABLE, "初始化失败"))
|
||||
void platformRegistrationFailsWhenFourDefaultBoxDimensionsCannotBeInitialized() {
|
||||
doThrow(new BizException(ResultCode.SERVICE_UNAVAILABLE, "初始化失败"))
|
||||
.when(dimensionRuleInitialization).initialize(any(Long.class), any(Long.class));
|
||||
|
||||
BizException failure = assertThrows(BizException.class, () -> service.register(new RegisterRequest(
|
||||
"Example Merchant", "Example Merchant Ltd", "Bob", "Alice", "13800138000",
|
||||
"alice@example.com", "基础版", null, null, 30, null,
|
||||
"alice@example.com", "基础版", null, null, 30, null,
|
||||
null, null, "CNY", null, null), 9001L));
|
||||
|
||||
assertEquals(ResultCode.SERVICE_UNAVAILABLE, failure.getResultCode());
|
||||
@@ -347,7 +347,7 @@ class TenantServiceTest {
|
||||
|
||||
var created = service.register(new RegisterRequest(
|
||||
"Example Merchant", "Example Merchant Ltd", "Bob", "Alice", "13800138000",
|
||||
"alice@example.com", "基础版", null, null, 30, null,
|
||||
"alice@example.com", "基础版", null, null, 30, null,
|
||||
null, null, "CNY", null, null), 9001L);
|
||||
|
||||
assertEquals(null, created.tenant().unifiedSocialCreditCode());
|
||||
@@ -420,7 +420,7 @@ class TenantServiceTest {
|
||||
TenantAdministratorProvisioningService.ProvisioningResult.created(
|
||||
81L, "merchant_10001", "Password1234")).when(provisioning).initialize(any());
|
||||
|
||||
var result = service.review(71L, 9001L, true, "资料完整");
|
||||
var result = service.review(71L, 9001L, true, "资料完整");
|
||||
|
||||
assertEquals(10001L, result.tenantId());
|
||||
assertEquals(true, result.administratorCreated());
|
||||
@@ -431,6 +431,7 @@ class TenantServiceTest {
|
||||
verify(repository).saveReview(review);
|
||||
verify(repository).saveTenant(tenant);
|
||||
verify(securityEvents).tenantStatus(10001L, "ACTIVE");
|
||||
verify(securityEvents).tenantStatus(10001L, "ACTIVE");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -446,7 +447,7 @@ class TenantServiceTest {
|
||||
doReturn(TenantAdministratorProvisioningService.ProvisioningResult.existing())
|
||||
.when(provisioning).initialize(any());
|
||||
|
||||
var result = service.review(71L, 9001L, true, "资料完整");
|
||||
var result = service.review(71L, 9001L, true, "资料完整");
|
||||
|
||||
assertEquals(false, result.administratorCreated());
|
||||
assertEquals(null, result.administratorUsername());
|
||||
@@ -470,7 +471,7 @@ class TenantServiceTest {
|
||||
doReturn(administrator).when(provisioning).initialize(any());
|
||||
doThrow(new RuntimeException("review write failed")).when(repository).saveReview(review);
|
||||
|
||||
assertThrows(RuntimeException.class, () -> service.review(71L, 9001L, true, "资料完整"));
|
||||
assertThrows(RuntimeException.class, () -> service.review(71L, 9001L, true, "资料完整"));
|
||||
|
||||
verify(provisioning).compensate(any(), eq(administrator));
|
||||
verify(repository, never()).saveTenant(tenant);
|
||||
@@ -492,26 +493,12 @@ class TenantServiceTest {
|
||||
assertEquals(true, withQualification.eligible());
|
||||
}
|
||||
|
||||
@Test
|
||||
void activeCustomerCannotOrderUntilDefaultDimensionsAreReady() {
|
||||
IamTenant tenant = merchant(10001L, "ACTIVE");
|
||||
tenant.setDimensionInitializationStatus("FAILED");
|
||||
when(repository.findTenant(10001L)).thenReturn(tenant);
|
||||
|
||||
var result = service.orderEligibility(10001L);
|
||||
|
||||
assertEquals(false, result.eligible());
|
||||
assertEquals("Customer default dimensions are not ready", result.reason());
|
||||
verify(profileRepository, never()).findQualifications(10001L);
|
||||
}
|
||||
|
||||
private IamTenant merchant(long id, String status) {
|
||||
IamTenant tenant = new IamTenant();
|
||||
tenant.setId(id);
|
||||
tenant.setTenantCode("TEN" + id);
|
||||
tenant.setTenantType("MERCHANT");
|
||||
tenant.setStatus(status);
|
||||
tenant.setDimensionInitializationStatus("READY");
|
||||
tenant.setTenantName("Example Merchant");
|
||||
tenant.setLegalName("Example Merchant Ltd");
|
||||
tenant.setUnifiedSocialCreditCode("91330100EXAMPLE001");
|
||||
@@ -544,3 +531,4 @@ class TenantServiceTest {
|
||||
return review;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -130,19 +130,6 @@ test('every reviewed synchronous client has a complete and exclusive executable
|
||||
}
|
||||
})
|
||||
|
||||
test('IAM customer dimension Feign is reachable only from the background relay', async () => {
|
||||
const references = []
|
||||
for (const file of await javaFiles(path.join(root, 'iam', 'src', 'main', 'java'))) {
|
||||
const source = await readFile(file, 'utf8')
|
||||
if (source.includes('CustomerDimensionRuleClient')) {
|
||||
references.push(path.relative(root, file).replaceAll('\\', '/'))
|
||||
}
|
||||
}
|
||||
assert.deepEqual(references.sort(), [
|
||||
'iam/src/main/java/com/baiyue/iam/client/CustomerDimensionRuleClient.java',
|
||||
'iam/src/main/java/com/baiyue/iam/service/CustomerDimensionInitializationRelay.java'
|
||||
])
|
||||
})
|
||||
|
||||
test('all four Lastleg RestClient gateways use explicit bounded transports', async () => {
|
||||
const clients = new Map([
|
||||
|
||||
Reference in New Issue
Block a user