/*
* Copyright 2013-2015 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
*
* http://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.netflix.turbine;
import com.netflix.config.DynamicBooleanProperty;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.config.DynamicStringProperty;
import com.netflix.turbine.data.DataFromSingleInstance;
import com.netflix.turbine.discovery.Instance;
import com.netflix.turbine.handler.PerformanceCriteria;
import com.netflix.turbine.monitor.MonitorConsole;
import com.netflix.turbine.monitor.cluster.AggregateClusterMonitor;
import com.netflix.turbine.monitor.cluster.ObservationCriteria;
import com.netflix.turbine.monitor.instance.InstanceUrlClosure;
/**
* @author Spencer Gibb
*/
public class SpringClusterMonitor extends AggregateClusterMonitor {
// TODO: convert to ConfigurationProperties (how to do per-cluster configuration?
public SpringClusterMonitor(String name, String clusterName) {
super(name, new ObservationCriteria.ClusterBasedObservationCriteria(clusterName),
new PerformanceCriteria.AggClusterPerformanceCriteria(clusterName),
new MonitorConsole<DataFromSingleInstance>(), InstanceMonitorDispatcher,
SpringClusterMonitor.ClusterConfigBasedUrlClosure);
}
/**
* TODO: make this a template of some kind (secure, management port, etc...) Helper
* class that decides how to connect to a server based on injected config. Note that
* the cluster name must be provided here since one can have different configs for
* different clusters
*/
public static InstanceUrlClosure ClusterConfigBasedUrlClosure = new InstanceUrlClosure() {
private final DynamicStringProperty defaultUrlClosureConfig = DynamicPropertyFactory
.getInstance().getStringProperty("turbine.instanceUrlSuffix",
"hystrix.stream");
private final DynamicBooleanProperty instanceInsertPort = DynamicPropertyFactory
.getInstance().getBooleanProperty("turbine.instanceInsertPort", true);
@Override
public String getUrlPath(Instance host) {
if (host.getCluster() == null) {
throw new RuntimeException(
"Host must have cluster name in order to use ClusterConfigBasedUrlClosure");
}
// find url
String key = "turbine.instanceUrlSuffix." + host.getCluster();
DynamicStringProperty urlClosureConfig = DynamicPropertyFactory.getInstance()
.getStringProperty(key, null);
String url = urlClosureConfig.get();
if (url == null) {
url = this.defaultUrlClosureConfig.get();
}
if (url == null) {
throw new RuntimeException("Config property: "
+ urlClosureConfig.getName() + " or "
+ this.defaultUrlClosureConfig.getName() + " must be set");
}
// find port and scheme
String port;
String scheme;
if (host.getAttributes().containsKey("securePort")) {
port = host.getAttributes().get("securePort");
scheme = "https";
} else {
port = host.getAttributes().get("port");
scheme = "http";
}
if (host.getAttributes().containsKey("fusedHostPort")) {
return String.format("%s://%s/%s", scheme, host.getAttributes().get("fusedHostPort"), url);
}
// determine if to insert port
String insertPortKey = "turbine.instanceInsertPort." + host.getCluster();
DynamicStringProperty insertPortProp = DynamicPropertyFactory.getInstance()
.getStringProperty(insertPortKey, null);
boolean insertPort;
if (insertPortProp.get() == null) {
insertPort = this.instanceInsertPort.get();
}
else {
insertPort = Boolean.parseBoolean(insertPortProp.get());
}
// format url with port
if (insertPort) {
if (url.startsWith("/")) {
url = url.substring(1);
}
if (port == null) {
throw new RuntimeException(
"Configured to use port, but port or securePort is not in host attributes");
}
return String.format("%s://%s:%s/%s", scheme, host.getHostname(), port, url);
}
//format url without port
return scheme + "://" + host.getHostname() + url;
}
};
}