mjsax commented on code in PR #22970:
URL: https://github.com/apache/kafka/pull/22970#discussion_r3671145851


##########
group-coordinator/src/test/java/org/apache/kafka/coordinator/group/streams/TargetAssignmentBuilderTest.java:
##########
@@ -177,6 +179,42 @@ public void 
testCreateMemberMetadataAndStateSourcesWarmupTasksFromCurrentAssignm
         assertEquals(Map.of(fooSubtopologyId, Set.of(1, 2, 3)), 
memberMetadata.warmupTasks());
     }
 
+    @Test
+    public void 
testCreateMemberMetadataAndStateReturnsUnmodifiableCollections() {

Review Comment:
   I think we can actually remove this test? It seems to replicate what we 
already get from `MemberMetadataAndStateImplTest` so no need to duplicate test 
coverage. We reach the same `MemberMetadataAndStateImpl` code just from our 
more layer around it -- doesn't really add anything.
   
   We should just move the client-tag test coverage that we only have here, to 
the other test.



##########
group-coordinator/src/main/java/org/apache/kafka/coordinator/group/streams/assignor/MemberMetadataAndStateImpl.java:
##########
@@ -56,11 +57,23 @@ public record MemberMetadataAndStateImpl(
         Objects.requireNonNull(rackId);
         Objects.requireNonNull(processId);
         clientTags = 
Collections.unmodifiableMap(Objects.requireNonNull(clientTags));
-        activeTasks = 
Collections.unmodifiableMap(Objects.requireNonNull(activeTasks));
-        standbyTasks = 
Collections.unmodifiableMap(Objects.requireNonNull(standbyTasks));
-        warmupTasks = 
Collections.unmodifiableMap(Objects.requireNonNull(warmupTasks));
-        taskOffsets = 
Collections.unmodifiableMap(Objects.requireNonNull(taskOffsets));
-        taskEndOffsets = 
Collections.unmodifiableMap(Objects.requireNonNull(taskEndOffsets));
+        // These collections belong to the coordinator (the member's current 
assignment and the offsets reported in
+        // the last heartbeat) and are only unmodifiable at the outer level 
there, so wrap the nested ones as well.
+        activeTasks = unmodifiableTasks(activeTasks);
+        standbyTasks = unmodifiableTasks(standbyTasks);
+        warmupTasks = unmodifiableTasks(warmupTasks);
+        taskOffsets = unmodifiableOffsets(taskOffsets);
+        taskEndOffsets = unmodifiableOffsets(taskEndOffsets);
+    }
+
+    private static Map<String, Set<Integer>> unmodifiableTasks(Map<String, 
Set<Integer>> tasks) {
+        return Objects.requireNonNull(tasks).entrySet().stream()
+            .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, entry -> 
Collections.unmodifiableSet(entry.getValue())));
+    }
+
+    private static Map<String, Map<Integer, Long>> 
unmodifiableOffsets(Map<String, Map<Integer, Long>> offsets) {
+        return Objects.requireNonNull(offsets).entrySet().stream()
+            .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, entry -> 
Collections.unmodifiableMap(entry.getValue())));

Review Comment:
   ```suggestion
               .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, entry 
-> Map.copyOf(entry.getValue())));
   ```



##########
group-coordinator/src/main/java/org/apache/kafka/coordinator/group/streams/assignor/MemberMetadataAndStateImpl.java:
##########
@@ -56,11 +57,23 @@ public record MemberMetadataAndStateImpl(
         Objects.requireNonNull(rackId);
         Objects.requireNonNull(processId);
         clientTags = 
Collections.unmodifiableMap(Objects.requireNonNull(clientTags));
-        activeTasks = 
Collections.unmodifiableMap(Objects.requireNonNull(activeTasks));
-        standbyTasks = 
Collections.unmodifiableMap(Objects.requireNonNull(standbyTasks));
-        warmupTasks = 
Collections.unmodifiableMap(Objects.requireNonNull(warmupTasks));
-        taskOffsets = 
Collections.unmodifiableMap(Objects.requireNonNull(taskOffsets));
-        taskEndOffsets = 
Collections.unmodifiableMap(Objects.requireNonNull(taskEndOffsets));
+        // These collections belong to the coordinator (the member's current 
assignment and the offsets reported in
+        // the last heartbeat) and are only unmodifiable at the outer level 
there, so wrap the nested ones as well.
+        activeTasks = unmodifiableTasks(activeTasks);
+        standbyTasks = unmodifiableTasks(standbyTasks);
+        warmupTasks = unmodifiableTasks(warmupTasks);
+        taskOffsets = unmodifiableOffsets(taskOffsets);
+        taskEndOffsets = unmodifiableOffsets(taskEndOffsets);
+    }
+
+    private static Map<String, Set<Integer>> unmodifiableTasks(Map<String, 
Set<Integer>> tasks) {
+        return Objects.requireNonNull(tasks).entrySet().stream()
+            .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, entry -> 
Collections.unmodifiableSet(entry.getValue())));

Review Comment:
   ```suggestion
               .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, entry 
-> Set.copyOf(entry.getValue())));
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to