-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(config-server): add MongoDB environment repository support
This commit introduces MongoDB as a new backend option for the Spring Cloud Config Server, enabling users to store and manage their configuration properties in a MongoDB database.
- Loading branch information
Showing
8 changed files
with
637 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
...ava/org/springframework/cloud/config/server/environment/MongoDbEnvironmentProperties.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/* | ||
* Copyright 2018-2019 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.springframework.cloud.config.server.environment; | ||
|
||
import org.springframework.boot.context.properties.ConfigurationProperties; | ||
import org.springframework.cloud.config.server.support.EnvironmentRepositoryProperties; | ||
import org.springframework.core.Ordered; | ||
|
||
/** | ||
* Properties related to MongoDB environment repository. | ||
* | ||
* @author Alexandros Pappas | ||
*/ | ||
@ConfigurationProperties("spring.cloud.config.server.mongodb") | ||
public class MongoDbEnvironmentProperties implements EnvironmentRepositoryProperties { | ||
|
||
/** | ||
* Flag to indicate that MongoDB environment repository configuration is enabled. | ||
*/ | ||
private boolean enabled = true; | ||
|
||
/** | ||
* Order of the MongoDB environment repository. | ||
*/ | ||
private int order = Ordered.LOWEST_PRECEDENCE - 10; | ||
|
||
/** | ||
* Name of the MongoDB collection to query for configuration properties. | ||
*/ | ||
private String collection = "properties"; | ||
|
||
/** | ||
* Flag to determine how to handle query exceptions. | ||
*/ | ||
private boolean failOnError = true; | ||
|
||
/** | ||
* Default label to use if none is specified. | ||
*/ | ||
private String defaultLabel = "master"; | ||
|
||
public boolean isEnabled() { | ||
return enabled; | ||
} | ||
|
||
public void setEnabled(boolean enabled) { | ||
this.enabled = enabled; | ||
} | ||
|
||
public int getOrder() { | ||
return order; | ||
} | ||
|
||
@Override | ||
public void setOrder(int order) { | ||
this.order = order; | ||
} | ||
|
||
public String getCollection() { | ||
return collection; | ||
} | ||
|
||
public void setCollection(String collection) { | ||
this.collection = collection; | ||
} | ||
|
||
public boolean isFailOnError() { | ||
return failOnError; | ||
} | ||
|
||
public void setFailOnError(boolean failOnError) { | ||
this.failOnError = failOnError; | ||
} | ||
|
||
public String getDefaultLabel() { | ||
return defaultLabel; | ||
} | ||
|
||
public void setDefaultLabel(String defaultLabel) { | ||
this.defaultLabel = defaultLabel; | ||
} | ||
|
||
} |
128 changes: 128 additions & 0 deletions
128
...ava/org/springframework/cloud/config/server/environment/MongoDbEnvironmentRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
/* | ||
* Copyright 2018-2019 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.springframework.cloud.config.server.environment; | ||
|
||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import java.util.stream.Collectors; | ||
|
||
import com.mongodb.MongoException; | ||
import org.apache.commons.logging.Log; | ||
import org.apache.commons.logging.LogFactory; | ||
|
||
import org.springframework.cloud.config.environment.Environment; | ||
import org.springframework.cloud.config.environment.PropertySource; | ||
import org.springframework.core.Ordered; | ||
import org.springframework.dao.DataAccessException; | ||
import org.springframework.data.mongodb.core.MongoTemplate; | ||
import org.springframework.data.mongodb.core.query.Criteria; | ||
import org.springframework.data.mongodb.core.query.Query; | ||
import org.springframework.util.StringUtils; | ||
|
||
/** | ||
* @author Alexandros Pappas | ||
*/ | ||
public class MongoDbEnvironmentRepository implements EnvironmentRepository, Ordered { | ||
|
||
private static final Log logger = LogFactory.getLog(JdbcEnvironmentRepository.class); | ||
|
||
private final MongoTemplate mongoTemplate; | ||
|
||
private final MongoDbEnvironmentProperties properties; | ||
|
||
public MongoDbEnvironmentRepository(MongoTemplate mongoTemplate, MongoDbEnvironmentProperties properties) { | ||
this.mongoTemplate = mongoTemplate; | ||
this.properties = properties; | ||
} | ||
|
||
@Override | ||
public Environment findOne(String application, String profile, String label) { | ||
label = Optional.ofNullable(label).filter(StringUtils::hasText).orElse(this.properties.getDefaultLabel()); | ||
profile = Optional.ofNullable(profile).filter(StringUtils::hasText).orElse("default"); | ||
|
||
// Prepare the environment with applications and profiles | ||
String[] profilesArray = StringUtils.commaDelimitedListToStringArray(profile); | ||
Environment environment = new Environment(application, profilesArray, label, null, null); | ||
|
||
// Prepend "application," to config if not already present | ||
String config = application.startsWith("application") ? application : "application," + application; | ||
|
||
List<String> applications = Arrays.stream(StringUtils.commaDelimitedListToStringArray(config)).distinct() | ||
.collect(Collectors.toList()); | ||
List<String> profiles = Arrays.stream(profilesArray).distinct().collect(Collectors.toList()); | ||
|
||
// Reverse for the intended processing order | ||
Collections.reverse(applications); | ||
Collections.reverse(profiles); | ||
|
||
// Add property sources for each combination of application and profile | ||
for (String env : profiles) { | ||
for (String app : applications) { | ||
addPropertySource(environment, app, env, label); | ||
} | ||
} | ||
// add properties without profile, equivalent to foo.yml, application.yml | ||
for (String app : applications) { | ||
addPropertySource(environment, app, null, label); | ||
} | ||
return environment; | ||
} | ||
|
||
private void addPropertySource(Environment environment, String application, String profile, String label) { | ||
try { | ||
Criteria criteria = Criteria.where("application").is(application).and("label").is(label); | ||
if (profile != null) { | ||
criteria = criteria.and("profile").is(profile); | ||
} | ||
else { | ||
// Handling properties without profile by explicitly looking for them | ||
criteria = criteria.andOperator(Criteria.where("profile").is(null)); | ||
} | ||
|
||
Query query = new Query(criteria); | ||
List<Map> propertyMaps = this.mongoTemplate.find(query, Map.class, this.properties.getCollection()); | ||
|
||
for (Map propertyMap : propertyMaps) { | ||
String propertySourceName = (profile != null) ? application + "-" + profile : application; | ||
@SuppressWarnings("unchecked") | ||
Map<String, Object> source = (Map<String, Object>) propertyMap.get("properties"); | ||
if (source != null && !source.isEmpty()) { | ||
environment.add(new PropertySource(propertySourceName, source)); | ||
} | ||
} | ||
} | ||
catch (DataAccessException | MongoException e) { | ||
if (!this.properties.isFailOnError()) { | ||
if (logger.isDebugEnabled()) { | ||
logger.debug("Failed to retrieve configuration from MongoDB", e); | ||
} | ||
} | ||
else { | ||
throw e; | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public int getOrder() { | ||
return this.properties.getOrder(); | ||
} | ||
|
||
} |
40 changes: 40 additions & 0 deletions
40
.../springframework/cloud/config/server/environment/MongoDbEnvironmentRepositoryFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
* Copyright 2018-2019 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.springframework.cloud.config.server.environment; | ||
|
||
import org.springframework.data.mongodb.core.MongoTemplate; | ||
|
||
/** | ||
* Factory for creating instances of MongoDbEnvironmentRepository. | ||
* | ||
* @author Alexandros Pappas | ||
*/ | ||
public class MongoDbEnvironmentRepositoryFactory | ||
implements EnvironmentRepositoryFactory<MongoDbEnvironmentRepository, MongoDbEnvironmentProperties> { | ||
|
||
private final MongoTemplate mongoTemplate; | ||
|
||
public MongoDbEnvironmentRepositoryFactory(MongoTemplate mongoTemplate) { | ||
this.mongoTemplate = mongoTemplate; | ||
} | ||
|
||
@Override | ||
public MongoDbEnvironmentRepository build(MongoDbEnvironmentProperties environmentProperties) { | ||
return new MongoDbEnvironmentRepository(this.mongoTemplate, environmentProperties); | ||
} | ||
|
||
} |
Oops, something went wrong.