fix-2148: reload issue#2164
Conversation
Signed-off-by: wind57 <[email protected]>
| * limitations under the License. | ||
| */ | ||
|
|
||
| package org.springframework.cloud.kubernetes.commons.config; |
There was a problem hiding this comment.
the actual fix is made from two parts. this is part 1.
introduce a new abstraction ConfigMapPropertySource ( we already have this one for secrets ).
Every property source that is derived from configmap will extend this one; and also every type that is derived from a secret will extend the SecretsPropertySource ( again, which we already have )
|
|
||
| import org.springframework.cloud.bootstrap.config.BootstrapPropertySource; | ||
| import org.springframework.cloud.bootstrap.config.PropertySourceLocator; | ||
| import org.springframework.cloud.kubernetes.commons.config.ConfigMapPropertySource; |
There was a problem hiding this comment.
this is part 2 of the fix and this is what I am doing:
in the reload method, we always receive a certain type ( I mean the argument for existingSourcesType ). It's either Fabric8SecretsPropertySource.class / KubernetesClientSecretsPropertySource.class or Fabric8ConfigMapPropertySource.class / KubernetesClientConfigMapPropertySource.class.
Let's suppose we got the Fabric8ConfigMapPropertySource.class here as the type ( exactly as in the bug OP opened ). We would have taken two property sources as such:
- an instance of
Fabric8ConfigMapPropertySource - an instance of
MountSecretPropertySource
though, the change that triggered this was caused by a config map change, so secrets ( and you pointed out to me in the bug details Ryan ) makes little sense.
As such, I introduced that extra abstraction : ConfigMapPropertySource and now can do :
else if (source instanceof MountConfigMapPropertySource mountConfigMapPropertySource
&& ConfigMapPropertySource.class.isAssignableFrom(sourceClass)) {
// we know that the type is correct here
managedSources.add((S) mountConfigMapPropertySource);
}
else if (source instanceof MountSecretPropertySource mountSecretPropertySource
&& SecretsPropertySource.class.isAssignableFrom(sourceClass)) {
// we know that the type is correct here
managedSources.add((S) mountSecretPropertySource);
}
so that the MountSecretPropertySource is not taken.
|
@ryanjbaxter this is ready, I've tested it against the bug issue that was opened |
There was a problem hiding this comment.
Pull request overview
This PR addresses a config reload issue (fix-2148) by introducing a common ConfigMapPropertySource base type and adjusting how ConfigReloadUtil.findPropertySources(...) selects mount-based property sources during reload comparisons.
Changes:
- Added
ConfigMapPropertySourceas a shared base class for configmap-backedPropertySources. - Updated
MountConfigMapPropertySourceandSourceDataEntriesProcessorto extendConfigMapPropertySource. - Tightened
ConfigReloadUtil.findPropertySources(...)matching rules and expanded unit tests around mount/configmap/secret selection behavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
spring-cloud-kubernetes-commons/src/test/java/.../ConfigReloadUtilTests.java |
Updates/extends tests for findPropertySources behavior with mount/configmap/secret sources. |
spring-cloud-kubernetes-commons/src/main/java/.../reload/ConfigReloadUtil.java |
Adds conditional matching for mount sources based on configmap/secret type hierarchies. |
spring-cloud-kubernetes-commons/src/main/java/.../config/SourceDataEntriesProcessor.java |
Switches to extending the new ConfigMapPropertySource. |
spring-cloud-kubernetes-commons/src/main/java/.../config/MountConfigMapPropertySource.java |
Switches to extending the new ConfigMapPropertySource. |
spring-cloud-kubernetes-commons/src/main/java/.../config/ConfigMapPropertySource.java |
Introduces the new shared base class for configmap property sources. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| else if (source instanceof MountConfigMapPropertySource mountConfigMapPropertySource | ||
| && ConfigMapPropertySource.class.isAssignableFrom(sourceClass)) { | ||
| // we know that the type is correct here | ||
| managedSources.add((S) mountConfigMapPropertySource); | ||
| } | ||
| else if (source instanceof MountSecretPropertySource mountSecretPropertySource) { | ||
| else if (source instanceof MountSecretPropertySource mountSecretPropertySource | ||
| && SecretsPropertySource.class.isAssignableFrom(sourceClass)) { | ||
| // we know that the type is correct here | ||
| managedSources.add((S) mountSecretPropertySource); |
There was a problem hiding this comment.
findPropertySources(Class<S> ...) can now add MountConfigMapPropertySource / MountSecretPropertySource even when sourceClass is a more specific subtype (e.g. Fabric8ConfigMapPropertySource). That violates the method’s generic contract (returning a List<S> that may contain elements not assignable to S) and can trigger ClassCastException in callers that use List<Fabric8ConfigMapPropertySource> (there are such call sites in tests). Consider either: (1) changing reload call sites to pass ConfigMapPropertySource.class / SecretsPropertySource.class so plain sourceClass.isInstance works and you can remove these unsafe branches, or (2) changing the method signature/return type to not claim List<S> when it can return other implementations.
There was a problem hiding this comment.
copilot here is correct. I never took a closer look here, but there is a minor issue. The thing is, this works because we only put elements in that list ( and it works due to type erasure ), but otherwise the pattern is pretty broken here.
I am looking how to properly fix it.
Signed-off-by: wind57 <[email protected]>
Signed-off-by: wind57 <[email protected]>
|
@ryanjbaxter can you re-trigger copilot here please? I will explain what I am fixing and how after I review his review |
Signed-off-by: wind57 <[email protected]>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: wind57 <[email protected]>
Signed-off-by: wind57 <[email protected]>
|
|
||
| @BeforeAll | ||
| static void beforeAll() { | ||
| wireMockServer = new WireMockServer(options().dynamicPort()); |
There was a problem hiding this comment.
these tests here are exactly as in the bug description
| @Deprecated(forRemoval = false) | ||
| @SuppressWarnings("unchecked") | ||
| public static <S extends PropertySource<?>> List<S> findPropertySources(Class<S> sourceClass, | ||
| public static <S extends MapPropertySource> List<MapPropertySource> findPropertySources(Class<S> sourceClass, |
There was a problem hiding this comment.
I've changed the method generics type a little. It was a bug, really. It was a classic "heap pollution" where we could put entries in this List and after that it was completely useless: you could not instantiate it properly and when taking elements out, it would throw a ClassCastException.
We were only comparing size of it all the time, that is why it did not fail until now. Still, I think its worth to change it properly.
| return new Fabric8ConfigMapPropertySource(context); | ||
| } | ||
|
|
||
| public static Fabric8SecretsPropertySource secretPropertySource(KubernetesClient kubernetesClient) { |
There was a problem hiding this comment.
I don't want to change the visibility of Fabric8SecretsPropertySource and also ConfigReloadUtil::findPropertySources is not public in main, so I need to create this indirection to be able to access them
There was a problem hiding this comment.
Could you just add a comment to the class explaining its existance?
There was a problem hiding this comment.
done. I have a PR that also merges 3.3.x into main, I'll wait until 3.3.x passes, then merge it, then will tag you when the PR is ready. It's just that there are deletions there and it would be easier for me to do it and take that burned off you
There was a problem hiding this comment.
Thanks I was just looking at the merge and it is terrible LOL
Signed-off-by: wind57 <[email protected]>
|
@ryanjbaxter fixed all copilot comments, its good to look at. thank you |
Signed-off-by: wind57 <[email protected]>
No description provided.