Traditionally we use property files to load properties like
<context:property-placeholder location="/WEB-INF/database.properties" ignore-unresolvable="true" ignore-resource-not-found="true"/>
So if you place the property file inside the server you need to re- deploy every time we did a change in the property values
The work around is place a property file in a remote location like Amazon S3 or a database
import java.io.StringWriter;
import java.util.Properties;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectInputStream;
public class CustomPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
@Override
protected void loadProperties(final Properties props) throws IOException {
props.putAll(getProperties("database.properties"));
}
private Properties getProperties(String key) throws IOException{
String accessKey = "XXXXXX";
String secretKey = "YYYYYYYYYYY";
String bucketName = "ZZZZZZZZZ";
AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey,secretKey);
AmazonS3 client=new AmazonS3Client(awsCredentials);
S3Object object = client.getObject(bucketName, key);
S3ObjectInputStream objectContent = object.getObjectContent();
StringWriter writer=new StringWriter();
IOUtils.copy(objectContent, writer);
return PropertiesConverter.stringToProperties(writer.toString());
}
}
import java.io.IOException;
import java.io.StringReader;
import java.util.Properties;
import org.springframework.util.DefaultPropertiesPersister;
import org.springframework.util.PropertiesPersister;
import org.springframework.util.StringUtils;
public final class PropertiesConverter {
private static final PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();
// prevents the class from being instantiated
private PropertiesConverter() {
};
public static Properties stringToProperties(String stringToParse) {
if (stringToParse == null) {
return new Properties();
}
if (!contains(stringToParse, "\n")) {
return StringUtils.splitArrayElementsIntoProperties(StringUtils
.commaDelimitedListToStringArray(stringToParse), "=");
}
StringReader stringReader = new StringReader(stringToParse);
Properties properties = new Properties();
try {
propertiesPersister.load(properties, stringReader);
}
catch (IOException ex) {
throw new IllegalStateException("Error while trying to parse String to java.util.Properties,"
+ " given String: " + properties);
}
return properties;
}
private static boolean contains(String str, String searchStr) {
return str.indexOf(searchStr) != -1;
}
}
You can invoke from spring config like
<bean id="placeholderPropertiesDatabase" class="xxx.xxxxxxxxxx.CustomPropertyPlaceholderConfigurer" >
<property name="order" value="1" />
</bean>
Also you can edit the CustomPropertyPlaceholderConfigurer.java loadProperties method to load properties from RDBMS or NoSQL Database
No comments:
Post a Comment