From d86294753839c7e87e271da21879dbad3d500237 Mon Sep 17 00:00:00 2001 From: Noah Bjerkli Aanonli Date: Tue, 8 Oct 2024 09:33:29 +0200 Subject: [PATCH 01/10] Receive item updates from SynQ --- .../synq/SynqBatchItemUpdatePayload.kt | 17 +++++++++ .../synqapi/synq/SynqController.kt | 19 ++++++++-- .../mlt/wls/domain/ports/inbound/MoveItem.kt | 11 ++++++ .../repositories/item/MongoItemRepository.kt | 35 +++++++++++-------- 4 files changed, 65 insertions(+), 17 deletions(-) diff --git a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqBatchItemUpdatePayload.kt b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqBatchItemUpdatePayload.kt index 63a5ca5c..186b574f 100644 --- a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqBatchItemUpdatePayload.kt +++ b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqBatchItemUpdatePayload.kt @@ -1,6 +1,8 @@ package no.nb.mlt.wls.application.synqapi.synq import io.swagger.v3.oas.annotations.media.Schema +import no.nb.mlt.wls.domain.model.HostName +import no.nb.mlt.wls.domain.ports.inbound.MoveItemPayload @Schema( description = "Payload for receiving Item updates in batch from SynQ storage system.", @@ -187,3 +189,18 @@ data class Position( ) val zPosition: Int ) + +fun SynqBatchItemUpdatePayload.mapToItemPayloads(): List { + val list = mutableListOf() + for (product in loadUnit) { + list.add( + MoveItemPayload( + hostId = product.productId, + hostName = HostName.valueOf(product.hostName.uppercase()), + quantity = product.quantityOnHand, + location = location + ) + ) + } + return list +} diff --git a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt index 5b25ba44..1fd7b755 100644 --- a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt +++ b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt @@ -8,6 +8,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse import io.swagger.v3.oas.annotations.responses.ApiResponses import io.swagger.v3.oas.annotations.tags.Tag import no.nb.mlt.wls.domain.model.Owner +import no.nb.mlt.wls.domain.ports.inbound.MoveItem import no.nb.mlt.wls.domain.ports.inbound.OrderStatusUpdate import org.springframework.http.ResponseEntity import org.springframework.security.core.annotation.AuthenticationPrincipal @@ -22,8 +23,22 @@ import org.springframework.web.bind.annotation.RestController @RequestMapping(path = [ "/synq/v1"]) @Tag(name = "SynQ Controller", description = "API for receiving product and order updates from SynQ in Hermes WLS") class SynqController( + private val moveItem: MoveItem, private val orderStatusUpdate: OrderStatusUpdate ) { + // TODO - Swagger docs + @PutMapping("/item-update") + suspend fun updateItem( + @AuthenticationPrincipal jwt: JwtAuthenticationToken, + @RequestBody synqBatchItemUpdatePayload: SynqBatchItemUpdatePayload + ): ResponseEntity { + for (payload in synqBatchItemUpdatePayload.mapToItemPayloads()) { + val item = moveItem.moveItem(payload) + println(item) + } + return ResponseEntity.ok().build() + } + @Operation( summary = "Updates order status based on SynQ order status update", description = """Finds a specified order and updates its status given the message we receive from SynQ. @@ -63,9 +78,9 @@ class SynqController( @PathVariable owner: Owner, @Parameter(description = "Order ID in the storage system") @PathVariable orderId: String - ): ResponseEntity { + ): ResponseEntity { orderStatusUpdate.updateOrderStatus(orderUpdatePayload.hostName, orderId, orderUpdatePayload.getConvertedStatus()) - return ResponseEntity.ok().build() + return ResponseEntity.ok().build() } } diff --git a/src/main/kotlin/no/nb/mlt/wls/domain/ports/inbound/MoveItem.kt b/src/main/kotlin/no/nb/mlt/wls/domain/ports/inbound/MoveItem.kt index 004ca10d..5549298e 100644 --- a/src/main/kotlin/no/nb/mlt/wls/domain/ports/inbound/MoveItem.kt +++ b/src/main/kotlin/no/nb/mlt/wls/domain/ports/inbound/MoveItem.kt @@ -18,4 +18,15 @@ interface MoveItem { quantity: Double, location: String ): Item + + suspend fun moveItem(moveItemPayload: MoveItemPayload): Item { + return moveItem(moveItemPayload.hostId, moveItemPayload.hostName, moveItemPayload.quantity, moveItemPayload.location) + } } + +data class MoveItemPayload( + val hostId: String, + val hostName: HostName, + val quantity: Double, + val location: String +) diff --git a/src/main/kotlin/no/nb/mlt/wls/infrastructure/repositories/item/MongoItemRepository.kt b/src/main/kotlin/no/nb/mlt/wls/infrastructure/repositories/item/MongoItemRepository.kt index 2028355e..6d4f07c6 100644 --- a/src/main/kotlin/no/nb/mlt/wls/infrastructure/repositories/item/MongoItemRepository.kt +++ b/src/main/kotlin/no/nb/mlt/wls/infrastructure/repositories/item/MongoItemRepository.kt @@ -65,20 +65,25 @@ class ItemRepositoryMongoAdapter( quantity: Double, location: String ): Item { - mongoRepo - .findAndUpdateItemByHostNameAndHostId(hostId, hostName, quantity, location) - .timeout(Duration.ofSeconds(8)) - .doOnError { - logger.error(it) { - if (it is TimeoutException) { - "Timed out while updating Item. Order ID: $hostId, Host: $hostName" - } else { - "Error while updating order" + val itemsModified = + mongoRepo + .findAndUpdateItemByHostNameAndHostId(hostName, hostId, quantity, location) + .timeout(Duration.ofSeconds(8)) + .doOnError { + logger.error(it) { + if (it is TimeoutException) { + "Timed out while updating Item. Host ID: $hostId, Host: $hostName" + } else { + "Error while updating order" + } } } - } - .onErrorMap { ItemMovingException(it.message ?: "Item could not be moved", it) } - .awaitSingleOrNull() ?: ItemNotFoundException("Item with host ID $hostId for $hostName does not exist in WLS database") + .onErrorMap { ItemMovingException(it.message ?: "Item could not be moved", it) } + .awaitSingle() + + if (itemsModified == 0L) { + throw ItemNotFoundException("Item was not found. Host ID: $hostId, Host: $hostName") + } return getItem(hostName, hostId)!! } @@ -94,12 +99,12 @@ interface ItemMongoRepository : ReactiveMongoRepository { @Query(count = true, value = "{ '\$or': ?0 }") fun countItemsMatchingIds(ids: List): Mono - @Query("{hostName: ?0, hostOrderId: ?1}") + @Query("{hostName: ?0,hostId: ?1}") @Update("{'\$set':{quantity: ?2,location: ?3}}") fun findAndUpdateItemByHostNameAndHostId( - hostOrderId: String, hostName: HostName, + hostId: String, quantity: Double, location: String - ): Mono + ): Mono } From 82b26842fe59007116679dda62ed34e607827d1f Mon Sep 17 00:00:00 2001 From: Noah Bjerkli Aanonli Date: Wed, 9 Oct 2024 08:47:46 +0200 Subject: [PATCH 02/10] Handle item notifications --- .../wls/application/synqapi/synq/SynqController.kt | 3 +-- src/main/kotlin/no/nb/mlt/wls/domain/WLSService.kt | 4 +++- .../callbacks/InventoryNotifierAdapter.kt | 11 ++++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt index 1fd7b755..10ff811a 100644 --- a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt +++ b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt @@ -33,8 +33,7 @@ class SynqController( @RequestBody synqBatchItemUpdatePayload: SynqBatchItemUpdatePayload ): ResponseEntity { for (payload in synqBatchItemUpdatePayload.mapToItemPayloads()) { - val item = moveItem.moveItem(payload) - println(item) + moveItem.moveItem(payload) } return ResponseEntity.ok().build() } diff --git a/src/main/kotlin/no/nb/mlt/wls/domain/WLSService.kt b/src/main/kotlin/no/nb/mlt/wls/domain/WLSService.kt index ba6e1c0a..bf34cbea 100644 --- a/src/main/kotlin/no/nb/mlt/wls/domain/WLSService.kt +++ b/src/main/kotlin/no/nb/mlt/wls/domain/WLSService.kt @@ -71,7 +71,9 @@ class WLSService( throw ValidationException("Location can not be blank") } val item = getItem(hostName, hostId) ?: throw ItemNotFoundException("Item with id '$hostId' does not exist for '$hostName'") - return itemRepository.moveItem(item.hostId, item.hostName, quantity, location) + itemRepository.moveItem(item.hostId, item.hostName, quantity, location) + inventoryNotifier.itemChanged(item) + return item } override suspend fun createOrder(orderDTO: CreateOrderDTO): Order { diff --git a/src/main/kotlin/no/nb/mlt/wls/infrastructure/callbacks/InventoryNotifierAdapter.kt b/src/main/kotlin/no/nb/mlt/wls/infrastructure/callbacks/InventoryNotifierAdapter.kt index ca94dd73..0bc0c6a8 100644 --- a/src/main/kotlin/no/nb/mlt/wls/infrastructure/callbacks/InventoryNotifierAdapter.kt +++ b/src/main/kotlin/no/nb/mlt/wls/infrastructure/callbacks/InventoryNotifierAdapter.kt @@ -11,7 +11,16 @@ class InventoryNotifierAdapter( private val webClient: WebClient ) : InventoryNotifier { override fun itemChanged(item: Item) { - TODO("Future task") + if (item.callbackUrl != null) { + webClient + .post() + .uri(item.callbackUrl) + .bodyValue(item) + .retrieve() + .bodyToMono(Void::class.java) + .retry(5) + .subscribe() + } } override fun orderChanged(order: Order) { From 98113d5682b5e217e44cedffdbc129c3a875cf76 Mon Sep 17 00:00:00 2001 From: Noah Bjerkli Aanonli Date: Wed, 9 Oct 2024 09:03:54 +0200 Subject: [PATCH 03/10] Fix errors with item moving logic --- src/main/kotlin/no/nb/mlt/wls/domain/WLSService.kt | 6 +++--- src/test/kotlin/no/nb/mlt/wls/domain/WLSServiceTest.kt | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/no/nb/mlt/wls/domain/WLSService.kt b/src/main/kotlin/no/nb/mlt/wls/domain/WLSService.kt index bf34cbea..acee1596 100644 --- a/src/main/kotlin/no/nb/mlt/wls/domain/WLSService.kt +++ b/src/main/kotlin/no/nb/mlt/wls/domain/WLSService.kt @@ -71,9 +71,9 @@ class WLSService( throw ValidationException("Location can not be blank") } val item = getItem(hostName, hostId) ?: throw ItemNotFoundException("Item with id '$hostId' does not exist for '$hostName'") - itemRepository.moveItem(item.hostId, item.hostName, quantity, location) - inventoryNotifier.itemChanged(item) - return item + val movedItem = itemRepository.moveItem(item.hostId, item.hostName, quantity, location) + inventoryNotifier.itemChanged(movedItem) + return movedItem } override suspend fun createOrder(orderDTO: CreateOrderDTO): Order { diff --git a/src/test/kotlin/no/nb/mlt/wls/domain/WLSServiceTest.kt b/src/test/kotlin/no/nb/mlt/wls/domain/WLSServiceTest.kt index 3b56268f..d9f5efa2 100644 --- a/src/test/kotlin/no/nb/mlt/wls/domain/WLSServiceTest.kt +++ b/src/test/kotlin/no/nb/mlt/wls/domain/WLSServiceTest.kt @@ -4,6 +4,7 @@ import io.mockk.clearAllMocks import io.mockk.coEvery import io.mockk.coJustRun import io.mockk.coVerify +import io.mockk.every import io.mockk.mockk import kotlinx.coroutines.test.runTest import no.nb.mlt.wls.domain.model.Environment @@ -133,6 +134,7 @@ class WLSServiceTest { ) coEvery { itemRepoMock.getItem(any(), any()) } returns testItem coEvery { itemRepoMock.moveItem(any(), any(), any(), any()) } returns expectedItem + every { inventoryNotifierMock.itemChanged(any()) } answers {} val cut = WLSService(itemRepoMock, orderRepoMock, storageSystemRepoMock, inventoryNotifierMock) runTest { From b9d8421722bd168315c9397a770d2f4101eb5074 Mon Sep 17 00:00:00 2001 From: Noah Bjerkli Aanonli Date: Wed, 9 Oct 2024 12:19:19 +0200 Subject: [PATCH 04/10] Rename payload to SynqBatchMoveItemPayload --- ...qBatchItemUpdatePayload.kt => SynqBatchMoveItemPayload.kt} | 4 ++-- .../no/nb/mlt/wls/application/synqapi/synq/SynqController.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/{SynqBatchItemUpdatePayload.kt => SynqBatchMoveItemPayload.kt} (98%) diff --git a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqBatchItemUpdatePayload.kt b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqBatchMoveItemPayload.kt similarity index 98% rename from src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqBatchItemUpdatePayload.kt rename to src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqBatchMoveItemPayload.kt index 186b574f..5c729d6a 100644 --- a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqBatchItemUpdatePayload.kt +++ b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqBatchMoveItemPayload.kt @@ -37,7 +37,7 @@ import no.nb.mlt.wls.domain.ports.inbound.MoveItemPayload "warehouse" : "Sikringsmagasin_2" }""" ) -data class SynqBatchItemUpdatePayload( +data class SynqBatchMoveItemPayload( @Schema( description = "ID of the transport unit in the SynQ storage system.", example = "6942066642" @@ -190,7 +190,7 @@ data class Position( val zPosition: Int ) -fun SynqBatchItemUpdatePayload.mapToItemPayloads(): List { +fun SynqBatchMoveItemPayload.mapToItemPayloads(): List { val list = mutableListOf() for (product in loadUnit) { list.add( diff --git a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt index 10ff811a..eef249ac 100644 --- a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt +++ b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt @@ -30,9 +30,9 @@ class SynqController( @PutMapping("/item-update") suspend fun updateItem( @AuthenticationPrincipal jwt: JwtAuthenticationToken, - @RequestBody synqBatchItemUpdatePayload: SynqBatchItemUpdatePayload + @RequestBody synqBatchMoveItemPayload: SynqBatchMoveItemPayload ): ResponseEntity { - for (payload in synqBatchItemUpdatePayload.mapToItemPayloads()) { + for (payload in synqBatchMoveItemPayload.mapToItemPayloads()) { moveItem.moveItem(payload) } return ResponseEntity.ok().build() From 70db0d31d4d1c5b5d86219858942cfc89db53bcd Mon Sep 17 00:00:00 2001 From: Noah Bjerkli Aanonli Date: Wed, 9 Oct 2024 12:19:36 +0200 Subject: [PATCH 05/10] Add Swagger documentation for item-update --- .../synqapi/synq/SynqController.kt | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt index eef249ac..9fc3364c 100644 --- a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt +++ b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt @@ -26,7 +26,35 @@ class SynqController( private val moveItem: MoveItem, private val orderStatusUpdate: OrderStatusUpdate ) { - // TODO - Swagger docs + @Operation( + summary = "Updates the status and location for items", + description = """Parses all the items from the SynQ load unit, and updates + both status & location for them. + """ + ) + @ApiResponses( + ApiResponse( + responseCode = "200", + description = """Item with given 'hostName' and 'hostId' was found and updated.""", + content = [Content(schema = Schema())] + ), + ApiResponse( + responseCode = "400", + description = "The payload for moving items was invalid and nothing got updated.", + content = [Content(schema = Schema())] + ), + ApiResponse( + responseCode = "403", + description = "A valid 'Authorization' header is missing from the request.", + content = [Content(schema = Schema())] + ), + ApiResponse( + responseCode = "404", + description = """An item for a specific 'hostName' and 'hostId' was not found. + Error message contains information about the missing item.""", + content = [Content(schema = Schema())] + ) + ) @PutMapping("/item-update") suspend fun updateItem( @AuthenticationPrincipal jwt: JwtAuthenticationToken, From 043c4f6c4bda839ab9cc3b65339644aa353cac3c Mon Sep 17 00:00:00 2001 From: Noah Bjerkli Aanonli Date: Thu, 10 Oct 2024 08:36:01 +0200 Subject: [PATCH 06/10] Clear unneeded text blocks --- .../nb/mlt/wls/application/synqapi/synq/SynqController.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt index 9fc3364c..913feae7 100644 --- a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt +++ b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt @@ -28,14 +28,12 @@ class SynqController( ) { @Operation( summary = "Updates the status and location for items", - description = """Parses all the items from the SynQ load unit, and updates - both status & location for them. - """ + description = "Parses all the items from the SynQ load unit, and updates both status & location for them." ) @ApiResponses( ApiResponse( responseCode = "200", - description = """Item with given 'hostName' and 'hostId' was found and updated.""", + description = "Item with given 'hostName' and 'hostId' was found and updated.", content = [Content(schema = Schema())] ), ApiResponse( From 23ae6954919fd42bd6aba3b21ab88d983723038c Mon Sep 17 00:00:00 2001 From: Noah Bjerkli Aanonli Date: Thu, 10 Oct 2024 09:24:06 +0200 Subject: [PATCH 07/10] Use DTO instead of fields for moving items --- .../synqapi/synq/SynqBatchMoveItemPayload.kt | 22 +++++++++---------- .../synqapi/synq/SynqController.kt | 6 ++--- .../kotlin/no/nb/mlt/wls/domain/WLSService.kt | 20 ++++++++--------- .../mlt/wls/domain/ports/inbound/MoveItem.kt | 11 +--------- 4 files changed, 24 insertions(+), 35 deletions(-) diff --git a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqBatchMoveItemPayload.kt b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqBatchMoveItemPayload.kt index 5c729d6a..556876ae 100644 --- a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqBatchMoveItemPayload.kt +++ b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqBatchMoveItemPayload.kt @@ -190,17 +190,17 @@ data class Position( val zPosition: Int ) +fun Product.toPayload(location: String): MoveItemPayload { + return MoveItemPayload( + hostId = productId, + hostName = HostName.valueOf(hostName.uppercase()), + quantity = quantityOnHand, + location = location + ) +} + fun SynqBatchMoveItemPayload.mapToItemPayloads(): List { - val list = mutableListOf() - for (product in loadUnit) { - list.add( - MoveItemPayload( - hostId = product.productId, - hostName = HostName.valueOf(product.hostName.uppercase()), - quantity = product.quantityOnHand, - location = location - ) - ) + return loadUnit.map { + it.toPayload(location) } - return list } diff --git a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt index 913feae7..40629356 100644 --- a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt +++ b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt @@ -20,7 +20,7 @@ import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController @RestController -@RequestMapping(path = [ "/synq/v1"]) +@RequestMapping(path = ["/synq/v1"]) @Tag(name = "SynQ Controller", description = "API for receiving product and order updates from SynQ in Hermes WLS") class SynqController( private val moveItem: MoveItem, @@ -58,9 +58,7 @@ class SynqController( @AuthenticationPrincipal jwt: JwtAuthenticationToken, @RequestBody synqBatchMoveItemPayload: SynqBatchMoveItemPayload ): ResponseEntity { - for (payload in synqBatchMoveItemPayload.mapToItemPayloads()) { - moveItem.moveItem(payload) - } + synqBatchMoveItemPayload.mapToItemPayloads().map { moveItem.moveItem(it) } return ResponseEntity.ok().build() } diff --git a/src/main/kotlin/no/nb/mlt/wls/domain/WLSService.kt b/src/main/kotlin/no/nb/mlt/wls/domain/WLSService.kt index acee1596..ae95ce3b 100644 --- a/src/main/kotlin/no/nb/mlt/wls/domain/WLSService.kt +++ b/src/main/kotlin/no/nb/mlt/wls/domain/WLSService.kt @@ -14,6 +14,7 @@ import no.nb.mlt.wls.domain.ports.inbound.GetOrder import no.nb.mlt.wls.domain.ports.inbound.ItemMetadata import no.nb.mlt.wls.domain.ports.inbound.ItemNotFoundException import no.nb.mlt.wls.domain.ports.inbound.MoveItem +import no.nb.mlt.wls.domain.ports.inbound.MoveItemPayload import no.nb.mlt.wls.domain.ports.inbound.OrderNotFoundException import no.nb.mlt.wls.domain.ports.inbound.OrderStatusUpdate import no.nb.mlt.wls.domain.ports.inbound.ServerException @@ -58,20 +59,19 @@ class WLSService( .awaitSingle() } - override suspend fun moveItem( - hostId: String, - hostName: HostName, - quantity: Double, - location: String - ): Item { - if (quantity < 0.0) { + override suspend fun moveItem(moveItemPayload: MoveItemPayload): Item { + if (moveItemPayload.quantity < 0.0) { throw ValidationException("Quantity can not be negative") } - if (location.isBlank()) { + if (moveItemPayload.location.isBlank()) { throw ValidationException("Location can not be blank") } - val item = getItem(hostName, hostId) ?: throw ItemNotFoundException("Item with id '$hostId' does not exist for '$hostName'") - val movedItem = itemRepository.moveItem(item.hostId, item.hostName, quantity, location) + val item = + getItem( + moveItemPayload.hostName, + moveItemPayload.hostId + ) ?: throw ItemNotFoundException("Item with id '${moveItemPayload.hostId}' does not exist for '${moveItemPayload.hostName}'") + val movedItem = itemRepository.moveItem(item.hostId, item.hostName, moveItemPayload.quantity, moveItemPayload.location) inventoryNotifier.itemChanged(movedItem) return movedItem } diff --git a/src/main/kotlin/no/nb/mlt/wls/domain/ports/inbound/MoveItem.kt b/src/main/kotlin/no/nb/mlt/wls/domain/ports/inbound/MoveItem.kt index 5549298e..6d125a13 100644 --- a/src/main/kotlin/no/nb/mlt/wls/domain/ports/inbound/MoveItem.kt +++ b/src/main/kotlin/no/nb/mlt/wls/domain/ports/inbound/MoveItem.kt @@ -12,16 +12,7 @@ import no.nb.mlt.wls.domain.model.Item * In both cases we want to know where the item went, and if the count changed */ interface MoveItem { - suspend fun moveItem( - hostId: String, - hostName: HostName, - quantity: Double, - location: String - ): Item - - suspend fun moveItem(moveItemPayload: MoveItemPayload): Item { - return moveItem(moveItemPayload.hostId, moveItemPayload.hostName, moveItemPayload.quantity, moveItemPayload.location) - } + suspend fun moveItem(moveItemPayload: MoveItemPayload): Item } data class MoveItemPayload( From bbdc365a1e30755684fbfbc0a95a0d8b0537f7a0 Mon Sep 17 00:00:00 2001 From: Noah Bjerkli Aanonli Date: Thu, 10 Oct 2024 09:24:44 +0200 Subject: [PATCH 08/10] Fix typo --- .../wls/infrastructure/repositories/item/MongoItemRepository.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/no/nb/mlt/wls/infrastructure/repositories/item/MongoItemRepository.kt b/src/main/kotlin/no/nb/mlt/wls/infrastructure/repositories/item/MongoItemRepository.kt index 6d4f07c6..b150e26c 100644 --- a/src/main/kotlin/no/nb/mlt/wls/infrastructure/repositories/item/MongoItemRepository.kt +++ b/src/main/kotlin/no/nb/mlt/wls/infrastructure/repositories/item/MongoItemRepository.kt @@ -74,7 +74,7 @@ class ItemRepositoryMongoAdapter( if (it is TimeoutException) { "Timed out while updating Item. Host ID: $hostId, Host: $hostName" } else { - "Error while updating order" + "Error while updating item" } } } From 57787688623e4a42eee566175792548b71329a57 Mon Sep 17 00:00:00 2001 From: Noah Bjerkli Aanonli Date: Thu, 10 Oct 2024 09:27:53 +0200 Subject: [PATCH 09/10] Remove unneeded JWT declarations --- .../no/nb/mlt/wls/application/synqapi/synq/SynqController.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt index 40629356..c1e8d8d7 100644 --- a/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt +++ b/src/main/kotlin/no/nb/mlt/wls/application/synqapi/synq/SynqController.kt @@ -11,8 +11,6 @@ import no.nb.mlt.wls.domain.model.Owner import no.nb.mlt.wls.domain.ports.inbound.MoveItem import no.nb.mlt.wls.domain.ports.inbound.OrderStatusUpdate import org.springframework.http.ResponseEntity -import org.springframework.security.core.annotation.AuthenticationPrincipal -import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.PutMapping import org.springframework.web.bind.annotation.RequestBody @@ -55,7 +53,6 @@ class SynqController( ) @PutMapping("/item-update") suspend fun updateItem( - @AuthenticationPrincipal jwt: JwtAuthenticationToken, @RequestBody synqBatchMoveItemPayload: SynqBatchMoveItemPayload ): ResponseEntity { synqBatchMoveItemPayload.mapToItemPayloads().map { moveItem.moveItem(it) } @@ -95,7 +92,6 @@ class SynqController( ) @PutMapping("/order-update/{owner}/{orderId}") suspend fun updateOrder( - @AuthenticationPrincipal jwt: JwtAuthenticationToken, @RequestBody orderUpdatePayload: SynqOrderStatusUpdatePayload, @Parameter(description = "Owner of the order items") @PathVariable owner: Owner, From d7c5cd81da0ae30fc9f683134fbb2c358d30928b Mon Sep 17 00:00:00 2001 From: Noah Bjerkli Aanonli Date: Thu, 10 Oct 2024 09:37:43 +0200 Subject: [PATCH 10/10] Fix tests --- .../no/nb/mlt/wls/domain/WLSServiceTest.kt | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/test/kotlin/no/nb/mlt/wls/domain/WLSServiceTest.kt b/src/test/kotlin/no/nb/mlt/wls/domain/WLSServiceTest.kt index d9f5efa2..df4d7416 100644 --- a/src/test/kotlin/no/nb/mlt/wls/domain/WLSServiceTest.kt +++ b/src/test/kotlin/no/nb/mlt/wls/domain/WLSServiceTest.kt @@ -16,6 +16,7 @@ import no.nb.mlt.wls.domain.model.Packaging import no.nb.mlt.wls.domain.ports.inbound.CreateOrderDTO import no.nb.mlt.wls.domain.ports.inbound.ItemMetadata import no.nb.mlt.wls.domain.ports.inbound.ItemNotFoundException +import no.nb.mlt.wls.domain.ports.inbound.MoveItemPayload import no.nb.mlt.wls.domain.ports.inbound.OrderNotFoundException import no.nb.mlt.wls.domain.ports.inbound.ValidationException import no.nb.mlt.wls.domain.ports.outbound.InventoryNotifier @@ -138,7 +139,7 @@ class WLSServiceTest { val cut = WLSService(itemRepoMock, orderRepoMock, storageSystemRepoMock, inventoryNotifierMock) runTest { - val movedItem = cut.moveItem(testItem.hostId, testItem.hostName, 1.0, "Somewhere nice") + val movedItem = cut.moveItem(testMoveItemPayload) assertThat(movedItem).isEqualTo(expectedItem) coVerify(exactly = 1) { itemRepoMock.getItem(any(), any()) } @@ -154,7 +155,7 @@ class WLSServiceTest { val cut = WLSService(itemRepoMock, orderRepoMock, storageSystemRepoMock, inventoryNotifierMock) runTest { assertThrows { - cut.moveItem(testItem.hostId, testItem.hostName, 1.0, "Somewhere nice") + cut.moveItem(testMoveItemPayload) } coVerify(exactly = 1) { itemRepoMock.getItem(any(), any()) } @@ -170,7 +171,7 @@ class WLSServiceTest { val cut = WLSService(itemRepoMock, orderRepoMock, storageSystemRepoMock, inventoryNotifierMock) runTest { assertThrows { - cut.moveItem(testItem.hostId, testItem.hostName, -1.0, "Somewhere nice") + cut.moveItem(testMoveItemPayload.copy(quantity = -1.0)) } coVerify(exactly = 0) { itemRepoMock.getItem(any(), any()) } @@ -186,7 +187,7 @@ class WLSServiceTest { val cut = WLSService(itemRepoMock, orderRepoMock, storageSystemRepoMock, inventoryNotifierMock) runTest { assertThrows { - cut.moveItem(testItem.hostId, testItem.hostName, 1.0, " ") + cut.moveItem(testMoveItemPayload.copy(location = " ")) } coVerify(exactly = 0) { itemRepoMock.getItem(any(), any()) } @@ -435,6 +436,14 @@ class WLSServiceTest { ) ) + private val testMoveItemPayload = + MoveItemPayload( + "12345", + HostName.AXIELL, + 1.0, + "Somewhere nice" + ) + private fun Order.toCreateOrderDTO() = CreateOrderDTO( hostName = testOrder.hostName,