Describe the bug I have 3 configurations for the vault repository and 1 for git setup under spring.cloud.config.server.composite.*. Client microservice passes multiple profiles while invoking the config server. The flow goes as below.
public class CompositeEnvironmentRepository implements EnvironmentRepository {
public Environment findOne(String application, String profile, String label, boolean includeOrigin) {
Environment env = new Environment(application, new String[] { profile }, label, null, null);
if (this.environmentRepositories.size() == 1) {
Environment envRepo = this.environmentRepositories.get(0)
.findOne(application, profile, label, includeOrigin);
env.addAll(envRepo.getPropertySources());
env.setVersion(envRepo.getVersion());
env.setState(envRepo.getState());
}
else {
for (EnvironmentRepository repo : environmentRepositories) {
try {
env.addAll(repo.findOne(application, profile, label, includeOrigin).getPropertySources());
}
catch (Exception e) {. // ****************EXCEPTION GET CAUGHT HERE****************
if (failOnError) {
throw e;
}
else {
log.info("Error adding environment for " + repo);
}
}
}
}
return env;
}
}
public abstract class AbstractVaultEnvironmentRepository implements EnvironmentRepository, Ordered {
@Override
public Environment findOne(String application, String profile, String label) {
if (ObjectUtils.isEmpty(profile)) {
profile = DEFAULT_PROFILE;
}
if (ObjectUtils.isEmpty(label)) {
label = defaultLabel;
}
var environment = new Environment(application, split(profile), label, null, getWatchState());
var profiles = normalize(profile, DEFAULT_PROFILE);
var applications = normalize(application, this.defaultKey);
for (String prof : profiles) {
for (String app : applications) {
var key = vaultKey(app, prof, label);
// read raw 'data' key from vault
String data = read(key); // EXCEPTION GET PROPOGATE HERE AND ENTIRE LOOP IS SKIPPED INSTEAD OF CONTINUE
if (data != null) {
// data is in json format of which, yaml is a superset, so parse
var yaml = new YamlPropertiesFactoryBean();
yaml.setResources(new ByteArrayResource(data.getBytes()));
var properties = yaml.getObject();
if (properties != null && !properties.isEmpty()) {
environment.add(new PropertySource("vault:" + key, properties));
}
}
}
}
return environment;
}
}
public class SpringVaultEnvironmentRepository extends AbstractVaultEnvironmentRepository {
protected String read(String key) {
VaultResponse response = this.keyValueTemplate.get(this.path + key); // 403 EXCEPTION NOT HANDLER HERE
if (response != null) {
try {
return objectMapper.writeValueAsString(response.getData());
}
catch (JsonProcessingException e) { // BUG HERE
throw new RuntimeException("Error creating Vault response", e);
}
}
return null;
}
}
}
abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSupport {
@Nullable
<T> T doRead(Function<RestOperations, ResponseEntity<T>> callback) {
return (T)this.vaultOperations.doWithSession((restOperations) -> {
try {
return ((ResponseEntity)callback.apply(restOperations)).getBody();
} catch (HttpStatusCodeException e) {
if (HttpStatusUtil.isNotFound(e.getStatusCode())) { // RETURN NULL ONLY FOR NOT FOUND ERROR
return null;
} else {
throw VaultResponses.buildException(e, this.path); // THROWS EXCEPTION FOR OTHER
}
}
});
}
}
Sample
Whenever a 403 Forriben error is sent, SpringVaultEnvironmentRepository-> read() couldn't handle it as it only handles JsonProcessException. This issue is causing a loss of the response received from the earlier executed repository. Can be reproduced on the latest version of the below jars
Comment From: ryanjbaxter
See the notes on failures when using a composite environment repository here.
https://docs.spring.io/spring-cloud-config/reference/server/environment-repository/composite-repositories.html
You can set a property to allow things to continue when one environment repository has a failure.
Comment From: himnay
Yes, this flag is already set to false spring.cloud.config.server.failOnCompositeError to false. The client doesn't get an error response, but the response is partially missing.
Comment From: ryanjbaxter
Can you provide a complete, minimal, verifiable sample that reproduces the problem? It should be available as a GitHub (or similar) project or attached to this issue as a zip file.
Comment From: spring-cloud-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: spring-cloud-issues
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.