fix(file): make ocean booking documents platform owned
This commit is contained in:
+1
-1
@@ -19,7 +19,7 @@
|
|||||||
| 海外异常订单证据 | 通用内部业务文件入口;固定 `businessType=OVERSEAS_EXCEPTION_EVIDENCE`、`tenantId=异常订单所属客户ID`、`businessId=异常订单ID`,File 只校验文件复合归属,异常状态、完成门禁和证据引用归 Lastleg |
|
| 海外异常订单证据 | 通用内部业务文件入口;固定 `businessType=OVERSEAS_EXCEPTION_EVIDENCE`、`tenantId=异常订单所属客户ID`、`businessId=异常订单ID`,File 只校验文件复合归属,异常状态、完成门禁和证据引用归 Lastleg |
|
||||||
| 入库扣货凭证 | 通用内部业务文件入口;固定 `businessType=INBOUND_HOLD_EVIDENCE`、`tenantId=客户ID`、`businessId=入库单ID`,客户作用域单文件最多 10MiB;可见性与历史引用由 Firstleg 校验 |
|
| 入库扣货凭证 | 通用内部业务文件入口;固定 `businessType=INBOUND_HOLD_EVIDENCE`、`tenantId=客户ID`、`businessId=入库单ID`,客户作用域单文件最多 10MiB;可见性与历史引用由 Firstleg 校验 |
|
||||||
| 报关源文件、完成文件与买单明细导出 | `src/main/resources/openapi/customs-file-and-export-v1.yaml`;文件类别 `LOADING_LIST_CUSTOMS_SOURCE`、`LOADING_LIST_CUSTOMS_RESULT` 均为客户作用域且最多 50MB,异步导出类型 `LOADING_LIST_BUY_DECLARATION_ITEMS` 由 Firstleg Provider 按固定十三列供数 |
|
| 报关源文件、完成文件与买单明细导出 | `src/main/resources/openapi/customs-file-and-export-v1.yaml`;文件类别 `LOADING_LIST_CUSTOMS_SOURCE`、`LOADING_LIST_CUSTOMS_RESULT` 均为客户作用域且最多 50MB,异步导出类型 `LOADING_LIST_BUY_DECLARATION_ITEMS` 由 Firstleg Provider 按固定十三列供数 |
|
||||||
| 订舱文件 | 通用内部业务文件入口,契约 `src/main/resources/openapi/ocean-booking-file-v1.yaml`;类型固定 `OCEAN_BOOKING_DOCUMENT`、`tenantId=订舱customerId`、`businessId=oceanBookingId`,任意格式且最多 50MiB,不得绑定拖车;`BOOKING_CONFIRMATION/BILL_OF_LADING` 文档类型及有效状态由 Firstleg 保存 |
|
| 订舱文件 | 通用内部业务文件入口,契约 `src/main/resources/openapi/ocean-booking-file-v1.yaml`;类型固定 `OCEAN_BOOKING_DOCUMENT`、`tenantId=0`(平台专属,客户可选快照不改变文件归属,拒绝客户作用域)、`businessId=oceanBookingId`,任意格式且最多 50MiB,不得绑定拖车;`BOOKING_CONFIRMATION/BILL_OF_LADING` 文档类型及有效状态由 Firstleg 保存 |
|
||||||
| 拖车预约附件 | 通用内部业务文件入口;固定 `tenantId=0`、`businessType=TRUCK_APPOINTMENT_ATTACHMENT`、`businessId=appointmentId`,只允许派车单、司机/车辆资料和其他平台附件;提单文件归订舱 `OCEAN_BOOKING_DOCUMENT`,不得复制为拖车附件 |
|
| 拖车预约附件 | 通用内部业务文件入口;固定 `tenantId=0`、`businessType=TRUCK_APPOINTMENT_ATTACHMENT`、`businessId=appointmentId`,只允许派车单、司机/车辆资料和其他平台附件;提单文件归订舱 `OCEAN_BOOKING_DOCUMENT`,不得复制为拖车附件 |
|
||||||
| 存储与实体 | `service/LocalQualificationStorage.java`、`MeasurementImageStorage.java`、`entity/FileObjectEntity.java` |
|
| 存储与实体 | `service/LocalQualificationStorage.java`、`MeasurementImageStorage.java`、`entity/FileObjectEntity.java` |
|
||||||
| 派送单七类资料 | `src/main/resources/openapi/delivery-files-v1.yaml`;七类 `DELIVERY_*` 对象均按客户、派送内部ID、类别隔离,任意格式单文件50MiB,元数据返回真实createdAt;Lastleg持有分类绑定、保存、替换删除和历史可见性,File保留不可变对象 |
|
| 派送单七类资料 | `src/main/resources/openapi/delivery-files-v1.yaml`;七类 `DELIVERY_*` 对象均按客户、派送内部ID、类别隔离,任意格式单文件50MiB,元数据返回真实createdAt;Lastleg持有分类绑定、保存、替换删除和历史可见性,File保留不可变对象 |
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ enum BusinessFileCategory {
|
|||||||
DELIVERY_LOADING_PHOTO(true, FormatPolicy.ARBITRARY, Limits.CUSTOMS, BusinessIdPolicy.POSITIVE_LONG),
|
DELIVERY_LOADING_PHOTO(true, FormatPolicy.ARBITRARY, Limits.CUSTOMS, BusinessIdPolicy.POSITIVE_LONG),
|
||||||
DELIVERY_EXPRESS_RECEIPT(true, FormatPolicy.ARBITRARY, Limits.CUSTOMS, BusinessIdPolicy.POSITIVE_LONG),
|
DELIVERY_EXPRESS_RECEIPT(true, FormatPolicy.ARBITRARY, Limits.CUSTOMS, BusinessIdPolicy.POSITIVE_LONG),
|
||||||
TRUCK_APPOINTMENT_ATTACHMENT(false, FormatPolicy.STANDARD, Limits.STANDARD, BusinessIdPolicy.POSITIVE_LONG),
|
TRUCK_APPOINTMENT_ATTACHMENT(false, FormatPolicy.STANDARD, Limits.STANDARD, BusinessIdPolicy.POSITIVE_LONG),
|
||||||
OCEAN_BOOKING_DOCUMENT(true, FormatPolicy.ARBITRARY, Limits.CUSTOMS, BusinessIdPolicy.POSITIVE_LONG),
|
OCEAN_BOOKING_DOCUMENT(false, FormatPolicy.ARBITRARY, Limits.CUSTOMS, BusinessIdPolicy.POSITIVE_LONG),
|
||||||
CUSTOMS_DOCUMENT(false, FormatPolicy.STANDARD, Limits.STANDARD, BusinessIdPolicy.POSITIVE_LONG),
|
CUSTOMS_DOCUMENT(false, FormatPolicy.STANDARD, Limits.STANDARD, BusinessIdPolicy.POSITIVE_LONG),
|
||||||
CUSTOMS_RECEIPT(false, FormatPolicy.STANDARD, Limits.STANDARD, BusinessIdPolicy.POSITIVE_LONG),
|
CUSTOMS_RECEIPT(false, FormatPolicy.STANDARD, Limits.STANDARD, BusinessIdPolicy.POSITIVE_LONG),
|
||||||
FINANCE_VOUCHER(false, FormatPolicy.STANDARD, Limits.STANDARD, BusinessIdPolicy.POSITIVE_LONG),
|
FINANCE_VOUCHER(false, FormatPolicy.STANDARD, Limits.STANDARD, BusinessIdPolicy.POSITIVE_LONG),
|
||||||
@@ -57,6 +57,9 @@ enum BusinessFileCategory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void validateOwner(long tenantId) {
|
void validateOwner(long tenantId) {
|
||||||
|
if (this == OCEAN_BOOKING_DOCUMENT && tenantId != 0) {
|
||||||
|
throw new BizException(ResultCode.BAD_REQUEST, "订舱附件必须归属平台");
|
||||||
|
}
|
||||||
if (customerOwned && tenantId <= 0) {
|
if (customerOwned && tenantId <= 0) {
|
||||||
throw new BizException(ResultCode.BAD_REQUEST, "该附件类型必须归属明确客户");
|
throw new BizException(ResultCode.BAD_REQUEST, "该附件类型必须归属明确客户");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ info:
|
|||||||
title: Ocean Booking Document Internal API
|
title: Ocean Booking Document Internal API
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
description: >-
|
description: >-
|
||||||
订舱文件归属订舱聚合,不归属拖车。固定ownerScope=CUSTOMER、tenantId=订舱customerId、
|
订舱文件归属订舱聚合,不归属拖车。固定ownerScope=PLATFORM、tenantId=0、
|
||||||
businessType=OCEAN_BOOKING_DOCUMENT、businessId=oceanBookingId。BOOKING_CONFIRMATION与
|
businessType=OCEAN_BOOKING_DOCUMENT、businessId=oceanBookingId。BOOKING_CONFIRMATION与
|
||||||
BILL_OF_LADING文档类型、版本和有效状态归Firstleg;File不判断订舱业务状态。
|
BILL_OF_LADING文档类型、版本和有效状态归Firstleg;File不判断订舱业务状态。客户为可选快照,有值、为空或清空均不改变文件归属,客户作用域上传读取一律拒绝。
|
||||||
x-firstleg-document-types: [BOOKING_CONFIRMATION, BILL_OF_LADING]
|
x-firstleg-document-types: [BOOKING_CONFIRMATION, BILL_OF_LADING]
|
||||||
x-lifecycle-owner: FIRSTLEG
|
x-lifecycle-owner: FIRSTLEG
|
||||||
x-file-object-semantics: IMMUTABLE_CREATE_ONLY
|
x-file-object-semantics: IMMUTABLE_CREATE_ONLY
|
||||||
@@ -70,8 +70,8 @@ components:
|
|||||||
name: tenantId
|
name: tenantId
|
||||||
in: path
|
in: path
|
||||||
required: true
|
required: true
|
||||||
description: 订舱customerId
|
description: 平台固定0,与订舱客户快照无关
|
||||||
schema: {$ref: '#/components/schemas/Id'}
|
schema: {type: string, enum: ['0']}
|
||||||
OceanBookingId:
|
OceanBookingId:
|
||||||
name: oceanBookingId
|
name: oceanBookingId
|
||||||
in: path
|
in: path
|
||||||
@@ -100,10 +100,11 @@ components:
|
|||||||
required: [fileId, ownerScope, tenantId, businessType, businessId, fileName, sha256, contentType, sizeBytes]
|
required: [fileId, ownerScope, tenantId, businessType, businessId, fileName, sha256, contentType, sizeBytes]
|
||||||
properties:
|
properties:
|
||||||
fileId: {$ref: '#/components/schemas/Id'}
|
fileId: {$ref: '#/components/schemas/Id'}
|
||||||
ownerScope: {type: string, enum: [CUSTOMER]}
|
ownerScope: {type: string, enum: [PLATFORM]}
|
||||||
tenantId:
|
tenantId:
|
||||||
allOf: [{$ref: '#/components/schemas/Id'}]
|
type: string
|
||||||
description: 订舱customerId
|
enum: ['0']
|
||||||
|
description: 平台固定0,与订舱客户快照无关
|
||||||
businessType: {type: string, enum: [OCEAN_BOOKING_DOCUMENT]}
|
businessType: {type: string, enum: [OCEAN_BOOKING_DOCUMENT]}
|
||||||
businessId:
|
businessId:
|
||||||
allOf: [{$ref: '#/components/schemas/Id'}]
|
allOf: [{$ref: '#/components/schemas/Id'}]
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
|
|
||||||
class OceanBookingFileContractTest {
|
class OceanBookingFileContractTest {
|
||||||
@Test
|
@Test
|
||||||
void freezesInternalCustomerOwnedBookingDocumentContract() throws Exception {
|
void freezesInternalPlatformOwnedBookingDocumentContract() throws Exception {
|
||||||
String yaml = Files.readString(Path.of("src/main/resources/openapi/ocean-booking-file-v1.yaml"));
|
String yaml = Files.readString(Path.of("src/main/resources/openapi/ocean-booking-file-v1.yaml"));
|
||||||
|
|
||||||
assertThat(yaml)
|
assertThat(yaml)
|
||||||
.contains("/internal/file/v1/business-files/{tenantId}/OCEAN_BOOKING_DOCUMENT/{oceanBookingId}:")
|
.contains("/internal/file/v1/business-files/{tenantId}/OCEAN_BOOKING_DOCUMENT/{oceanBookingId}:")
|
||||||
.contains("ownerScope: {type: string, enum: [CUSTOMER]}")
|
.contains("ownerScope: {type: string, enum: [PLATFORM]}")
|
||||||
.contains("description: 订舱customerId")
|
.contains("description: 平台固定0,与订舱客户快照无关")
|
||||||
.contains("description: oceanBookingId")
|
.contains("description: oceanBookingId")
|
||||||
.contains("x-firstleg-document-types: [BOOKING_CONFIRMATION, BILL_OF_LADING]")
|
.contains("x-firstleg-document-types: [BOOKING_CONFIRMATION, BILL_OF_LADING]")
|
||||||
.contains("x-lifecycle-owner: FIRSTLEG")
|
.contains("x-lifecycle-owner: FIRSTLEG")
|
||||||
|
|||||||
+2
-2
@@ -59,11 +59,11 @@ class InternalBusinessFileControllerTest {
|
|||||||
|
|
||||||
@Test void unicodeSpecialFileNameUsesUtf8AttachmentDisposition() {
|
@Test void unicodeSpecialFileNameUsesUtf8AttachmentDisposition() {
|
||||||
String fileName = "订舱 确认 🚢 #[]()+,最终版.xlsx";
|
String fileName = "订舱 确认 🚢 #[]()+,最终版.xlsx";
|
||||||
when(service.download(10001L, "OCEAN_BOOKING_DOCUMENT", "61", 93L))
|
when(service.download(0L, "OCEAN_BOOKING_DOCUMENT", "61", 93L))
|
||||||
.thenReturn(new InternalBusinessFileService.Download(fileName,
|
.thenReturn(new InternalBusinessFileService.Download(fileName,
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", new byte[]{4}));
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", new byte[]{4}));
|
||||||
|
|
||||||
var response = controller.download("internal-token", 10001L,
|
var response = controller.download("internal-token", 0L,
|
||||||
"OCEAN_BOOKING_DOCUMENT", "61", 93L);
|
"OCEAN_BOOKING_DOCUMENT", "61", 93L);
|
||||||
|
|
||||||
assertThat(response.getHeaders().getContentDisposition().getType()).isEqualTo("attachment");
|
assertThat(response.getHeaders().getContentDisposition().getType()).isEqualTo("attachment");
|
||||||
|
|||||||
@@ -75,46 +75,61 @@ class InternalBusinessFileServiceTest {
|
|||||||
verify(storage).store(11L, "51", file, BusinessFileCategory.OVERSEAS_UNLOAD_PHOTO);
|
verify(storage).store(11L, "51", file, BusinessFileCategory.OVERSEAS_UNLOAD_PHOTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test void oceanBookingDocumentUsesCustomerAndBookingOwnership() {
|
@Test void oceanBookingDocumentUsesPlatformAndBookingOwnership() {
|
||||||
MockMultipartFile file = new MockMultipartFile("file", "booking.xlsx",
|
MockMultipartFile file = new MockMultipartFile("file", "booking.xlsx",
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx".getBytes());
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx".getBytes());
|
||||||
when(storage.store(10001L, "61", file, BusinessFileCategory.OCEAN_BOOKING_DOCUMENT))
|
when(storage.store(0L, "61", file, BusinessFileCategory.OCEAN_BOOKING_DOCUMENT))
|
||||||
.thenReturn(new BusinessFileStorage.Stored("business-files/10001/61/booking",
|
.thenReturn(new BusinessFileStorage.Stored("business-files/0/61/booking",
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||||
file.getSize(), "f".repeat(64), "booking.xlsx"));
|
file.getSize(), "f".repeat(64), "booking.xlsx"));
|
||||||
when(files.insert(any(FileObjectEntity.class))).thenAnswer(invocation -> {
|
when(files.insert(any(FileObjectEntity.class))).thenAnswer(invocation -> {
|
||||||
((FileObjectEntity) invocation.getArgument(0)).setId(111L); return 1;
|
((FileObjectEntity) invocation.getArgument(0)).setId(111L); return 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
var metadata = service.upload(10001L, "OCEAN_BOOKING_DOCUMENT", "61", 7L, file);
|
var metadata = service.upload(0L, "OCEAN_BOOKING_DOCUMENT", "61", 7L, file);
|
||||||
|
|
||||||
assertThat(metadata).extracting(InternalBusinessFileService.Metadata::ownerScope,
|
assertThat(metadata).extracting(InternalBusinessFileService.Metadata::ownerScope,
|
||||||
InternalBusinessFileService.Metadata::tenantId,
|
InternalBusinessFileService.Metadata::tenantId,
|
||||||
InternalBusinessFileService.Metadata::businessType,
|
InternalBusinessFileService.Metadata::businessType,
|
||||||
InternalBusinessFileService.Metadata::businessId)
|
InternalBusinessFileService.Metadata::businessId)
|
||||||
.containsExactly("CUSTOMER", 10001L, "OCEAN_BOOKING_DOCUMENT", "61");
|
.containsExactly("PLATFORM", 0L, "OCEAN_BOOKING_DOCUMENT", "61");
|
||||||
assertThatThrownBy(() -> service.upload(0L, "OCEAN_BOOKING_DOCUMENT", "61", 7L, file))
|
assertThatThrownBy(() -> service.upload(10001L, "OCEAN_BOOKING_DOCUMENT", "61", 7L, file))
|
||||||
.isInstanceOf(BizException.class).hasMessageContaining("明确客户");
|
.isInstanceOf(BizException.class).hasMessageContaining("必须归属平台");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test void oceanBookingDocumentRejectsWrongCustomerBookingAndTruckOwnership() {
|
@Test void oceanBookingDocumentRejectsWrongCustomerBookingAndTruckOwnership() {
|
||||||
FileObjectEntity value = new FileObjectEntity(); value.setId(111L); value.setTenantId(10001L);
|
FileObjectEntity value = new FileObjectEntity(); value.setId(111L); value.setTenantId(0L);
|
||||||
value.setBusinessType("OCEAN_BOOKING_DOCUMENT"); value.setBusinessId("61");
|
value.setBusinessType("OCEAN_BOOKING_DOCUMENT"); value.setBusinessId("61");
|
||||||
value.setOriginalName("booking.xlsx"); value.setObjectKey("business-files/10001/61/booking");
|
value.setOriginalName("booking.xlsx"); value.setObjectKey("business-files/0/61/booking");
|
||||||
value.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
value.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
value.setSha256("f".repeat(64)); value.setSizeBytes(8L);
|
value.setSha256("f".repeat(64)); value.setSizeBytes(8L);
|
||||||
when(files.selectOne(any())).thenReturn(value, null, null, null);
|
when(files.selectOne(any())).thenReturn(value, null, null);
|
||||||
|
|
||||||
assertThat(service.metadata(10001L, "OCEAN_BOOKING_DOCUMENT", "61", 111L).ownerScope())
|
assertThat(service.metadata(0L, "OCEAN_BOOKING_DOCUMENT", "61", 111L).ownerScope())
|
||||||
.isEqualTo("CUSTOMER");
|
.isEqualTo("PLATFORM");
|
||||||
assertThatThrownBy(() -> service.metadata(10002L, "OCEAN_BOOKING_DOCUMENT", "61", 111L))
|
assertThatThrownBy(() -> service.metadata(10002L, "OCEAN_BOOKING_DOCUMENT", "61", 111L))
|
||||||
.isInstanceOf(BizException.class).hasMessageContaining("归属不匹配");
|
.isInstanceOf(BizException.class).hasMessageContaining("必须归属平台");
|
||||||
assertThatThrownBy(() -> service.metadata(10001L, "OCEAN_BOOKING_DOCUMENT", "62", 111L))
|
assertThatThrownBy(() -> service.metadata(0L, "OCEAN_BOOKING_DOCUMENT", "62", 111L))
|
||||||
.isInstanceOf(BizException.class).hasMessageContaining("归属不匹配");
|
.isInstanceOf(BizException.class).hasMessageContaining("归属不匹配");
|
||||||
assertThatThrownBy(() -> service.metadata(10001L, "TRUCK_APPOINTMENT_ATTACHMENT", "61", 111L))
|
assertThatThrownBy(() -> service.metadata(10001L, "TRUCK_APPOINTMENT_ATTACHMENT", "61", 111L))
|
||||||
.isInstanceOf(BizException.class).hasMessageContaining("归属不匹配");
|
.isInstanceOf(BizException.class).hasMessageContaining("归属不匹配");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test void bookingFileScopeRemainsPlatformRegardlessOfOptionalCustomerSnapshot() {
|
||||||
|
FileObjectEntity value = new FileObjectEntity(); value.setId(111L); value.setTenantId(0L);
|
||||||
|
value.setBusinessType("OCEAN_BOOKING_DOCUMENT"); value.setBusinessId("61");
|
||||||
|
value.setOriginalName("booking.bin"); value.setObjectKey("business-files/0/61/object");
|
||||||
|
when(files.selectOne(any())).thenReturn(value);
|
||||||
|
when(storage.read(value.getObjectKey())).thenReturn(new byte[]{1, 2});
|
||||||
|
// Customer snapshot is deliberately absent from File commands before and after clearing it.
|
||||||
|
assertThat(service.metadata(0L, "OCEAN_BOOKING_DOCUMENT", "61", 111L).ownerScope()).isEqualTo("PLATFORM");
|
||||||
|
assertThat(service.download(0L, "OCEAN_BOOKING_DOCUMENT", "61", 111L).content()).containsExactly(1, 2);
|
||||||
|
assertThat(service.metadata(0L, "OCEAN_BOOKING_DOCUMENT", "61", 111L).fileId()).isEqualTo(111L);
|
||||||
|
assertThatThrownBy(() -> service.download(10001L, "OCEAN_BOOKING_DOCUMENT", "61", 111L))
|
||||||
|
.isInstanceOf(BizException.class).hasMessageContaining("必须归属平台");
|
||||||
|
verify(storage, times(1)).read(value.getObjectKey());
|
||||||
|
}
|
||||||
|
|
||||||
@Test void rejectsNegativeTenantAndInvalidOwnershipInputs() {
|
@Test void rejectsNegativeTenantAndInvalidOwnershipInputs() {
|
||||||
MockMultipartFile file = new MockMultipartFile("file", "a.txt", "text/plain", "x".getBytes());
|
MockMultipartFile file = new MockMultipartFile("file", "a.txt", "text/plain", "x".getBytes());
|
||||||
assertThatThrownBy(() -> service.upload(-1L, "CONTAINER_CLEARANCE_DOCUMENT", "41", 7L, file))
|
assertThatThrownBy(() -> service.upload(-1L, "CONTAINER_CLEARANCE_DOCUMENT", "41", 7L, file))
|
||||||
@@ -269,7 +284,7 @@ class InternalBusinessFileServiceTest {
|
|||||||
@Test void concurrentRepeatedUploadsCreateDistinctImmutableObjectsForFirstlegToVersion() throws Exception {
|
@Test void concurrentRepeatedUploadsCreateDistinctImmutableObjectsForFirstlegToVersion() throws Exception {
|
||||||
MockMultipartFile file = new MockMultipartFile("file", "booking.bin",
|
MockMultipartFile file = new MockMultipartFile("file", "booking.bin",
|
||||||
"application/x-booking", new byte[]{1, 2, 3});
|
"application/x-booking", new byte[]{1, 2, 3});
|
||||||
when(storage.store(10001L, "61", file, BusinessFileCategory.OCEAN_BOOKING_DOCUMENT))
|
when(storage.store(0L, "61", file, BusinessFileCategory.OCEAN_BOOKING_DOCUMENT))
|
||||||
.thenReturn(new BusinessFileStorage.Stored("business-files/10001/61/object",
|
.thenReturn(new BusinessFileStorage.Stored("business-files/10001/61/object",
|
||||||
"application/x-booking", 3, "a".repeat(64), "booking.bin"));
|
"application/x-booking", 3, "a".repeat(64), "booking.bin"));
|
||||||
AtomicLong ids = new AtomicLong(200);
|
AtomicLong ids = new AtomicLong(200);
|
||||||
@@ -280,9 +295,9 @@ class InternalBusinessFileServiceTest {
|
|||||||
var executor = Executors.newFixedThreadPool(2);
|
var executor = Executors.newFixedThreadPool(2);
|
||||||
try {
|
try {
|
||||||
var firstFuture = executor.submit(() ->
|
var firstFuture = executor.submit(() ->
|
||||||
service.upload(10001L, "OCEAN_BOOKING_DOCUMENT", "61", 7L, file));
|
service.upload(0L, "OCEAN_BOOKING_DOCUMENT", "61", 7L, file));
|
||||||
var secondFuture = executor.submit(() ->
|
var secondFuture = executor.submit(() ->
|
||||||
service.upload(10001L, "OCEAN_BOOKING_DOCUMENT", "61", 7L, file));
|
service.upload(0L, "OCEAN_BOOKING_DOCUMENT", "61", 7L, file));
|
||||||
|
|
||||||
var first = firstFuture.get();
|
var first = firstFuture.get();
|
||||||
var second = secondFuture.get();
|
var second = secondFuture.get();
|
||||||
|
|||||||
Reference in New Issue
Block a user