Repository: pagopa/pn-delayer
Pull request #14: [PN-14477] refactor PaperDeliveryDriverCapacitiesDispatched DAO and entity
Author: login: flaminiaScarciofolo
Created: 2025-04-14T07:30:23Z | Merged: 2025-04-14T10:59:13Z



Diff:
diff --git a/src/main/java/it/pagopa/pn/delayer/middleware/dao/PaperDeliveryDriverCapacitiesDispatchedDAO.java b/src/main/java/it/pagopa/pn/delayer/middleware/dao/PaperDeliveryDriverCapacitiesDispatchedDAO.java
index 77601828..c0116b69 100644
--- a/src/main/java/it/pagopa/pn/delayer/middleware/dao/PaperDeliveryDriverCapacitiesDispatchedDAO.java
+++ b/src/main/java/it/pagopa/pn/delayer/middleware/dao/PaperDeliveryDriverCapacitiesDispatchedDAO.java
@@ -1,5 +1,6 @@
 package it.pagopa.pn.delayer.middleware.dao;
 
+
 import it.pagopa.pn.delayer.middleware.dao.dynamo.entity.PaperDeliveryDriverCapacitiesDispatched;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
@@ -10,9 +11,10 @@
 
 public interface PaperDeliveryDriverCapacitiesDispatchedDAO {
 
-    Mono<UpdateItemResponse> updateCounter(String pk, Instant deliveryDate, Integer increment);
+    Mono<UpdateItemResponse> updateCounter(String deliveryDriverId, String geoKey, Integer increment, Instant deliveryDate);
 
-    Mono<PaperDeliveryDriverCapacitiesDispatched> get(String pk, Instant deliveryDate);
+    Mono<Integer> get(String deliveryDriverId, String geoKey, Instant deliveryDate);
 
     Flux<PaperDeliveryDriverCapacitiesDispatched> batchGetItem(List<String> pks, Instant deliveryDate);
+
 }
diff --git a/src/main/java/it/pagopa/pn/delayer/middleware/dao/dynamo/PaperDeliveryDriverCapacitiesDispatchedDAOImpl.java b/src/main/java/it/pagopa/pn/delayer/middleware/dao/dynamo/PaperDeliveryDriverCapacitiesDispatchedDAOImpl.java
index 865fd48f..1804c9bb 100644
--- a/src/main/java/it/pagopa/pn/delayer/middleware/dao/dynamo/PaperDeliveryDriverCapacitiesDispatchedDAOImpl.java
+++ b/src/main/java/it/pagopa/pn/delayer/middleware/dao/dynamo/PaperDeliveryDriverCapacitiesDispatchedDAOImpl.java
@@ -21,6 +21,8 @@
 import java.util.List;
 import java.util.Map;
 
+import static it.pagopa.pn.delayer.middleware.dao.dynamo.entity.PaperDeliveryDriverCapacitiesDispatched.*;
+
 @Component
 @Slf4j
 public class PaperDeliveryDriverCapacitiesDispatchedDAOImpl implements PaperDeliveryDriverCapacitiesDispatchedDAO {
@@ -36,7 +38,8 @@ public PaperDeliveryDriverCapacitiesDispatchedDAOImpl(PnDelayerConfigs pnDelayer
     }
 
     @Override
-    public Mono<UpdateItemResponse> updateCounter(String pk, Instant deliveryDate, Integer increment) {
+    public Mono<UpdateItemResponse> updateCounter(String deliveryDriverId, String geoKey, Integer increment, Instant deliveryDate) {
+        String pk = PaperDeliveryDriverCapacitiesDispatched.buildPk(deliveryDriverId, geoKey);
         log.info("update pk={} increment={}", pk, increment);
 
         Map<String, AttributeValue> key = new HashMap<>();
@@ -45,10 +48,14 @@ public Mono<UpdateItemResponse> updateCounter(String pk, Instant deliveryDate, I
 
         Map<String, AttributeValue> attributeValue = new HashMap<>();
         attributeValue.put(":v", AttributeValue.builder().n(String.valueOf(increment)).build());
+        attributeValue.put(":deliveryDriver", AttributeValue.builder().s(deliveryDriverId).build());
+        attributeValue.put(":geoKey", AttributeValue.builder().s(geoKey).build());
+
         UpdateItemRequest updateRequest = UpdateItemRequest.builder()
                 .tableName(table.tableName())
                 .key(key)
-                .updateExpression("ADD " + PaperDeliveryDriverCapacitiesDispatched.COL_CAPACITY + " :v")
+                .updateExpression("ADD " + COL_USED_CAPACITY + " :v" +
+                        " SET " + COL_DELIVERY_DRIVER_ID + " = :deliveryDriver," + COL_GEO_KEY + "= :geoKey")
                 .expressionAttributeValues(attributeValue)
                 .build();
 
@@ -58,18 +65,21 @@ public Mono<UpdateItemResponse> updateCounter(String pk, Instant deliveryDate, I
     }
 
     @Override
-    public Mono<PaperDeliveryDriverCapacitiesDispatched> get(String pk, Instant deliveryDate) {
+    public Mono<Integer> get(String deliveryDriverId, String geoKey, Instant deliveryDate) {
+        String pk = PaperDeliveryDriverCapacitiesDispatched.buildPk(deliveryDriverId, geoKey);
         return Mono.fromFuture(table.getItem(Key.builder()
                         .partitionValue(pk)
                         .sortValue(String.valueOf(deliveryDate))
                         .build()))
-                .doOnSuccess(item -> log.info("Retrieved item: {}", item))
-                .doOnError(e -> log.error("Error retrieving item with pk {}: {}", pk, e.getMessage()));
+                .map(PaperDeliveryDriverCapacitiesDispatched::getUsedCapacity)
+                .switchIfEmpty(Mono.just(0))
+                .doOnSuccess(item -> log.info("Retrieved used capacity for pk [{}] and deliveryWeek [{}] = {}",pk, deliveryDate, item))
+                .doOnError(e -> log.error("Error retrieving usedCapacity item with pk {}: {}", pk, e.getMessage()));
     }
 
     @Override
     public Flux<PaperDeliveryDriverCapacitiesDispatched> batchGetItem(List<String> pks, Instant deliveryDate) {
-        log.info("batchGetItem pks={} deliveryDate={}", pks, deliveryDate);
+        log.info("batchGetItem for usedCapacity pks={} deliveryDate={}", pks, deliveryDate);
 
         List<Key> keys = pks.stream()
                 .map(pk -> Key.builder()
@@ -91,9 +101,9 @@ public Flux<PaperDeliveryDriverCapacitiesDispatched> batchGetItem(List<String> p
 
         return Mono.from(dynamoDbEnhancedClient.batchGetItem(request))
                 .map(batchGetResultPage -> batchGetResultPage.resultsForTable(table))
-                .doOnNext(items -> log.info("Retrieved item: {}", items.size()))
+                .doOnNext(items -> log.info("Retrieved usedCapacity items: {}", items.size()))
                 .flatMapMany(Flux::fromIterable)
-                .doOnError(e -> log.error("Error retrieving items with pks {}: {}", pks, e.getMessage()));
+                .doOnError(e -> log.error("Error retrieving usedCapacity items with pks {}: {}", pks, e.getMessage()));
     }
 }
 
diff --git a/src/main/java/it/pagopa/pn/delayer/middleware/dao/dynamo/entity/PaperDeliveryDriverCapacitiesDispatched.java b/src/main/java/it/pagopa/pn/delayer/middleware/dao/dynamo/entity/PaperDeliveryDriverCapacitiesDispatched.java
index 3b721f40..a77b0972 100644
--- a/src/main/java/it/pagopa/pn/delayer/middleware/dao/dynamo/entity/PaperDeliveryDriverCapacitiesDispatched.java
+++ b/src/main/java/it/pagopa/pn/delayer/middleware/dao/dynamo/entity/PaperDeliveryDriverCapacitiesDispatched.java
@@ -15,22 +15,23 @@ public class PaperDeliveryDriverCapacitiesDispatched {
 
     public static final String COL_DELIVERY_DRIVER_ID_GEOKEY = "deliveryDriverIdGeokey";
     public static final String COL_DELIVERY_DATE = "deliveryDate";
-    public static final String COL_TENDER_ID = "tenderId";
     public static final String COL_DELIVERY_DRIVER_ID = "deliveryDriverId";
     public static final String COL_GEO_KEY = "geoKey";
-    public static final String COL_CAPACITY = "usedCapacity";
+    public static final String COL_USED_CAPACITY = "usedCapacity";
 
 
     @Getter(onMethod = @__({@DynamoDbPartitionKey, @DynamoDbAttribute(COL_DELIVERY_DRIVER_ID_GEOKEY)}))
     private String deliveryDriverIdGeokey;
     @Getter(onMethod = @__({@DynamoDbSortKey, @DynamoDbAttribute(COL_DELIVERY_DATE)}))
     private Instant deliveryDate;
-    @Getter(onMethod = @__({@DynamoDbAttribute(COL_TENDER_ID)}))
-    private String tenderId;
     @Getter(onMethod = @__({@DynamoDbAttribute(COL_DELIVERY_DRIVER_ID)}))
     private String deliveryDriverId;
     @Getter(onMethod = @__({@DynamoDbAttribute(COL_GEO_KEY)}))
-    private String geokey;
-    @Getter(onMethod = @__({@DynamoDbAttribute(COL_CAPACITY)}))
+    private String geoKey;
+    @Getter(onMethod = @__({@DynamoDbAttribute(COL_USED_CAPACITY)}))
     private int usedCapacity;
+
+    public static String buildPk(String deliveryDriverId, String geoKey) {
+        return String.join("##", deliveryDriverId, geoKey);
+    }
 }
diff --git a/src/test/java/it/pagopa/pn/delayer/middleware/dao/PaperDeliveryDriverCapacitiesDispatchedDaoIT.java b/src/test/java/it/pagopa/pn/delayer/middleware/dao/PaperDeliveryDriverCapacitiesDispatchedDaoIT.java
index 5d811c6a..2da2fb79 100644
--- a/src/test/java/it/pagopa/pn/delayer/middleware/dao/PaperDeliveryDriverCapacitiesDispatchedDaoIT.java
+++ b/src/test/java/it/pagopa/pn/delayer/middleware/dao/PaperDeliveryDriverCapacitiesDispatchedDaoIT.java
@@ -7,7 +7,11 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import reactor.test.StepVerifier;
 
+import java.time.DayOfWeek;
 import java.time.Instant;
+import java.time.LocalDate;
+import java.time.ZoneOffset;
+import java.time.temporal.TemporalAdjusters;
 import java.util.List;
 
 
@@ -16,37 +20,43 @@ class PaperDeliveryDriverCapacitiesDispatchedDaoIT extends BaseTest.WithLocalSta
     @Autowired
     PaperDeliveryDriverCapacitiesDispatchedDAO paperDeliveryDriverCapacitiesDispatchedDao;
 
+    @Test
+    void testGet(){
+        Integer response = paperDeliveryDriverCapacitiesDispatchedDao.get("testEmpty", "RM", Instant.now()).block();
+        Assertions.assertEquals(0, response);
+    }
+
     @Test
     void testUpdateAndGet() {
         PaperDeliveryDriverCapacitiesDispatched entity = new PaperDeliveryDriverCapacitiesDispatched();
-        entity.setDeliveryDriverIdGeokey("pk");
-        Instant deliveryDate = Instant.parse("2025-04-07T00:00:00Z");
+        LocalDate dateTime = LocalDate.ofInstant(Instant.now(), ZoneOffset.UTC);
+        LocalDate nextWeek = dateTime.with(TemporalAdjusters.next(DayOfWeek.of(1)));
+        Instant deliveryDate = nextWeek.atStartOfDay().toInstant(ZoneOffset.UTC);
+        entity.setDeliveryDriverIdGeokey("1##RM");
         entity.setDeliveryDate(deliveryDate);
 
-        paperDeliveryDriverCapacitiesDispatchedDao.updateCounter("pk", deliveryDate, 5).block();
+        paperDeliveryDriverCapacitiesDispatchedDao.updateCounter("1", "RM",  5, deliveryDate).block();
 
-        PaperDeliveryDriverCapacitiesDispatched response = paperDeliveryDriverCapacitiesDispatchedDao.get("pk", deliveryDate).block();
+        Integer response = paperDeliveryDriverCapacitiesDispatchedDao.get("1", "RM", deliveryDate).block();
         assert response != null;
-        Assertions.assertEquals(entity.getDeliveryDriverIdGeokey(), response.getDeliveryDriverIdGeokey());
-        Assertions.assertEquals(entity.getDeliveryDate(), response.getDeliveryDate());
-        Assertions.assertEquals(5, response.getUsedCapacity());
+        Assertions.assertEquals(5, response);
 
-        paperDeliveryDriverCapacitiesDispatchedDao.updateCounter("pk", deliveryDate, 5).block();
+        paperDeliveryDriverCapacitiesDispatchedDao.updateCounter("1", "RM",   5, deliveryDate).block();
 
-        PaperDeliveryDriverCapacitiesDispatched response2 = paperDeliveryDriverCapacitiesDispatchedDao.get("pk", deliveryDate).block();
+        Integer response2 = paperDeliveryDriverCapacitiesDispatchedDao.get("1", "RM", deliveryDate).block();
         assert response2 != null;
-        Assertions.assertEquals(entity.getDeliveryDriverIdGeokey(), response2.getDeliveryDriverIdGeokey());
-        Assertions.assertEquals(entity.getDeliveryDate(), response2.getDeliveryDate());
-        Assertions.assertEquals(10, response2.getUsedCapacity());
+        Assertions.assertEquals(10, response2);
     }
 
     @Test
     void testBatchGetItem() {
-        List<String> pks = List.of("test-pk1", "test-pk2", "test-pk3");
-        Instant deliveryDate = Instant.now();
+        List<String> pks = List.of("test##pk1", "test##pk2", "test##pk3");
+        LocalDate dateTime = LocalDate.ofInstant(Instant.now(), ZoneOffset.UTC);
+        LocalDate nextWeek = dateTime.with(TemporalAdjusters.next(DayOfWeek.of(1)));
+        Instant deliveryDate = nextWeek.atStartOfDay().toInstant(ZoneOffset.UTC);
 
-        paperDeliveryDriverCapacitiesDispatchedDao.updateCounter("test-pk1", deliveryDate, 5).block();
-        paperDeliveryDriverCapacitiesDispatchedDao.updateCounter("test-pk2", deliveryDate, 5).block();
+        paperDeliveryDriverCapacitiesDispatchedDao.updateCounter("test","pk1", 5, deliveryDate).block();
+        paperDeliveryDriverCapacitiesDispatchedDao.updateCounter("test","pk2", 5, deliveryDate).block();
 
         StepVerifier.create(paperDeliveryDriverCapacitiesDispatchedDao.batchGetItem(pks, deliveryDate))
                 .expectNextCount(2)
diff --git a/src/test/resources/application-test.properties b/src/test/resources/application-test.properties
new file mode 100644
index 00000000..36876231
--- /dev/null
+++ b/src/test/resources/application-test.properties
@@ -0,0 +1,9 @@
+logging.config=classpath:logback-base.xml
+
+pn.env.runtime=PROD
+spring.application.name=PN-DELAYER-MS-BE
+
+pn.delayer.dao.paper-delivery-driver-capacities-table-name=pn-PaperDeliveryDriverCapacities
+pn.delayer.dao.paper-delivery-driver-capacities-dispatched-table-name=pn-PaperDeliveryDriverCapacitiesDispatched
+pn.delayer.dao.paper-delivery-high-priority-table-name=pn-PaperDeliveryHighPriority
+pn.delayer.dao.paper-delivery-ready-to-send-table-name=pn-PaperDeliveryReadyToSend


Reviews:
user: login: vincenzo-racca-pa
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-14T10:27:59Z
user: login: vincenzo-racca-pa
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-14T10:33:14Z
user: login: vincenzo-racca-pa
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-14T10:35:21Z
user: login: vincenzo-racca-pa
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-14T10:55:10Z

Review comments:
diff_hunk: @@ -58,12 +65,15 @@ public Mono<UpdateItemResponse> updateCounter(String pk, Instant deliveryDate, I
     }
 
     @Override
-    public Mono<PaperDeliveryDriverCapacitiesDispatched> get(String pk, Instant deliveryDate) {
+    public Mono<Integer> get(String deliveryDriverId, String geoKey, Instant deliveryDate) {
+        String pk = PaperDeliveryDriverCapacitiesDispatched.buildPk(deliveryDriverId, geoKey);
         return Mono.fromFuture(table.getItem(Key.builder()
                         .partitionValue(pk)
                         .sortValue(String.valueOf(deliveryDate))
                         .build()))
-                .doOnSuccess(item -> log.info("Retrieved item: {}", item))
+                .map(PaperDeliveryDriverCapacitiesDispatched::getUsedCapacity)
+                .switchIfEmpty(Mono.just(0))
+                .doOnSuccess(item -> log.info("Retrieved capacity for pk [{}] and deliveryWeek [{}] = {}",pk, deliveryDate, item))
path: src/main/java/it/pagopa/pn/delayer/middleware/dao/dynamo/PaperDeliveryDriverCapacitiesDispatchedDAOImpl.java
user: login: vincenzo-racca-pa
body: Modificherei il messaggio in "Retrieved used capacity for..."
created_at: 2025-04-14T10:27:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -25,12 +24,14 @@ public class PaperDeliveryDriverCapacitiesDispatched {
     private String deliveryDriverIdGeokey;
     @Getter(onMethod = @__({@DynamoDbSortKey, @DynamoDbAttribute(COL_DELIVERY_DATE)}))
     private Instant deliveryDate;
-    @Getter(onMethod = @__({@DynamoDbAttribute(COL_TENDER_ID)}))
-    private String tenderId;
     @Getter(onMethod = @__({@DynamoDbAttribute(COL_DELIVERY_DRIVER_ID)}))
     private String deliveryDriverId;
     @Getter(onMethod = @__({@DynamoDbAttribute(COL_GEO_KEY)}))
-    private String geokey;
+    private String geoKey;
     @Getter(onMethod = @__({@DynamoDbAttribute(COL_CAPACITY)}))
path: src/main/java/it/pagopa/pn/delayer/middleware/dao/dynamo/entity/PaperDeliveryDriverCapacitiesDispatched.java
user: login: vincenzo-racca-pa
body: COL_USED_CAPACITY
created_at: 2025-04-14T10:27:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -58,18 +65,21 @@ public Mono<UpdateItemResponse> updateCounter(String pk, Instant deliveryDate, I
     }
 
     @Override
-    public Mono<PaperDeliveryDriverCapacitiesDispatched> get(String pk, Instant deliveryDate) {
+    public Mono<Integer> get(String deliveryDriverId, String geoKey, Instant deliveryDate) {
+        String pk = PaperDeliveryDriverCapacitiesDispatched.buildPk(deliveryDriverId, geoKey);
         return Mono.fromFuture(table.getItem(Key.builder()
                         .partitionValue(pk)
                         .sortValue(String.valueOf(deliveryDate))
                         .build()))
-                .doOnSuccess(item -> log.info("Retrieved item: {}", item))
-                .doOnError(e -> log.error("Error retrieving item with pk {}: {}", pk, e.getMessage()));
+                .map(PaperDeliveryDriverCapacitiesDispatched::getUsedCapacity)
+                .switchIfEmpty(Mono.just(0))
+                .doOnSuccess(item -> log.info("Retrieved used capacity for pk [{}] and deliveryWeek [{}] = {}",pk, deliveryDate, item))
+                .doOnError(e -> log.error("Error retrieving userCapacity item with pk {}: {}", pk, e.getMessage()));
path: src/main/java/it/pagopa/pn/delayer/middleware/dao/dynamo/PaperDeliveryDriverCapacitiesDispatchedDAOImpl.java
user: login: vincenzo-racca-pa
body: usedCapacity
created_at: 2025-04-14T10:32:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -91,9 +101,9 @@ public Flux<PaperDeliveryDriverCapacitiesDispatched> batchGetItem(List<String> p
 
         return Mono.from(dynamoDbEnhancedClient.batchGetItem(request))
                 .map(batchGetResultPage -> batchGetResultPage.resultsForTable(table))
-                .doOnNext(items -> log.info("Retrieved item: {}", items.size()))
+                .doOnNext(items -> log.info("Retrieved userCapacity items: {}", items.size()))
path: src/main/java/it/pagopa/pn/delayer/middleware/dao/dynamo/PaperDeliveryDriverCapacitiesDispatchedDAOImpl.java
user: login: vincenzo-racca-pa
body: usedCapacity
created_at: 2025-04-14T10:33:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -91,9 +101,9 @@ public Flux<PaperDeliveryDriverCapacitiesDispatched> batchGetItem(List<String> p
 
         return Mono.from(dynamoDbEnhancedClient.batchGetItem(request))
                 .map(batchGetResultPage -> batchGetResultPage.resultsForTable(table))
-                .doOnNext(items -> log.info("Retrieved item: {}", items.size()))
+                .doOnNext(items -> log.info("Retrieved userCapacity items: {}", items.size()))
                 .flatMapMany(Flux::fromIterable)
-                .doOnError(e -> log.error("Error retrieving items with pks {}: {}", pks, e.getMessage()));
+                .doOnError(e -> log.error("Error retrieving userCapacity items with pks {}: {}", pks, e.getMessage()));
path: src/main/java/it/pagopa/pn/delayer/middleware/dao/dynamo/PaperDeliveryDriverCapacitiesDispatchedDAOImpl.java
user: login: vincenzo-racca-pa
body: usedCapacity
created_at: 2025-04-14T10:33:08Z
author_association: CONTRIBUTOR

PR comments:
user: login: sonarqubecloud[bot]
created_at: 2025-04-14T11:05:09Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=pagopa_pn-delayer&pullRequest=14) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=pagopa_pn-delayer&pullRequest=14&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=pagopa_pn-delayer&pullRequest=14&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=pagopa_pn-delayer&pullRequest=14&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [100.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=pagopa_pn-delayer&pullRequest=14&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=pagopa_pn-delayer&pullRequest=14&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=pagopa_pn-delayer&pullRequest=14)


author_association: NONE