diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/informers/cache/Cache.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/informers/cache/Cache.java index 04905cb85a4..d10fed04fec 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/informers/cache/Cache.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/informers/cache/Cache.java @@ -31,17 +31,17 @@ public interface Cache extends Indexer { // NAMESPACE_INDEX is the default index function for caching objects - public static final String NAMESPACE_INDEX = "namespace"; + String NAMESPACE_INDEX = "namespace"; /** - * It's is a convenient default KeyFunc which know show to make keys for API + * A convenient default KeyFunc which knows how to make keys for API * objects which implement HasMetadata interface. The key uses the format * namespace/name unless namespace is empty, then it's just name * * @param obj specific object * @return the key */ - public static String metaNamespaceKeyFunc(HasMetadata obj) { + static String metaNamespaceKeyFunc(HasMetadata obj) { if (obj == null) { return ""; } @@ -53,7 +53,7 @@ public static String metaNamespaceKeyFunc(HasMetadata obj) { return namespaceKeyFunc(metadata.getNamespace(), metadata.getName()); } - public static String metaUidKeyFunc(HasMetadata obj) { + static String metaUidKeyFunc(HasMetadata obj) { if (obj == null || obj.getMetadata() == null) { return ""; } @@ -66,7 +66,7 @@ public static String metaUidKeyFunc(HasMetadata obj) { * * @see #metaNamespaceKeyFunc */ - public static String namespaceKeyFunc(String objectNamespace, String objectName) { + static String namespaceKeyFunc(String objectNamespace, String objectName) { if (Utils.isNullOrEmpty(objectNamespace)) { return objectName; } @@ -74,13 +74,14 @@ public static String namespaceKeyFunc(String objectNamespace, String objectName) } /** - * It is a default index function that indexes based on an object's namespace + * Default index function that indexes based on an object's namespace * * @param obj the specific object * @return the indexed value */ - public static List metaNamespaceIndexFunc(HasMetadata obj) { - return Optional.ofNullable(obj).map(HasMetadata::getMetadata) - .map(metadata -> Collections.singletonList(metadata.getNamespace())).orElse(Collections.emptyList()); + static List metaNamespaceIndexFunc(HasMetadata obj) { + return Optional.ofNullable(obj) + .map(hm -> List.of(hm.getMetadata().getNamespace())) + .orElse(Collections.emptyList()); } } diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/informers/cache/ItemStore.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/informers/cache/ItemStore.java index b9cdce82f72..3708b23565c 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/informers/cache/ItemStore.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/informers/cache/ItemStore.java @@ -25,10 +25,10 @@ * all entries until they are deleted. At its simplest this is just a map coupled with a key function. *

* Modifications to this store once the informer is running, by anything other than the informer will alter the event stream. If - * for example an item is not found, an subsequent update from the api version will send notifications to + * for example an item is not found, any subsequent update from the api version will send notifications to * {@link ResourceEventHandler}s as an add. *

- * Direct modifications to this store by anything other than the informer will not updated indexes nor emit events. + * Direct modifications to this store by anything other than the informer will not update indexes nor emit events. *

* The implementation should be safe with respect to concurrency. Modifications from the informer * will be single threaded, but not necessarily the same thread. Reads may be concurrent with writes. @@ -60,8 +60,6 @@ public interface ItemStore { *
* If false, then the initial add events must be processed as they * occur - meaning that the store state may not be complete. - * - * @return */ default boolean isFullState() { return true; diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/informers/cache/ReducedStateItemStore.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/informers/cache/ReducedStateItemStore.java index 3858d5753a3..2f581b3d55b 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/informers/cache/ReducedStateItemStore.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/informers/cache/ReducedStateItemStore.java @@ -37,11 +37,12 @@ public class ReducedStateItemStore implements ItemStore { private static final String METADATA = "metadata"; + private static final Object[] NOT_FOUND_KEY_VALUE = new Object[1]; private final ConcurrentHashMap store = new ConcurrentHashMap<>(); private final List fields = new ArrayList<>(); private final Class typeClass; private final KeyState keyState; - private KubernetesSerialization serialization; + private final KubernetesSerialization serialization; public static class KeyState { @@ -64,17 +65,20 @@ public KeyState(Function keyFunction, Function { - int index = k.indexOf("/"); + int index = k.indexOf('/'); if (index == -1) { return new String[] { null, k }; } return new String[] { k.substring(0, index), k.substring(index + 1) }; - }, new String[] { METADATA, "namespace" }, new String[] { METADATA, "name" }); + }, new String[] { METADATA, NAMESPACE }, new String[] { METADATA, NAME }); + private static final String UID = "uid"; public static final KeyState UID_KEY_STATE = new KeyState(Cache::metaUidKeyFunc, - k -> new String[] { k }, new String[] { METADATA, "uid" }); + k -> new String[] { k }, new String[] { METADATA, UID }); /** * Create a state store with only the fields specified. @@ -106,14 +110,15 @@ public ReducedStateItemStore(KeyState keyState, Class typeClass, KubernetesSe this.keyState = keyState; fields.add(new String[] { METADATA, "resourceVersion" }); if (valueFields != null) { - for (int i = 0; i < valueFields.length; i++) { - fields.add(valueFields[i].split("\\.")); + for (String valueField : valueFields) { + fields.add(valueField.split("\\.")); } } this.typeClass = typeClass; this.serialization = serialization; } + @SuppressWarnings("unchecked") Object[] store(V value) { if (value == null) { return null; @@ -134,6 +139,7 @@ V restore(String key, Object[] values) { return serialization.convertValue(raw, typeClass); } + @SuppressWarnings("unchecked") private static void applyFields(Object[] values, Map raw, List fields) { for (int i = 0; i < fields.size(); i++) { Object value = values[i]; @@ -175,7 +181,7 @@ public V get(String key) { } public String getResourceVersion(String key) { - return (String) store.getOrDefault(key, new Object[1])[0]; + return (String) store.getOrDefault(key, NOT_FOUND_KEY_VALUE)[0]; } @Override diff --git a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/informers/cache/ReducedStateItemStoreTest.java b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/informers/cache/ReducedStateItemStoreTest.java index eab49d741bd..f901a56d4ad 100644 --- a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/informers/cache/ReducedStateItemStoreTest.java +++ b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/informers/cache/ReducedStateItemStoreTest.java @@ -34,6 +34,8 @@ void testStoreRestore() { Pod pod = new PodBuilder().withNewSpec().endSpec().withNewMetadata().withUid("x").withName("y").addToLabels("one", "1") .addToLabels("two", "2").withResourceVersion("2").endMetadata().withNewStatus().endStatus().build(); + final var uid = pod.getMetadata().getUid(); + Object[] values = store.store(pod); assertEquals(3, values.length); @@ -41,18 +43,18 @@ void testStoreRestore() { assertEquals(pod.getMetadata().getLabels(), values[1]); assertNull(values[2]); - Pod restored = store.restore("x", values); + Pod restored = store.restore(uid, values); assertNull(restored.getSpec()); assertNull(restored.getStatus()); - assertEquals("x", restored.getMetadata().getUid()); + assertEquals(uid, restored.getMetadata().getUid()); assertEquals(pod.getMetadata().getLabels(), restored.getMetadata().getLabels()); - assertNull(store.put("x", pod)); - assertNotNull(store.get("x")); - assertEquals("2", store.getResourceVersion("x")); + assertNull(store.put(uid, pod)); + assertNotNull(store.get(uid)); + assertEquals("2", store.getResourceVersion(uid)); assertEquals(1, store.size()); - assertNotNull(store.remove("x")); + assertNotNull(store.remove(uid)); } } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/informers/impl/cache/CacheImpl.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/informers/impl/cache/CacheImpl.java index 6e9b8659868..8f4f0cf6ba5 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/informers/impl/cache/CacheImpl.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/informers/impl/cache/CacheImpl.java @@ -16,11 +16,9 @@ package io.fabric8.kubernetes.client.informers.impl.cache; import io.fabric8.kubernetes.api.model.HasMetadata; -import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.client.informers.cache.BasicItemStore; import io.fabric8.kubernetes.client.informers.cache.Cache; import io.fabric8.kubernetes.client.informers.cache.ItemStore; -import io.fabric8.kubernetes.client.utils.Utils; import java.util.ArrayList; import java.util.Collections; @@ -45,36 +43,14 @@ */ public class CacheImpl implements Cache { - private static class Index { - private Map> values = new ConcurrentHashMap>(); - - public void update(String indexKey, String key, boolean remove) { - if (remove) { - values.computeIfPresent(indexKey == null ? this : indexKey, (k, v) -> { - v.remove(key); - return v.isEmpty() ? null : v; - }); - } else { - values.computeIfAbsent(indexKey == null ? this : indexKey, k -> ConcurrentHashMap.newKeySet()).add(key); - } - } - - public Set get(String indexKey) { - return values.getOrDefault(indexKey == null ? this : indexKey, Collections.emptySet()); - } - } - // NAMESPACE_INDEX is the default index function for caching objects public static final String NAMESPACE_INDEX = "namespace"; - // indexers stores index functions by their names private final Map>> indexers = Collections.synchronizedMap(new HashMap<>()); - - // items stores object instances - private ItemStore items; - // indices stores objects' key by their indices private final ConcurrentMap indices = new ConcurrentHashMap<>(); + // items stores object instances + private ItemStore items; public CacheImpl() { this(NAMESPACE_INDEX, Cache::metaNamespaceIndexFunc, Cache::metaNamespaceKeyFunc); @@ -85,6 +61,30 @@ public CacheImpl(String indexName, Function> indexFunc, Function addIndexFunc(indexName, indexFunc); } + /** + * @deprecated use {@link Cache#metaNamespaceKeyFunc(HasMetadata)} instead + */ + public static String metaNamespaceKeyFunc(Object obj) { + if (obj == null) { + return ""; + } + return Cache.metaNamespaceKeyFunc((HasMetadata) obj); + } + + /** + * @deprecated Use {@link Cache#namespaceKeyFunc(String, String)} instead + */ + public static String namespaceKeyFunc(String objectNamespace, String objectName) { + return Cache.namespaceKeyFunc(objectNamespace, objectName); + } + + /** + * @deprecated Use {@link Cache#metaNamespaceKeyFunc(HasMetadata)} instead + */ + public static List metaNamespaceIndexFunc(Object obj) { + return Cache.metaNamespaceIndexFunc((HasMetadata) obj); + } + public void setItemStore(ItemStore items) { this.items = items; } @@ -263,7 +263,6 @@ public List byIndex(String indexName, String indexKey) { * UpdateIndices modifies the objects location in the managed indexes, if there is * an update, you must provide an oldObj * - * * @param oldObj old object * @param newObj new object * @param key the key @@ -312,63 +311,6 @@ public synchronized CacheImpl addIndexFunc(String indexName, Function metaNamespaceIndexFunc(Object obj) { - final ObjectMeta metadata; - if (obj instanceof HasMetadata) { - metadata = ((HasMetadata) obj).getMetadata(); - } else if (obj instanceof ObjectMeta) { - metadata = (ObjectMeta) obj; - } else { - metadata = null; - } - return metadata == null ? Collections.emptyList() : Collections.singletonList(metadata.getNamespace()); - } - @Override public synchronized void removeIndexer(String name) { this.indices.remove(name); @@ -383,4 +325,23 @@ public Object getLockObject() { return this; } + private static class Index { + private final Map> values = new ConcurrentHashMap<>(); + + public void update(String indexKey, String key, boolean remove) { + if (remove) { + values.computeIfPresent(indexKey == null ? this : indexKey, (k, v) -> { + v.remove(key); + return v.isEmpty() ? null : v; + }); + } else { + values.computeIfAbsent(indexKey == null ? this : indexKey, k -> ConcurrentHashMap.newKeySet()).add(key); + } + } + + public Set get(String indexKey) { + return values.getOrDefault(indexKey == null ? this : indexKey, Collections.emptySet()); + } + } + }