package org.springframework.cloud.localconfig;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import org.springframework.cloud.service.UriBasedServiceData;
public final class LocalConfigUtil {
private static final Logger logger = Logger.getLogger(LocalConfigConnector.class.getName());
private LocalConfigUtil() {
}
static List<UriBasedServiceData> readServicesData(LinkedHashMap<String, Properties> propertySources) {
// we'll turn this into KVPs to return but need to eliminate duplicates first
Map<String, String> collectedServices = new HashMap<String, String>();
// iterate over the property sources in order, extracting matching properties
for (Map.Entry<String, Properties> propertySource : propertySources.entrySet()) {
if (propertySource.getValue().isEmpty()) {
logger.info("no " + propertySource.getKey());
continue;
}
logger.info("reading services from " + propertySource.getKey());
Map<String, String> services = readServices(propertySource.getValue());
// add each of the found services to the list, warning about duplicates
for (Map.Entry<String, String> service : services.entrySet()) {
String oldUri = collectedServices.put(service.getKey(), service.getValue());
if (oldUri == null)
logger.info("added service '" + service.getKey() + "' from " + propertySource.getKey());
else
logger.warning("replaced service '" + service.getKey() + "' with new URI from " + propertySource.getKey());
}
}
// now we have a collated set of service IDs and URIs
List<UriBasedServiceData> serviceData = new ArrayList<UriBasedServiceData>(collectedServices.size());
for (Map.Entry<String, String> serviceInfo : collectedServices.entrySet()) {
serviceData.add(new UriBasedServiceData(serviceInfo.getKey(), serviceInfo.getValue()));
}
return serviceData;
}
/**
* Goes through a {@code Properties} object, finding all service definitions (properties
* prefixed with {@code spring.cloud.} but not in {@code META_PROPERTIES}) and collects {@code (id,URI)} pairs.
*
* @param properties the {@code Properties} object to read
* @return all of the service definitions found
*/
static Map<String, String> readServices(Properties properties) {
Map<String, String> services = new HashMap<String, String>();
for (String propertyName : properties.stringPropertyNames()) {
if (LocalConfigConnector.META_PROPERTIES.contains(propertyName)) {
logger.finer("skipping meta property " + propertyName);
continue;
}
Matcher m = LocalConfigConnector.SERVICE_PROPERTY_PATTERN.matcher(propertyName);
if (!m.matches()) {
logger.finest("skipping non-Spring-Cloud property " + propertyName);
continue;
}
String serviceId = m.group(1);
String serviceUri = properties.getProperty(propertyName);
// no URI here because they will contain passwords
logger.fine("found service URI for service " + serviceId);
services.put(serviceId, serviceUri);
}
return services;
}
}