package org.springframework.cloud.netflix.ribbon;
import java.net.URI;
import org.springframework.web.util.UriComponentsBuilder;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.IClientConfig;
import com.netflix.config.ConfigurationManager;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.config.DynamicStringProperty;
import com.netflix.loadbalancer.Server;
/**
* @author Spencer Gibb
* @author Jacques-Etienne Beaudet
*/
public class RibbonUtils {
public static final String VALUE_NOT_SET = "__not__set__";
public static final String DEFAULT_NAMESPACE = "ribbon";
public static void setRibbonProperty(String serviceId, String suffix, String value) {
// how to set the namespace properly?
String key = getRibbonKey(serviceId, suffix);
DynamicStringProperty property = getProperty(key);
if (property.get().equals(VALUE_NOT_SET)) {
ConfigurationManager.getConfigInstance().setProperty(key, value);
}
}
public static String getRibbonKey(String serviceId, String suffix) {
return serviceId + "." + DEFAULT_NAMESPACE + "." + suffix;
}
public static DynamicStringProperty getProperty(String key) {
return DynamicPropertyFactory.getInstance().getStringProperty(key, VALUE_NOT_SET);
}
/**
* Determine if client is secure. If the supplied {@link IClientConfig} has the {@link CommonClientConfigKey#IsSecure}
* set, return that value. Otherwise, query the supplied {@link ServerIntrospector}.
* @param config the supplied client configuration.
* @param serverIntrospector
* @param server
* @return true if the client is secure
*/
public static boolean isSecure(IClientConfig config, ServerIntrospector serverIntrospector, Server server) {
if (config != null) {
Boolean isSecure = config.get(CommonClientConfigKey.IsSecure);
if (isSecure != null) {
return isSecure;
}
}
return serverIntrospector.isSecure(server);
}
/**
* Replace the scheme to https if needed. If the uri doesn't start with https and
* {@link #isSecure(IClientConfig, ServerIntrospector, Server)} is true, update the scheme.
* This assumes the uri is already encoded to avoid double encoding.
*
* @param uri
* @param config
* @param serverIntrospector
* @param server
* @return
*/
public static URI updateToHttpsIfNeeded(URI uri, IClientConfig config, ServerIntrospector serverIntrospector,
Server server) {
String scheme = uri.getScheme();
if (!"".equals(uri.toString()) && !"https".equals(scheme) && isSecure(config, serverIntrospector, server)) {
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUri(uri).scheme("https");
if (uri.getRawQuery() != null) {
// When building the URI, UriComponentsBuilder verify the allowed characters and does not
// support the '+' so we replace it for its equivalent '%20'.
// See issue https://jira.spring.io/browse/SPR-10172
uriComponentsBuilder.replaceQuery(uri.getRawQuery().replace("+", "%20"));
}
return uriComponentsBuilder.build(true).toUri();
}
return uri;
}
}