Skip to content

Commit 0dd0ad1

Browse files
shawkinsmanusa
authored andcommitted
fix #3272: addressing npe and index logic in general
1 parent 8692965 commit 0dd0ad1

File tree

3 files changed

+15
-9
lines changed

3 files changed

+15
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
* Fix #3216: made the mock server aware of apiVersions
1616
* Fix #3225: Pod metric does not have corresponding label selector variant
1717
* Fix #3243: pipes provided to exec command are no longer closed on connection close, so that client can fully read the buffer after the command finishes.
18+
* Fix #3272: prevent index npe after informer sees an empty list
1819

1920
#### Improvements
2021
* Fix #3078: adding javadocs to further clarify patch, edit, replace, etc. and note the possibility of items being modified.

kubernetes-client/src/main/java/io/fabric8/kubernetes/client/informers/cache/Cache.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ public class Cache<T> implements Indexer<T> {
4444
public static final String NAMESPACE_INDEX = "namespace";
4545

4646
// indexers stores index functions by their names
47-
private Map<String, Function<T, List<String>>> indexers = new HashMap<>();
47+
private final Map<String, Function<T, List<String>>> indexers = new HashMap<>();
4848

4949
// items stores object instances
5050
private volatile ConcurrentHashMap<String, T> items = new ConcurrentHashMap<>();
5151

5252
// indices stores objects' key by their indices
53-
private Map<String, Map<String, Set<String>>> indices = new HashMap<>();
53+
private final Map<String, Map<String, Set<String>>> indices = new HashMap<>();
5454

5555
private BooleanSupplier isRunning = () -> false;
5656

@@ -74,12 +74,12 @@ public void setIsRunning(BooleanSupplier isRunning) {
7474
* @return registered indexers
7575
*/
7676
@Override
77-
public Map<String, Function<T, List<String>>> getIndexers() {
78-
return indexers;
77+
public synchronized Map<String, Function<T, List<String>>> getIndexers() {
78+
return Collections.unmodifiableMap(indexers);
7979
}
8080

8181
@Override
82-
public void addIndexers(Map<String, Function<T, List<String>>> indexersNew) {
82+
public synchronized void addIndexers(Map<String, Function<T, List<String>>> indexersNew) {
8383
if (isRunning.getAsBoolean()) {
8484
throw new IllegalStateException("Cannot add indexers to a running informer.");
8585
}
@@ -147,7 +147,7 @@ public synchronized Map<String, T> replace(List<T> list) {
147147
this.items = newItems;
148148

149149
// rebuild any index
150-
this.indices = new HashMap<>();
150+
this.indices.values().stream().forEach(Map::clear);
151151
for (Map.Entry<String, T> itemEntry : items.entrySet()) {
152152
this.updateIndices(null, itemEntry.getValue(), itemEntry.getKey());
153153
}
@@ -294,7 +294,7 @@ public synchronized List<T> byIndex(String indexName, String indexKey) {
294294
* @param newObj new object
295295
* @param key the key
296296
*/
297-
public void updateIndices(T oldObj, T newObj, String key) {
297+
void updateIndices(T oldObj, T newObj, String key) {
298298
if (oldObj != null) {
299299
deleteFromIndices(oldObj, key);
300300
}
@@ -307,7 +307,7 @@ public void updateIndices(T oldObj, T newObj, String key) {
307307
continue;
308308
}
309309

310-
Map<String, Set<String>> index = this.indices.computeIfAbsent(indexName, k -> new HashMap<>());
310+
Map<String, Set<String>> index = this.indices.get(indexName);
311311
for (String indexValue : indexValues) {
312312
Set<String> indexSet = index.computeIfAbsent(indexValue, k -> new HashSet<>());
313313
indexSet.add(key);
@@ -350,7 +350,7 @@ private void deleteFromIndices(T oldObj, String key) {
350350
* @param indexName the index name
351351
* @param indexFunc the index func
352352
*/
353-
public void addIndexFunc(String indexName, Function<T, List<String>> indexFunc) {
353+
public synchronized void addIndexFunc(String indexName, Function<T, List<String>> indexFunc) {
354354
this.indices.put(indexName, new HashMap<>());
355355
this.indexers.put(indexName, indexFunc);
356356
}

kubernetes-client/src/test/java/io/fabric8/kubernetes/client/informers/cache/CacheTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@
2020
import org.junit.jupiter.api.Test;
2121

2222
import java.util.Arrays;
23+
import java.util.Collections;
2324
import java.util.HashMap;
2425
import java.util.List;
2526
import java.util.Map;
2627
import java.util.function.Function;
2728

2829
import static org.junit.jupiter.api.Assertions.assertEquals;
30+
import static org.junit.jupiter.api.Assertions.assertNull;
2931

3032
class CacheTest {
3133
private static Cache cache = new Cache("mock", CacheTest::mockIndexFunction, CacheTest::mockKeyFunction);
@@ -49,6 +51,9 @@ void testCacheIndex() {
4951
List<String> allExistingKeys = cache.listKeys();
5052
assertEquals(1, allExistingKeys.size());
5153
assertEquals(key, allExistingKeys.get(0));
54+
55+
cache.replace(Collections.emptyList());
56+
assertEquals(0, cache.byIndex("mock", "y").size());
5257
}
5358

5459
@Test

0 commit comments

Comments
 (0)