From b10bf9c305c4f485e7437a2c3296d08608daae2c Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Fri, 25 Sep 2015 17:08:15 -0600 Subject: [PATCH] Use eureka securePort if enabled for turbine http aggregation. fixes gh-417 --- .../turbine/EurekaInstanceDiscovery.java | 12 +++- .../netflix/turbine/SpringClusterMonitor.java | 29 ++++++-- .../turbine/EurekaInstanceDiscoveryTest.java | 68 ++++++++++++++++--- 3 files changed, 93 insertions(+), 16 deletions(-) diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java index c854ea33..0955f255 100644 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java +++ b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java @@ -146,20 +146,30 @@ public class EurekaInstanceDiscovery implements InstanceDiscovery { Boolean status = parseInstanceStatus(instanceInfo.getStatus()); if (hostname != null && cluster != null && status != null) { Instance instance = new Instance(hostname, cluster, status); + + // add metadata Map metadata = instanceInfo.getMetadata(); if (metadata != null) { instance.getAttributes().putAll(metadata); } + + // add amazon metadata String asgName = instanceInfo.getASGName(); if (asgName != null) { instance.getAttributes().put("asg", asgName); } - instance.getAttributes().put("port", String.valueOf(instanceInfo.getPort())); DataCenterInfo dcInfo = instanceInfo.getDataCenterInfo(); if (dcInfo != null && dcInfo.getName().equals(DataCenterInfo.Name.Amazon)) { AmazonInfo amznInfo = (AmazonInfo) dcInfo; instance.getAttributes().putAll(amznInfo.getMetadata()); } + + // add ports + instance.getAttributes().put("port", String.valueOf(instanceInfo.getPort())); + boolean securePortEnabled = instanceInfo.isPortEnabled(InstanceInfo.PortType.SECURE); + if (securePortEnabled) { + instance.getAttributes().put("securePort", String.valueOf(instanceInfo.getSecurePort())); + } return instance; } else { diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringClusterMonitor.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringClusterMonitor.java index 2c881eb7..2013495d 100644 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringClusterMonitor.java +++ b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringClusterMonitor.java @@ -61,6 +61,8 @@ public class SpringClusterMonitor extends AggregateClusterMonitor { 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); @@ -73,6 +75,19 @@ public class SpringClusterMonitor extends AggregateClusterMonitor { + 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"; + } + + // determine if to insert port String insertPortKey = "turbine.instanceInsertPort." + host.getCluster(); DynamicStringProperty insertPortProp = DynamicPropertyFactory.getInstance() .getStringProperty(insertPortKey, null); @@ -83,18 +98,22 @@ public class SpringClusterMonitor extends AggregateClusterMonitor { else { insertPort = Boolean.parseBoolean(insertPortProp.get()); } + + // format url with port if (insertPort) { if (url.startsWith("/")) { url = url.substring(1); } - if (!host.getAttributes().containsKey("port")) { + if (port == null) { throw new RuntimeException( - "Configured to use port, but port is not in host attributes"); + "Configured to use port, but port or securePort is not in host attributes"); } - return String.format("http://%s:%s/%s", host.getHostname(), host - .getAttributes().get("port"), url); + + return String.format("%s://%s:%s/%s", scheme, host.getHostname(), port, url); } - return "http://" + host.getHostname() + url; + + //format url without port + return scheme + "://" + host.getHostname() + url; } }; diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTest.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTest.java index 90b26cd5..253f111d 100644 --- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTest.java +++ b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTest.java @@ -19,6 +19,8 @@ package org.springframework.cloud.netflix.turbine; import static org.mockito.Mockito.*; import com.netflix.discovery.EurekaClient; +import com.netflix.turbine.discovery.Instance; +import org.junit.Before; import org.junit.Test; import com.netflix.appinfo.InstanceInfo; @@ -30,26 +32,74 @@ import static org.junit.Assert.assertEquals; */ public class EurekaInstanceDiscoveryTest { + private EurekaClient eurekaClient; + private TurbineProperties turbineProperties; + private InstanceInfo.Builder builder; + + @Before + public void setUp() throws Exception { + eurekaClient = mock(EurekaClient.class); + turbineProperties = new TurbineProperties(); + builder = InstanceInfo.Builder.newBuilder(); + } + @Test public void testGetClusterName() { - EurekaClient eurekaClient = mock(EurekaClient.class); - String appName = "testAppName"; EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery( - new TurbineProperties(), eurekaClient); - InstanceInfo instanceInfo = InstanceInfo.Builder.newBuilder().setAppName(appName) + turbineProperties, eurekaClient); + String appName = "testAppName"; + InstanceInfo instanceInfo = builder.setAppName(appName) .build(); String clusterName = discovery.getClusterName(instanceInfo); assertEquals("clusterName is wrong", appName.toUpperCase(), clusterName); } + @Test + public void testGetPort() { + EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery( + turbineProperties, eurekaClient); + String appName = "testAppName"; + int port = 8080; + String hostName = "myhost"; + InstanceInfo instanceInfo = builder.setAppName(appName) + .setHostName(hostName) + .setPort(port) + .build(); + Instance instance = discovery.marshallInstanceInfo(instanceInfo); + assertEquals("port is wrong", String.valueOf(port), instance.getAttributes().get("port")); + + String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure.getUrlPath(instance); + assertEquals("url is wrong", "http://"+hostName+":"+port+"/hystrix.stream", urlPath); + } + + @Test + public void testGetSecurePort() { + EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery( + turbineProperties, eurekaClient); + String appName = "testAppName"; + int port = 8080; + int securePort = 8443; + String hostName = "myhost"; + InstanceInfo instanceInfo = builder.setAppName(appName) + .setHostName(hostName) + .setPort(port) + .setSecurePort(securePort) + .enablePort(InstanceInfo.PortType.SECURE, true) + .build(); + Instance instance = discovery.marshallInstanceInfo(instanceInfo); + assertEquals("port is wrong", String.valueOf(port), instance.getAttributes().get("port")); + assertEquals("securePort is wrong", String.valueOf(securePort), instance.getAttributes().get("securePort")); + + String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure.getUrlPath(instance); + assertEquals("url is wrong", "https://"+hostName+":"+securePort+"/hystrix.stream", urlPath); + } + @Test public void testGetClusterNameCustomExpression() { - EurekaClient eurekaClient = mock(EurekaClient.class); - TurbineProperties turbineProperties = new TurbineProperties(); turbineProperties.setClusterNameExpression("aSGName"); EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties, eurekaClient); String asgName = "myAsgName"; - InstanceInfo instanceInfo = InstanceInfo.Builder.newBuilder() + InstanceInfo instanceInfo = builder .setAppName("testApp").setASGName(asgName).build(); String clusterName = discovery.getClusterName(instanceInfo); assertEquals("clusterName is wrong", asgName, clusterName); @@ -57,12 +107,10 @@ public class EurekaInstanceDiscoveryTest { @Test public void testGetClusterNameInstanceMetadataMapExpression() { - EurekaClient eurekaClient = mock(EurekaClient.class); - TurbineProperties turbineProperties = new TurbineProperties(); turbineProperties.setClusterNameExpression("metadata['cluster']"); EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties, eurekaClient); String metadataProperty = "myCluster"; - InstanceInfo instanceInfo = InstanceInfo.Builder.newBuilder() + InstanceInfo instanceInfo = builder .setAppName("testApp").add("cluster", metadataProperty).build(); String clusterName = discovery.getClusterName(instanceInfo); assertEquals("clusterName is wrong", metadataProperty, clusterName);