diff --git a/docs/pom.xml b/docs/pom.xml index 8ff32cb88..1ea475814 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT + 3.0.0.BUILD-SNAPSHOT spring-cloud-netflix-docs pom @@ -15,14 +15,10 @@ spring-cloud-netflix 1.2.x,1.3.x,1.4.x - .*.eureka.*|.*.hystrix.*|.*.ribbon.*|.*.sidecar.*|.*.turbine.*|.*.zuul.*|.*.archaius.* + .*.eureka.* - - ${project.groupId} - spring-cloud-starter-netflix-archaius - ${project.groupId} spring-cloud-starter-netflix-eureka-client @@ -31,30 +27,6 @@ ${project.groupId} spring-cloud-starter-netflix-eureka-server - - ${project.groupId} - spring-cloud-starter-netflix-hystrix - - - ${project.groupId} - spring-cloud-starter-netflix-hystrix-dashboard - - - ${project.groupId} - spring-cloud-starter-netflix-ribbon - - - ${project.groupId} - spring-cloud-starter-netflix-turbine - - - ${project.groupId} - spring-cloud-starter-netflix-turbine-stream - - - ${project.groupId} - spring-cloud-starter-netflix-zuul - diff --git a/pom.xml b/pom.xml index ab7bfefb1..fe4cff6ee 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT + 3.0.0.BUILD-SNAPSHOT pom Spring Cloud Netflix Spring Cloud Netflix @@ -79,12 +79,6 @@ - - org.springframework.cloud - spring-cloud-netflix-hystrix-contract - ${project.version} - test - org.springframework.cloud spring-cloud-netflix-dependencies @@ -131,19 +125,6 @@ javax.inject 1 - - - commons-configuration - commons-configuration - 1.8 - - - commons-logging - commons-logging - - - - com.sun.jersey @@ -188,22 +169,11 @@ spring-cloud-netflix-dependencies - spring-cloud-netflix-archaius - - - spring-cloud-netflix-core spring-cloud-netflix-concurrency-limits - spring-cloud-netflix-hystrix-dashboard - spring-cloud-netflix-hystrix-stream spring-cloud-netflix-eureka-client spring-cloud-netflix-eureka-server - spring-cloud-netflix-turbine - spring-cloud-netflix-turbine-stream - spring-cloud-netflix-sidecar - spring-cloud-netflix-zuul - spring-cloud-netflix-ribbon - spring-cloud-starter-netflix - spring-cloud-netflix-hystrix + spring-cloud-starter-netflix-eureka-client + spring-cloud-starter-netflix-eureka-server docs diff --git a/spring-cloud-netflix-archaius/pom.xml b/spring-cloud-netflix-archaius/pom.xml deleted file mode 100644 index 09cf9f680..000000000 --- a/spring-cloud-netflix-archaius/pom.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - 4.0.0 - - spring-cloud-netflix - org.springframework.cloud - 2.2.2.BUILD-SNAPSHOT - .. - - - - spring-cloud-netflix-archaius - jar - Spring Cloud Netflix Archaius - Spring Cloud Netflix Archaius - - - - org.springframework.boot - spring-boot-starter-actuator - true - - - org.springframework.cloud - spring-cloud-context - true - - - com.netflix.archaius - archaius-core - true - - - commons-configuration - commons-configuration - true - - - - org.springframework.boot - spring-boot-starter-test - test - - - - diff --git a/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java b/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java deleted file mode 100644 index dbabdee59..000000000 --- a/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.archaius; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; - -import javax.annotation.PreDestroy; - -import com.netflix.config.AggregatedConfiguration; -import com.netflix.config.ConcurrentCompositeConfiguration; -import com.netflix.config.ConfigurationManager; -import com.netflix.config.DeploymentContext; -import com.netflix.config.DynamicProperty; -import com.netflix.config.DynamicPropertyFactory; -import com.netflix.config.DynamicURLConfiguration; -import org.apache.commons.configuration.AbstractConfiguration; -import org.apache.commons.configuration.ConfigurationBuilder; -import org.apache.commons.configuration.EnvironmentConfiguration; -import org.apache.commons.configuration.SystemConfiguration; -import org.apache.commons.configuration.event.ConfigurationEvent; -import org.apache.commons.configuration.event.ConfigurationListener; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.autoconfigure.AutoConfigureOrder; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; -import org.springframework.core.Ordered; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.Environment; -import org.springframework.util.ReflectionUtils; - -import static com.netflix.config.ConfigurationManager.APPLICATION_PROPERTIES; -import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_ENV_CONFIG; -import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_SYS_CONFIG; -import static com.netflix.config.ConfigurationManager.ENV_CONFIG_NAME; -import static com.netflix.config.ConfigurationManager.SYS_CONFIG_NAME; -import static com.netflix.config.ConfigurationManager.URL_CONFIG_NAME; - -/** - * @author Spencer Gibb - * @author Liang Yong - */ -@Lazy(false) -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ ConcurrentCompositeConfiguration.class, - ConfigurationBuilder.class }) -@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) -public class ArchaiusAutoConfiguration { - - private static final Log log = LogFactory.getLog(ArchaiusAutoConfiguration.class); - - private static final AtomicBoolean initialized = new AtomicBoolean(false); - - @Autowired - private ConfigurableEnvironment env; - - @Autowired(required = false) - private List externalConfigurations = new ArrayList<>(); - - private static DynamicURLConfiguration defaultURLConfig; - - @PreDestroy - public void close() { - if (defaultURLConfig != null) { - defaultURLConfig.stopLoading(); - } - setStatic(ConfigurationManager.class, "instance", null); - setStatic(ConfigurationManager.class, "customConfigurationInstalled", false); - setStatic(DynamicPropertyFactory.class, "config", null); - setStatic(DynamicPropertyFactory.class, "initializedWithDefaultConfig", false); - setStatic(DynamicProperty.class, "dynamicPropertySupportImpl", null); - initialized.compareAndSet(true, false); - } - - @Bean - public static ConfigurableEnvironmentConfiguration configurableEnvironmentConfiguration( - ConfigurableEnvironment env, ApplicationContext context) { - Map abstractConfigurationMap = context - .getBeansOfType(AbstractConfiguration.class); - List externalConfigurations = new ArrayList<>( - abstractConfigurationMap.values()); - ConfigurableEnvironmentConfiguration envConfig = new ConfigurableEnvironmentConfiguration( - env); - configureArchaius(envConfig, env, externalConfigurations); - return envConfig; - } - - protected static void configureArchaius( - ConfigurableEnvironmentConfiguration envConfig, ConfigurableEnvironment env, - List externalConfigurations) { - if (initialized.compareAndSet(false, true)) { - String appName = env.getProperty("spring.application.name"); - if (appName == null) { - appName = "application"; - log.warn("No spring.application.name found, defaulting to 'application'"); - } - System.setProperty(DeploymentContext.ContextKey.appId.getKey(), appName); - - ConcurrentCompositeConfiguration config = new ConcurrentCompositeConfiguration(); - - // support to add other Configurations (Jdbc, DynamoDb, Zookeeper, jclouds, - // etc...) - if (externalConfigurations != null) { - for (AbstractConfiguration externalConfig : externalConfigurations) { - config.addConfiguration(externalConfig); - } - } - config.addConfiguration(envConfig, - ConfigurableEnvironmentConfiguration.class.getSimpleName()); - - defaultURLConfig = new DynamicURLConfiguration(); - try { - config.addConfiguration(defaultURLConfig, URL_CONFIG_NAME); - } - catch (Throwable ex) { - log.error("Cannot create config from " + defaultURLConfig, ex); - } - - // TODO: sys/env above urls? - if (!Boolean.getBoolean(DISABLE_DEFAULT_SYS_CONFIG)) { - SystemConfiguration sysConfig = new SystemConfiguration(); - config.addConfiguration(sysConfig, SYS_CONFIG_NAME); - } - if (!Boolean.getBoolean(DISABLE_DEFAULT_ENV_CONFIG)) { - EnvironmentConfiguration environmentConfiguration = new EnvironmentConfiguration(); - config.addConfiguration(environmentConfiguration, ENV_CONFIG_NAME); - } - - ConcurrentCompositeConfiguration appOverrideConfig = new ConcurrentCompositeConfiguration(); - config.addConfiguration(appOverrideConfig, APPLICATION_PROPERTIES); - config.setContainerConfigurationIndex( - config.getIndexOfConfiguration(appOverrideConfig)); - - addArchaiusConfiguration(config); - } - else { - // TODO: reinstall ConfigurationManager - log.warn( - "Netflix ConfigurationManager has already been installed, unable to re-install"); - } - } - - private static void addArchaiusConfiguration( - ConcurrentCompositeConfiguration config) { - if (ConfigurationManager.isConfigurationInstalled()) { - AbstractConfiguration installedConfiguration = ConfigurationManager - .getConfigInstance(); - if (installedConfiguration instanceof ConcurrentCompositeConfiguration) { - ConcurrentCompositeConfiguration configInstance = (ConcurrentCompositeConfiguration) installedConfiguration; - configInstance.addConfiguration(config); - } - else { - installedConfiguration.append(config); - if (!(installedConfiguration instanceof AggregatedConfiguration)) { - log.warn( - "Appending a configuration to an existing non-aggregated installed configuration will have no effect"); - } - } - } - else { - ConfigurationManager.install(config); - } - } - - private static void setStatic(Class type, String name, Object value) { - // Hack a private static field - Field field = ReflectionUtils.findField(type, name); - ReflectionUtils.makeAccessible(field); - ReflectionUtils.setField(field, null, value); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(Health.class) - protected static class ArchaiusEndpointConfiguration { - - @Bean - @ConditionalOnAvailableEndpoint - protected ArchaiusEndpoint archaiusEndpoint() { - return new ArchaiusEndpoint(); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnProperty(value = "archaius.propagate.environmentChangedEvent", - matchIfMissing = true) - @ConditionalOnClass(EnvironmentChangeEvent.class) - protected static class PropagateEventsConfiguration - implements ApplicationListener { - - @Autowired - private Environment env; - - @Override - public void onApplicationEvent(EnvironmentChangeEvent event) { - AbstractConfiguration manager = ConfigurationManager.getConfigInstance(); - for (String key : event.getKeys()) { - for (ConfigurationListener listener : manager - .getConfigurationListeners()) { - Object source = event.getSource(); - // TODO: Handle add vs set vs delete? - int type = AbstractConfiguration.EVENT_SET_PROPERTY; - String value = this.env.getProperty(key); - boolean beforeUpdate = false; - listener.configurationChanged(new ConfigurationEvent(source, type, - key, value, beforeUpdate)); - } - } - } - - } - -} diff --git a/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusDelegatingProxyUtils.java b/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusDelegatingProxyUtils.java deleted file mode 100644 index 2d95ab4c5..000000000 --- a/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusDelegatingProxyUtils.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.archaius; - -import com.netflix.config.ConfigurationManager; -import org.apache.commons.configuration.AbstractConfiguration; - -import org.springframework.context.ApplicationContext; -import org.springframework.context.ConfigurableApplicationContext; - -/** - * @author Dave Syer - */ -public final class ArchaiusDelegatingProxyUtils { - - private ArchaiusDelegatingProxyUtils() { - } - - /** - * {@code ApplicationContext} class name. - */ - public static String APPLICATION_CONTEXT = ApplicationContext.class.getName(); - - public static T getNamedInstance(Class type, String name) { - ApplicationContext context = (ApplicationContext) ConfigurationManager - .getConfigInstance().getProperty(APPLICATION_CONTEXT); - return context != null && context.containsBean(name) ? context.getBean(name, type) - : null; - } - - public static T getInstanceWithPrefix(Class type, String prefix) { - String name = prefix + type.getSimpleName(); - return getNamedInstance(type, name); - } - - public static void addApplicationContext(ConfigurableApplicationContext context) { - AbstractConfiguration config = ConfigurationManager.getConfigInstance(); - config.clearProperty(APPLICATION_CONTEXT); - config.setProperty(APPLICATION_CONTEXT, context); - } - -} diff --git a/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpoint.java b/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpoint.java deleted file mode 100644 index fce93bbfb..000000000 --- a/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpoint.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.archaius; - -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; - -import com.netflix.config.ConcurrentCompositeConfiguration; -import com.netflix.config.ConfigurationManager; -import org.apache.commons.configuration.AbstractConfiguration; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.EnvironmentConfiguration; -import org.apache.commons.configuration.SystemConfiguration; - -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; - -/** - * An actuator endpoint that returns Archaius configuration. - * - * @author Dave Syer - */ -@Endpoint(id = "archaius") -public class ArchaiusEndpoint { - - @ReadOperation - public Map invoke() { - Map map = new LinkedHashMap<>(); - AbstractConfiguration config = ConfigurationManager.getConfigInstance(); - if (config instanceof ConcurrentCompositeConfiguration) { - ConcurrentCompositeConfiguration composite = (ConcurrentCompositeConfiguration) config; - for (Configuration item : composite.getConfigurations()) { - append(map, item); - } - } - else { - append(map, config); - } - return map; - } - - private void append(Map map, Configuration config) { - if (config instanceof ConfigurableEnvironmentConfiguration) { - return; - } - if (config instanceof SystemConfiguration) { - return; - } - if (config instanceof EnvironmentConfiguration) { - return; - } - for (Iterator iter = config.getKeys(); iter.hasNext();) { - String key = iter.next(); - map.put(key, config.getProperty(key)); - } - } - -} diff --git a/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ConfigurableEnvironmentConfiguration.java b/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ConfigurableEnvironmentConfiguration.java deleted file mode 100644 index b036a1fe4..000000000 --- a/spring-cloud-netflix-archaius/src/main/java/org/springframework/cloud/netflix/archaius/ConfigurableEnvironmentConfiguration.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.archaius; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.configuration.AbstractConfiguration; - -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.EnumerablePropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.core.env.StandardEnvironment; - -/** - * EnvironmentConfiguration wrapper class providing further configuration possibilities. - * - * @author Spencer Gibb - */ -public class ConfigurableEnvironmentConfiguration extends AbstractConfiguration { - - private final ConfigurableEnvironment environment; - - public ConfigurableEnvironmentConfiguration(ConfigurableEnvironment environment) { - this.environment = environment; - } - - @Override - protected void addPropertyDirect(String key, Object value) { - - } - - @Override - public boolean isEmpty() { - return !getKeys().hasNext(); // TODO: find a better way to do this - } - - @Override - public boolean containsKey(String key) { - return this.environment.containsProperty(key); - } - - @Override - public Object getProperty(String key) { - return this.environment.getProperty(key); - } - - @Override - public Iterator getKeys() { - List result = new ArrayList<>(); - for (Map.Entry> entry : getPropertySources() - .entrySet()) { - PropertySource source = entry.getValue(); - if (source instanceof EnumerablePropertySource) { - EnumerablePropertySource enumerable = (EnumerablePropertySource) source; - for (String name : enumerable.getPropertyNames()) { - result.add(name); - } - } - } - return result.iterator(); - } - - private Map> getPropertySources() { - Map> map = new LinkedHashMap<>(); - MutablePropertySources sources = (this.environment != null - ? this.environment.getPropertySources() - : new StandardEnvironment().getPropertySources()); - for (PropertySource source : sources) { - extract("", map, source); - } - return map; - } - - private void extract(String root, Map> map, - PropertySource source) { - if (source instanceof CompositePropertySource) { - for (PropertySource nest : ((CompositePropertySource) source) - .getPropertySources()) { - extract(source.getName() + ":", map, nest); - } - } - else { - map.put(root + source.getName(), source); - } - } - -} diff --git a/spring-cloud-netflix-archaius/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-netflix-archaius/src/main/resources/META-INF/additional-spring-configuration-metadata.json deleted file mode 100644 index 0edf13794..000000000 --- a/spring-cloud-netflix-archaius/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "properties": [ - { - "defaultValue": "true", - "name": "archaius.propagate.environmentChangedEvent", - "description": "Propagates EnvironmentChanged events to Archaius ConfigurationManager.", - "type": "java.lang.Boolean" - } - ] -} \ No newline at end of file diff --git a/spring-cloud-netflix-archaius/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-archaius/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 834129ccb..000000000 --- a/spring-cloud-netflix-archaius/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration \ No newline at end of file diff --git a/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java b/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java deleted file mode 100644 index 8bfa87e5d..000000000 --- a/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfigurationTests.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.archaius; - -import java.util.Collections; - -import com.netflix.config.ConfigurationManager; -import com.netflix.config.DynamicPropertyFactory; -import com.netflix.config.DynamicStringProperty; -import org.apache.commons.configuration.AbstractConfiguration; -import org.junit.After; -import org.junit.Test; - -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -public class ArchaiusAutoConfigurationTests { - - private AnnotationConfigApplicationContext context; - - private Object propertyValue; - - @After - public void close() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - public void configurationCreated() { - this.context = new AnnotationConfigApplicationContext( - ArchaiusAutoConfiguration.class); - AbstractConfiguration config = this.context - .getBean(ConfigurableEnvironmentConfiguration.class); - assertThat(config.getString("java.io.tmpdir")).isNotNull(); - } - - @Test - public void environmentChangeEventPropagated() { - this.context = new AnnotationConfigApplicationContext( - ArchaiusAutoConfiguration.class); - ConfigurationManager.getConfigInstance().addConfigurationListener(event -> { - if (event.getPropertyName().equals("my.prop")) { - ArchaiusAutoConfigurationTests.this.propertyValue = event - .getPropertyValue(); - } - }); - TestPropertyValues.of("my.prop=my.newval").applyTo(this.context); - this.context.publishEvent( - new EnvironmentChangeEvent(Collections.singleton("my.prop"))); - assertThat(this.propertyValue).isEqualTo("my.newval"); - } - - @Test - public void configurationWithoutExternalConfigurations() throws Exception { - this.context = new AnnotationConfigApplicationContext( - ArchaiusAutoConfiguration.class); - DynamicStringProperty dbProperty = DynamicPropertyFactory.getInstance() - .getStringProperty("db.property", null); - DynamicStringProperty staticProperty = DynamicPropertyFactory.getInstance() - .getStringProperty("archaius.file.property", null); - - assertThat(dbProperty.getValue()).isNull(); - assertThat(staticProperty.getValue()).isNotNull(); - assertThat(staticProperty.getValue()).isEqualTo("Static config file property"); - } - - @Test - public void configurationWithInjectedConfiguration() throws Exception { - this.context = new AnnotationConfigApplicationContext( - ArchaiusAutoConfiguration.class, TestArchaiusExternalConfiguration.class); - DynamicStringProperty dbProperty = DynamicPropertyFactory.getInstance() - .getStringProperty("db.property", null); - DynamicStringProperty secondDbProperty = DynamicPropertyFactory.getInstance() - .getStringProperty("db.second.property", null); - DynamicStringProperty staticProperty = DynamicPropertyFactory.getInstance() - .getStringProperty("archaius.file.property", null); - - assertThat(dbProperty.getValue()).isNotNull(); - assertThat(secondDbProperty.getValue()).isNotNull(); - assertThat(staticProperty.getValue()).isNotNull(); - assertThat(dbProperty.getValue()).isEqualTo("this is a db property"); - assertThat(secondDbProperty.getValue()).isEqualTo("this is another db property"); - assertThat(staticProperty.getValue()).isEqualTo("Static config file property"); - } - -} diff --git a/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpointTests.java b/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpointTests.java deleted file mode 100644 index f0fe562e6..000000000 --- a/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/ArchaiusEndpointTests.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.archaius; - -import java.util.Map; - -import com.netflix.config.ConcurrentCompositeConfiguration; -import com.netflix.config.ConfigurationManager; -import org.junit.Test; - -import org.springframework.core.env.StandardEnvironment; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -public class ArchaiusEndpointTests { - - private ArchaiusEndpoint endpoint = new ArchaiusEndpoint(); - - @Test - public void detectsPropertiesWhenSet() { - ConfigurationManager.getConfigInstance().setProperty("foo", "bar"); - assertThat(this.endpoint.invoke().containsKey("foo")).isTrue(); - } - - @Test - public void doesNotIncludeSpringEnvironment() { - ConcurrentCompositeConfiguration composite = new ConcurrentCompositeConfiguration( - ConfigurationManager.getConfigInstance()); - ConfigurableEnvironmentConfiguration config = new ConfigurableEnvironmentConfiguration( - new StandardEnvironment()); - assertThat(config.containsKey("user.dir")).isTrue(); - composite.addConfiguration(config); - ConfigurationManager.getConfigInstance().setProperty("foo", "bar"); - Map map = this.endpoint.invoke(); - assertThat(map.containsKey("foo")).isTrue(); - assertThat(map.containsKey("user.dir")).isFalse(); - } - -} diff --git a/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/LazyLoadConfigurationTests.java b/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/LazyLoadConfigurationTests.java deleted file mode 100644 index aa456d0f6..000000000 --- a/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/LazyLoadConfigurationTests.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.archaius; - -import com.netflix.config.DynamicProperty; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Liang Yong - */ - -@SpringBootTest(classes = LazyLoadConfigurationTests.TestConfig.class, - properties = { "client.ribbon.listOfServers=foo.com,bar.com", - "spring.main.lazy-initialization=true" }) -public class LazyLoadConfigurationTests { - - @Test - public void enableLazyInitialization() { - DynamicProperty instance = DynamicProperty - .getInstance("client.ribbon.listOfServers"); - assertThat(instance.getString()).isEqualTo("foo.com,bar.com"); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - static class TestConfig { - - } - -} diff --git a/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/TestArchaiusExternalConfiguration.java b/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/TestArchaiusExternalConfiguration.java deleted file mode 100644 index ff4c8d792..000000000 --- a/spring-cloud-netflix-archaius/src/test/java/org/springframework/cloud/netflix/archaius/TestArchaiusExternalConfiguration.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.archaius; - -import com.netflix.config.ConcurrentMapConfiguration; -import org.apache.commons.configuration.AbstractConfiguration; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Alexandru-George Burghelea - */ -@Configuration(proxyBeanMethods = false) -public class TestArchaiusExternalConfiguration { - - @Bean - @Qualifier("dynamicConfiguration") - public AbstractConfiguration createDynamicConfiguration() { - ConcurrentMapConfiguration config = new ConcurrentMapConfiguration(); - config.addProperty("db.property", "this is a db property"); - config.addProperty("db.second.property", "this is another db property"); - return config; - } - -} diff --git a/spring-cloud-netflix-archaius/src/test/resources/config.properties b/spring-cloud-netflix-archaius/src/test/resources/config.properties deleted file mode 100644 index 1e9c021f4..000000000 --- a/spring-cloud-netflix-archaius/src/test/resources/config.properties +++ /dev/null @@ -1,2 +0,0 @@ -archaius.file.property=Static config file property -db.second.property=It should be overridden diff --git a/spring-cloud-netflix-concurrency-limits/pom.xml b/spring-cloud-netflix-concurrency-limits/pom.xml index 38b91cefa..84a7a4fc0 100644 --- a/spring-cloud-netflix-concurrency-limits/pom.xml +++ b/spring-cloud-netflix-concurrency-limits/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT + 3.0.0.BUILD-SNAPSHOT .. spring-cloud-netflix-concurrency-limits diff --git a/spring-cloud-netflix-core/pom.xml b/spring-cloud-netflix-core/pom.xml deleted file mode 100644 index 310d0ddb3..000000000 --- a/spring-cloud-netflix-core/pom.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT - .. - - spring-cloud-netflix-core - jar - Spring Cloud Netflix Core - Deprecated - Deprecated Spring Cloud Netflix Core - will be removed. Please use spring-cloud-netflix-hystrix instead. - - - org.springframework.cloud - spring-cloud-netflix-hystrix - - - org.springframework.boot - spring-boot-autoconfigure - true - - - - - java8plus - - [1.8,2.0) - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - -parameters - - - - - - - - diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/core/CoreAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/core/CoreAutoConfiguration.java deleted file mode 100644 index 0590b20e2..000000000 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/core/CoreAutoConfiguration.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2018-2019 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 - * - * https://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.core; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.context.annotation.Configuration; - -/** - * @author Olga Maciaszek-Sharma - * @since 2.1.0 - * @deprecated Module spring-cloud-netflix-core is deprecated as of 2.1.0, use - * spring-cloud-netflix-hystrix instead. - */ -@Configuration(proxyBeanMethods = false) -@Deprecated -public class CoreAutoConfiguration { - - private static final Log LOG = LogFactory.getLog(CoreAutoConfiguration.class); - - public CoreAutoConfiguration() { - LOG.warn( - "This module is deprecated. It will be removed in the next major release. " - + "Please use spring-cloud-netflix-hystrix instead."); - } - -} diff --git a/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 7362ab93f..000000000 --- a/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.core.CoreAutoConfiguration \ No newline at end of file diff --git a/spring-cloud-netflix-dependencies/pom.xml b/spring-cloud-netflix-dependencies/pom.xml index 442a57709..7e2cf9467 100644 --- a/spring-cloud-netflix-dependencies/pom.xml +++ b/spring-cloud-netflix-dependencies/pom.xml @@ -5,24 +5,17 @@ spring-cloud-dependencies-parent org.springframework.cloud - 2.2.1.RELEASE + 2.2.2.BUILD-SNAPSHOT spring-cloud-netflix-dependencies - 2.2.2.BUILD-SNAPSHOT + 3.0.0.BUILD-SNAPSHOT pom spring-cloud-netflix-dependencies Spring Cloud Netflix Dependencies - 0.7.6 0.1.12 1.9.13 - 0.3.0 - 1.5.18 - 2.3.0 - 0.12.21 - 1.3.1 - 1.0.0 @@ -31,16 +24,6 @@ spring-cloud-netflix-eureka-client ${project.version} - - org.springframework.cloud - spring-cloud-netflix-archaius - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - ${project.version} - org.springframework.cloud spring-cloud-starter-netflix-eureka-client @@ -51,111 +34,16 @@ spring-cloud-starter-netflix-eureka-server ${project.version} - - org.springframework.cloud - spring-cloud-starter-netflix-hystrix - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-hystrix-contract - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-netflix-hystrix-dashboard - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-netflix-turbine - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-netflix-turbine-stream - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-netflix-zuul - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-core - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-hystrix - ${project.version} - org.springframework.cloud spring-cloud-netflix-eureka-server ${project.version} - - org.springframework.cloud - spring-cloud-netflix-hystrix-dashboard - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-hystrix-stream - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-sidecar - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-turbine - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-turbine-stream - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-zuul - ${project.version} - - - org.springframework.cloud - spring-cloud-netflix-ribbon - ${project.version} - - + com.netflix.concurrency-limits concurrency-limits-core @@ -166,17 +54,6 @@ concurrency-limits-servlet ${concurrency-limits.version} - - com.netflix.servo - servo-core - ${servo.version} - - - com.google.code.findbugs - annotations - - - com.netflix.eureka eureka-client @@ -243,137 +120,6 @@ - - com.netflix.hystrix - hystrix-core - ${hystrix.version} - - - com.google.code.findbugs - annotations - - - - - com.netflix.hystrix - hystrix-serialization - ${hystrix.version} - - - com.google.code.findbugs - annotations - - - - - com.netflix.hystrix - hystrix-metrics-event-stream - ${hystrix.version} - - - javax.servlet - servlet-api - - - - - com.netflix.hystrix - hystrix-javanica - ${hystrix.version} - - - com.google.code.findbugs - jsr305 - - - com.google.code.findbugs - annotations - - - org.aspectj - aspectjrt - - - - - com.netflix.ribbon - ribbon - ${ribbon.version} - - - commons-logging - commons-logging - - - - - com.netflix.ribbon - ribbon-core - ${ribbon.version} - - - com.google.code.findbugs - annotations - - - - - com.netflix.ribbon - ribbon-httpclient - ${ribbon.version} - - - com.google.code.findbugs - annotations - - - - - com.netflix.ribbon - ribbon-eureka - ${ribbon.version} - - - com.google.code.findbugs - annotations - - - javax.servlet - servlet-api - - - - - com.netflix.ribbon - ribbon-loadbalancer - ${ribbon.version} - - - com.google.code.findbugs - annotations - - - - - com.netflix.zuul - zuul-core - ${zuul.version} - - - groovy-all - org.codehaus.groovy - - - mockito-all - org.mockito - - - - - com.netflix.netflix-commons - netflix-eventbus - ${eventbus.version} - diff --git a/spring-cloud-netflix-eureka-client/pom.xml b/spring-cloud-netflix-eureka-client/pom.xml index c93ad9874..ab30b7881 100644 --- a/spring-cloud-netflix-eureka-client/pom.xml +++ b/spring-cloud-netflix-eureka-client/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT + 3.0.0.BUILD-SNAPSHOT .. spring-cloud-netflix-eureka-client @@ -32,15 +32,6 @@ spring-boot-starter-webflux true - - org.springframework.cloud - spring-cloud-netflix-hystrix - - - org.springframework.cloud - spring-cloud-netflix-ribbon - true - org.springframework.cloud spring-cloud-config-client @@ -82,41 +73,11 @@ jersey-apache-client4 true - - com.netflix.archaius - archaius-core - true - - - com.netflix.ribbon - ribbon - true - - + org.springframework.boot spring-boot-autoconfigure-processor diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/loadbalancer/EurekaLoadBalancerClientConfiguration.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/loadbalancer/EurekaLoadBalancerClientConfiguration.java index 36890dd65..3956baa34 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/loadbalancer/EurekaLoadBalancerClientConfiguration.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/loadbalancer/EurekaLoadBalancerClientConfiguration.java @@ -26,7 +26,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerProperties; -import org.springframework.cloud.netflix.ribbon.eureka.ZoneUtils; +import org.springframework.cloud.netflix.eureka.support.ZoneUtils; import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ZoneUtils.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/support/ZoneUtils.java similarity index 95% rename from spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ZoneUtils.java rename to spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/support/ZoneUtils.java index 1f374d8c8..ecb2bf817 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ZoneUtils.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/support/ZoneUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.netflix.ribbon.eureka; +package org.springframework.cloud.netflix.eureka.support; import org.springframework.util.StringUtils; diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ConditionalOnRibbonAndEurekaEnabled.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ConditionalOnRibbonAndEurekaEnabled.java deleted file mode 100644 index cc98d0a6d..000000000 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/ConditionalOnRibbonAndEurekaEnabled.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.eureka; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import com.netflix.discovery.EurekaClient; -import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList; - -import org.springframework.boot.autoconfigure.condition.AllNestedConditions; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.context.annotation.Conditional; - -/** - * Conditional that requires both Ribbon and Eureka to be enabled. - * @author Ihor Kryvenko - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - */ -@Target({ ElementType.TYPE, ElementType.METHOD }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Conditional(ConditionalOnRibbonAndEurekaEnabled.OnRibbonAndEurekaEnabledCondition.class) -public @interface ConditionalOnRibbonAndEurekaEnabled { - - class OnRibbonAndEurekaEnabledCondition extends AllNestedConditions { - - OnRibbonAndEurekaEnabledCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @ConditionalOnClass(DiscoveryEnabledNIWSServerList.class) - @ConditionalOnBean(SpringClientFactory.class) - @ConditionalOnProperty(value = "ribbon.eureka.enabled", matchIfMissing = true) - static class Defaults { - - } - - @ConditionalOnBean(EurekaClient.class) - static class EurekaBeans { - - } - - @ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true) - @ConditionalOnDiscoveryEnabled - static class OnEurekaClientEnabled { - - } - - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java deleted file mode 100644 index ed640554f..000000000 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.eureka; - -import java.util.ArrayList; -import java.util.List; - -import com.netflix.appinfo.InstanceInfo; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.niws.loadbalancer.DiscoveryEnabledServer; - -import org.springframework.cloud.netflix.ribbon.RibbonProperties; - -/** - * @author Dave Syer - */ -public class DomainExtractingServerList implements ServerList { - - private ServerList list; - - private final RibbonProperties ribbon; - - private boolean approximateZoneFromHostname; - - public DomainExtractingServerList(ServerList list, - IClientConfig clientConfig, boolean approximateZoneFromHostname) { - this.list = list; - this.ribbon = RibbonProperties.from(clientConfig); - this.approximateZoneFromHostname = approximateZoneFromHostname; - } - - @Override - public List getInitialListOfServers() { - List servers = setZones( - this.list.getInitialListOfServers()); - return servers; - } - - @Override - public List getUpdatedListOfServers() { - List servers = setZones( - this.list.getUpdatedListOfServers()); - return servers; - } - - private List setZones(List servers) { - List result = new ArrayList<>(); - boolean isSecure = this.ribbon.isSecure(true); - boolean shouldUseIpAddr = this.ribbon.isUseIPAddrForServer(); - for (DiscoveryEnabledServer server : servers) { - result.add(new DomainExtractingServer(server, isSecure, shouldUseIpAddr, - this.approximateZoneFromHostname)); - } - return result; - } - -} - -class DomainExtractingServer extends DiscoveryEnabledServer { - - private String id; - - @Override - public String getId() { - return id; - } - - @Override - public void setId(String id) { - this.id = id; - } - - DomainExtractingServer(DiscoveryEnabledServer server, boolean useSecurePort, - boolean useIpAddr, boolean approximateZoneFromHostname) { - // host and port are set in super() - super(server.getInstanceInfo(), useSecurePort, useIpAddr); - if (server.getInstanceInfo().getMetadata().containsKey("zone")) { - setZone(server.getInstanceInfo().getMetadata().get("zone")); - } - else if (approximateZoneFromHostname) { - setZone(ZoneUtils.extractApproximateZone(server.getHost())); - } - else { - setZone(server.getZone()); - } - setId(extractId(server)); - setAlive(server.isAlive()); - setReadyToServe(server.isReadyToServe()); - } - - private String extractId(Server server) { - if (server instanceof DiscoveryEnabledServer) { - DiscoveryEnabledServer enabled = (DiscoveryEnabledServer) server; - InstanceInfo instance = enabled.getInstanceInfo(); - if (instance.getMetadata().containsKey("instanceId")) { - return instance.getHostName() + ":" - + instance.getMetadata().get("instanceId"); - } - } - return super.getId(); - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfiguration.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfiguration.java deleted file mode 100644 index 2dbb747fb..000000000 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfiguration.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.eureka; - -import javax.annotation.PostConstruct; -import javax.inject.Provider; - -import com.netflix.appinfo.EurekaInstanceConfig; -import com.netflix.client.config.IClientConfig; -import com.netflix.config.ConfigurationManager; -import com.netflix.config.DeploymentContext.ContextKey; -import com.netflix.discovery.EurekaClient; -import com.netflix.discovery.EurekaClientConfig; -import com.netflix.loadbalancer.IPing; -import com.netflix.loadbalancer.ServerList; -import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList; -import com.netflix.niws.loadbalancer.NIWSDiscoveryPing; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.cloud.netflix.ribbon.PropertiesFactory; -import org.springframework.cloud.netflix.ribbon.RibbonClientName; -import org.springframework.cloud.netflix.ribbon.RibbonUtils; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.StringUtils; - -/** - * Preprocessor that configures defaults for eureka-discovered ribbon clients. Such as: - * @zone, NIWSServerListClassName, DeploymentContextBasedVipAddresses, - * NFLoadBalancerRuleClassName, NIWSServerListFilterClassName and more - * - * @author Spencer Gibb - * @author Dave Syer - * @author Ryan Baxter - */ -@Configuration(proxyBeanMethods = false) -public class EurekaRibbonClientConfiguration { - - private static final Log log = LogFactory - .getLog(EurekaRibbonClientConfiguration.class); - - @Value("${ribbon.eureka.approximateZoneFromHostname:false}") - private boolean approximateZoneFromHostname = false; - - @RibbonClientName - private String serviceId = "client"; - - @Autowired(required = false) - private EurekaClientConfig clientConfig; - - @Autowired(required = false) - private EurekaInstanceConfig eurekaConfig; - - @Autowired - private PropertiesFactory propertiesFactory; - - public EurekaRibbonClientConfiguration() { - } - - public EurekaRibbonClientConfiguration(EurekaClientConfig clientConfig, - String serviceId, EurekaInstanceConfig eurekaConfig, - boolean approximateZoneFromHostname) { - this.clientConfig = clientConfig; - this.serviceId = serviceId; - this.eurekaConfig = eurekaConfig; - this.approximateZoneFromHostname = approximateZoneFromHostname; - } - - @Bean - @ConditionalOnMissingBean - public IPing ribbonPing(IClientConfig config) { - if (this.propertiesFactory.isSet(IPing.class, serviceId)) { - return this.propertiesFactory.get(IPing.class, config, serviceId); - } - NIWSDiscoveryPing ping = new NIWSDiscoveryPing(); - ping.initWithNiwsConfig(config); - return ping; - } - - @Bean - @ConditionalOnMissingBean - public ServerList ribbonServerList(IClientConfig config, - Provider eurekaClientProvider) { - if (this.propertiesFactory.isSet(ServerList.class, serviceId)) { - return this.propertiesFactory.get(ServerList.class, config, serviceId); - } - DiscoveryEnabledNIWSServerList discoveryServerList = new DiscoveryEnabledNIWSServerList( - config, eurekaClientProvider); - DomainExtractingServerList serverList = new DomainExtractingServerList( - discoveryServerList, config, this.approximateZoneFromHostname); - return serverList; - } - - @Bean - public ServerIntrospector serverIntrospector() { - return new EurekaServerIntrospector(); - } - - @PostConstruct - public void preprocess() { - String zone = ConfigurationManager.getDeploymentContext() - .getValue(ContextKey.zone); - if (this.clientConfig != null && StringUtils.isEmpty(zone)) { - if (this.approximateZoneFromHostname && this.eurekaConfig != null) { - String approxZone = ZoneUtils - .extractApproximateZone(this.eurekaConfig.getHostName(false)); - log.debug("Setting Zone To " + approxZone); - ConfigurationManager.getDeploymentContext().setValue(ContextKey.zone, - approxZone); - } - else { - String availabilityZone = this.eurekaConfig == null ? null - : this.eurekaConfig.getMetadataMap().get("zone"); - if (availabilityZone == null) { - String[] zones = this.clientConfig - .getAvailabilityZones(this.clientConfig.getRegion()); - // Pick the first one from the regions we want to connect to - availabilityZone = zones != null && zones.length > 0 ? zones[0] - : null; - } - if (availabilityZone != null) { - // You can set this with archaius.deployment.* (maybe requires - // custom deployment context)? - ConfigurationManager.getDeploymentContext().setValue(ContextKey.zone, - availabilityZone); - } - } - } - RibbonUtils.initializeRibbonDefaults(serviceId); - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaServerIntrospector.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaServerIntrospector.java deleted file mode 100644 index fe833f328..000000000 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaServerIntrospector.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.eureka; - -import java.util.Map; - -import com.netflix.appinfo.InstanceInfo; -import com.netflix.loadbalancer.Server; -import com.netflix.niws.loadbalancer.DiscoveryEnabledServer; - -import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; - -/** - * @author Spencer Gibb - */ -public class EurekaServerIntrospector extends DefaultServerIntrospector { - - @Override - public boolean isSecure(Server server) { - if (server instanceof DiscoveryEnabledServer) { - DiscoveryEnabledServer discoveryServer = (DiscoveryEnabledServer) server; - return discoveryServer.getInstanceInfo() - .isPortEnabled(InstanceInfo.PortType.SECURE); - } - return super.isSecure(server); - } - - @Override - public Map getMetadata(Server server) { - if (server instanceof DiscoveryEnabledServer) { - DiscoveryEnabledServer discoveryServer = (DiscoveryEnabledServer) server; - return discoveryServer.getInstanceInfo().getMetadata(); - } - return super.getMetadata(server); - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfiguration.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfiguration.java deleted file mode 100644 index 1c6b0fc71..000000000 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfiguration.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.eureka; - -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.context.annotation.Configuration; - -/** - * Spring configuration for configuring Ribbon defaults to be Eureka based if Eureka - * client is enabled. - * - * @author Dave Syer - * @author Biju Kunjummen - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties -@ConditionalOnRibbonAndEurekaEnabled -@AutoConfigureAfter(RibbonAutoConfiguration.class) -@RibbonClients(defaultConfiguration = EurekaRibbonClientConfiguration.class) -public class RibbonEurekaAutoConfiguration { - -} diff --git a/spring-cloud-netflix-eureka-client/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-eureka-client/src/main/resources/META-INF/spring.factories index 12659725c..b212aa39b 100644 --- a/spring-cloud-netflix-eureka-client/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-netflix-eureka-client/src/main/resources/META-INF/spring.factories @@ -2,7 +2,6 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.netflix.eureka.config.EurekaClientConfigServerAutoConfiguration,\ org.springframework.cloud.netflix.eureka.config.EurekaDiscoveryClientConfigServiceAutoConfiguration,\ org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration,\ -org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration,\ org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration,\ org.springframework.cloud.netflix.eureka.reactive.EurekaReactiveDiscoveryClientConfiguration,\ org.springframework.cloud.netflix.eureka.loadbalancer.LoadBalancerEurekaAutoConfiguration diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/ZoneUtilsTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/support/ZoneUtilsTests.java similarity index 90% rename from spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/ZoneUtilsTests.java rename to spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/support/ZoneUtilsTests.java index 45eb60137..0fdb872ee 100644 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/ZoneUtilsTests.java +++ b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/support/ZoneUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.netflix.ribbon.eureka; +package org.springframework.cloud.netflix.eureka.support; import org.junit.Test; diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerListTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerListTests.java deleted file mode 100644 index 258dd7d26..000000000 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerListTests.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.eureka; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.netflix.appinfo.InstanceInfo; -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.niws.loadbalancer.DiscoveryEnabledServer; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * @author Spencer Gibb - */ -public class DomainExtractingServerListTests { - - static final String IP_ADDR = "10.0.0.2"; - - static final int PORT = 8080; - - static final String ZONE = "myzone.mydomain.com"; - - static final String HOST_NAME = "myHostName." + ZONE; - - static final String INSTANCE_ID = "myInstanceId"; - - private Map metadata = Collections - .singletonMap("instanceId", INSTANCE_ID); - - @Test - public void testDomainExtractingServer() { - DomainExtractingServerList serverList = getDomainExtractingServerList( - new DefaultClientConfigImpl(), true); - List servers = serverList.getInitialListOfServers(); - assertThat(servers).as("servers was null").isNotNull(); - assertThat(servers.size()).as("servers was not size 1").isEqualTo(1); - DomainExtractingServer des = assertDomainExtractingServer(servers, ZONE); - assertThat(des.getHostPort()).as("hostPort was wrong") - .isEqualTo(HOST_NAME + ":" + PORT); - } - - @Test - public void testZoneInMetaData() { - this.metadata = new HashMap<>(); - this.metadata.put("zone", "us-west-1"); - this.metadata.put("instanceId", INSTANCE_ID); - DomainExtractingServerList serverList = getDomainExtractingServerList( - new DefaultClientConfigImpl(), false); - List servers = serverList.getInitialListOfServers(); - assertThat(servers).as("servers was null").isNotNull(); - assertThat(servers.size()).as("servers was not size 1").isEqualTo(1); - DomainExtractingServer des = assertDomainExtractingServer(servers, "us-west-1"); - assertThat(des.getZone()).as("Zone was wrong").isEqualTo("us-west-1"); - } - - @Test - public void testDomainExtractingServerDontApproximateZone() { - DomainExtractingServerList serverList = getDomainExtractingServerList( - new DefaultClientConfigImpl(), false); - List servers = serverList.getInitialListOfServers(); - assertThat(servers).as("servers was null").isNotNull(); - assertThat(servers.size()).as("servers was not size 1").isEqualTo(1); - DomainExtractingServer des = assertDomainExtractingServer(servers, null); - assertThat(des.getHostPort()).as("hostPort was wrong") - .isEqualTo(HOST_NAME + ":" + PORT); - } - - protected DomainExtractingServer assertDomainExtractingServer( - List servers, String zone) { - Server actualServer = servers.get(0); - assertThat(actualServer instanceof DomainExtractingServer) - .as("server was not a DomainExtractingServer").isTrue(); - DomainExtractingServer des = DomainExtractingServer.class.cast(actualServer); - assertThat(des.getZone()).as("zone was wrong").isEqualTo(zone); - assertThat(des.getId()).as("instanceId was wrong") - .isEqualTo(HOST_NAME + ":" + INSTANCE_ID); - return des; - } - - @Test - public void testDomainExtractingServerUseIpAddress() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.setProperty(CommonClientConfigKey.UseIPAddrForServer, true); - DomainExtractingServerList serverList = getDomainExtractingServerList(config, - true); - List servers = serverList.getInitialListOfServers(); - assertThat(servers).as("servers was null").isNotNull(); - assertThat(servers.size()).as("servers was not size 1").isEqualTo(1); - DomainExtractingServer des = assertDomainExtractingServer(servers, ZONE); - assertThat(des.getHostPort()).as("hostPort was wrong") - .isEqualTo(IP_ADDR + ":" + PORT); - } - - protected DomainExtractingServerList getDomainExtractingServerList( - DefaultClientConfigImpl config, boolean approximateZoneFromHostname) { - DiscoveryEnabledServer server = mock(DiscoveryEnabledServer.class); - @SuppressWarnings("unchecked") - ServerList originalServerList = mock(ServerList.class); - InstanceInfo instanceInfo = mock(InstanceInfo.class); - given(server.getInstanceInfo()).willReturn(instanceInfo); - given(server.getHost()).willReturn(HOST_NAME); - given(instanceInfo.getMetadata()).willReturn(this.metadata); - given(instanceInfo.getHostName()).willReturn(HOST_NAME); - given(instanceInfo.getIPAddr()).willReturn(IP_ADDR); - given(instanceInfo.getPort()).willReturn(PORT); - given(originalServerList.getInitialListOfServers()) - .willReturn(Arrays.asList(server)); - return new DomainExtractingServerList(originalServerList, config, - approximateZoneFromHostname); - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaDisabledRibbonClientIntegrationTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaDisabledRibbonClientIntegrationTests.java deleted file mode 100644 index d54ceca7c..000000000 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaDisabledRibbonClientIntegrationTests.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.ribbon.eureka; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAvoidanceRule; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import com.netflix.niws.loadbalancer.NIWSDiscoveryPing; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration; -import org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.eureka.EurekaRibbonClientPreprocessorIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Ribbon Eureka client should be disabled if Eureka client is not enabled. - * - * @author Biju Kunjummen - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = TestConfiguration.class, - properties = "eureka.client.enabled=false") -@DirtiesContext -public class EurekaDisabledRibbonClientIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void serverListShouldNotBeEurekaBased() throws Exception { - assertThat(getLoadBalancer().getServerListImpl()) - .isNotInstanceOf(DomainExtractingServerList.class); - } - - @Test - public void ruleDefaultsToZoneAvoidance() throws Exception { - ZoneAvoidanceRule.class.cast(getLoadBalancer().getRule()); - } - - @Test - public void pingShouldNotBeEurekaBased() throws Exception { - assertThat(getLoadBalancer().getPing()).isNotInstanceOf(NIWSDiscoveryPing.class); - } - - @Test - public void serverIntrospectorShouldNotBeEurekaBased() throws Exception { - assertThat(this.factory.getInstance("foo", ServerIntrospector.class)) - .isNotInstanceOf(EurekaServerIntrospector.class); - } - - @SuppressWarnings("unchecked") - private ZoneAwareLoadBalancer getLoadBalancer() { - return (ZoneAwareLoadBalancer) this.factory.getLoadBalancer("foo"); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient("foo") - @Import({ UtilAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, - ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class, - EurekaDiscoveryClientConfiguration.class, EurekaClientAutoConfiguration.class, - RibbonEurekaAutoConfiguration.class }) - protected static class TestConfiguration { - - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfigurationTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfigurationTests.java deleted file mode 100644 index 7da3f6d80..000000000 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfigurationTests.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.eureka; - -import com.netflix.config.ConfigurationManager; -import com.netflix.config.DeploymentContext.ContextKey; -import com.netflix.config.DynamicStringProperty; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import com.netflix.niws.loadbalancer.DiscoveryEnabledServer; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import org.springframework.cloud.commons.util.InetUtils; -import org.springframework.cloud.commons.util.InetUtilsProperties; -import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.VALUE_NOT_SET; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.getProperty; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.getRibbonKey; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.setRibbonProperty; - -/** - * @author Dave Syer - * @author Ryan Baxter - */ -public class EurekaRibbonClientConfigurationTests { - - @After - @Before - public void close() { - ConfigurationManager.getDeploymentContext().setValue(ContextKey.zone, ""); - } - - @Test - @Ignore - public void basicConfigurationCreatedForLoadBalancer() { - EurekaClientConfigBean client = new EurekaClientConfigBean(); - EurekaInstanceConfigBean configBean = getEurekaInstanceConfigBean(); - client.getAvailabilityZones().put(client.getRegion(), "foo"); - SpringClientFactory clientFactory = new SpringClientFactory(); - EurekaRibbonClientConfiguration clientPreprocessor = new EurekaRibbonClientConfiguration( - client, "service", configBean, false); - clientPreprocessor.preprocess(); - ILoadBalancer balancer = clientFactory.getLoadBalancer("service"); - assertThat(balancer).isNotNull(); - @SuppressWarnings("unchecked") - ZoneAwareLoadBalancer aware = (ZoneAwareLoadBalancer) balancer; - assertThat(aware.getServerListImpl() instanceof DomainExtractingServerList) - .isTrue(); - assertThat(ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone)) - .isEqualTo("foo"); - } - - private EurekaInstanceConfigBean getEurekaInstanceConfigBean() { - return new EurekaInstanceConfigBean(new InetUtils(new InetUtilsProperties())); - } - - @Test - public void testSetProp() { - EurekaClientConfigBean client = new EurekaClientConfigBean(); - EurekaInstanceConfigBean configBean = getEurekaInstanceConfigBean(); - EurekaRibbonClientConfiguration preprocessor = new EurekaRibbonClientConfiguration( - client, "myService", configBean, false); - String serviceId = "myService"; - String suffix = "mySuffix"; - String value = "myValue"; - DynamicStringProperty property = getProperty(getRibbonKey(serviceId, suffix)); - assertThat(property.get()).as("property doesn't have default value") - .isEqualTo(VALUE_NOT_SET); - setRibbonProperty(serviceId, suffix, value); - assertThat(property.get()).as("property has wrong value").isEqualTo(value); - setRibbonProperty(serviceId, suffix, value); - assertThat(property.get()).as("property has wrong value").isEqualTo(value); - } - - @Test - public void testExplicitZone() { - EurekaClientConfigBean client = new EurekaClientConfigBean(); - EurekaInstanceConfigBean configBean = getEurekaInstanceConfigBean(); - configBean.getMetadataMap().put("zone", "myZone"); - EurekaRibbonClientConfiguration preprocessor = new EurekaRibbonClientConfiguration( - client, "myService", configBean, false); - preprocessor.preprocess(); - assertThat(ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone)) - .isEqualTo("myZone"); - } - - @Test - public void testDefaultZone() { - EurekaClientConfigBean client = new EurekaClientConfigBean(); - EurekaInstanceConfigBean configBean = getEurekaInstanceConfigBean(); - EurekaRibbonClientConfiguration preprocessor = new EurekaRibbonClientConfiguration( - client, "myService", configBean, false); - preprocessor.preprocess(); - assertThat(ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone)) - .isEqualTo("defaultZone"); - } - - @Test - public void testApproximateZone() { - EurekaClientConfigBean client = new EurekaClientConfigBean(); - EurekaInstanceConfigBean configBean = getEurekaInstanceConfigBean(); - configBean.setHostname("this.is.a.test.com"); - EurekaRibbonClientConfiguration preprocessor = new EurekaRibbonClientConfiguration( - client, "myService", configBean, true); - preprocessor.preprocess(); - assertThat(ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone)) - .isEqualTo("is.a.test.com"); - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPreprocessorIntegrationTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPreprocessorIntegrationTests.java deleted file mode 100644 index 70b5e8811..000000000 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPreprocessorIntegrationTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.eureka; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAvoidanceRule; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import com.netflix.niws.loadbalancer.NIWSDiscoveryPing; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration; -import org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.eureka.EurekaRibbonClientPreprocessorIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = TestConfiguration.class) -@DirtiesContext -public class EurekaRibbonClientPreprocessorIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void serverListDefaultsToDomainExtracting() throws Exception { - DomainExtractingServerList.class.cast(getLoadBalancer().getServerListImpl()); - } - - @Test - public void ruleDefaultsToZoneAvoidance() throws Exception { - ZoneAvoidanceRule.class.cast(getLoadBalancer().getRule()); - } - - @Test - public void pingDefaultsToDiscoveryPing() throws Exception { - NIWSDiscoveryPing.class.cast(getLoadBalancer().getPing()); - } - - @Test - public void serverIntrospectorDefaultsToEureka() throws Exception { - EurekaServerIntrospector.class - .cast(this.factory.getInstance("foo", ServerIntrospector.class)); - } - - @SuppressWarnings("unchecked") - private ZoneAwareLoadBalancer getLoadBalancer() { - return (ZoneAwareLoadBalancer) this.factory.getLoadBalancer("foo"); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient("foo") - @Import({ UtilAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, - ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class, - EurekaDiscoveryClientConfiguration.class, EurekaClientAutoConfiguration.class, - RibbonEurekaAutoConfiguration.class }) - protected static class TestConfiguration { - - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPropertyOverrideIntegrationTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPropertyOverrideIntegrationTests.java deleted file mode 100644 index 787c2dbba..000000000 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPropertyOverrideIntegrationTests.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.eureka; - -import com.netflix.discovery.EurekaClient; -import com.netflix.loadbalancer.ConfigurationBasedServerList; -import com.netflix.loadbalancer.DummyPing; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import com.netflix.niws.loadbalancer.NIWSDiscoveryPing; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.mockito.Mockito.mock; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest( - classes = EurekaRibbonClientPropertyOverrideIntegrationTests.TestConfiguration.class) -@DirtiesContext -public class EurekaRibbonClientPropertyOverrideIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void pingOverridesToDummy() throws Exception { - DummyPing.class.cast(getLoadBalancer("foo3").getPing()); - NIWSDiscoveryPing.class.cast(getLoadBalancer("bar").getPing()); - } - - @Test - public void serverListOverridesToTest() throws Exception { - ConfigurationBasedServerList.class - .cast(getLoadBalancer("foo3").getServerListImpl()); - DomainExtractingServerList.class.cast(getLoadBalancer("bar").getServerListImpl()); - } - - @SuppressWarnings("unchecked") - private ZoneAwareLoadBalancer getLoadBalancer(String name) { - return (ZoneAwareLoadBalancer) this.factory.getLoadBalancer(name); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClients - @ImportAutoConfiguration({ UtilAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class, - RibbonAutoConfiguration.class, RibbonEurekaAutoConfiguration.class }) - protected static class TestConfiguration { - - @Bean - public EurekaClient eurekaClient() { - return mock(EurekaClient.class); - } - - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonClientPreprocessorIntegrationTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonClientPreprocessorIntegrationTests.java deleted file mode 100644 index d556c3d30..000000000 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonClientPreprocessorIntegrationTests.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.eureka; - -import com.netflix.discovery.EurekaClient; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAvoidanceRule; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.util.InetUtils; -import org.springframework.cloud.commons.util.InetUtilsProperties; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilter; -import org.springframework.cloud.netflix.ribbon.eureka.RibbonClientPreprocessorIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = TestConfiguration.class) -@DirtiesContext -public class RibbonClientPreprocessorIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void serverListIsWrapped() throws Exception { - @SuppressWarnings("unchecked") - ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) this.factory - .getLoadBalancer("foo"); - DomainExtractingServerList.class.cast(loadBalancer.getServerListImpl()); - } - - @Test - public void ruleDefaultsToAvoidance() throws Exception { - @SuppressWarnings("unchecked") - ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) this.factory - .getLoadBalancer("foo"); - ZoneAvoidanceRule.class.cast(loadBalancer.getRule()); - } - - @Test - public void serverListFilterOverride() throws Exception { - @SuppressWarnings("unchecked") - ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) this.factory - .getLoadBalancer("foo"); - assertThat(ZonePreferenceServerListFilter.class.cast(loadBalancer.getFilter()) - .getZone()).isEqualTo("myTestZone"); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient("foo") - @ImportAutoConfiguration({ PropertyPlaceholderAutoConfiguration.class, - ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class }) - protected static class PlainConfiguration { - - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient(name = "foo", configuration = FooConfiguration.class) - @ImportAutoConfiguration({ PropertyPlaceholderAutoConfiguration.class, - ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class, - RibbonEurekaAutoConfiguration.class }) - protected static class TestConfiguration { - - @Bean - EurekaClient eurekaClient() { - return Mockito.mock(EurekaClient.class); - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class FooConfiguration { - - @Bean - public ZonePreferenceServerListFilter serverListFilter() { - ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - filter.setZone("myTestZone"); - return filter; - } - - @Bean - public EurekaInstanceConfigBean getEurekaInstanceConfigBean() { - EurekaInstanceConfigBean bean = new EurekaInstanceConfigBean( - new InetUtils(new InetUtilsProperties())); - return bean; - } - - } - -} diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfigurationTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfigurationTests.java deleted file mode 100644 index 29724e83c..000000000 --- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfigurationTests.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2016-2019 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 - * - * https://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.ribbon.eureka; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; -import org.springframework.context.annotation.Bean; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest( - classes = RibbonEurekaAutoConfigurationTests.EurekaClientDisabledApp.class, - properties = { "eureka.client.enabled=false", - "spring.application.name=eurekadisabledtest" }, - webEnvironment = RANDOM_PORT) -@DirtiesContext -public class RibbonEurekaAutoConfigurationTests { - - @Autowired - TestLoadbalancerClient testLoadbalancerClient; - - @Test - public void contextLoads() { - assertThat(testLoadbalancerClient.instanceFound).isFalse(); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - public static class EurekaClientDisabledApp { - - @Bean - public TestLoadbalancerClient testLoadbalanceClient( - LoadBalancerClient loadBalancerClient) { - return new TestLoadbalancerClient(loadBalancerClient); - } - - @Bean - public CommandLineRunner commandLineRunner( - final TestLoadbalancerClient testLoadbalancerClient) { - return args -> testLoadbalancerClient.doStuff(); - } - - } - - private static class TestLoadbalancerClient { - - Log log = LogFactory.getLog(this.getClass()); - - private LoadBalancerClient loadBalancerClient; - - private boolean instanceFound = false; - - TestLoadbalancerClient(LoadBalancerClient loadBalancerClient) { - this.loadBalancerClient = loadBalancerClient; - } - - public void doStuff() { - ServiceInstance serviceInstance = loadBalancerClient - .choose("https://host/doStuff"); - if (serviceInstance != null) { - log.info( - "There is a service instance, because Eureka discovery is enabled and the service is registered"); - instanceFound = true; - } - else { - log.warn( - "No instance found, because Eureka is disabled or there is no service matching."); - } - } - - } - -} diff --git a/spring-cloud-netflix-eureka-server/pom.xml b/spring-cloud-netflix-eureka-server/pom.xml index 6b3c43607..6c6e11b1e 100644 --- a/spring-cloud-netflix-eureka-server/pom.xml +++ b/spring-cloud-netflix-eureka-server/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT + 3.0.0.BUILD-SNAPSHOT .. spring-cloud-netflix-eureka-server @@ -41,10 +41,6 @@ spring-cloud-context true - - org.springframework.cloud - spring-cloud-netflix-hystrix - org.springframework.cloud spring-cloud-netflix-eureka-client @@ -75,17 +71,6 @@ - - com.netflix.archaius - archaius-core - - - - commons-configuration - commons-configuration - true - - javax.inject javax.inject diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java index 28bc67991..8bb5f8f41 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java @@ -30,7 +30,6 @@ import com.netflix.appinfo.AmazonInfo; import com.netflix.appinfo.ApplicationInfoManager; import com.netflix.appinfo.DataCenterInfo; import com.netflix.appinfo.InstanceInfo; -import com.netflix.config.ConfigurationManager; import com.netflix.discovery.shared.Application; import com.netflix.discovery.shared.Pair; import com.netflix.eureka.EurekaServerContext; @@ -118,10 +117,8 @@ public class EurekaController { private void populateHeader(Map model) { model.put("currentTime", StatusResource.getCurrentTimeAsString()); model.put("upTime", StatusInfo.getUpTime()); - model.put("environment", - ConfigurationManager.getDeploymentContext().getDeploymentEnvironment()); - model.put("datacenter", - ConfigurationManager.getDeploymentContext().getDeploymentDatacenter()); + model.put("environment", "N/A"); // FIXME: + model.put("datacenter", "N/A"); // FIXME: PeerAwareInstanceRegistry registry = getRegistry(); model.put("registry", registry); model.put("isBelowRenewThresold", registry.isBelowRenewThresold() == 1); diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerBootstrap.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerBootstrap.java index 2889f9272..329d4f89f 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerBootstrap.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerBootstrap.java @@ -21,7 +21,6 @@ import javax.servlet.ServletContext; import com.netflix.appinfo.ApplicationInfoManager; import com.netflix.appinfo.DataCenterInfo; import com.netflix.appinfo.InstanceInfo; -import com.netflix.config.ConfigurationManager; import com.netflix.discovery.EurekaClientConfig; import com.netflix.discovery.converters.JsonXStream; import com.netflix.discovery.converters.XmlXStream; @@ -44,18 +43,6 @@ public class EurekaServerBootstrap { private static final Log log = LogFactory.getLog(EurekaServerBootstrap.class); - private static final String TEST = "test"; - - private static final String ARCHAIUS_DEPLOYMENT_ENVIRONMENT = "archaius.deployment.environment"; - - private static final String EUREKA_ENVIRONMENT = "eureka.environment"; - - private static final String DEFAULT = "default"; - - private static final String ARCHAIUS_DEPLOYMENT_DATACENTER = "archaius.deployment.datacenter"; - - private static final String EUREKA_DATACENTER = "eureka.datacenter"; - protected EurekaServerConfig eurekaServerConfig; protected ApplicationInfoManager applicationInfoManager; @@ -109,30 +96,6 @@ public class EurekaServerBootstrap { protected void initEurekaEnvironment() throws Exception { log.info("Setting the eureka configuration.."); - String dataCenter = ConfigurationManager.getConfigInstance() - .getString(EUREKA_DATACENTER); - if (dataCenter == null) { - log.info( - "Eureka data center value eureka.datacenter is not set, defaulting to default"); - ConfigurationManager.getConfigInstance() - .setProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, DEFAULT); - } - else { - ConfigurationManager.getConfigInstance() - .setProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, dataCenter); - } - String environment = ConfigurationManager.getConfigInstance() - .getString(EUREKA_ENVIRONMENT); - if (environment == null) { - ConfigurationManager.getConfigInstance() - .setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, TEST); - log.info( - "Eureka environment value eureka.environment is not set, defaulting to test"); - } - else { - ConfigurationManager.getConfigInstance() - .setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, environment); - } } protected void initEurekaServerContext() throws Exception { diff --git a/spring-cloud-netflix-hystrix-contract/pom.xml b/spring-cloud-netflix-hystrix-contract/pom.xml deleted file mode 100644 index ffd5ca7fa..000000000 --- a/spring-cloud-netflix-hystrix-contract/pom.xml +++ /dev/null @@ -1,115 +0,0 @@ - - - 4.0.0 - - org.springframework.cloud - spring-cloud-build - 2.2.2.BUILD-SNAPSHOT - - - spring-cloud-netflix-hystrix-contract - 2.2.2.BUILD-SNAPSHOT - jar - spring-cloud-netflix-hystrix-contract - Spring Cloud Netflix Hystrix Contract - - 2.1.3.RELEASE - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.assertj - assertj-core - 3.11.0 - - - org.springframework.boot - spring-boot-starter-test - - - org.assertj - assertj-core - - - - - org.springframework.cloud - spring-cloud-contract-verifier - ${donotreplacespring-cloud-contract.version} - - - org.assertj - assertj-core - - - - - - - spring - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/libs-snapshot-local - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/libs-snapshot-local - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/libs-release-local - - false - - - - - - diff --git a/spring-cloud-netflix-hystrix-contract/src/main/java/org/springframework/cloud/netflix/hystrix/contract/HystrixContractUtils.java b/spring-cloud-netflix-hystrix-contract/src/main/java/org/springframework/cloud/netflix/hystrix/contract/HystrixContractUtils.java deleted file mode 100644 index 0fa0fb9a6..000000000 --- a/spring-cloud-netflix-hystrix-contract/src/main/java/org/springframework/cloud/netflix/hystrix/contract/HystrixContractUtils.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2016-2019 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 - * - * https://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.hystrix.contract; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Map; - -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.util.StreamUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * @author Daniel Lavoie - * - */ -public final class HystrixContractUtils { - - private HystrixContractUtils() { - throw new AssertionError("Must not instantiate utility class."); - } - - - public static String simpleBody() { - try { - return StreamUtils.copyToString(new DefaultResourceLoader() - .getResource("classpath:/stubs/simpleBody.json").getInputStream(), - StandardCharsets.UTF_8); - } - catch (IOException e) { - throw new IllegalStateException("Cannot read stub", e); - } - } - - public static void checkEvent(String event) { - assertThat(event).isNotNull(); - assertThat(event).isEqualTo("message"); - } - - public static void checkOrigin(Map origin) { - assertThat(origin.get("host")).isNotNull(); - assertThat(origin.get("port")).isNotNull(); - assertThat(origin.get("serviceId")).isEqualTo("application"); - // TODO: boot 2 changed application context id generation - assertThat(origin.get("id")).asString().startsWith("application"); - } - - public static void checkData(Map data, String group, String name) { - if (!data.get("type").equals("HystrixCommand")) { - assertThat(data.get("type")).isEqualTo("HystrixThreadPool"); - return; - } - assertThat(data.get("type")).isEqualTo("HystrixCommand"); - if (!data.get("name").equals(name)) { - return; - } - assertThat(data.get("name")).asString().isEqualTo(name); - assertThat(data.get("group")).isNotNull(); - assertThat(data.get("group")).isEqualTo(group); - assertThat(data.get("errorCount")).isEqualTo(0); - assertThat(data.get("errorPercentage")).isEqualTo(0); - assertThat(data.get("requestCount")).isInstanceOf(java.lang.Integer.class); - assertThat(data.get("currentConcurrentExecutionCount")) - .isInstanceOf(java.lang.Integer.class); - assertThat(data.get("rollingCountFailure")).isEqualTo(0); - assertThat(data.get("rollingCountSuccess")).isInstanceOf(java.lang.Integer.class); - assertThat(data.get("rollingCountShortCircuited")).isEqualTo(0); - assertThat(data.get("rollingCountFallbackSuccess")).isEqualTo(0); - assertThat(data.get("isCircuitBreakerOpen")).isEqualTo(false); - } - -} diff --git a/spring-cloud-netflix-hystrix-contract/src/main/resources/stubs/simpleBody.json b/spring-cloud-netflix-hystrix-contract/src/main/resources/stubs/simpleBody.json deleted file mode 100644 index 7e1bcfef5..000000000 --- a/spring-cloud-netflix-hystrix-contract/src/main/resources/stubs/simpleBody.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "origin":{ - "host":"192.168.1.192", - "port":0, - "serviceId":"application", - "id":"application:0" - }, - "event" : "message", - "data":{ - "type":"HystrixCommand", - "name":"application.hello", - "group":"Application", - "currentTime":1494840901153, - "isCircuitBreakerOpen":false, - "errorPercentage":0, - "errorCount":0, - "requestCount":1, - "rollingCountCollapsedRequests":0, - "rollingCountExceptionsThrown":0, - "rollingCountFailure":0, - "rollingCountFallbackFailure":0, - "rollingCountFallbackRejection":0, - "rollingCountFallbackSuccess":0, - "rollingCountResponsesFromCache":0, - "rollingCountSemaphoreRejected":0, - "rollingCountShortCircuited":0, - "rollingCountSuccess":0, - "rollingCountThreadPoolRejected":0, - "rollingCountTimeout":0, - "currentConcurrentExecutionCount":0, - "latencyExecute_mean":0, - "latencyExecute":{ - "0":0, - "25":0, - "50":0, - "75":0, - "90":0, - "95":0, - "99":0, - "99.5":0, - "100":0 - }, - "latencyTotal_mean":0, - "latencyTotal":{ - "0":0, - "25":0, - "50":0, - "75":0, - "90":0, - "95":0, - "99":0, - "99.5":0, - "100":0 - }, - "propertyValue_circuitBreakerRequestVolumeThreshold":20, - "propertyValue_circuitBreakerSleepWindowInMilliseconds":5000, - "propertyValue_circuitBreakerErrorThresholdPercentage":50, - "propertyValue_circuitBreakerForceOpen":false, - "propertyValue_circuitBreakerForceClosed":false, - "propertyValue_circuitBreakerEnabled":true, - "propertyValue_executionIsolationStrategy":"THREAD", - "propertyValue_executionIsolationThreadTimeoutInMilliseconds":1000, - "propertyValue_executionIsolationThreadInterruptOnTimeout":true, - "propertyValue_executionIsolationThreadPoolKeyOverride":null, - "propertyValue_executionIsolationSemaphoreMaxConcurrentRequests":10, - "propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests":10, - "propertyValue_metricsRollingStatisticalWindowInMilliseconds":10000, - "propertyValue_requestCacheEnabled":true, - "propertyValue_requestLogEnabled":true, - "reportingHosts":1 - } -} diff --git a/spring-cloud-netflix-hystrix-dashboard/pom.xml b/spring-cloud-netflix-hystrix-dashboard/pom.xml deleted file mode 100644 index 05bd2ba82..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/pom.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - 4.0.0 - spring-cloud-netflix-hystrix-dashboard - Spring Cloud Netflix Hystrix - https://projects.spring.io/spring-cloud/ - - org.springframework.cloud - spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT - .. - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-freemarker - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework.cloud - spring-cloud-netflix-hystrix - - - org.apache.httpcomponents - httpclient - - - com.netflix.hystrix - hystrix-core - - - com.netflix.hystrix - hystrix-metrics-event-stream - - - org.webjars - jquery - 2.1.1 - - - org.webjars - d3js - 3.4.11 - - - org.springframework.boot - spring-boot-starter-test - test - - - diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/EnableHystrixDashboard.java b/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/EnableHystrixDashboard.java deleted file mode 100644 index d5c38b61a..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/EnableHystrixDashboard.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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 - * - * https://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.hystrix.dashboard; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.context.annotation.Import; - -/** - * @author Spencer Gibb - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Import(HystrixDashboardConfiguration.class) -public @interface EnableHystrixDashboard { - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfiguration.java b/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfiguration.java deleted file mode 100644 index 6d6a78c42..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfiguration.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.dashboard; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Map; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.Header; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.conn.PoolingClientConnectionManager; -import org.apache.http.params.HttpConnectionParams; -import org.apache.http.params.HttpParams; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpHeaders; -import org.springframework.ui.freemarker.SpringTemplateLoader; -import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; - -/** - * @author Dave Syer - * @author Roy Clarkson - * @author Fahim Farook - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties(HystrixDashboardProperties.class) -public class HystrixDashboardConfiguration { - - private static final String DEFAULT_TEMPLATE_LOADER_PATH = "classpath:/templates/"; - - private static final String DEFAULT_CHARSET = "UTF-8"; - - @Autowired - private HystrixDashboardProperties dashboardProperties; - - @Bean - public HasFeatures hystrixDashboardFeature() { - return HasFeatures.namedFeature("Hystrix Dashboard", - HystrixDashboardConfiguration.class); - } - - /** - * Overrides Spring Boot's {@link FreeMarkerAutoConfiguration} to prefer using a - * {@link SpringTemplateLoader} instead of the file system. This corrects an issue - * where Spring Boot may use an empty 'templates' file resource to resolve templates - * instead of the packaged Hystrix classpath templates. - * @return FreeMarker configuration - */ - @Bean - public FreeMarkerConfigurer freeMarkerConfigurer() { - FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); - configurer.setTemplateLoaderPaths(DEFAULT_TEMPLATE_LOADER_PATH); - configurer.setDefaultEncoding(DEFAULT_CHARSET); - configurer.setPreferFileSystemAccess(false); - return configurer; - } - - @Bean - public ServletRegistrationBean proxyStreamServlet() { - final ProxyStreamServlet proxyStreamServlet = new ProxyStreamServlet(); - proxyStreamServlet.setEnableIgnoreConnectionCloseHeader( - this.dashboardProperties.isEnableIgnoreConnectionCloseHeader()); - final ServletRegistrationBean registration = new ServletRegistrationBean( - proxyStreamServlet, "/proxy.stream"); - registration.setInitParameters(this.dashboardProperties.getInitParameters()); - return registration; - } - - @Bean - public HystrixDashboardController hsytrixDashboardController() { - return new HystrixDashboardController(); - } - - /** - * Proxy an EventStream request (data.stream via proxy.stream) since EventStream does - * not yet support CORS (https://bugs.webkit.org/show_bug.cgi?id=61862) so that a UI - * can request a stream from a different server. - */ - public static class ProxyStreamServlet extends HttpServlet { - - private static final Log log = LogFactory.getLog(ProxyStreamServlet.class); - - private static final long serialVersionUID = 1L; - - private static final String CONNECTION_CLOSE_VALUE = "close"; - - private boolean enableIgnoreConnectionCloseHeader = false; - - public void setEnableIgnoreConnectionCloseHeader( - boolean enableIgnoreConnectionCloseHeader) { - this.enableIgnoreConnectionCloseHeader = enableIgnoreConnectionCloseHeader; - } - - public ProxyStreamServlet() { - super(); - } - - /** - * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest - * request, javax.servlet.http.HttpServletResponse response) - */ - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - String origin = request.getParameter("origin"); - if (origin == null) { - response.setStatus(500); - response.getWriter().println( - "Required parameter 'origin' missing. Example: 107.20.175.135:7001"); - return; - } - origin = origin.trim(); - - HttpGet httpget = null; - InputStream is = null; - boolean hasFirstParameter = false; - StringBuilder url = new StringBuilder(); - if (!origin.startsWith("http")) { - url.append("http://"); - } - url.append(origin); - if (origin.contains("?")) { - hasFirstParameter = true; - } - Map params = request.getParameterMap(); - for (String key : params.keySet()) { - if (!key.equals("origin")) { - String[] values = params.get(key); - String value = values[0].trim(); - if (hasFirstParameter) { - url.append("&"); - } - else { - url.append("?"); - hasFirstParameter = true; - } - url.append(key).append("=").append(value); - } - } - String proxyUrl = url.toString(); - log.info("\n\nProxy opening connection to: " + proxyUrl + "\n\n"); - try { - httpget = new HttpGet(proxyUrl); - HttpClient client = ProxyConnectionManager.httpClient; - HttpResponse httpResponse = client.execute(httpget); - int statusCode = httpResponse.getStatusLine().getStatusCode(); - if (statusCode == HttpStatus.SC_OK) { - // writeTo swallows exceptions and never quits even if outputstream is - // throwing IOExceptions (such as broken pipe) ... since the - // inputstream is infinite - // httpResponse.getEntity().writeTo(new - // OutputStreamWrapper(response.getOutputStream())); - // so I copy it manually ... - is = httpResponse.getEntity().getContent(); - - // set headers - copyHeadersToServletResponse(httpResponse.getAllHeaders(), response); - - // copy data from source to response - OutputStream os = response.getOutputStream(); - int b = -1; - while ((b = is.read()) != -1) { - try { - os.write(b); - if (b == 10 /** flush buffer on line feed */ - ) { - os.flush(); - } - } - catch (Exception ex) { - if (ex.getClass().getSimpleName() - .equalsIgnoreCase("ClientAbortException")) { - // don't throw an exception as this means the user closed - // the connection - log.debug( - "Connection closed by client. Will stop proxying ..."); - // break out of the while loop - break; - } - else { - // received unknown error while writing so throw an - // exception - throw new RuntimeException(ex); - } - } - } - } - else { - log.warn("Failed opening connection to " + proxyUrl + " : " - + statusCode + " : " + httpResponse.getStatusLine()); - } - } - catch (Exception ex) { - log.error("Error proxying request: " + url, ex); - } - finally { - if (httpget != null) { - try { - httpget.abort(); - } - catch (Exception ex) { - log.error("failed aborting proxy connection.", ex); - } - } - - // httpget.abort() MUST be called first otherwise is.close() hangs - // (because data is still streaming?) - if (is != null) { - // this should already be closed by httpget.abort() above - try { - is.close(); - } - catch (Exception ex) { - // ignore errors on close - } - } - } - - } - - private void copyHeadersToServletResponse(Header[] headers, - HttpServletResponse response) { - for (Header header : headers) { - // Some versions of Cloud Foundry (HAProxy) are - // incorrectly setting a "Connection: close" header - // causing the Hystrix dashboard to close the connection - // to the stream - // https://github.com/cloudfoundry/gorouter/issues/71 - if (this.enableIgnoreConnectionCloseHeader - && HttpHeaders.CONNECTION.equalsIgnoreCase(header.getName()) - && CONNECTION_CLOSE_VALUE.equalsIgnoreCase(header.getValue())) { - log.warn("Ignoring 'Connection: close' header from stream response"); - } - else if (!HttpHeaders.TRANSFER_ENCODING - .equalsIgnoreCase(header.getName())) { - response.addHeader(header.getName(), header.getValue()); - } - } - } - - @SuppressWarnings("deprecation") - private static class ProxyConnectionManager { - - private final static PoolingClientConnectionManager threadSafeConnectionManager = new PoolingClientConnectionManager(); - - private final static HttpClient httpClient = new DefaultHttpClient( - threadSafeConnectionManager); - - static { - log.debug("Initialize ProxyConnectionManager"); - /* common settings */ - HttpParams httpParams = httpClient.getParams(); - HttpConnectionParams.setConnectionTimeout(httpParams, 5000); - HttpConnectionParams.setSoTimeout(httpParams, 10000); - - /* number of connections to allow */ - threadSafeConnectionManager.setDefaultMaxPerRoute(400); - threadSafeConnectionManager.setMaxTotal(400); - } - - } - - } - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardController.java b/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardController.java deleted file mode 100644 index 3d372e9b6..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardController.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.dashboard; - -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.context.request.RequestAttributes; -import org.springframework.web.context.request.WebRequest; - -/** - * @author Dave Syer - */ -@Controller -public class HystrixDashboardController { - - @RequestMapping("/hystrix") - public String home(Model model, WebRequest request) { - model.addAttribute("basePath", extractPath(request)); - return "hystrix/index"; - } - - @RequestMapping("/hystrix/{path}") - public String monitor(@PathVariable String path, Model model, WebRequest request) { - model.addAttribute("basePath", extractPath(request)); - model.addAttribute("contextPath", request.getContextPath()); - return "hystrix/" + path; - } - - private String extractPath(WebRequest request) { - String path = request.getContextPath() + request.getAttribute( - "org.springframework." - + "web.servlet.HandlerMapping.pathWithinHandlerMapping", - RequestAttributes.SCOPE_REQUEST); - return path; - } - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardProperties.java b/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardProperties.java deleted file mode 100644 index dc80f9bc1..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardProperties.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.dashboard; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * @author Roy Clarkson - * @author Fahim Farook - */ -@ConfigurationProperties("hystrix.dashboard") -public class HystrixDashboardProperties { - - /** - * Directs the Hystrix dashboard to ignore 'Connection:close' headers if present in - * the Hystrix response stream. - */ - private boolean enableIgnoreConnectionCloseHeader = false; - - /** - * Initialization parameters for {@link ProxyStreamServlet}. ProxyStreamServlet itself - * is not dependent on any initialization parameters, but could be used for adding web - * container specific configurations. i.e. wl-dispatch-policy for WebLogic. - */ - private Map initParameters = new HashMap<>(); - - public boolean isEnableIgnoreConnectionCloseHeader() { - return enableIgnoreConnectionCloseHeader; - } - - public void setEnableIgnoreConnectionCloseHeader( - boolean enableIgnoreConnectionCloseHeader) { - this.enableIgnoreConnectionCloseHeader = enableIgnoreConnectionCloseHeader; - } - - public Map getInitParameters() { - return this.initParameters; - } - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/hystrixCommand.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/hystrixCommand.css deleted file mode 100644 index c31117435..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/hystrixCommand.css +++ /dev/null @@ -1,200 +0,0 @@ -.dependencies .spacer { - width: 100%; - margin: 0 auto; - padding-top:4px; - clear:both; -} - - -.dependencies .last { - margin-right: 0px; -} - -.dependencies span.loading { - display: block; - padding-top: 6%; - padding-bottom: 6%; - color: gray; - text-align: center; -} - -.dependencies span.loading.failed { - color: red; -} - - -.dependencies div.monitor { - float: left; - margin-right:5px; - margin-top:5px; -} - -.dependencies div.monitor p.name { - font-weight:bold; - font-size: 10pt; - text-align: right; - padding-bottom: 5px; -} - -.dependencies div.monitor_data { - margin: 0 auto; -} - -/* override the HREF when we have specified it as a tooltip to not act like a link */ -.dependencies div.monitor_data a.tooltip { - text-decoration: none; - cursor: default; -} - -.dependencies div.monitor_data div.counters { - text-align: right; - padding-bottom: 10px; - font-size: 10pt; - clear: both; - -} - -.dependencies div.monitor_data div.counters div.cell { - display: inline; - float: right; -} - -.dependencies .borderRight { - border-right: 1px solid grey; - padding-right: 6px; - padding-left: 8px; -} - -.dependencies div.cell .line { - display: block; -} - -.dependencies div.monitor_data a, -.dependencies span.rate_value { - font-weight:bold; -} - - -.dependencies span.smaller { - font-size: 8pt; - color: grey; -} - - - -.dependencies div.tableRow { - width:100%; - white-space: nowrap; - font-size: 8pt; - margin: 0 auto; - clear:both; - padding-left:26%; -} - -.dependencies div.tableRow .cell { - float:left; -} - -.dependencies div.tableRow .header { - width:18%; - text-align:right; - padding-right:2%; -} - -.dependencies div.tableRow .data { - width:17%; - font-weight: bold; - text-align:right; -} - - -.dependencies div.monitor { - width: 245px; /* we want a fixed width instead of percentage as I want the boxes to be a set size and then fill in as many as can fit in each row ... this allows 3 columns on an iPad */ - height: 155px; -} - -.dependencies .success { - color: green; -} -.dependencies .shortCircuited { - color: blue; -} -.dependencies .timeout { - color: #FF9900; /* shade of orange */ -} -.dependencies .failure { - color: red; -} - -.badRequest { - color: #00CC99; -} - -.dependencies .rejected { - color: purple; -} - -.dependencies .exceptionsThrown { - color: brown; -} - -.dependencies div.monitor_data a.rate { - color: black; - font-size: 11pt; -} - -.dependencies div.rate { - padding-top: 1px; - clear:both; - text-align:right; -} - -.dependencies .errorPercentage { - color: grey; -} - -.dependencies div.cell .errorPercentage { - padding-left:5px; - font-size: 12pt !important; -} - - -.dependencies div.monitor div.chart { -} - -.dependencies div.monitor div.chart svg { -} - -.dependencies div.monitor div.chart svg text { - fill: white; -} - - -.dependencies div.circuitStatus { - width:100%; - white-space: nowrap; - font-size: 9pt; - margin: 0 auto; - clear:both; - text-align:right; - padding-top: 4px; -} - -.dependencies #hidden { - width:1px; - height:1px; - background: lightgrey; - display: none; -} - - - -/* sparkline */ -.dependencies path { - stroke: steelblue; - stroke-width: 1; - fill: none; -} - - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/hystrixCommand.js b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/hystrixCommand.js deleted file mode 100644 index 9d5724d27..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/hystrixCommand.js +++ /dev/null @@ -1,542 +0,0 @@ - -(function(window) { - - // cache the templates we use on this page as global variables (asynchronously) - jQuery.get(getRelativePath("components/hystrixCommand/templates/hystrixCircuit.html"), function(data) { - hystrixTemplateCircuit = data; - }); - jQuery.get(getRelativePath("components/hystrixCommand/templates/hystrixCircuitContainer.html"), function(data) { - hystrixTemplateCircuitContainer = data; - }); - - function getRelativePath(path) { - var p = location.pathname.slice(0, location.pathname.lastIndexOf("/")+1); - return p + path; - } - - /** - * Object containing functions for displaying and updating the UI with streaming data. - * - * Publish this externally as "HystrixCommandMonitor" - */ - window.HystrixCommandMonitor = function(containerId, args) { - - var self = this; // keep scope under control - self.args = args; - if(self.args == undefined) { - self.args = {}; - } - - this.containerId = containerId; - - /** - * Initialization on construction - */ - // intialize various variables we use for visualization - var maxXaxisForCircle="40%"; - var maxYaxisForCircle="40%"; - var maxRadiusForCircle="125"; - - // CIRCUIT_BREAKER circle visualization settings - self.circuitCircleRadius = d3.scale.pow().exponent(0.5).domain([0, 400]).range(["5", maxRadiusForCircle]); // requests per second per host - self.circuitCircleYaxis = d3.scale.linear().domain([0, 400]).range(["30%", maxXaxisForCircle]); - self.circuitCircleXaxis = d3.scale.linear().domain([0, 400]).range(["30%", maxYaxisForCircle]); - self.circuitColorRange = d3.scale.linear().domain([10, 25, 40, 50]).range(["green", "#FFCC00", "#FF9900", "red"]); - self.circuitErrorPercentageColorRange = d3.scale.linear().domain([0, 10, 35, 50]).range(["grey", "black", "#FF9900", "red"]); - - /** - * We want to keep sorting in the background since data values are always changing, so this will re-sort every X milliseconds - * to maintain whatever sort the user (or default) has chosen. - * - * In other words, sorting only for adds/deletes is not sufficient as all but alphabetical sort are dynamically changing. - */ - setInterval(function() { - // sort since we have added a new one - self.sortSameAsLast(); - }, 10000); - - - /** - * END of Initialization on construction - */ - - /** - * Event listener to handle new messages from EventSource as streamed from the server. - */ - /* public */ self.eventSourceMessageListener = function(e) { - var data = JSON.parse(e.data); - if(data) { - // check for reportingHosts (if not there, set it to 1 for singleHost vs cluster) - if(!data.reportingHosts) { - data.reportingHosts = 1; - } - - if(data && data.type == 'HystrixCommand') { - if (data.deleteData == 'true') { - deleteCircuit(data.escapedName); - } else { - displayCircuit(data); - } - } - } - }; - - /** - * Pre process the data before displying in the UI. - * e.g Get Averages from sums, do rate calculation etc. - */ - function preProcessData(data) { - // set defaults for values that may be missing from older streams - setIfMissing(data, "rollingCountBadRequests", 0); - // assert all the values we need - validateData(data); - // escape string used in jQuery & d3 selectors - data.escapedName = data.name.replace(/([ !"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g,'\\$1'); - // do math - convertAllAvg(data); - calcRatePerSecond(data); - } - - function setIfMissing(data, key, defaultValue) { - if(data[key] == undefined) { - data[key] = defaultValue; - } - } - - /** - * Since the stream of data can be aggregated from multiple hosts in a tiered manner - * the aggregation just sums everything together and provides us the denominator (reportingHosts) - * so we must divide by it to get an average per instance value. - * - * We want to do this on any numerical values where we want per instance rather than cluster-wide sum. - */ - function convertAllAvg(data) { - convertAvg(data, "errorPercentage", true); - convertAvg(data, "latencyExecute_mean", false); - convertAvg(data, "latencyTotal_mean", false); - } - - function convertAvg(data, key, decimal) { - if (decimal) { - data[key] = getInstanceAverage(data[key], data["reportingHosts"], decimal); - } else { - data[key] = getInstanceAverage(data[key], data["reportingHosts"], decimal); - } - } - - function getInstanceAverage(value, reportingHosts, decimal) { - if (decimal) { - return roundNumber(value/reportingHosts); - } else { - return Math.floor(value/reportingHosts); - } - } - - function calcRatePerSecond(data) { - var numberSeconds = data["propertyValue_metricsRollingStatisticalWindowInMilliseconds"] / 1000; - - var totalRequests = data["requestCount"]; - if (totalRequests < 0) { - totalRequests = 0; - } - data["ratePerSecond"] = roundNumber(totalRequests / numberSeconds); - data["ratePerSecondPerHost"] = roundNumber(totalRequests / numberSeconds / data["reportingHosts"]) ; - } - - function validateData(data) { - assertNotNull(data,"reportingHosts"); - assertNotNull(data,"type"); - assertNotNull(data,"name"); - assertNotNull(data,"group"); - // assertNotNull(data,"currentTime"); - assertNotNull(data,"isCircuitBreakerOpen"); - assertNotNull(data,"errorPercentage"); - assertNotNull(data,"errorCount"); - assertNotNull(data,"requestCount"); - assertNotNull(data,"rollingCountCollapsedRequests"); - assertNotNull(data,"rollingCountExceptionsThrown"); - assertNotNull(data,"rollingCountFailure"); - assertNotNull(data,"rollingCountFallbackFailure"); - assertNotNull(data,"rollingCountFallbackRejection"); - assertNotNull(data,"rollingCountFallbackSuccess"); - assertNotNull(data,"rollingCountResponsesFromCache"); - assertNotNull(data,"rollingCountSemaphoreRejected"); - assertNotNull(data,"rollingCountShortCircuited"); - assertNotNull(data,"rollingCountSuccess"); - assertNotNull(data,"rollingCountThreadPoolRejected"); - assertNotNull(data,"rollingCountTimeout"); - assertNotNull(data,"rollingCountBadRequests"); - assertNotNull(data,"currentConcurrentExecutionCount"); - assertNotNull(data,"latencyExecute_mean"); - assertNotNull(data,"latencyExecute"); - assertNotNull(data,"latencyTotal_mean"); - assertNotNull(data,"latencyTotal"); - assertNotNull(data,"propertyValue_circuitBreakerRequestVolumeThreshold"); - assertNotNull(data,"propertyValue_circuitBreakerSleepWindowInMilliseconds"); - assertNotNull(data,"propertyValue_circuitBreakerErrorThresholdPercentage"); - assertNotNull(data,"propertyValue_circuitBreakerForceOpen"); - assertNotNull(data,"propertyValue_circuitBreakerForceClosed"); - assertNotNull(data,"propertyValue_executionIsolationStrategy"); - assertNotNull(data,"propertyValue_executionIsolationThreadTimeoutInMilliseconds"); - assertNotNull(data,"propertyValue_executionIsolationThreadInterruptOnTimeout"); - // assertNotNull(data,"propertyValue_executionIsolationThreadPoolKeyOverride"); - assertNotNull(data,"propertyValue_executionIsolationSemaphoreMaxConcurrentRequests"); - assertNotNull(data,"propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests"); - assertNotNull(data,"propertyValue_requestCacheEnabled"); - assertNotNull(data,"propertyValue_requestLogEnabled"); - assertNotNull(data,"propertyValue_metricsRollingStatisticalWindowInMilliseconds"); - } - - function assertNotNull(data, key) { - if(data[key] == undefined) { - throw new Error("Key Missing: " + key + " for " + data.name); - } - } - - /** - * Method to display the CIRCUIT data - * - * @param data - */ - /* private */ function displayCircuit(data) { - - try { - preProcessData(data); - } catch (err) { - log("Failed preProcessData: " + err.message); - return; - } - - // add the 'addCommas' function to the 'data' object so the HTML templates can use it - data.addCommas = addCommas; - // add the 'roundNumber' function to the 'data' object so the HTML templates can use it - data.roundNumber = roundNumber; - // add the 'getInstanceAverage' function to the 'data' object so the HTML templates can use it - data.getInstanceAverage = getInstanceAverage; - - var addNew = false; - // check if we need to create the container - if(!$('#CIRCUIT_' + data.escapedName).length) { - // args for display - if(self.args.includeDetailIcon != undefined && self.args.includeDetailIcon) { - data.includeDetailIcon = true; - }else { - data.includeDetailIcon = false; - } - - // it doesn't exist so add it - var html = tmpl(hystrixTemplateCircuitContainer, data); - // remove the loading thing first - $('#' + containerId + ' span.loading').remove(); - // now create the new data and add it - $('#' + containerId + '').append(html); - - // add the default sparkline graph - d3.selectAll('#graph_CIRCUIT_' + data.escapedName + ' svg').append("svg:path"); - - // remember this is new so we can trigger a sort after setting data - addNew = true; - } - - - // now update/insert the data - $('#CIRCUIT_' + data.escapedName + ' div.monitor_data').html(tmpl(hystrixTemplateCircuit, data)); - - var ratePerSecond = data.ratePerSecond; - var ratePerSecondPerHost = data.ratePerSecondPerHost; - var ratePerSecondPerHostDisplay = ratePerSecondPerHost; - var errorThenVolume = (data.errorPercentage * 100000000) + ratePerSecond; - - // set the rates on the div element so it's available for sorting - $('#CIRCUIT_' + data.escapedName).attr('rate_value', ratePerSecond); - $('#CIRCUIT_' + data.escapedName).attr('error_then_volume', errorThenVolume); - - // update errorPercentage color on page - $('#CIRCUIT_' + data.escapedName + ' a.errorPercentage').css('color', self.circuitErrorPercentageColorRange(data.errorPercentage)); - - updateCircle('circuit', '#CIRCUIT_' + data.escapedName + ' circle', ratePerSecondPerHostDisplay, data.errorPercentage); - - if(data.graphValues) { - // we have a set of values to initialize with - updateSparkline('circuit', '#CIRCUIT_' + data.escapedName + ' path', data.graphValues); - } else { - updateSparkline('circuit', '#CIRCUIT_' + data.escapedName + ' path', ratePerSecond); - } - - if(addNew) { - // sort since we added a new circuit - self.sortSameAsLast(); - } - } - - /* round a number to X digits: num => the number to round, dec => the number of decimals */ - /* private */ function roundNumber(num) { - var dec=1; - var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec); - var resultAsString = result.toString(); - if(resultAsString.indexOf('.') == -1) { - resultAsString = resultAsString + '.0'; - } - return resultAsString; - }; - - - - - /* private */ function updateCircle(variablePrefix, cssTarget, rate, errorPercentage) { - var newXaxisForCircle = self[variablePrefix + 'CircleXaxis'](rate); - if(parseInt(newXaxisForCircle) > parseInt(maxXaxisForCircle)) { - newXaxisForCircle = maxXaxisForCircle; - } - var newYaxisForCircle = self[variablePrefix + 'CircleYaxis'](rate); - if(parseInt(newYaxisForCircle) > parseInt(maxYaxisForCircle)) { - newYaxisForCircle = maxYaxisForCircle; - } - var newRadiusForCircle = self[variablePrefix + 'CircleRadius'](rate); - if(parseInt(newRadiusForCircle) > parseInt(maxRadiusForCircle)) { - newRadiusForCircle = maxRadiusForCircle; - } - - d3.selectAll(cssTarget) - .transition() - .duration(400) - .attr("cy", newYaxisForCircle) - .attr("cx", newXaxisForCircle) - .attr("r", newRadiusForCircle) - .style("fill", self[variablePrefix + 'ColorRange'](errorPercentage)); - } - - /* private */ function updateSparkline(variablePrefix, cssTarget, newDataPoint) { - var currentTimeMilliseconds = new Date().getTime(); - var data = self[variablePrefix + cssTarget + '_data']; - if(typeof data == 'undefined') { - // else it's new - if(typeof newDataPoint == 'object') { - // we received an array of values, so initialize with it - data = newDataPoint; - } else { - // v: VALUE, t: TIME_IN_MILLISECONDS - data = [{"v":parseFloat(newDataPoint),"t":currentTimeMilliseconds}]; - } - self[variablePrefix + cssTarget + '_data'] = data; - } else { - if(typeof newDataPoint == 'object') { - /* if an array is passed in we'll replace the cached one */ - data = newDataPoint; - } else { - // else we just add to the existing one - data.push({"v":parseFloat(newDataPoint),"t":currentTimeMilliseconds}); - } - } - - while(data.length > 200) { // 400 should be plenty for the 2 minutes we have the scale set to below even with a very low update latency - // remove data so we don't keep increasing forever - data.shift(); - } - - if(data.length == 1 && data[0].v == 0) { - //console.log("we have a single 0 so skipping"); - // don't show if we have a single 0 - return; - } - - if(data.length > 1 && data[0].v == 0 && data[1].v != 0) { - //console.log("we have a leading 0 so removing it"); - // get rid of a leading 0 if the following number is not a 0 - data.shift(); - } - - var xScale = d3.time.scale().domain([new Date(currentTimeMilliseconds-(60*1000*2)), new Date(currentTimeMilliseconds)]).range([0, 140]); - - var yMin = d3.min(data, function(d) { return d.v; }); - var yMax = d3.max(data, function(d) { return d.v; }); - var yScale = d3.scale.linear().domain([yMin, yMax]).nice().range([60, 0]); // y goes DOWN, so 60 is the "lowest" - - sparkline = d3.svg.line() - // assign the X function to plot our line as we wish - .x(function(d,i) { - // return the X coordinate where we want to plot this datapoint based on the time - return xScale(new Date(d.t)); - }) - .y(function(d) { - return yScale(d.v); - }) - .interpolate("basis"); - - d3.selectAll(cssTarget).attr("d", sparkline(data)); - } - - /* private */ function deleteCircuit(circuitName) { - $('#CIRCUIT_' + circuitName).remove(); - } - - }; - - // public methods for sorting - HystrixCommandMonitor.prototype.sortByVolume = function() { - var direction = "desc"; - if(this.sortedBy == 'rate_desc') { - direction = 'asc'; - } - this.sortByVolumeInDirection(direction); - }; - - HystrixCommandMonitor.prototype.sortByVolumeInDirection = function(direction) { - this.sortedBy = 'rate_' + direction; - $('#' + this.containerId + ' div.monitor').tsort({order: direction, attr: 'rate_value'}); - }; - - HystrixCommandMonitor.prototype.sortAlphabetically = function() { - var direction = "asc"; - if(this.sortedBy == 'alph_asc') { - direction = 'desc'; - } - this.sortAlphabeticalInDirection(direction); - }; - - HystrixCommandMonitor.prototype.sortAlphabeticalInDirection = function(direction) { - this.sortedBy = 'alph_' + direction; - $('#' + this.containerId + ' div.monitor').tsort("p.name", {order: direction}); - }; - - - HystrixCommandMonitor.prototype.sortByError = function() { - var direction = "desc"; - if(this.sortedBy == 'error_desc') { - direction = 'asc'; - } - this.sortByErrorInDirection(direction); - }; - - HystrixCommandMonitor.prototype.sortByErrorInDirection = function(direction) { - this.sortedBy = 'error_' + direction; - $('#' + this.containerId + ' div.monitor').tsort(".errorPercentage .value", {order: direction}); - }; - - HystrixCommandMonitor.prototype.sortByErrorThenVolume = function() { - var direction = "desc"; - if(this.sortedBy == 'error_then_volume_desc') { - direction = 'asc'; - } - this.sortByErrorThenVolumeInDirection(direction); - }; - - HystrixCommandMonitor.prototype.sortByErrorThenVolumeInDirection = function(direction) { - this.sortedBy = 'error_then_volume_' + direction; - $('#' + this.containerId + ' div.monitor').tsort({order: direction, attr: 'error_then_volume'}); - }; - - HystrixCommandMonitor.prototype.sortByLatency90 = function() { - var direction = "desc"; - if(this.sortedBy == 'lat90_desc') { - direction = 'asc'; - } - this.sortedBy = 'lat90_' + direction; - this.sortByMetricInDirection(direction, ".latency90 .value"); - }; - - HystrixCommandMonitor.prototype.sortByLatency99 = function() { - var direction = "desc"; - if(this.sortedBy == 'lat99_desc') { - direction = 'asc'; - } - this.sortedBy = 'lat99_' + direction; - this.sortByMetricInDirection(direction, ".latency99 .value"); - }; - - HystrixCommandMonitor.prototype.sortByLatency995 = function() { - var direction = "desc"; - if(this.sortedBy == 'lat995_desc') { - direction = 'asc'; - } - this.sortedBy = 'lat995_' + direction; - this.sortByMetricInDirection(direction, ".latency995 .value"); - }; - - HystrixCommandMonitor.prototype.sortByLatencyMean = function() { - var direction = "desc"; - if(this.sortedBy == 'latMean_desc') { - direction = 'asc'; - } - this.sortedBy = 'latMean_' + direction; - this.sortByMetricInDirection(direction, ".latencyMean .value"); - }; - - HystrixCommandMonitor.prototype.sortByLatencyMedian = function() { - var direction = "desc"; - if(this.sortedBy == 'latMedian_desc') { - direction = 'asc'; - } - this.sortedBy = 'latMedian_' + direction; - this.sortByMetricInDirection(direction, ".latencyMedian .value"); - }; - - HystrixCommandMonitor.prototype.sortByMetricInDirection = function(direction, metric) { - $('#' + this.containerId + ' div.monitor').tsort(metric, {order: direction}); - }; - - // this method is for when new divs are added to cause the elements to be sorted to whatever the user last chose - HystrixCommandMonitor.prototype.sortSameAsLast = function() { - if(this.sortedBy == 'alph_asc') { - this.sortAlphabeticalInDirection('asc'); - } else if(this.sortedBy == 'alph_desc') { - this.sortAlphabeticalInDirection('desc'); - } else if(this.sortedBy == 'rate_asc') { - this.sortByVolumeInDirection('asc'); - } else if(this.sortedBy == 'rate_desc') { - this.sortByVolumeInDirection('desc'); - } else if(this.sortedBy == 'error_asc') { - this.sortByErrorInDirection('asc'); - } else if(this.sortedBy == 'error_desc') { - this.sortByErrorInDirection('desc'); - } else if(this.sortedBy == 'error_then_volume_asc') { - this.sortByErrorThenVolumeInDirection('asc'); - } else if(this.sortedBy == 'error_then_volume_desc') { - this.sortByErrorThenVolumeInDirection('desc'); - } else if(this.sortedBy == 'lat90_asc') { - this.sortByMetricInDirection('asc', '.latency90 .value'); - } else if(this.sortedBy == 'lat90_desc') { - this.sortByMetricInDirection('desc', '.latency90 .value'); - } else if(this.sortedBy == 'lat99_asc') { - this.sortByMetricInDirection('asc', '.latency99 .value'); - } else if(this.sortedBy == 'lat99_desc') { - this.sortByMetricInDirection('desc', '.latency99 .value'); - } else if(this.sortedBy == 'lat995_asc') { - this.sortByMetricInDirection('asc', '.latency995 .value'); - } else if(this.sortedBy == 'lat995_desc') { - this.sortByMetricInDirection('desc', '.latency995 .value'); - } else if(this.sortedBy == 'latMean_asc') { - this.sortByMetricInDirection('asc', '.latencyMean .value'); - } else if(this.sortedBy == 'latMean_desc') { - this.sortByMetricInDirection('desc', '.latencyMean .value'); - } else if(this.sortedBy == 'latMedian_asc') { - this.sortByMetricInDirection('asc', '.latencyMedian .value'); - } else if(this.sortedBy == 'latMedian_desc') { - this.sortByMetricInDirection('desc', '.latencyMedian .value'); - } - }; - - // default sort type and direction - this.sortedBy = 'alph_asc'; - - - // a temporary home for the logger until we become more sophisticated - function log(message) { - console.log(message); - }; - - function addCommas(nStr){ - nStr += ''; - if(nStr.length <=3) { - return nStr; //shortcut if we don't need commas - } - x = nStr.split('.'); - x1 = x[0]; - x2 = x.length > 1 ? '.' + x[1] : ''; - var rgx = /(\d+)(\d{3})/; - while (rgx.test(x1)) { - x1 = x1.replace(rgx, '$1' + ',' + '$2'); - } - return x1 + x2; - } -})(window); diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/magnifying-glass-icon-20.png b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/magnifying-glass-icon-20.png deleted file mode 100644 index 4898b4854..000000000 Binary files a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/magnifying-glass-icon-20.png and /dev/null differ diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/magnifying-glass-icon.png b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/magnifying-glass-icon.png deleted file mode 100644 index 04feae917..000000000 Binary files a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/magnifying-glass-icon.png and /dev/null differ diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuit.html b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuit.html deleted file mode 100644 index e9328ab8f..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuit.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - - -
- <% if(propertyValue_circuitBreakerForceClosed) { %> - [ Forced Closed ] - <% } %> - <% if(propertyValue_circuitBreakerForceOpen) { %> - Circuit Forced Open - <% } else { %> - <% if(isCircuitBreakerOpen == reportingHosts) { %> - Circuit Open - <% } else if(isCircuitBreakerOpen == 0) { %> - Circuit Closed - <% } else { - /* We have some circuits that are open */ - %> - Circuit <%= isCircuitBreakerOpen.toString().replace("true", "Open").replace("false", "Closed") %>) - <% } %> - <% } %> -
- -
- -
- <% if(typeof reportingHosts != 'undefined') { %> -
Hosts
-
<%= reportingHosts %>
- <% } else { %> -
Host
-
Single
- <% } %> -
90th
-
<%= getInstanceAverage(latencyExecute['90'], reportingHosts, false) %>ms
-
-
-
Median
-
<%= getInstanceAverage(latencyExecute['50'], reportingHosts, false) %>ms
-
99th
-
<%= getInstanceAverage(latencyExecute['99'], reportingHosts, false) %>ms
-
-
-
Mean
-
<%= latencyExecute_mean %>ms
-
99.5th
-
<%= getInstanceAverage(latencyExecute['99.5'], reportingHosts, false) %>ms
-
- - diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuitContainer.html b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuitContainer.html deleted file mode 100644 index 1a47ef7b7..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuitContainer.html +++ /dev/null @@ -1,40 +0,0 @@ -
- <% - var displayName = name; - var toolTip = ""; - if(displayName.length > 32) { - displayName = displayName.substring(0,4) + "..." + displayName.substring(displayName.length-20, displayName.length); - toolTip = "title=\"" + name + "\""; - } - %> - -
-
- <% if(includeDetailIcon) { %> -

style="padding-right:16px"> - <%= displayName %> - -

- <% } else { %> -

><%= displayName %>

- <% } %> -
-
-
-
-
- - -
diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuitProperties.html b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuitProperties.html deleted file mode 100644 index 5b8c0fae8..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixCommand/templates/hystrixCircuitProperties.html +++ /dev/null @@ -1,6 +0,0 @@ -
-
Median
-
<%= sla_medianLastMinute %>ms
-
99th
-
<%= sla_percentile99LastMinute %>ms
-
diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/hystrixThreadPool.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/hystrixThreadPool.css deleted file mode 100644 index e82ea5cc1..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/hystrixThreadPool.css +++ /dev/null @@ -1,141 +0,0 @@ -.dependencyThreadPools .spacer { - width: 100%; - margin: 0 auto; - padding-top:4px; - clear:both; -} - - -.dependencyThreadPools .last { - margin-right: 0px; -} - -.dependencyThreadPools span.loading { - display: block; - padding-top: 6%; - padding-bottom: 6%; - color: gray; - text-align: center; -} - -.dependencyThreadPools span.loading.failed { - color: red; -} - - -.dependencyThreadPools div.monitor { - float: left; - margin-right:5px; /* these are tweaked to look good on desktop and iPad portrait, and fit things densely */ - margin-top:5px; -} - -.dependencyThreadPools div.monitor p.name { - font-weight:bold; - font-size: 10pt; - text-align: right; - padding-bottom: 5px; -} - -.dependencyThreadPools div.monitor_data { - margin: 0 auto; -} - -.dependencyThreadPools span.smaller { - font-size: 8pt; - color: grey; -} - - -.dependencyThreadPools div.tableRow { - width:100%; - white-space: nowrap; - font-size: 8pt; - margin: 0 auto; - clear:both; -} - -.dependencyThreadPools div.tableRow .cell { - float:left; -} - -.dependencyThreadPools div.tableRow .header { - text-align:right; - padding-right:5px; -} - -.dependencyThreadPools div.tableRow .header.left { - width:85px; -} - -.dependencyThreadPools div.tableRow .header.right { - width:75px; -} - -.dependencyThreadPools div.tableRow .data { - font-weight: bold; - text-align:right; -} - -.dependencyThreadPools div.tableRow .data.left { - width:30px; -} - -.dependencyThreadPools div.tableRow .data.right { - width:45px; -} - -.dependencyThreadPools div.monitor { - width: 245px; /* we want a fixed width instead of percentage as I want the boxes to be a set size and then fill in as many as can fit in each row ... this allows 3 columns on an iPad */ - height: 110px; -} - - - - - -/* override the HREF when we have specified it as a tooltip to not act like a link */ -.dependencyThreadPools div.monitor_data a.tooltip { - text-decoration: none; - cursor: default; -} - -.dependencyThreadPools div.monitor_data a.rate { - font-weight:bold; - color: black; - font-size: 11pt; -} - -.dependencyThreadPools div.rate { - padding-top: 1px; - clear:both; - text-align:right; -} - -.dependencyThreadPools span.rate_value { - font-weight:bold; -} - - - - - - - -.dependencyThreadPools div.monitor div.chart { -} - -.dependencyThreadPools div.monitor div.chart svg { -} - -.dependencyThreadPools div.monitor div.chart svg text { - fill: white; -} - -.dependencyThreadPools #hidden { - width:1px; - height:1px; - background: lightgrey; - display: none; -} - - diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/hystrixThreadPool.js b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/hystrixThreadPool.js deleted file mode 100644 index 851562bf8..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/hystrixThreadPool.js +++ /dev/null @@ -1,343 +0,0 @@ - -(function(window) { - - // cache the templates we use on this page as global variables (asynchronously) - jQuery.get(getRelativePath("components/hystrixThreadPool/templates/hystrixThreadPool.html"), function(data) { - htmlTemplate = data; - }); - jQuery.get(getRelativePath("components/hystrixThreadPool/templates/hystrixThreadPoolContainer.html"), function(data) { - htmlTemplateContainer = data; - }); - - function getRelativePath(path) { - var p = location.pathname.slice(0, location.pathname.lastIndexOf("/")+1); - return p + path; - } - - /** - * Object containing functions for displaying and updating the UI with streaming data. - * - * Publish this externally as "HystrixThreadPoolMonitor" - */ - window.HystrixThreadPoolMonitor = function(containerId) { - - var self = this; // keep scope under control - - this.containerId = containerId; - - /** - * Initialization on construction - */ - // intialize various variables we use for visualization - var maxXaxisForCircle="40%"; - var maxYaxisForCircle="40%"; - var maxRadiusForCircle="125"; - var maxDomain = 2000; - - self.circleRadius = d3.scale.pow().exponent(0.5).domain([0, maxDomain]).range(["5", maxRadiusForCircle]); // requests per second per host - self.circleYaxis = d3.scale.linear().domain([0, maxDomain]).range(["30%", maxXaxisForCircle]); - self.circleXaxis = d3.scale.linear().domain([0, maxDomain]).range(["30%", maxYaxisForCircle]); - self.colorRange = d3.scale.linear().domain([10, 25, 40, 50]).range(["green", "#FFCC00", "#FF9900", "red"]); - self.errorPercentageColorRange = d3.scale.linear().domain([0, 10, 35, 50]).range(["grey", "black", "#FF9900", "red"]); - - /** - * We want to keep sorting in the background since data values are always changing, so this will re-sort every X milliseconds - * to maintain whatever sort the user (or default) has chosen. - * - * In other words, sorting only for adds/deletes is not sufficient as all but alphabetical sort are dynamically changing. - */ - setInterval(function() { - // sort since we have added a new one - self.sortSameAsLast(); - }, 1000) - - /** - * END of Initialization on construction - */ - - /** - * Event listener to handle new messages from EventSource as streamed from the server. - */ - /* public */ self.eventSourceMessageListener = function(e) { - var data = JSON.parse(e.data); - if(data) { - // check for reportingHosts (if not there, set it to 1 for singleHost vs cluster) - if(!data.reportingHosts) { - data.reportingHosts = 1; - } - - if(data && data.type == 'HystrixThreadPool') { - if (data.deleteData == 'true') { - deleteThreadPool(data.escapedName); - } else { - displayThreadPool(data); - } - } - } - } - - /** - * Pre process the data before displying in the UI. - * e.g Get Averages from sums, do rate calculation etc. - */ - function preProcessData(data) { - validateData(data); - // escape string used in jQuery & d3 selectors - data.escapedName = data.name.replace(/([ !"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g,'\\$1'); - // do math - converAllAvg(data); - calcRatePerSecond(data); - } - - function converAllAvg(data) { - convertAvg(data, "propertyValue_queueSizeRejectionThreshold", false); - } - - function convertAvg(data, key, decimal) { - if (decimal) { - data[key] = roundNumber(data[key]/data["reportingHosts"]); - } else { - data[key] = Math.floor(data[key]/data["reportingHosts"]); - } - } - - function calcRatePerSecond(data) { - var numberSeconds = data["propertyValue_metricsRollingStatisticalWindowInMilliseconds"] / 1000; - - var totalThreadsExecuted = data["rollingCountThreadsExecuted"]; - if (totalThreadsExecuted < 0) { - totalThreadsExecuted = 0; - } - data["ratePerSecond"] = roundNumber(totalThreadsExecuted / numberSeconds); - data["ratePerSecondPerHost"] = roundNumber(totalThreadsExecuted / numberSeconds / data["reportingHosts"]); - } - - function validateData(data) { - - assertNotNull(data,"type"); - assertNotNull(data,"name"); - // assertNotNull(data,"currentTime"); - assertNotNull(data,"currentActiveCount"); - assertNotNull(data,"currentCompletedTaskCount"); - assertNotNull(data,"currentCorePoolSize"); - assertNotNull(data,"currentLargestPoolSize"); - assertNotNull(data,"currentMaximumPoolSize"); - assertNotNull(data,"currentPoolSize"); - assertNotNull(data,"currentQueueSize"); - assertNotNull(data,"currentTaskCount"); - assertNotNull(data,"rollingCountThreadsExecuted"); - assertNotNull(data,"rollingMaxActiveThreads"); - assertNotNull(data,"reportingHosts"); - - assertNotNull(data,"propertyValue_queueSizeRejectionThreshold"); - assertNotNull(data,"propertyValue_metricsRollingStatisticalWindowInMilliseconds"); - } - - function assertNotNull(data, key) { - if(data[key] == undefined) { - if (key == "dependencyOwner") { - data["dependencyOwner"] = data.name; - } else { - throw new Error("Key Missing: " + key + " for " + data.name) - } - } - } - - /** - * Method to display the THREAD_POOL data - * - * @param data - */ - /* private */ function displayThreadPool(data) { - - try { - preProcessData(data); - } catch (err) { - log("Failed preProcessData: " + err.message); - return; - } - - // add the 'addCommas' function to the 'data' object so the HTML templates can use it - data.addCommas = addCommas; - // add the 'roundNumber' function to the 'data' object so the HTML templates can use it - data.roundNumber = roundNumber; - - var addNew = false; - // check if we need to create the container - if(!$('#THREAD_POOL_' + data.escapedName).length) { - // it doesn't exist so add it - var html = tmpl(htmlTemplateContainer, data); - // remove the loading thing first - $('#' + containerId + ' span.loading').remove(); - // get the current last column and remove the 'last' class from it - $('#' + containerId + ' div.last').removeClass('last'); - // now create the new data and add it - $('#' + containerId + '').append(html); - // add the 'last' class to the column we just added - $('#' + containerId + ' div.monitor').last().addClass('last'); - - // add the default sparkline graph - d3.selectAll('#graph_THREAD_POOL_' + data.escapedName + ' svg').append("svg:path"); - - // remember this is new so we can trigger a sort after setting data - addNew = true; - } - - // set the rate on the div element so it's available for sorting - $('#THREAD_POOL_' + data.escapedName).attr('rate_value', data.ratePerSecondPerHost); - - // now update/insert the data - $('#THREAD_POOL_' + data.escapedName + ' div.monitor_data').html(tmpl(htmlTemplate, data)); - - // set variables for circle visualization - var rate = data.ratePerSecondPerHost; - // we will treat each item in queue as 1% of an error visualization - // ie. 5 threads in queue per instance == 5% error percentage - var errorPercentage = data.currentQueueSize / data.reportingHosts; - - updateCircle('#THREAD_POOL_' + data.escapedName + ' circle', rate, errorPercentage); - - if(addNew) { - // sort since we added a new circuit - self.sortSameAsLast(); - } - } - - /* round a number to X digits: num => the number to round, dec => the number of decimals */ - /* private */ function roundNumber(num) { - var dec=1; // we are hardcoding to support only 1 decimal so that our padding logic at the end is simple - var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec); - var resultAsString = result.toString(); - if(resultAsString.indexOf('.') == -1) { - resultAsString = resultAsString + '.'; - for(var i=0; i parseInt(maxXaxisForCircle)) { - newXaxisForCircle = maxXaxisForCircle; - } - var newYaxisForCircle = self.circleYaxis(rate); - if(parseInt(newYaxisForCircle) > parseInt(maxYaxisForCircle)) { - newYaxisForCircle = maxYaxisForCircle; - } - var newRadiusForCircle = self.circleRadius(rate); - if(parseInt(newRadiusForCircle) > parseInt(maxRadiusForCircle)) { - newRadiusForCircle = maxRadiusForCircle; - } - - d3.selectAll(cssTarget) - .transition() - .duration(400) - .attr("cy", newYaxisForCircle) - .attr("cx", newXaxisForCircle) - .attr("r", newRadiusForCircle) - .style("fill", self.colorRange(errorPercentage)); - } - - /* private */ function deleteThreadPool(poolName) { - $('#THREAD_POOL_' + poolName).remove(); - } - - } - - // public methods for sorting - HystrixThreadPoolMonitor.prototype.sortByVolume = function() { - var direction = "desc"; - if(this.sortedBy == 'rate_desc') { - direction = 'asc'; - } - this.sortByVolumeInDirection(direction); - } - - HystrixThreadPoolMonitor.prototype.sortByVolumeInDirection = function(direction) { - this.sortedBy = 'rate_' + direction; - $('#' + this.containerId + ' div.monitor').tsort({order: direction, attr: 'rate_value'}); - } - - HystrixThreadPoolMonitor.prototype.sortAlphabetically = function() { - var direction = "asc"; - if(this.sortedBy == 'alph_asc') { - direction = 'desc'; - } - this.sortAlphabeticalInDirection(direction); - } - - HystrixThreadPoolMonitor.prototype.sortAlphabeticalInDirection = function(direction) { - this.sortedBy = 'alph_' + direction; - $('#' + this.containerId + ' div.monitor').tsort("p.name", {order: direction}); - } - - HystrixThreadPoolMonitor.prototype.sortByMetricInDirection = function(direction, metric) { - $('#' + this.containerId + ' div.monitor').tsort(metric, {order: direction}); - } - - // this method is for when new divs are added to cause the elements to be sorted to whatever the user last chose - HystrixThreadPoolMonitor.prototype.sortSameAsLast = function() { - if(this.sortedBy == 'alph_asc') { - this.sortAlphabeticalInDirection('asc'); - } else if(this.sortedBy == 'alph_desc') { - this.sortAlphabeticalInDirection('desc'); - } else if(this.sortedBy == 'rate_asc') { - this.sortByVolumeInDirection('asc'); - } else if(this.sortedBy == 'rate_desc') { - this.sortByVolumeInDirection('desc'); - } else if(this.sortedBy == 'error_asc') { - this.sortByErrorInDirection('asc'); - } else if(this.sortedBy == 'error_desc') { - this.sortByErrorInDirection('desc'); - } else if(this.sortedBy == 'lat90_asc') { - this.sortByMetricInDirection('asc', 'p90'); - } else if(this.sortedBy == 'lat90_desc') { - this.sortByMetricInDirection('desc', 'p90'); - } else if(this.sortedBy == 'lat99_asc') { - this.sortByMetricInDirection('asc', 'p99'); - } else if(this.sortedBy == 'lat99_desc') { - this.sortByMetricInDirection('desc', 'p99'); - } else if(this.sortedBy == 'lat995_asc') { - this.sortByMetricInDirection('asc', 'p995'); - } else if(this.sortedBy == 'lat995_desc') { - this.sortByMetricInDirection('desc', 'p995'); - } else if(this.sortedBy == 'latMean_asc') { - this.sortByMetricInDirection('asc', 'pMean'); - } else if(this.sortedBy == 'latMean_desc') { - this.sortByMetricInDirection('desc', 'pMean'); - } else if(this.sortedBy == 'latMedian_asc') { - this.sortByMetricInDirection('asc', 'pMedian'); - } else if(this.sortedBy == 'latMedian_desc') { - this.sortByMetricInDirection('desc', 'pMedian'); - } - } - - // default sort type and direction - this.sortedBy = 'alph_asc'; - - - // a temporary home for the logger until we become more sophisticated - function log(message) { - console.log(message); - }; - - function addCommas(nStr){ - nStr += ''; - if(nStr.length <=3) { - return nStr; //shortcut if we don't need commas - } - x = nStr.split('.'); - x1 = x[0]; - x2 = x.length > 1 ? '.' + x[1] : ''; - var rgx = /(\d+)(\d{3})/; - while (rgx.test(x1)) { - x1 = x1.replace(rgx, '$1' + ',' + '$2'); - } - return x1 + x2; - } -})(window) - - diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/templates/hystrixThreadPool.html b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/templates/hystrixThreadPool.html deleted file mode 100644 index 1e653ccbf..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/templates/hystrixThreadPool.html +++ /dev/null @@ -1,33 +0,0 @@ - -
- - - - -
- -
-
Active
-
<%= currentActiveCount%>
- -
Max Active
-
<%= addCommas(rollingMaxActiveThreads)%>
-
- -
-
Queued
-
<%= currentQueueSize %>
-
Executions
-
<%= addCommas(rollingCountThreadsExecuted)%>
-
-
-
Pool Size
-
<%= currentPoolSize %>
-
Queue Size
-
<%= propertyValue_queueSizeRejectionThreshold %>
-
- \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/templates/hystrixThreadPoolContainer.html b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/templates/hystrixThreadPoolContainer.html deleted file mode 100644 index 035ae845e..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/components/hystrixThreadPool/templates/hystrixThreadPoolContainer.html +++ /dev/null @@ -1,34 +0,0 @@ -
- - <% - var displayName = name; - var toolTip = ""; - if(displayName.length > 32) { - displayName = displayName.substring(0,4) + "..." + displayName.substring(displayName.length-20, displayName.length); - toolTip = "title=\"" + name + "\""; - } - %> - -
-

><%= displayName %>

-
-
-
- - - - -
diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/global.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/global.css deleted file mode 100644 index 74e80d171..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/global.css +++ /dev/null @@ -1,71 +0,0 @@ -@IMPORT url("resets.css"); - -body { - font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; -} - -img, object, embed { - max-width: 100%; -} - -img { - height: auto; -} - - -#header { - background: #FFFFFF url(../images/hystrix-logo-tagline-tiny.png) no-repeat scroll 99% 0%; - height: 65px; - margin-bottom: 5px; -} - -#header h2 { - float:left; - color: black; - position:relative; - padding-left: 20px; - top: 26px; - font-size: 20px; - font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; -} - -#header .header_nav { - position:absolute; - top:48px; - right:15px; -} - -#header .header_links { - float:left; - color: lightgray; - font-size: 18px; - top: 3px; - padding-left: 10px; - font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; -} - -#header .header_links a { - color: white; -} - -#header .header_clusters { - float:left; - position:relative; - padding-left: 10px; - top: -1px; - font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; -} - - -@media screen and (min-width: 1500px) { - - #header .header_nav { - top:13px; - right:130px; - } - - #header { - background: #FFFFFF url(../images/hystrix-logo-tagline-tiny.png) no-repeat scroll 99% 50%; - height: 65px; - } -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/monitor.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/monitor.css deleted file mode 100644 index 04b929c22..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/monitor.css +++ /dev/null @@ -1,105 +0,0 @@ -.container { - padding-left: 20px; - padding-right: 20px; -} - -.row { - width: 100%; - margin: 0 auto; - overflow: hidden; -} - -.spacer { - width: 100%; - margin: 0 auto; - padding-top:4px; - clear:both; -} - - -.last { - margin-right: 0px; -} - -.menubar { - overflow: hidden; - border-bottom: 1px solid black; -} - -.menubar div { - padding-bottom:5px; - - margin: 0 auto; - overflow: hidden; - - font-size: 80%; - font-family:'Bookman Old Style',Bookman,'URW Bookman L','Palatino Linotype',serif; - - float:left; -} - -.menubar .title { - float: left; - padding-right: 20px; - - font-size: 110%; - font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; - font-weight: bold; - - vertical-align: bottom; -} - -.menubar .menu_actions { - float: left; - position:relative; - top: 4px; -} - -.menubar .menu_legend { - float: right; - position:relative; - top: 4px; - -} - -h3.sectionHeader { - color: black; - font-size: 110%; - padding-top: 4px; - padding-bottom: 4px; - padding-left: 8px; - font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; - background: lightgrey; -} - -.success { - color: green; -} -.shortCircuited { - color: blue; -} -.timeout { - color: #FF9900; /* shade of orange */ -} -.failure { - color: red; -} - -.rejected { - color: purple; -} - -.exceptionsThrown { - color: brown; -} - -.badRequest { - color: #00CC99; -} - -@media screen and (max-width: 1100px) { - .container { - padding-left: 5px; - padding-right: 5px; - } -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/resets.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/resets.css deleted file mode 100644 index 4d137c7e3..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/resets.css +++ /dev/null @@ -1,102 +0,0 @@ -/* -html5doctor.com Reset Stylesheet -v1.6.1 -Last Updated: 2010-09-17 -Author: Richard Clark - http://richclarkdesign.com -Twitter: @rich_clark -*/ - -html, body, div, span, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -abbr, address, cite, code, -del, dfn, em, img, ins, kbd, q, samp, -small, strong, sub, sup, var, -b, i, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, figcaption, figure, -footer, header, hgroup, menu, nav, section, summary, -time, mark, audio, video { - margin:0; - padding:0; - border:0; - outline:0; - font-size:100%; - vertical-align:baseline; - background:transparent; -} - -body { - line-height:1; -} - -article,aside,details,figcaption,figure, -footer,header,hgroup,menu,nav,section { - display:block; -} - -nav ul { - list-style:none; -} - -blockquote, q { - quotes:none; -} - -blockquote:before, blockquote:after, -q:before, q:after { - content:''; - content:none; -} - -a { - margin:0; - padding:0; - font-size:100%; - vertical-align:baseline; - background:transparent; -} - -/* change colours to suit your needs */ -ins { - background-color:#ff9; - color:#000; - text-decoration:none; -} - -/* change colours to suit your needs */ -mark { - background-color:#ff9; - color:#000; - font-style:italic; - font-weight:bold; -} - -del { - text-decoration: line-through; -} - -abbr[title], dfn[title] { - border-bottom:1px dotted; - cursor:help; -} - -table { - border-collapse:collapse; - border-spacing:0; -} - -/* change border colour to suit your needs */ -hr { - display:block; - height:1px; - border:0; - border-top:1px solid #cccccc; - margin:1em 0; - padding:0; -} - -input, select { - vertical-align:middle; -} \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/1236_grid.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/1236_grid.css deleted file mode 100644 index ca5653416..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/1236_grid.css +++ /dev/null @@ -1,21 +0,0 @@ -/* SimpleGrid - a fork of CSSGrid by Crowd Favorite (https://github.com/crowdfavorite/css-grid) - * https://simplegrid.info - * by Conor Muirhead (http://conor.cc) of Early LLC (https://earlymade.com) - * License: https://creativecommons.org/licenses/MIT/ */ - -/* Containers */ -body { font-size: 1.125em; } -.grid{ width:1206px; } - -/* 6-Col Grid Sizes */ -.slot-0,.slot-1,.slot-2,.slot-3,.slot-4,.slot-5{ width:176px; } /* Sixths */ -.slot-0-1,.slot-1-2,.slot-2-3,.slot-3-4,.slot-4-5{ width:382px; } /* Thirds */ -.slot-0-1-2-3,.slot-1-2-3-4,.slot-2-3-4-5{ width:794px; } /* Two-Thirds */ -.slot-0-1-2-3-4,.slot-1-2-3-4-5{ width:1000px; } /* Five-Sixths */ - -/* 4-Col Grid Sizes */ -.slot-6,.slot-7,.slot-8,.slot-9{ width:279px; } /* Quarters */ -.slot-6-7-8,.slot-7-8-9{ width:897px; } /* Three-Quarters */ - -/* 6-Col/4-Col Shared Grid Sizes */ -.slot-0-1-2,.slot-1-2-3,.slot-2-3-4,.slot-3-4-5, .slot-6-7,.slot-7-8,.slot-8-9{ width:588px; } /* Halves */ \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/720_grid.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/720_grid.css deleted file mode 100644 index c694dc27d..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/720_grid.css +++ /dev/null @@ -1,33 +0,0 @@ -/* SimpleGrid - a fork of CSSGrid by Crowd Favorite (https://github.com/crowdfavorite/css-grid) - * https://simplegrid.info - * by Conor Muirhead (http://conor.cc) of Early LLC (https://earlymade.com) - * License: https://creativecommons.org/licenses/MIT/ */ - -/* Containers */ -body { font-size: 0.875em; padding: 0; } -.grid{ margin:0 auto; padding: 0 10px; width:700px; } -.row{ clear:left; } - -/* Slots Setup */ -.slot-0,.slot-1,.slot-2,.slot-3,.slot-4,.slot-5,.slot-0-1,.slot-0-1-2,.slot-0-1-2-3,.slot-0-1-2-3-4,.slot-0-1-2-3-4-5,.slot-1-2,.slot-1-2-3,.slot-1-2-3-4,.slot-1-2-3-4-5,.slot-2-3,.slot-2-3-4,.slot-2-3-4-5,.slot-3-4,.slot-3-4-5,.slot-4-5,.slot-6,.slot-7,.slot-8,.slot-9,.slot-6-7,.slot-6-7-8,.slot-6-7-8-9,.slot-7-8,.slot-7-8-9,.slot-8-9{ display:inline; float:left; margin-left:20px; } - -/* 6-Col Grid Sizes */ -.slot-0,.slot-1,.slot-2,.slot-3,.slot-4,.slot-5{ width:100px; } /* Sixths */ -.slot-0-1,.slot-1-2,.slot-2-3,.slot-3-4,.slot-4-5{ width:220px; } /* Thirds */ -.slot-0-1-2-3,.slot-1-2-3-4,.slot-2-3-4-5{ width:460px; } /* Two-Thirds */ -.slot-0-1-2-3-4,.slot-1-2-3-4-5{ width:580px; } /* Five-Sixths */ - -/* 4-Col Grid Sizes */ -.slot-6,.slot-7,.slot-8,.slot-9{ width:160px; } /* Quarters */ -.slot-6-7-8,.slot-7-8-9{ width:520px; } /* Three-Quarters */ - -/* 6-Col/4-Col Shared Grid Sizes */ -.slot-0-1-2,.slot-1-2-3,.slot-2-3-4,.slot-3-4-5, .slot-6-7,.slot-7-8,.slot-8-9{ width:340px; } /* Halves */ -.slot-0-1-2-3-4-5, .slot-6-7-8-9{ width: 100%; } /* Full-Width */ - -/* Zeroing Out Leftmost Slot Margins */ -.slot-0,.slot-0-1,.slot-0-1-2,.slot-0-1-2-3,.slot-0-1-2-3-4,.slot-0-1-2-3-4-5,.slot-6,.slot-6-7,.slot-6-7-8,.slot-6-7-8-9,.slot-1 .slot-1,.slot-1-2 .slot-1,.slot-1-2 .slot-1-2,.slot-1-2-3 .slot-1,.slot-1-2-3 .slot-1-2,.slot-1-2-3 .slot-1-2-3,.slot-1-2-3-4 .slot-1,.slot-1-2-3-4 .slot-1-2,.slot-1-2-3-4 .slot-1-2-3,.slot-1-2-3-4 .slot-1-2-3-4,.slot-1-2-3-4-5 .slot-1,.slot-1-2-3-4-5 .slot-1-2,.slot-1-2-3-4-5 .slot-1-2-3,.slot-1-2-3-4-5 .slot-1-2-3-4,.slot-1-2-3-4-5 .slot-1-2-3-4-5,.slot-2 .slot-2,.slot-2-3 .slot-2,.slot-2-3 .slot-2-3,.slot-2-3-4 .slot-2,.slot-2-3-4 .slot-2-3,.slot-2-3-4 .slot-2-3-4,.slot-2-3-4-5 .slot-2,.slot-2-3-4-5 .slot-2-3,.slot-2-3-4-5 .slot-2-3-4,.slot-2-3-4-5 .slot-2-3-4-5,.slot-3 .slot-3,.slot-3-4 .slot-3,.slot-3-4 .slot-3-4,.slot-3-4-5 .slot-3,.slot-3-4-5 .slot-3-4,.slot-3-4-5 .slot-3-4-5,.slot-4 .slot-4,.slot-4-5 .slot-4,.slot-4-5 .slot-4-5,.slot-5 .slot-5,.slot-7 .slot-7,.slot-7-8 .slot-7,.slot-7-8 .slot-7-8,.slot-7-8-9 .slot-7,.slot-7-8-9 .slot-7-8,.slot-7-8-9 .slot-7-8-9,.slot-8 .slot-8,.slot-8-9 .slot-8,.slot-8-9 .slot-8-9{ margin-left:0 !important; } /* Important is to avoid repeating this in larger screen css files */ - -/* Row Clearfix */ -.row:after{ visibility:hidden; display:block; font-size:0; content:" "; clear:both; height:0; } -.row{ zoom:1; } \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/986_grid.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/986_grid.css deleted file mode 100644 index 0496041f7..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/986_grid.css +++ /dev/null @@ -1,24 +0,0 @@ -/* SimpleGrid - a fork of CSSGrid by Crowd Favorite (https://github.com/crowdfavorite/css-grid) - * https://simplegrid.info - * by Conor Muirhead (http://conor.cc) of Early LLC (https://earlymade.com) - * License: https://creativecommons.org/licenses/MIT/ */ - -/* Containers */ -body { font-size: 100%; } -.grid{ width:966px; } - -/* Slots Setup */ -.slot-0,.slot-1,.slot-2,.slot-3,.slot-4,.slot-5,.slot-0-1,.slot-0-1-2,.slot-0-1-2-3,.slot-0-1-2-3-4,.slot-0-1-2-3-4-5,.slot-1-2,.slot-1-2-3,.slot-1-2-3-4,.slot-1-2-3-4-5,.slot-2-3,.slot-2-3-4,.slot-2-3-4-5,.slot-3-4,.slot-3-4-5,.slot-4-5,.slot-6,.slot-7,.slot-8,.slot-9,.slot-6-7,.slot-6-7-8,.slot-6-7-8-9,.slot-7-8,.slot-7-8-9,.slot-8-9{ display:inline; float:left; margin-left:30px; } - -/* 6-Col Grid Sizes */ -.slot-0,.slot-1,.slot-2,.slot-3,.slot-4,.slot-5{ width:136px; } /* Sixths */ -.slot-0-1,.slot-1-2,.slot-2-3,.slot-3-4,.slot-4-5{ width:302px; } /* Thirds */ -.slot-0-1-2-3,.slot-1-2-3-4,.slot-2-3-4-5{ width:634px; } /* Two-Thirds */ -.slot-0-1-2-3-4,.slot-1-2-3-4-5{ width:800px; } /* Five-Sixths */ - -/* 4-Col Grid Sizes */ -.slot-6,.slot-7,.slot-8,.slot-9{ width:219px; } /* Quarters */ -.slot-6-7-8,.slot-7-8-9{ width:717px; } /* Three-Quarters */ - -/* 6-Col/4-Col Shared Grid Sizes */ -.slot-0-1-2,.slot-1-2-3,.slot-2-3-4,.slot-3-4-5, .slot-6-7,.slot-7-8,.slot-8-9{ width:468px; } /* Halves */ \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/LICENSE.txt b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/LICENSE.txt deleted file mode 100644 index e942914a7..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/LICENSE.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2011 Crowd Favorite, Ltd. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/README.txt b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/README.txt deleted file mode 100644 index 772768319..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/README.txt +++ /dev/null @@ -1 +0,0 @@ -https://simplegrid.info/ \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/percentage_grid.css b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/percentage_grid.css deleted file mode 100644 index 1254f636d..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/css/simplegrid/percentage_grid.css +++ /dev/null @@ -1,27 +0,0 @@ -/* Extension of SimpleGrid by benjchristensen to allow percentage based sizing on very large displays - * - * SimpleGrid - a fork of CSSGrid by Crowd Favorite (https://github.com/crowdfavorite/css-grid) - * https://simplegrid.info - * by Conor Muirhead (http://conor.cc) of Early LLC (https://earlymade.com) - * License: https://creativecommons.org/licenses/MIT/ */ - -/* Containers */ -body { font-size: 1.125em; } -.grid{ width:100%; } - -/* Slots Setup */ -.slot-0,.slot-1,.slot-2,.slot-3,.slot-4,.slot-5,.slot-0-1,.slot-0-1-2,.slot-0-1-2-3,.slot-0-1-2-3-4,.slot-0-1-2-3-4-5,.slot-1-2,.slot-1-2-3,.slot-1-2-3-4,.slot-1-2-3-4-5,.slot-2-3,.slot-2-3-4,.slot-2-3-4-5,.slot-3-4,.slot-3-4-5,.slot-4-5,.slot-6,.slot-7,.slot-8,.slot-9,.slot-6-7,.slot-6-7-8,.slot-6-7-8-9,.slot-7-8,.slot-7-8-9,.slot-8-9{ display:inline; float:left; margin-left:0px; } - - -/* 6-Col Grid Sizes */ -.slot-0,.slot-1,.slot-2,.slot-3,.slot-4,.slot-5{ width:16.6%; } /* Sixths */ -.slot-0-1,.slot-1-2,.slot-2-3,.slot-3-4,.slot-4-5{ width:33.3%; } /* Thirds */ -.slot-0-1-2-3,.slot-1-2-3-4,.slot-2-3-4-5{ width:66.6%; } /* Two-Thirds */ -.slot-0-1-2-3-4,.slot-1-2-3-4-5{ width:83.3%; } /* Five-Sixths */ - -/* 4-Col Grid Sizes */ -.slot-6,.slot-7,.slot-8,.slot-9{ width:25%; } /* Quarters */ -.slot-6-7-8,.slot-7-8-9{ width:75%; } /* Three-Quarters */ - -/* 6-Col/4-Col Shared Grid Sizes */ -.slot-0-1-2,.slot-1-2-3,.slot-2-3-4,.slot-3-4-5, .slot-6-7,.slot-7-8,.slot-8-9{ width:50%; } /* Halves */ \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/images/hystrix-logo-tagline-tiny.png b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/images/hystrix-logo-tagline-tiny.png deleted file mode 100644 index 8919c2925..000000000 Binary files a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/images/hystrix-logo-tagline-tiny.png and /dev/null differ diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/images/hystrix-logo.png b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/images/hystrix-logo.png deleted file mode 100644 index 694a9c9cb..000000000 Binary files a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/images/hystrix-logo.png and /dev/null differ diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/js/jquery.tinysort.min.js b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/js/jquery.tinysort.min.js deleted file mode 100644 index 733bbec36..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/js/jquery.tinysort.min.js +++ /dev/null @@ -1,12 +0,0 @@ -/* -* jQuery TinySort - A plugin to sort child nodes by (sub) contents or attributes. -* -* Version: 1.0.5 -* -* Copyright (c) 2008-2011 Ron Valstar http://ronvalstar.nl/ -* -* Dual licensed under the MIT and GPL licenses: -* https://www.opensource.org/licenses/mit-license.php -* https://www.gnu.org/licenses/gpl.html -*/ -(function(b){b.tinysort={id:"TinySort",version:"1.0.5",copyright:"Copyright (c) 2008-2011 Ron Valstar",uri:"http://tinysort.sjeiti.com/",defaults:{order:"asc",attr:"",place:"start",returns:false,useVal:false}};b.fn.extend({tinysort:function(h,j){if(h&&typeof(h)!="string"){j=h;h=null}var e=b.extend({},b.tinysort.defaults,j);var p={};this.each(function(t){var v=(!h||h=="")?b(this):b(this).find(h);var u=e.order=="rand"?""+Math.random():(e.attr==""?(e.useVal?v.val():v.text()):v.attr(e.attr));var s=b(this).parent();if(!p[s]){p[s]={s:[],n:[]}}if(v.length>0){p[s].s.push({s:u,e:b(this),n:t})}else{p[s].n.push({e:b(this),n:t})}});for(var g in p){var d=p[g];d.s.sort(function k(t,s){var i=t.s.toLowerCase?t.s.toLowerCase():t.s;var u=s.s.toLowerCase?s.s.toLowerCase():s.s;if(c(t.s)&&c(s.s)){i=parseFloat(t.s);u=parseFloat(s.s)}return(e.order=="asc"?1:-1)*(iu?1:0))})}var m=[];for(var g in p){var d=p[g];var n=[];var f=b(this).length;switch(e.place){case"first":b.each(d.s,function(s,t){f=Math.min(f,t.n)});break;case"org":b.each(d.s,function(s,t){n.push(t.n)});break;case"end":f=d.n.length;break;default:f=0}var q=[0,0];for(var l=0;l=f&&l0?d[1]:false}function a(e,f){var d=false;b.each(e,function(h,g){if(!d){d=g==f}});return d}b.fn.TinySort=b.fn.Tinysort=b.fn.tsort=b.fn.tinysort})(jQuery); \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/js/tmpl.js b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/js/tmpl.js deleted file mode 100644 index 251b3681b..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/static/hystrix/js/tmpl.js +++ /dev/null @@ -1,43 +0,0 @@ - -//Simple JavaScript Templating -//John Resig - https://johnresig.com/ - MIT Licensed -// https://johnresig.com/blog/javascript-micro-templating/ -(function(window, undefined) { - var cache = {}; - - window.tmpl = function tmpl(str, data) { - try { - // Figure out if we're getting a template, or if we need to - // load the template - and be sure to cache the result. - var fn = !/\W/.test(str) ? - cache[str] = cache[str] || - tmpl(document.getElementById(str).innerHTML) : - - // Generate a reusable function that will serve as a template - // generator (and which will be cached). - new Function("obj", - "var p=[],print=function(){p.push.apply(p,arguments);};" + - - // Introduce the data as local variables using with(){} - "with(obj){p.push('" + - - // Convert the template into pure JavaScript - str - .replace(/[\r\t\n]/g, " ") - .split("<%").join("\t") - .replace(/((^|%>)[^\t]*)'/g, "$1\r") - .replace(/\t=(.*?)%>/g, "',$1,'") - .split("\t").join("');") - .split("%>").join("p.push('") - .split("\r").join("\\'") - + "');}return p.join('');"); - - //console.log(fn); - - // Provide some basic currying to the user - return data ? fn(data) : fn; - }catch(e) { - console.log(e); - } - }; -})(window); diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/templates/hystrix/index.ftlh b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/templates/hystrix/index.ftlh deleted file mode 100644 index d9d62a692..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/templates/hystrix/index.ftlh +++ /dev/null @@ -1,58 +0,0 @@ -<#import "/spring.ftl" as spring /> - - - - - -Hystrix Dashboard - - - - - - - -
- -
- -
-
- -

Hystrix Dashboard

- -

- Cluster via Turbine (default cluster): https://turbine-hostname:port/turbine.stream -
- Cluster via Turbine (custom cluster): https://turbine-hostname:port/turbine.stream?cluster=[clusterName] -
- Single Hystrix App: https://hystrix-app:port/actuator/hystrix.stream -

- Delay: ms -      - Title:
-
- -

-
- -
-
- - diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/templates/hystrix/monitor.ftlh b/spring-cloud-netflix-hystrix-dashboard/src/main/resources/templates/hystrix/monitor.ftlh deleted file mode 100644 index 373a2f2ee..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/resources/templates/hystrix/monitor.ftlh +++ /dev/null @@ -1,202 +0,0 @@ -<#import "/spring.ftl" as spring /> - - - - - - Hystrix Monitor - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
Loading ...
- -
- -
- -
-
Loading ...
-
- - - - - - - - diff --git a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfigurationTests.java b/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfigurationTests.java deleted file mode 100644 index d3261c8b6..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfigurationTests.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.dashboard; - -import java.util.Map; - -import org.apache.http.Header; -import org.apache.http.message.BasicHeader; -import org.junit.Test; - -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Roy Clarkson - * @author Fahim Farook - * @author Biju Kunjummen - */ -public class HystrixDashboardConfigurationTests { - - @Test - public void normal() { - MockHttpServletResponse response = new MockHttpServletResponse(); - Header[] headers = new Header[1]; - headers[0] = new BasicHeader("Content-Type", "text/proxy.stream"); - HystrixDashboardConfiguration.ProxyStreamServlet proxyStreamServlet = new HystrixDashboardConfiguration.ProxyStreamServlet(); - ReflectionTestUtils.invokeMethod(proxyStreamServlet, - "copyHeadersToServletResponse", headers, response); - assertThat(response.getHeaderNames().size()).isEqualTo(1); - assertThat(response.getHeader("Content-Type")).isEqualTo("text/proxy.stream"); - } - - @Test - public void connectionClose() { - MockHttpServletResponse response = new MockHttpServletResponse(); - Header[] headers = new Header[2]; - headers[0] = new BasicHeader("Content-Type", "text/proxy.stream"); - headers[1] = new BasicHeader("Connection", "close"); - HystrixDashboardConfiguration.ProxyStreamServlet proxyStreamServlet = new HystrixDashboardConfiguration.ProxyStreamServlet(); - ReflectionTestUtils.invokeMethod(proxyStreamServlet, - "copyHeadersToServletResponse", headers, response); - assertThat(response.getHeaderNames().size()).isEqualTo(2); - assertThat(response.getHeader("Content-Type")).isEqualTo("text/proxy.stream"); - assertThat(response.getHeader("Connection")).isEqualTo("close"); - } - - @Test - public void ignoreConnectionClose() { - MockHttpServletResponse response = new MockHttpServletResponse(); - Header[] headers = new Header[2]; - headers[0] = new BasicHeader("Content-Type", "text/proxy.stream"); - headers[1] = new BasicHeader("Connection", "close"); - HystrixDashboardConfiguration.ProxyStreamServlet proxyStreamServlet = new HystrixDashboardConfiguration.ProxyStreamServlet(); - proxyStreamServlet.setEnableIgnoreConnectionCloseHeader(true); - ReflectionTestUtils.invokeMethod(proxyStreamServlet, - "copyHeadersToServletResponse", headers, response); - assertThat(response.getHeaderNames().size()).isEqualTo(1); - assertThat(response.getHeader("Content-Type")).isEqualTo("text/proxy.stream"); - assertThat(response.getHeader("Connection")).isNull(); - } - - @Test - public void doNotIgnoreConnectionClose() { - MockHttpServletResponse response = new MockHttpServletResponse(); - Header[] headers = new Header[2]; - headers[0] = new BasicHeader("Content-Type", "text/proxy.stream"); - headers[1] = new BasicHeader("Connection", "close"); - HystrixDashboardConfiguration.ProxyStreamServlet proxyStreamServlet = new HystrixDashboardConfiguration.ProxyStreamServlet(); - proxyStreamServlet.setEnableIgnoreConnectionCloseHeader(false); - ReflectionTestUtils.invokeMethod(proxyStreamServlet, - "copyHeadersToServletResponse", headers, response); - assertThat(response.getHeaderNames().size()).isEqualTo(2); - assertThat(response.getHeader("Content-Type")).isEqualTo("text/proxy.stream"); - assertThat(response.getHeader("Connection")).isEqualTo("close"); - } - - @Test - public void initParameters() { - new ApplicationContextRunner() - .withUserConfiguration(HystrixDashboardConfiguration.class) - .withPropertyValues( - "hystrix.dashboard.init-parameters.wl-dispatch-polixy=work-manager-hystrix") - .run(context -> { - final ServletRegistrationBean registration = context - .getBean(ServletRegistrationBean.class); - assertThat(registration).isNotNull(); - - final Map initParameters = registration - .getInitParameters(); - assertThat(initParameters).isNotNull(); - assertThat(initParameters.get("wl-dispatch-polixy")) - .isEqualTo("work-manager-hystrix"); - }); - } - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardContextTests.java b/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardContextTests.java deleted file mode 100644 index 19aeebaa5..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardContextTests.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.dashboard; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.hystrix.dashboard.HystrixDashboardContextTests.Application; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, - properties = { "spring.application.name=hystrix-dashboard", - "server.servlet.context-path=/context" }) -public class HystrixDashboardContextTests { - - public static final String JQUERY_PATH = "/context/webjars/jquery/2.1.1/jquery.min.js"; - - @LocalServerPort - private int port = 0; - - @Test - public void homePage() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/context/hystrix", String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - String body = entity.getBody(); - assertThat(body.contains("base href=\"/context/hystrix\"")) - .as("wrong base path rendered in template").isTrue(); - } - - @Test - public void correctJavascriptLink() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/context/hystrix", String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - String body = entity.getBody(); - assertThat(body.contains("src=\"" + JQUERY_PATH + "\"")) - .as("wrong jquery path rendered in template").isTrue(); - } - - @Test - public void cssAvailable() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/context/hystrix/css/global.css", - String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void webjarsAvailable() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + JQUERY_PATH, String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void monitorPage() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/context/hystrix/monitor", - String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - String body = entity.getBody(); - assertThat(body.contains("base href=\"/context/hystrix/monitor\"")) - .as("wrong base path rendered in template").isTrue(); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @EnableHystrixDashboard - protected static class Application { - - } - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardHomePageTests.java b/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardHomePageTests.java deleted file mode 100644 index 9c3b36683..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardHomePageTests.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.dashboard; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.cloud.netflix.hystrix.dashboard.HystrixDashboardHomePageTests.Application; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestMapping; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "server.port=0", "spring.application.name=hystrix-dashboard" }) -public class HystrixDashboardHomePageTests { - - @Value("${local.server.port}") - private int port = 0; - - @Test - public void homePage() { - ResponseEntity entity = new TestRestTemplate() - .getForEntity("http://localhost:" + this.port, String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - entity.getBody().contains(""); - } - - @Test - public void cssAvailable() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/hystrix/css/global.css", - String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void monitorPage() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/hystrix/monitor", String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @EnableHystrixDashboard - @Controller - protected static class Application { - - @RequestMapping("/") - public String home() { - return "forward:/hystrix"; - } - - } - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardTests.java b/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardTests.java deleted file mode 100644 index 907063f2a..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/test/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardTests.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.dashboard; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.cloud.netflix.hystrix.dashboard.HystrixDashboardTests.Application; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "spring.application.name=hystrix-dashboard" }) -public class HystrixDashboardTests { - - @Value("${local.server.port}") - private int port = 0; - - @Test - public void homePage() { - ResponseEntity entity = new TestRestTemplate() - .getForEntity("http://localhost:" + this.port + "/hystrix", String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - String body = entity.getBody(); - assertThat(body.contains("")).isTrue(); - assertThat(body.contains("\"/webjars")).isTrue(); - assertThat(body.contains("= \"/hystrix/monitor")).isTrue(); - } - - @Test - public void cssAvailable() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/hystrix/css/global.css", - String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void monitorPage() { - ResponseEntity entity = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/hystrix/monitor", String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - String body = entity.getBody(); - assertThat(body.contains("")).isTrue(); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @EnableHystrixDashboard - protected static class Application { - - } - -} diff --git a/spring-cloud-netflix-hystrix-dashboard/src/test/resources/templates/test.txt b/spring-cloud-netflix-hystrix-dashboard/src/test/resources/templates/test.txt deleted file mode 100644 index 69d32d57c..000000000 --- a/spring-cloud-netflix-hystrix-dashboard/src/test/resources/templates/test.txt +++ /dev/null @@ -1 +0,0 @@ -The presence of this templates directory tests the Spring Boot FreeMarker configuration \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-stream/pom.xml b/spring-cloud-netflix-hystrix-stream/pom.xml deleted file mode 100644 index 0a988a863..000000000 --- a/spring-cloud-netflix-hystrix-stream/pom.xml +++ /dev/null @@ -1,171 +0,0 @@ - - - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT - .. - - spring-cloud-netflix-hystrix-stream - jar - Spring Cloud Netflix Hystrix Stream - Spring Cloud Netflix Hystrix Stream - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-logging - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework.cloud - spring-cloud-netflix-hystrix - - - org.springframework.cloud - spring-cloud-stream - - - com.fasterxml.jackson.core - jackson-databind - - - com.netflix.hystrix - hystrix-core - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - com.netflix.hystrix - hystrix-metrics-event-stream - test - - - com.netflix.hystrix - hystrix-javanica - test - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.boot - spring-boot-starter-web - test - - - org.springframework.boot - spring-boot-starter-actuator - test - - - org.springframework.cloud - spring-cloud-stream-test-support - test - - - org.springframework.cloud - spring-cloud-netflix-hystrix-contract - test - - - org.springframework.cloud - spring-cloud-contract-verifier - test - - - org.springframework.cloud - spring-cloud-starter-netflix-eureka-client - test - - - - - - org.springframework.cloud - spring-cloud-contract-maven-plugin - ${donotreplacespring-cloud-contract.version} - true - - - - .* - org.springframework.cloud.netflix.hystrix.stream.StreamSourceTestBase - - - - - - org.springframework.cloud - spring-cloud-netflix-hystrix-contract - ${project.version} - - - - - org.codehaus.mojo - build-helper-maven-plugin - - - add-source - generate-test-sources - - add-test-source - - - - ${project.build.directory}/generated-test-sources/contracts/ - - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.springframework.cloud - spring-cloud-contract-maven-plugin - [1.0.0.RELEASE,) - - convert - generateTests - - - - - - - - - - - - - - diff --git a/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfiguration.java b/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfiguration.java deleted file mode 100644 index 0b0e6f522..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfiguration.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.stream; - -import javax.annotation.PostConstruct; - -import com.netflix.hystrix.HystrixCircuitBreaker; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryProperties; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.cloud.stream.annotation.EnableBinding; -import org.springframework.cloud.stream.annotation.Output; -import org.springframework.cloud.stream.config.BindingProperties; -import org.springframework.cloud.stream.config.BindingServiceConfiguration; -import org.springframework.cloud.stream.config.BindingServiceProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.messaging.MessageChannel; -import org.springframework.scheduling.annotation.EnableScheduling; - -/** - * Autoconfiguration for a Spring Cloud Hystrix on Spring Cloud Stream. Enabled by default - * if spring-cloud-stream is on the classpath, and can be switched off with - * hystrix.stream.queue.enabled. There are some high level configuration - * options in {@link HystrixStreamProperties}. The binding name for Spring Cloud Stream is - * {@link HystrixStreamClient#OUTPUT} so you can configure stream other properties through - * that. - * - * @author Spencer Gibb - * @author Dave Syer - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ HystrixCircuitBreaker.class, EnableBinding.class }) -@ConditionalOnProperty(value = "hystrix.stream.queue.enabled", matchIfMissing = true) -@EnableConfigurationProperties -@EnableScheduling -@EnableBinding(HystrixStreamClient.class) -@AutoConfigureBefore(BindingServiceConfiguration.class) // Needed for bindings done in -// auto config -public class HystrixStreamAutoConfiguration { - - @Autowired - private BindingServiceProperties bindings; - - @Autowired - private HystrixStreamProperties properties; - - @Autowired - @Output(HystrixStreamClient.OUTPUT) - private MessageChannel outboundChannel; - - @Autowired(required = false) - private Registration registration; - - @Bean - public HasFeatures hystrixStreamQueueFeature() { - return HasFeatures.namedFeature("Hystrix Stream (Queue)", - HystrixStreamAutoConfiguration.class); - } - - @PostConstruct - public void init() { - BindingProperties outputBinding = this.bindings.getBindings() - .get(HystrixStreamClient.OUTPUT); - if (outputBinding == null) { - this.bindings.getBindings().put(HystrixStreamClient.OUTPUT, - new BindingProperties()); - } - BindingProperties output = this.bindings.getBindings() - .get(HystrixStreamClient.OUTPUT); - if (output.getDestination() == null) { - output.setDestination(this.properties.getDestination()); - } - if (output.getContentType() == null) { - output.setContentType(this.properties.getContentType()); - } - } - - @Bean - public HystrixStreamProperties hystrixStreamProperties() { - return new HystrixStreamProperties(); - } - - @Bean - public HystrixStreamTask hystrixStreamTask( - SimpleDiscoveryProperties simpleDiscoveryProperties) { - ServiceInstance serviceInstance = this.registration; - if (serviceInstance == null) { - serviceInstance = simpleDiscoveryProperties.getLocal(); - } - return new HystrixStreamTask(this.outboundChannel, serviceInstance, - this.properties); - } - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamClient.java b/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamClient.java deleted file mode 100644 index add5d36e6..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamClient.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.stream; - -import org.springframework.cloud.stream.annotation.Output; -import org.springframework.messaging.MessageChannel; - -/** - * Store Hystrix Stream Client output information. - * - * @author Dave Syer - */ -public interface HystrixStreamClient { - - /** - * Hystrix Stream Output channel name. - */ - String OUTPUT = "hystrixStreamOutput"; - - /** - * Provides Hystrix Stream Output setup. - * @return corresponding {@link MessageChannel} instance - */ - @Output(OUTPUT) - MessageChannel hystrixStreamOutput(); - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamProperties.java b/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamProperties.java deleted file mode 100644 index c42ce15fe..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamProperties.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.stream; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.netflix.hystrix.HystrixConstants; - -/** - * @author Spencer Gibb - */ -@ConfigurationProperties("hystrix.stream.queue") -public class HystrixStreamProperties { - - /** Flag to indicate that Hystrix Stream is enabled. Default is true. */ - private boolean enabled = true; - - /** Flag to indicate to prefix metric names with serviceId. Default is true. */ - private boolean prefixMetricName = true; - - /** Flag to indicate to send the id field in the metrics. Default is true */ - private boolean sendId = true; - - /** - * The destination of the stream. Destination as defined by Spring Cloud Stream. - * Defaults to springCloudHystrixStream - */ - private String destination = HystrixConstants.HYSTRIX_STREAM_DESTINATION; - - /** The content type of the messages. Defaults to application/json */ - private String contentType = "application/json"; - - /** How often (in ms) to send messages to the stream. Defaults to 500. */ - private long sendRate = 500; - - /** - * How often to put messages in the queue. This queue drains to the stream. Defaults - * to 500. - */ - private long gatherRate = 500; - - /** - * The size of the metrics queue. This queue drains to the stream. Defaults to 1000. - */ - private int size = 1000; - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public boolean isPrefixMetricName() { - return prefixMetricName; - } - - public void setPrefixMetricName(boolean prefixMetricName) { - this.prefixMetricName = prefixMetricName; - } - - public boolean isSendId() { - return sendId; - } - - public void setSendId(boolean sendId) { - this.sendId = sendId; - } - - public String getDestination() { - return destination; - } - - public void setDestination(String destination) { - this.destination = destination; - } - - public String getContentType() { - return contentType; - } - - public void setContentType(String contentType) { - this.contentType = contentType; - } - - public long getSendRate() { - return sendRate; - } - - public void setSendRate(long sendRate) { - this.sendRate = sendRate; - } - - public long getGatherRate() { - return gatherRate; - } - - public void setGatherRate(long gatherRate) { - this.gatherRate = gatherRate; - } - - public int getSize() { - return size; - } - - public void setSize(int size) { - this.size = size; - } - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTask.java b/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTask.java deleted file mode 100644 index d94cabd3b..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/main/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTask.java +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.stream; - -import java.io.IOException; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Collection; -import java.util.concurrent.LinkedBlockingQueue; - -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.netflix.hystrix.HystrixCircuitBreaker; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixCommandMetrics; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.HystrixThreadPoolKey; -import com.netflix.hystrix.HystrixThreadPoolMetrics; -import com.netflix.hystrix.util.HystrixRollingNumberEvent; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.BeansException; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.messaging.MessageChannel; -import org.springframework.messaging.MessageHeaders; -import org.springframework.messaging.support.MessageBuilder; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.util.Assert; - -/** - * @author Spencer Gibb - * @see com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller (nested - * private class MetricsPoller) - */ -public class HystrixStreamTask implements ApplicationContextAware { - - private static Log log = LogFactory.getLog(HystrixStreamTask.class); - - private MessageChannel outboundChannel; - - private ServiceInstance registration; - - private HystrixStreamProperties properties; - - private ApplicationContext context; - - // Visible for testing - final LinkedBlockingQueue jsonMetrics; - - private final JsonFactory jsonFactory = new JsonFactory(); - - public HystrixStreamTask(MessageChannel outboundChannel, ServiceInstance registration, - HystrixStreamProperties properties) { - Assert.notNull(outboundChannel, "outboundChannel may not be null"); - Assert.notNull(registration, "registration may not be null"); - Assert.notNull(properties, "properties may not be null"); - this.outboundChannel = outboundChannel; - this.registration = registration; - this.properties = properties; - this.jsonMetrics = new LinkedBlockingQueue<>(properties.getSize()); - } - - /* for testing */ ServiceInstance getRegistration() { - return registration; - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) - throws BeansException { - this.context = applicationContext; - } - - // TODO: use integration to split this up? - @Scheduled( - fixedRateString = "${hystrix.stream.queue.sendRate:${hystrix.stream.queue.send-rate:500}}") - public void sendMetrics() { - ArrayList metrics = new ArrayList<>(); - this.jsonMetrics.drainTo(metrics); - - if (!metrics.isEmpty()) { - if (log.isTraceEnabled()) { - log.trace("sending stream metrics size: " + metrics.size()); - } - for (String json : metrics) { - // TODO: batch all metrics to one message - try { - // TODO: remove the explicit content type when s-c-stream can handle - // that for us - this.outboundChannel.send(MessageBuilder.withPayload(json) - .setHeader(MessageHeaders.CONTENT_TYPE, - this.properties.getContentType()) - .build()); - } - catch (Exception ex) { - if (log.isTraceEnabled()) { - log.trace("failed sending stream metrics: " + ex.getMessage()); - } - } - } - } - } - - @Scheduled( - fixedRateString = "${hystrix.stream.queue.gatherRate:${hystrix.stream.queue.gather-rate:500}}") - public void gatherMetrics() { - try { - // command metrics - Collection instances = HystrixCommandMetrics - .getInstances(); - if (!instances.isEmpty()) { - log.trace("gathering metrics size: " + instances.size()); - } - - for (HystrixCommandMetrics commandMetrics : instances) { - HystrixCommandKey key = commandMetrics.getCommandKey(); - HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory - .getInstance(key); - - StringWriter jsonString = new StringWriter(); - JsonGenerator json = this.jsonFactory.createGenerator(jsonString); - - json.writeStartObject(); - - addServiceData(json, registration); - json.writeStringField("event", "message"); - json.writeObjectFieldStart("data"); - json.writeStringField("type", "HystrixCommand"); - String name = key.name(); - - if (this.properties.isPrefixMetricName() && registration != null) { - name = registration.getServiceId() + "." + name; - } - - json.writeStringField("name", name); - json.writeStringField("group", commandMetrics.getCommandGroup().name()); - json.writeNumberField("currentTime", System.currentTimeMillis()); - - // circuit breaker - if (circuitBreaker == null) { - // circuit breaker is disabled and thus never open - json.writeBooleanField("isCircuitBreakerOpen", false); - } - else { - json.writeBooleanField("isCircuitBreakerOpen", - circuitBreaker.isOpen()); - } - HystrixCommandMetrics.HealthCounts healthCounts = commandMetrics - .getHealthCounts(); - json.writeNumberField("errorPercentage", - healthCounts.getErrorPercentage()); - json.writeNumberField("errorCount", healthCounts.getErrorCount()); - json.writeNumberField("requestCount", healthCounts.getTotalRequests()); - - // rolling counters - json.writeNumberField("rollingCountCollapsedRequests", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.COLLAPSED)); - json.writeNumberField("rollingCountExceptionsThrown", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.EXCEPTION_THROWN)); - json.writeNumberField("rollingCountFailure", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.FAILURE)); - json.writeNumberField("rollingCountFallbackFailure", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.FALLBACK_FAILURE)); - json.writeNumberField("rollingCountFallbackRejection", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.FALLBACK_REJECTION)); - json.writeNumberField("rollingCountFallbackSuccess", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.FALLBACK_SUCCESS)); - json.writeNumberField("rollingCountResponsesFromCache", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.RESPONSE_FROM_CACHE)); - json.writeNumberField("rollingCountSemaphoreRejected", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.SEMAPHORE_REJECTED)); - json.writeNumberField("rollingCountShortCircuited", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.SHORT_CIRCUITED)); - json.writeNumberField("rollingCountSuccess", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.SUCCESS)); - json.writeNumberField("rollingCountThreadPoolRejected", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.THREAD_POOL_REJECTED)); - json.writeNumberField("rollingCountTimeout", commandMetrics - .getRollingCount(HystrixRollingNumberEvent.TIMEOUT)); - - json.writeNumberField("currentConcurrentExecutionCount", - commandMetrics.getCurrentConcurrentExecutionCount()); - - // latency percentiles - json.writeNumberField("latencyExecute_mean", - commandMetrics.getExecutionTimeMean()); - json.writeObjectFieldStart("latencyExecute"); - json.writeNumberField("0", commandMetrics.getExecutionTimePercentile(0)); - json.writeNumberField("25", - commandMetrics.getExecutionTimePercentile(25)); - json.writeNumberField("50", - commandMetrics.getExecutionTimePercentile(50)); - json.writeNumberField("75", - commandMetrics.getExecutionTimePercentile(75)); - json.writeNumberField("90", - commandMetrics.getExecutionTimePercentile(90)); - json.writeNumberField("95", - commandMetrics.getExecutionTimePercentile(95)); - json.writeNumberField("99", - commandMetrics.getExecutionTimePercentile(99)); - json.writeNumberField("99.5", - commandMetrics.getExecutionTimePercentile(99.5)); - json.writeNumberField("100", - commandMetrics.getExecutionTimePercentile(100)); - json.writeEndObject(); - // - json.writeNumberField("latencyTotal_mean", - commandMetrics.getTotalTimeMean()); - json.writeObjectFieldStart("latencyTotal"); - json.writeNumberField("0", commandMetrics.getTotalTimePercentile(0)); - json.writeNumberField("25", commandMetrics.getTotalTimePercentile(25)); - json.writeNumberField("50", commandMetrics.getTotalTimePercentile(50)); - json.writeNumberField("75", commandMetrics.getTotalTimePercentile(75)); - json.writeNumberField("90", commandMetrics.getTotalTimePercentile(90)); - json.writeNumberField("95", commandMetrics.getTotalTimePercentile(95)); - json.writeNumberField("99", commandMetrics.getTotalTimePercentile(99)); - json.writeNumberField("99.5", - commandMetrics.getTotalTimePercentile(99.5)); - json.writeNumberField("100", commandMetrics.getTotalTimePercentile(100)); - json.writeEndObject(); - - // property values for reporting what is actually seen by the command - // rather than what was set somewhere - HystrixCommandProperties commandProperties = commandMetrics - .getProperties(); - - json.writeNumberField( - "propertyValue_circuitBreakerRequestVolumeThreshold", - commandProperties.circuitBreakerRequestVolumeThreshold().get()); - json.writeNumberField( - "propertyValue_circuitBreakerSleepWindowInMilliseconds", - commandProperties.circuitBreakerSleepWindowInMilliseconds() - .get()); - json.writeNumberField( - "propertyValue_circuitBreakerErrorThresholdPercentage", - commandProperties.circuitBreakerErrorThresholdPercentage().get()); - json.writeBooleanField("propertyValue_circuitBreakerForceOpen", - commandProperties.circuitBreakerForceOpen().get()); - json.writeBooleanField("propertyValue_circuitBreakerForceClosed", - commandProperties.circuitBreakerForceClosed().get()); - json.writeBooleanField("propertyValue_circuitBreakerEnabled", - commandProperties.circuitBreakerEnabled().get()); - - json.writeStringField("propertyValue_executionIsolationStrategy", - commandProperties.executionIsolationStrategy().get().name()); - json.writeNumberField( - "propertyValue_executionIsolationThreadTimeoutInMilliseconds", - commandProperties.executionIsolationThreadTimeoutInMilliseconds() - .get()); - json.writeBooleanField( - "propertyValue_executionIsolationThreadInterruptOnTimeout", - commandProperties.executionIsolationThreadInterruptOnTimeout() - .get()); - json.writeStringField( - "propertyValue_executionIsolationThreadPoolKeyOverride", - commandProperties.executionIsolationThreadPoolKeyOverride() - .get()); - json.writeNumberField( - "propertyValue_executionIsolationSemaphoreMaxConcurrentRequests", - commandProperties - .executionIsolationSemaphoreMaxConcurrentRequests() - .get()); - json.writeNumberField( - "propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests", - commandProperties - .fallbackIsolationSemaphoreMaxConcurrentRequests().get()); - - // TODO - /* - * The following are commented out as these rarely change and are verbose - * for streaming for something people don't change. We could perhaps allow - * a property or request argument to include these. - */ - - // json.put("propertyValue_metricsRollingPercentileEnabled", - // commandProperties.metricsRollingPercentileEnabled().get()); - // json.put("propertyValue_metricsRollingPercentileBucketSize", - // commandProperties.metricsRollingPercentileBucketSize().get()); - // json.put("propertyValue_metricsRollingPercentileWindow", - // commandProperties.metricsRollingPercentileWindowInMilliseconds().get()); - // json.put("propertyValue_metricsRollingPercentileWindowBuckets", - // commandProperties.metricsRollingPercentileWindowBuckets().get()); - // json.put("propertyValue_metricsRollingStatisticalWindowBuckets", - // commandProperties.metricsRollingStatisticalWindowBuckets().get()); - json.writeNumberField( - "propertyValue_metricsRollingStatisticalWindowInMilliseconds", - commandProperties.metricsRollingStatisticalWindowInMilliseconds() - .get()); - - json.writeBooleanField("propertyValue_requestCacheEnabled", - commandProperties.requestCacheEnabled().get()); - json.writeBooleanField("propertyValue_requestLogEnabled", - commandProperties.requestLogEnabled().get()); - - json.writeNumberField("reportingHosts", 1); // this will get summed across - // all instances in a cluster - - json.writeEndObject(); // end data attribute - json.writeEndObject(); - json.close(); - - // output - this.jsonMetrics.add(jsonString.getBuffer().toString()); - } - - // thread pool metrics - for (HystrixThreadPoolMetrics threadPoolMetrics : HystrixThreadPoolMetrics - .getInstances()) { - HystrixThreadPoolKey key = threadPoolMetrics.getThreadPoolKey(); - - StringWriter jsonString = new StringWriter(); - JsonGenerator json = this.jsonFactory.createGenerator(jsonString); - json.writeStartObject(); - - addServiceData(json, this.registration); - json.writeObjectFieldStart("data"); - - json.writeStringField("type", "HystrixThreadPool"); - json.writeStringField("name", key.name()); - json.writeNumberField("currentTime", System.currentTimeMillis()); - - json.writeNumberField("currentActiveCount", - threadPoolMetrics.getCurrentActiveCount().intValue()); - json.writeNumberField("currentCompletedTaskCount", - threadPoolMetrics.getCurrentCompletedTaskCount().longValue()); - json.writeNumberField("currentCorePoolSize", - threadPoolMetrics.getCurrentCorePoolSize().intValue()); - json.writeNumberField("currentLargestPoolSize", - threadPoolMetrics.getCurrentLargestPoolSize().intValue()); - json.writeNumberField("currentMaximumPoolSize", - threadPoolMetrics.getCurrentMaximumPoolSize().intValue()); - json.writeNumberField("currentPoolSize", - threadPoolMetrics.getCurrentPoolSize().intValue()); - json.writeNumberField("currentQueueSize", - threadPoolMetrics.getCurrentQueueSize().intValue()); - json.writeNumberField("currentTaskCount", - threadPoolMetrics.getCurrentTaskCount().longValue()); - json.writeNumberField("rollingCountThreadsExecuted", - threadPoolMetrics.getRollingCountThreadsExecuted()); - json.writeNumberField("rollingMaxActiveThreads", - threadPoolMetrics.getRollingMaxActiveThreads()); - - json.writeNumberField("propertyValue_queueSizeRejectionThreshold", - threadPoolMetrics.getProperties().queueSizeRejectionThreshold() - .get()); - json.writeNumberField( - "propertyValue_metricsRollingStatisticalWindowInMilliseconds", - threadPoolMetrics.getProperties() - .metricsRollingStatisticalWindowInMilliseconds().get()); - - json.writeNumberField("reportingHosts", 1); // this will get summed across - // all instances in a cluster - - json.writeEndObject(); // end of data object - json.writeEndObject(); - json.close(); - // output to stream - this.jsonMetrics.add(jsonString.getBuffer().toString()); - } - } - catch (Exception ex) { - log.error("Error adding metrics to queue", ex); - } - } - - private void addServiceData(JsonGenerator json, ServiceInstance localService) - throws IOException { - json.writeObjectFieldStart("origin"); - json.writeStringField("host", localService.getHost()); - json.writeNumberField("port", localService.getPort()); - json.writeStringField("serviceId", localService.getServiceId()); - if (this.properties.isSendId()) { - json.writeStringField("id", this.context.getId()); - } - json.writeEndObject(); - } - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-hystrix-stream/src/main/resources/META-INF/spring.factories deleted file mode 100644 index ca7c0a243..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.hystrix.stream.HystrixStreamAutoConfiguration diff --git a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfigurationNoRegistrationTests.java b/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfigurationNoRegistrationTests.java deleted file mode 100644 index 40d66d3ac..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfigurationNoRegistrationTests.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.stream; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryProperties; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest({ "eureka.client.enabled=false" }) -@DirtiesContext -public class HystrixStreamAutoConfigurationNoRegistrationTests { - - @Autowired - HystrixStreamTask task; - - @Autowired(required = false) - Registration registration; - - @Autowired - SimpleDiscoveryProperties simpleDiscoveryProperties; - - @Test - public void withoutRegistrationWorks() throws Exception { - assertThat(this.registration).isNull(); - assertThat(this.simpleDiscoveryProperties).isNotNull(); - assertThat(task.getRegistration()) - .isEqualTo(this.simpleDiscoveryProperties.getLocal()); - } - - @EnableAutoConfiguration - @SpringBootConfiguration - protected static class Config { - - } - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfigurationTests.java b/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfigurationTests.java deleted file mode 100644 index 1ea188c14..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamAutoConfigurationTests.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.stream; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@DirtiesContext -public class HystrixStreamAutoConfigurationTests { - - @Autowired - HystrixStreamTask task; - - @Autowired - Registration registration; - - @Test - public void withRegistrationWorks() throws Exception { - assertThat(task.getRegistration()).isEqualTo(this.registration); - } - - @EnableAutoConfiguration - @SpringBootConfiguration - protected static class Config { - - } - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTaskTests.java b/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTaskTests.java deleted file mode 100644 index 42f968451..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTaskTests.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2016-2019 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 - * - * https://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.hystrix.stream; - -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixCommandMetrics; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.strategy.properties.HystrixPropertiesCommandDefault; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.junit.MockitoJUnitRunner; - -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.context.ApplicationContext; -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageChannel; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.verifyNoInteractions; - -/** - * @author Marcin Grzejszczak - */ -@RunWith(MockitoJUnitRunner.class) -public class HystrixStreamTaskTests { - - @Mock - MessageChannel outboundChannel; - - @Mock - DiscoveryClient discoveryClient; - - @Mock - ApplicationContext context; - - @Spy - HystrixStreamProperties properties; - - @Mock - Registration registration; - - @InjectMocks - HystrixStreamTask hystrixStreamTask; - - @Test - public void should_not_send_metrics_when_they_are_empty() throws Exception { - this.hystrixStreamTask.sendMetrics(); - - verifyNoInteractions(this.outboundChannel); - } - - @Test - public void should_send_metrics_when_they_are_not_empty() throws Exception { - this.hystrixStreamTask.jsonMetrics.put("someJson"); - - this.hystrixStreamTask.sendMetrics(); - - then(this.outboundChannel).should().send(any(Message.class)); - } - - @Test - public void should_gather_json_metrics() throws Exception { - HystrixCommandKey hystrixCommandKey = HystrixCommandKey.Factory - .asKey("commandKey"); - HystrixCommandMetrics.getInstance(hystrixCommandKey, - HystrixCommandGroupKey.Factory.asKey("commandGroupKey"), - new HystrixPropertiesCommandDefault(hystrixCommandKey, - HystrixCommandProperties.defaultSetter())); - - this.hystrixStreamTask.setApplicationContext(this.context); - this.hystrixStreamTask.gatherMetrics(); - - assertThat(this.hystrixStreamTask.jsonMetrics.isEmpty()).isFalse(); - } - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTests.java b/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTests.java deleted file mode 100644 index 835271704..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/HystrixStreamTests.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.stream; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.cloud.stream.test.binder.MessageCollector; -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageChannel; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - * @author Daniel Lavoie - */ -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = { "debug=true", - "spring.jmx.enabled=true", "spring.application.name=mytestapp" }) -@DirtiesContext -public class HystrixStreamTests { - - @Autowired - private HystrixStreamTask task; - - @Autowired - private Application application; - - @Autowired(required = false) - private Registration registration; - - @Autowired - private ObjectMapper mapper; - - @Autowired - private MessageCollector collector; - - @Autowired - @Qualifier(HystrixStreamClient.OUTPUT) - private MessageChannel output; - - @Test - public void contextLoads() throws Exception { - this.application.hello(); - // It is important that local service instance resolves for metrics - // origin details to be populated - assertThat(this.registration).isNotNull(); - assertThat(this.registration.getServiceId()).isEqualTo("mytestapp"); - this.task.gatherMetrics(); - Message message = this.collector.forChannel(output).take(); - JsonNode tree = mapper.readTree((String) message.getPayload()); - assertThat(tree.hasNonNull("origin")).isTrue(); - assertThat(tree.hasNonNull("data")).isTrue(); - assertThat(tree.hasNonNull("event")).isTrue(); - assertThat(tree.findValue("event").asText()).isEqualTo("message"); - } - - @EnableAutoConfiguration - @EnableCircuitBreaker - @RestController - @SpringBootConfiguration - public static class Application { - - @HystrixCommand - @RequestMapping("/") - public String hello() { - return "Hello World"; - } - - } - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/StreamSourceTestBase.java b/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/StreamSourceTestBase.java deleted file mode 100644 index 36e39faa0..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/test/java/org/springframework/cloud/netflix/hystrix/stream/StreamSourceTestBase.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.stream; - -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; -import org.junit.runner.RunWith; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; -import org.springframework.cloud.contract.verifier.messaging.MessageVerifier; -import org.springframework.cloud.contract.verifier.messaging.boot.AutoConfigureMessageVerifier; -import org.springframework.cloud.contract.verifier.messaging.stream.StreamStubMessages; -import org.springframework.cloud.netflix.hystrix.contract.HystrixContractUtils; -import org.springframework.cloud.netflix.hystrix.stream.StreamSourceTestBase.TestApplication; -import org.springframework.cloud.stream.config.BindingProperties; -import org.springframework.cloud.stream.config.BindingServiceProperties; -import org.springframework.cloud.stream.test.binder.MessageCollector; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageChannel; -import org.springframework.messaging.MessageHeaders; -import org.springframework.messaging.converter.DefaultContentTypeResolver; -import org.springframework.messaging.converter.MappingJackson2MessageConverter; -import org.springframework.messaging.support.MessageBuilder; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.MimeTypeUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * Base class for sensor autogenerated tests (used by Spring Cloud Contract). - * - * This bootstraps the Spring Boot application code. - * - * @author Marius Bogoevici - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = TestApplication.class, - properties = { "spring.application.name=application" }) -@AutoConfigureMessageVerifier -public abstract class StreamSourceTestBase { - - @Autowired - TestApplication application; - - public void createMetricsData() throws Exception { - application.hello(); - } - - public void assertOrigin(Object input) { - System.err.println(input); - @SuppressWarnings("unchecked") - Map origin = (Map) input; - HystrixContractUtils.checkOrigin(origin); - } - - public void assertData(Object input) { - // System.err.println(input); - @SuppressWarnings("unchecked") - Map data = (Map) input; - HystrixContractUtils.checkData(data, TestApplication.class.getSimpleName(), - "application.hello"); - } - - public void assertEvent(Object input) { - HystrixContractUtils.checkEvent((String) input); - } - - @EnableAutoConfiguration - @EnableCircuitBreaker - @RestController - public static class TestApplication { - - @HystrixCommand - @RequestMapping("/") - public String hello() { - return "Hello World"; - } - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - // TODO: remove this as soon as contract 2.0.0 is available - @Bean - MessageVerifier> contractVerifierMessageExchange( - ApplicationContext applicationContext) { - return new PatchedStubMessages(applicationContext); - } - - } - - static class PatchedStubMessages implements MessageVerifier> { - - private static final Logger log = LoggerFactory - .getLogger(StreamStubMessages.class); - - private final ApplicationContext context; - - private final MessageCollector messageCollector; - - private final ContractVerifierStreamMessageBuilder builder = new ContractVerifierStreamMessageBuilder(); - - PatchedStubMessages(ApplicationContext context) { - this.context = context; - this.messageCollector = context.getBean(MessageCollector.class); - } - - @Override - public void send(T payload, Map headers, String destination) { - send(this.builder.create(payload, headers), destination); - } - - @Override - public void send(Message message, String destination) { - try { - MessageChannel messageChannel = this.context - .getBean(resolvedDestination(destination), MessageChannel.class); - messageChannel.send(message); - } - catch (Exception e) { - log.error( - "Exception occurred while trying to send a message [" + message - + "] " + "to a channel with name [" + destination + "]", - e); - throw e; - } - } - - @Override - public Message receive(String destination, long timeout, TimeUnit timeUnit) { - try { - MessageChannel messageChannel = this.context - .getBean(resolvedDestination(destination), MessageChannel.class); - Message message = this.messageCollector.forChannel(messageChannel) - .poll(timeout, timeUnit); - if (message == null) { - return message; - } - return MessageBuilder.createMessage(message.getPayload(), - message.getHeaders()); - } - catch (Exception e) { - log.error("Exception occurred while trying to read a message from " - + " a channel with name [" + destination + "]", e); - throw new IllegalStateException(e); - } - } - - private String resolvedDestination(String destination) { - try { - BindingServiceProperties channelBindingServiceProperties = this.context - .getBean(BindingServiceProperties.class); - for (Map.Entry entry : channelBindingServiceProperties - .getBindings().entrySet()) { - if (destination.equals(entry.getValue().getDestination())) { - if (log.isDebugEnabled()) { - log.debug("Found a channel named [{}] with destination [{}]", - entry.getKey(), destination); - } - return entry.getKey(); - } - } - } - catch (Exception e) { - log.error( - "Exception took place while trying to resolve the destination. Will assume the name [" - + destination + "]", - e); - } - if (log.isDebugEnabled()) { - log.debug("No destination named [" + destination - + "] was found. Assuming that the destination equals the channel name", - destination); - } - return destination; - } - - @Override - public Message receive(String destination) { - return receive(destination, 5, TimeUnit.SECONDS); - } - - private MappingJackson2MessageConverter converter() { - ObjectMapper mapper = null; - try { - mapper = this.context.getBean(ObjectMapper.class); - } - catch (NoSuchBeanDefinitionException e) { - - } - MappingJackson2MessageConverter converter = createJacksonConverter(); - if (mapper != null) { - converter.setObjectMapper(mapper); - } - return converter; - } - - protected MappingJackson2MessageConverter createJacksonConverter() { - DefaultContentTypeResolver resolver = new DefaultContentTypeResolver(); - resolver.setDefaultMimeType(MimeTypeUtils.APPLICATION_JSON); - MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); - converter.setContentTypeResolver(resolver); - return converter; - } - - } - - static class ContractVerifierStreamMessageBuilder { - - public Message create(T payload, Map headers) { - return MessageBuilder.createMessage(payload, new MessageHeaders(headers)); - } - - } - -} diff --git a/spring-cloud-netflix-hystrix-stream/src/test/resources/application.yml b/spring-cloud-netflix-hystrix-stream/src/test/resources/application.yml deleted file mode 100644 index dc48699c9..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/test/resources/application.yml +++ /dev/null @@ -1,6 +0,0 @@ -server: - port: 17642 - -logging: - level: - org.springframework.netflix.hystrix.stream: TRACE \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-stream/src/test/resources/contracts/shouldProduceValidMetricsData.groovy b/spring-cloud-netflix-hystrix-stream/src/test/resources/contracts/shouldProduceValidMetricsData.groovy deleted file mode 100644 index 452bbd44b..000000000 --- a/spring-cloud-netflix-hystrix-stream/src/test/resources/contracts/shouldProduceValidMetricsData.groovy +++ /dev/null @@ -1,29 +0,0 @@ -package contracts - -import org.springframework.cloud.netflix.hystrix.contract.HystrixContractUtils - -org.springframework.cloud.contract.spec.Contract.make { - // Human readable description - description 'Should produce valid metrics data' - // Label by means of which the output message can be triggered - label 'metrics' - // input to the contract - input { - // the contract will be triggered by a method - triggeredBy('createMetricsData()') - } - // output message of the contract - outputMessage { - // destination to which the output message will be sent - sentTo 'hystrixStreamOutput' - headers { - header('contentType': 'application/json') - } - body(HystrixContractUtils.simpleBody()) - testMatchers { - jsonPath('$.origin', byCommand('assertOrigin($it)')) - jsonPath('$.event', byCommand('assertEvent($it)')) - jsonPath('$.data', byCommand('assertData($it)')) - } - } -} diff --git a/spring-cloud-netflix-hystrix/pom.xml b/spring-cloud-netflix-hystrix/pom.xml deleted file mode 100644 index 7d4800ff8..000000000 --- a/spring-cloud-netflix-hystrix/pom.xml +++ /dev/null @@ -1,186 +0,0 @@ - - - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT - .. - - spring-cloud-netflix-hystrix - jar - Spring Cloud Netflix Hystrix - Spring Cloud Netflix Hystrix - - - org.springframework.boot - spring-boot-autoconfigure - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-actuator - true - - - org.springframework.boot - spring-boot-starter-security - true - - - org.springframework.boot - spring-boot-starter-web - true - - - org.springframework.boot - spring-boot-starter-webflux - true - - - org.springframework.boot - spring-boot-starter-reactor-netty - true - - - io.netty - netty-codec-http - true - - - io.projectreactor - reactor-core - true - - - io.reactivex - rxjava-reactive-streams - true - - - org.springframework.retry - spring-retry - true - - - org.springframework.boot - spring-boot-starter-aop - - - org.springframework.cloud - spring-cloud-commons - true - - - org.springframework.cloud - spring-cloud-context - true - - - com.netflix.ribbon - ribbon-loadbalancer - true - - - com.netflix.hystrix - hystrix-core - true - - - com.netflix.hystrix - hystrix-serialization - true - - - com.netflix.hystrix - hystrix-metrics-event-stream - true - - - com.netflix.hystrix - hystrix-javanica - true - - - com.netflix.ribbon - ribbon-core - true - - - com.netflix.ribbon - ribbon-httpclient - true - - - io.reactivex - rxjava - true - - - com.sun.jersey.contribs - jersey-apache-client4 - true - - - com.squareup.okhttp3 - okhttp - true - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.cloud - spring-cloud-netflix-ribbon - test - - - org.springframework.cloud - spring-cloud-test-support - test - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - io.projectreactor - reactor-test - test - - - com.netflix.ribbon - ribbon - test - - - - - java8plus - - [1.8,2.0) - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - -parameters - - - - - - - - diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/AbstractHystrixConfigBuilder.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/AbstractHystrixConfigBuilder.java deleted file mode 100644 index 0fd465b7a..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/AbstractHystrixConfigBuilder.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2013-2018 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 - * - * https://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.hystrix; - -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixCommandProperties; - -import org.springframework.cloud.client.circuitbreaker.ConfigBuilder; -import org.springframework.util.StringUtils; - -/** - * @author Ryan Baxter - */ -public abstract class AbstractHystrixConfigBuilder - implements ConfigBuilder { - - private final String commandName; - - protected String groupName; - - protected HystrixCommandProperties.Setter commandProperties; - - public AbstractHystrixConfigBuilder(String id) { - this.commandName = id; - } - - public AbstractHystrixConfigBuilder groupName(String groupName) { - this.groupName = groupName; - return this; - } - - public AbstractHystrixConfigBuilder commandProperties( - HystrixCommandProperties.Setter commandProperties) { - this.commandProperties = commandProperties; - return this; - } - - protected HystrixCommandGroupKey getGroupKey() { - String groupNameToUse; - if (StringUtils.hasText(this.groupName)) { - groupNameToUse = this.groupName; - } - else { - groupNameToUse = commandName + "group"; - } - return HystrixCommandGroupKey.Factory.asKey(groupNameToUse); - } - - protected HystrixCommandKey getCommandKey() { - return HystrixCommandKey.Factory.asKey(this.commandName); - } - - protected HystrixCommandProperties.Setter getCommandPropertiesSetter() { - return this.commandProperties != null ? this.commandProperties - : HystrixCommandProperties.Setter(); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/EnableHystrix.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/EnableHystrix.java deleted file mode 100644 index 58ea88894..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/EnableHystrix.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 - * - * https://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.hystrix; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; - -/** - * Convenience annotation for clients to enable Hystrix circuit breakers (specifically). - * Use this (optionally) in case you want discovery and know for sure that it is Hystrix - * you want. All it does is turn on circuit breakers and let the autoconfiguration find - * the Hystrix classes if they are available (i.e. you need Hystrix on the classpath as - * well). - * - * @author Dave Syer - * @author Spencer Gibb - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@EnableCircuitBreaker -public @interface EnableHystrix { - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfiguration.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfiguration.java deleted file mode 100644 index 311bd4ae0..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfiguration.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -import com.netflix.hystrix.Hystrix; -import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect; -import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet; -import com.netflix.hystrix.metric.consumer.HystrixDashboardStream; -import com.netflix.hystrix.serial.SerialHystrixDashboardData; -import io.micrometer.core.instrument.binder.hystrix.HystrixMetricsBinder; -import org.reactivestreams.Publisher; -import rx.Observable; -import rx.RxReactiveStreams; - -import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.reactive.DispatcherHandler; - -import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.REACTIVE; -import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.SERVLET; - -/** - * Auto configuration for Hystrix. - * - * @author Christian Dupuis - * @author Dave Syer - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ Hystrix.class, HealthIndicator.class, - HealthContributorAutoConfiguration.class }) -@AutoConfigureAfter({ HealthContributorAutoConfiguration.class }) -public class HystrixAutoConfiguration { - - @Bean - @ConditionalOnEnabledHealthIndicator("hystrix") - public HystrixHealthIndicator hystrixHealthIndicator() { - return new HystrixHealthIndicator(); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnProperty(value = "management.metrics.binders.hystrix.enabled", - matchIfMissing = true) - @ConditionalOnClass({ HystrixMetricsBinder.class }) - protected static class HystrixMetricsConfiguration { - - @Bean - public HystrixMetricsBinder hystrixMetricsBinder() { - return new HystrixMetricsBinder(); - } - - } - - /** - * See original - * {@link org.springframework.boot.actuate.autoconfigure.jolokia.JolokiaEndpointAutoConfiguration}. - */ - @Configuration(proxyBeanMethods = false) - @ConditionalOnWebApplication(type = SERVLET) - @ConditionalOnBean(HystrixCommandAspect.class) // only install the stream if enabled - @ConditionalOnClass({ HystrixMetricsStreamServlet.class }) - @EnableConfigurationProperties(HystrixProperties.class) - protected static class HystrixServletAutoConfiguration { - - @Bean - @ConditionalOnAvailableEndpoint - public HystrixStreamEndpoint hystrixStreamEndpoint(HystrixProperties properties) { - return new HystrixStreamEndpoint(properties.getConfig()); - } - - @Bean - public HasFeatures hystrixStreamFeature() { - return HasFeatures.namedFeature("Hystrix Stream Servlet", - HystrixMetricsStreamServlet.class); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnWebApplication(type = REACTIVE) - @ConditionalOnBean(HystrixCommandAspect.class) // only install the stream if enabled - @ConditionalOnClass({ DispatcherHandler.class }) - @EnableConfigurationProperties(HystrixProperties.class) - protected static class HystrixWebfluxManagementContextConfiguration { - - @Bean - @ConditionalOnAvailableEndpoint - public HystrixWebfluxEndpoint hystrixWebfluxController() { - Observable serializedDashboardData = HystrixDashboardStream - .getInstance().observe() - .concatMap(dashboardData -> Observable.from(SerialHystrixDashboardData - .toMultipleJsonStrings(dashboardData))); - Publisher publisher = RxReactiveStreams - .toPublisher(serializedDashboardData); - return new HystrixWebfluxEndpoint(publisher); - } - - @Bean - public HasFeatures hystrixStreamFeature() { - return HasFeatures.namedFeature("Hystrix Stream Webflux", - HystrixWebfluxEndpoint.class); - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreaker.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreaker.java deleted file mode 100644 index 645704fa9..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreaker.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2013-2018 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 - * - * https://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.hystrix; - -import java.util.function.Function; -import java.util.function.Supplier; - -import com.netflix.hystrix.HystrixCommand; - -import org.springframework.cloud.client.circuitbreaker.CircuitBreaker; - -/** - * Hystrix implementation of {@link CircuitBreaker}. - * - * @author Ryan Baxter - */ -public class HystrixCircuitBreaker implements CircuitBreaker { - - private HystrixCommand.Setter setter; - - public HystrixCircuitBreaker(HystrixCommand.Setter setter) { - this.setter = setter; - } - - @Override - public T run(Supplier toRun, Function fallback) { - - HystrixCommand command = new HystrixCommand(setter) { - @Override - protected T run() throws Exception { - return toRun.get(); - } - - @Override - protected T getFallback() { - return fallback.apply(getExecutionException()); - } - }; - return command.execute(); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerAutoConfiguration.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerAutoConfiguration.java deleted file mode 100644 index 5cb1a8c18..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerAutoConfiguration.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -import java.util.ArrayList; -import java.util.List; - -import com.netflix.hystrix.Hystrix; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; -import org.springframework.cloud.client.circuitbreaker.Customizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Ryan Baxter - * @author Eric Bussieres - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ Hystrix.class }) -@ConditionalOnProperty(name = "spring.cloud.circuitbreaker.hystrix.enabled", - matchIfMissing = true) -public class HystrixCircuitBreakerAutoConfiguration { - - @Autowired(required = false) - private List> customizers = new ArrayList<>(); - - @Bean - @ConditionalOnMissingBean(CircuitBreakerFactory.class) - public CircuitBreakerFactory hystrixCircuitBreakerFactory() { - HystrixCircuitBreakerFactory factory = new HystrixCircuitBreakerFactory(); - customizers.forEach(customizer -> customizer.customize(factory)); - return factory; - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerConfiguration.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerConfiguration.java deleted file mode 100644 index 11dbc9f2a..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerConfiguration.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -import com.netflix.hystrix.Hystrix; -import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect; -import org.apache.catalina.core.ApplicationContext; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.actuator.NamedFeature; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - * @author Christian Dupuis - * @author Venil Noronha - */ -@Configuration(proxyBeanMethods = false) -public class HystrixCircuitBreakerConfiguration { - - @Bean - public HystrixCommandAspect hystrixCommandAspect() { - return new HystrixCommandAspect(); - } - - @Bean - public HystrixShutdownHook hystrixShutdownHook() { - return new HystrixShutdownHook(); - } - - @Bean - public HasFeatures hystrixFeature() { - return HasFeatures - .namedFeatures(new NamedFeature("Hystrix", HystrixCommandAspect.class)); - } - - /** - * {@link DisposableBean} that makes sure that Hystrix internal state is cleared when - * {@link ApplicationContext} shuts down. - */ - private class HystrixShutdownHook implements DisposableBean { - - @Override - public void destroy() throws Exception { - // Just call Hystrix to reset thread pool etc. - Hystrix.reset(); - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerFactory.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerFactory.java deleted file mode 100644 index 4b0b91e8c..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerFactory.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2013-2018 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 - * - * https://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.hystrix; - -import java.util.function.Function; - -import com.netflix.hystrix.HystrixCommand; -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; - -import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; -import org.springframework.util.Assert; - -/** - * Builds Hystrix circuit breakers. - * - * @author Ryan Baxter - */ -public class HystrixCircuitBreakerFactory extends - CircuitBreakerFactory { - - private Function defaultConfiguration = id -> HystrixCommand.Setter - .withGroupKey( - HystrixCommandGroupKey.Factory.asKey(getClass().getSimpleName())) - .andCommandKey(HystrixCommandKey.Factory.asKey(id)); - - public void configureDefault( - Function defaultConfiguration) { - this.defaultConfiguration = defaultConfiguration; - } - - public HystrixConfigBuilder configBuilder(String id) { - return new HystrixConfigBuilder(id); - } - - public HystrixCircuitBreaker create(String id) { - Assert.hasText(id, "A CircuitBreaker must have an id."); - HystrixCommand.Setter setter = getConfigurations().computeIfAbsent(id, - defaultConfiguration); - return new HystrixCircuitBreaker(setter); - } - - public static class HystrixConfigBuilder - extends AbstractHystrixConfigBuilder { - - public HystrixConfigBuilder(String id) { - super(id); - } - - @Override - public HystrixCommand.Setter build() { - return HystrixCommand.Setter.withGroupKey(getGroupKey()) - .andCommandKey(getCommandKey()) - .andCommandPropertiesDefaults(getCommandPropertiesSetter()); - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCommands.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCommands.java deleted file mode 100644 index 1eca90075..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixCommands.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -import java.util.function.Function; - -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.HystrixObservableCommand; -import com.netflix.hystrix.HystrixObservableCommand.Setter; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import rx.Observable; -import rx.RxReactiveStreams; - -import org.springframework.util.StringUtils; - -/** - * Utility class to wrap a {@see Publisher} in a {@see HystrixObservableCommand}. Good for - * use in a Spring WebFlux application. Allows more flexibility than the @HystrixCommand - * annotation. - * - * @author Spencer Gibb - */ -public final class HystrixCommands { - - private HystrixCommands() { - throw new AssertionError("Must not instantiate utility class."); - } - - /** - * @param publisher A {@link Publisher} to pass to the new - * {@link PublisherHystrixCommand} - * @param type of the {@link Publisher}s to be built by the returned builder - * @return a builder for Hystrix-command-specific {@link Publisher}s - */ - public static PublisherBuilder from(Publisher publisher) { - return new PublisherBuilder<>(publisher); - } - - /** - * A builder class for building Hystrix-command-specific {@link Publisher}s. - * - * @param type of the {@link Publisher}s to be built - */ - public static class PublisherBuilder { - - private final Publisher publisher; - - private String commandName; - - private String groupName; - - private Function> fallback; - - private Setter setter; - - private HystrixCommandProperties.Setter commandProperties; - - private boolean eager = false; - - private Function, Observable> toObservable; - - public PublisherBuilder(Publisher publisher) { - this.publisher = publisher; - } - - public PublisherBuilder commandName(String commandName) { - this.commandName = commandName; - return this; - } - - public PublisherBuilder groupName(String groupName) { - this.groupName = groupName; - return this; - } - - public PublisherBuilder fallback(Publisher fallback) { - this.fallback = throwable -> fallback; - return this; - } - - public PublisherBuilder fallback(Function> fallback) { - this.fallback = fallback; - return this; - } - - public PublisherBuilder setter(Setter setter) { - this.setter = setter; - return this; - } - - public PublisherBuilder commandProperties( - HystrixCommandProperties.Setter commandProperties) { - this.commandProperties = commandProperties; - return this; - } - - public PublisherBuilder commandProperties( - Function commandProperties) { - if (commandProperties == null) { - throw new IllegalArgumentException( - "commandProperties must not both be null"); - } - return this.commandProperties( - commandProperties.apply(HystrixCommandProperties.Setter())); - } - - public PublisherBuilder eager() { - this.eager = true; - return this; - } - - public PublisherBuilder toObservable( - Function, Observable> toObservable) { - this.toObservable = toObservable; - return this; - } - - public Publisher build() { - if (!StringUtils.hasText(commandName) && setter == null) { - throw new IllegalStateException( - "commandName and setter can not both be empty"); - } - Setter setterToUse = getSetter(); - - PublisherHystrixCommand command = new PublisherHystrixCommand<>( - setterToUse, this.publisher, this.fallback); - - Observable observable = getObservableFunction().apply(command); - - return RxReactiveStreams.toPublisher(observable); - } - - public Function, Observable> getObservableFunction() { - Function, Observable> observableFunc; - - if (this.toObservable != null) { - observableFunc = this.toObservable; - } - else if (this.eager) { - observableFunc = cmd -> cmd.observe(); - } - else { // apply a default onBackpressureBuffer if not eager - observableFunc = cmd -> cmd.toObservable().onBackpressureBuffer(); - } - return observableFunc; - } - - public Setter getSetter() { - Setter setterToUse; - if (this.setter != null) { - setterToUse = this.setter; - } - else { - String groupNameToUse; - if (StringUtils.hasText(this.groupName)) { - groupNameToUse = this.groupName; - } - else { - groupNameToUse = commandName + "group"; - } - - HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory - .asKey(groupNameToUse); - HystrixCommandKey commandKey = HystrixCommandKey.Factory - .asKey(this.commandName); - HystrixCommandProperties.Setter commandProperties = this.commandProperties != null - ? this.commandProperties : HystrixCommandProperties.Setter(); - setterToUse = Setter.withGroupKey(groupKey).andCommandKey(commandKey) - .andCommandPropertiesDefaults(commandProperties); - } - return setterToUse; - } - - public Flux toFlux() { - return Flux.from(build()); - } - - public Mono toMono() { - return Mono.from(build()); - } - - } - - private static class PublisherHystrixCommand extends HystrixObservableCommand { - - private Publisher publisher; - - private Function> fallback; - - protected PublisherHystrixCommand(Setter setter, Publisher publisher, - Function> fallback) { - super(setter); - this.publisher = publisher; - this.fallback = fallback; - } - - @Override - protected Observable construct() { - return RxReactiveStreams.toObservable(publisher); - } - - @Override - protected Observable resumeWithFallback() { - if (this.fallback != null) { - Publisher fallbackPublisher = fallback.apply(getExecutionException()); - return RxReactiveStreams.toObservable(fallbackPublisher); - } - return super.resumeWithFallback(); - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixConstants.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixConstants.java deleted file mode 100644 index f4a035b55..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixConstants.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -/** - * @author Spencer Gibb - */ -public final class HystrixConstants { - - /** - * Hystrix stream destination name. - */ - public static final String HYSTRIX_STREAM_DESTINATION = "springCloudHystrixStream"; - - private HystrixConstants() { - throw new AssertionError("Must not instantiate constant utility class"); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixHealthIndicator.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixHealthIndicator.java deleted file mode 100644 index 838ce1dbe..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixHealthIndicator.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -import java.util.ArrayList; -import java.util.List; - -import com.netflix.hystrix.HystrixCircuitBreaker; -import com.netflix.hystrix.HystrixCommandMetrics; - -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health.Builder; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; - -/** - * A {@link HealthIndicator} implementation for Hystrix circuit breakers. - *

- * This default implementation will not change the system state (e.g. OK) but - * includes all open circuits by name. - * - * @author Christian Dupuis - */ -public class HystrixHealthIndicator extends AbstractHealthIndicator { - - private static final Status CIRCUIT_OPEN = new Status("CIRCUIT_OPEN"); - - @Override - protected void doHealthCheck(Builder builder) throws Exception { - List openCircuitBreakers = new ArrayList<>(); - - // Collect all open circuit breakers from Hystrix - for (HystrixCommandMetrics metrics : HystrixCommandMetrics.getInstances()) { - HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory - .getInstance(metrics.getCommandKey()); - if (circuitBreaker != null && circuitBreaker.isOpen()) { - openCircuitBreakers.add(metrics.getCommandGroup().name() + "::" - + metrics.getCommandKey().name()); - } - } - - // If there is at least one open circuit report OUT_OF_SERVICE adding the command - // group - // and key name - if (!openCircuitBreakers.isEmpty()) { - builder.status(CIRCUIT_OPEN).withDetail("openCircuitBreakers", - openCircuitBreakers); - } - else { - builder.up(); - } - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixMetricsProperties.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixMetricsProperties.java deleted file mode 100644 index dc45c3ead..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixMetricsProperties.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -import java.util.Objects; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * @author Venil Noronha - * @author Gregor Zurowski - */ -@ConfigurationProperties("hystrix.metrics") -public class HystrixMetricsProperties { - - /** Enable Hystrix metrics polling. Defaults to true. */ - private boolean enabled = true; - - /** Interval between subsequent polling of metrics. Defaults to 2000 ms. */ - private Integer pollingIntervalMs = 2000; - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public Integer getPollingIntervalMs() { - return pollingIntervalMs; - } - - public void setPollingIntervalMs(Integer pollingIntervalMs) { - this.pollingIntervalMs = pollingIntervalMs; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - HystrixMetricsProperties that = (HystrixMetricsProperties) o; - return enabled == that.enabled - && Objects.equals(pollingIntervalMs, that.pollingIntervalMs); - } - - @Override - public int hashCode() { - return Objects.hash(enabled, pollingIntervalMs); - } - - @Override - public String toString() { - return new StringBuilder("HystrixMetricsProperties{").append("enabled=") - .append(enabled).append(", ").append("pollingIntervalMs=") - .append(pollingIntervalMs).append("}").toString(); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixProperties.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixProperties.java deleted file mode 100644 index a08fb0ce0..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixProperties.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Configuration properties for Hystrix Servlet. - * - * @author Spencer Gibb - * @since 2.0.0 - */ -@ConfigurationProperties(prefix = "management.endpoint.hystrix") -public class HystrixProperties { - - /** - * Hystrix settings. These are traditionally set using servlet parameters. Refer to - * the documentation of Hystrix for more details. - */ - private final Map config = new HashMap<>(); - - public Map getConfig() { - return this.config; - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpoint.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpoint.java deleted file mode 100644 index f4982aaee..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpoint.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -import java.util.Map; -import java.util.function.Supplier; - -import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet; - -import org.springframework.boot.actuate.endpoint.web.EndpointServlet; -import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpoint; - -/** - * {@link org.springframework.boot.actuate.endpoint.annotation.Endpoint} to expose a - * Jolokia {@link HystrixMetricsStreamServlet}. - * - * @author Phillip Webb - * @since 2.0.0 - */ -@ServletEndpoint(id = "hystrix.stream") -public class HystrixStreamEndpoint implements Supplier { - - private final Map initParameters; - - public HystrixStreamEndpoint(Map initParameters) { - this.initParameters = initParameters; - } - - @Override - public EndpointServlet get() { - return new EndpointServlet(HystrixMetricsStreamServlet.class) - .withInitParameters(this.initParameters); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixWebfluxEndpoint.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixWebfluxEndpoint.java deleted file mode 100644 index 80fda4ca0..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixWebfluxEndpoint.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -import java.time.Duration; - -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; - -import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.GetMapping; - -/** - * @author Spencer Gibb - */ -@RestControllerEndpoint(id = "hystrix.stream") -public class HystrixWebfluxEndpoint { - - private final Flux stream; - - public HystrixWebfluxEndpoint(Publisher dashboardData) { - stream = Flux.interval(Duration.ofMillis(500)).map(aLong -> "{\"type\":\"ping\"}") - .mergeWith(dashboardData).share(); - } - - // path needs to be empty, so it registers correct as /actuator/hystrix.stream - @GetMapping(path = "", produces = MediaType.TEXT_EVENT_STREAM_VALUE) - public Flux hystrixStream() { - return stream; - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreaker.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreaker.java deleted file mode 100644 index 699a0481f..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreaker.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2013-2018 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 - * - * https://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.hystrix; - -import java.util.function.Function; - -import com.netflix.hystrix.HystrixObservableCommand; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import rx.Observable; -import rx.RxReactiveStreams; -import rx.Subscription; - -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker; - -/** - * @author Ryan Baxter - */ -public class ReactiveHystrixCircuitBreaker implements ReactiveCircuitBreaker { - - private HystrixObservableCommand.Setter setter; - - public ReactiveHystrixCircuitBreaker(HystrixObservableCommand.Setter setter) { - this.setter = setter; - } - - @Override - public Mono run(Mono toRun, Function> fallback) { - HystrixObservableCommand command = createCommand(toRun, fallback); - - return Mono.create(s -> { - Subscription sub = command.toObservable().subscribe(s::success, s::error, - s::success); - s.onCancel(sub::unsubscribe); - }); - } - - @Override - public Flux run(Flux toRun, Function> fallback) { - HystrixObservableCommand command = createCommand(toRun, fallback); - - return Flux.create(s -> { - Subscription sub = command.toObservable().subscribe(s::next, s::error, - s::complete); - s.onCancel(sub::unsubscribe); - }); - } - - private HystrixObservableCommand createCommand(Publisher toRun, - Function fallback) { - HystrixObservableCommand command = new HystrixObservableCommand(setter) { - @Override - protected Observable construct() { - return RxReactiveStreams.toObservable(toRun); - } - - @Override - protected Observable resumeWithFallback() { - if (fallback == null) { - super.resumeWithFallback(); - } - return RxReactiveStreams.toObservable( - (Publisher) fallback.apply(this.getExecutionException())); - } - }; - return command; - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerAutoConfiguration.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerAutoConfiguration.java deleted file mode 100644 index ff9459a25..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerAutoConfiguration.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.client.circuitbreaker.Customizer; -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Eric Bussieres - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(name = { "reactor.core.publisher.Mono", "reactor.core.publisher.Flux", - "com.netflix.hystrix.Hystrix" }) -@ConditionalOnProperty(name = "spring.cloud.circuitbreaker.hystrix.enabled", - matchIfMissing = true) -public class ReactiveHystrixCircuitBreakerAutoConfiguration { - - @Autowired(required = false) - private List> customizers = new ArrayList<>(); - - @Bean - @ConditionalOnMissingBean(ReactiveCircuitBreakerFactory.class) - public ReactiveHystrixCircuitBreakerFactory reactiveHystrixCircuitBreakerFactory() { - ReactiveHystrixCircuitBreakerFactory factory = new ReactiveHystrixCircuitBreakerFactory(); - customizers.forEach(customizer -> customizer.customize(factory)); - return factory; - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerFactory.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerFactory.java deleted file mode 100644 index db8a70eb7..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerFactory.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2013-2018 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 - * - * https://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.hystrix; - -import java.util.function.Function; - -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixObservableCommand; - -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker; -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory; -import org.springframework.util.Assert; - -/** - * @author Ryan Baxter - */ -public class ReactiveHystrixCircuitBreakerFactory extends - ReactiveCircuitBreakerFactory { - - private Function defaultConfiguration = id -> HystrixObservableCommand.Setter - .withGroupKey( - HystrixCommandGroupKey.Factory.asKey(getClass().getSimpleName())) - .andCommandKey(HystrixCommandKey.Factory.asKey(id)); - - @Override - protected ReactiveHystrixConfigBuilder configBuilder(String id) { - return new ReactiveHystrixConfigBuilder(id); - } - - @Override - public void configureDefault( - Function defaultConfiguration) { - this.defaultConfiguration = defaultConfiguration; - } - - @Override - public ReactiveCircuitBreaker create(String id) { - Assert.hasText(id, "A CircuitBreaker must have an id."); - HystrixObservableCommand.Setter setter = getConfigurations().computeIfAbsent(id, - defaultConfiguration); - return new ReactiveHystrixCircuitBreaker(setter); - } - - public static class ReactiveHystrixConfigBuilder - extends AbstractHystrixConfigBuilder { - - public ReactiveHystrixConfigBuilder(String id) { - super(id); - } - - @Override - public HystrixObservableCommand.Setter build() { - return HystrixObservableCommand.Setter.withGroupKey(getGroupKey()) - .andCommandKey(getCommandKey()) - .andCommandPropertiesDefaults(getCommandPropertiesSetter()); - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityAutoConfiguration.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityAutoConfiguration.java deleted file mode 100644 index 8d4bb55ba..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityAutoConfiguration.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.security; - -import javax.annotation.PostConstruct; - -import com.netflix.hystrix.Hystrix; -import com.netflix.hystrix.strategy.HystrixPlugins; -import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy; -import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategyDefault; -import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; -import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook; -import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher; -import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.AllNestedConditions; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfiguration.HystrixSecurityCondition; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.core.context.SecurityContext; - -/** - * @author Daniel Lavoie - */ -@Configuration(proxyBeanMethods = false) -@Conditional(HystrixSecurityCondition.class) -@ConditionalOnClass({ Hystrix.class, SecurityContext.class }) -public class HystrixSecurityAutoConfiguration { - - private static final Log LOGGER = LogFactory - .getLog(HystrixSecurityAutoConfiguration.class); - - @Autowired(required = false) - private HystrixConcurrencyStrategy existingConcurrencyStrategy; - - @PostConstruct - public void init() { - // Keeps references of existing Hystrix plugins. - HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance() - .getEventNotifier(); - HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance() - .getMetricsPublisher(); - HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance() - .getPropertiesStrategy(); - HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance() - .getCommandExecutionHook(); - HystrixConcurrencyStrategy concurrencyStrategy = detectRegisteredConcurrencyStrategy(); - - HystrixPlugins.reset(); - - // Registers existing plugins excepts the Concurrent Strategy plugin. - HystrixPlugins.getInstance().registerConcurrencyStrategy( - new SecurityContextConcurrencyStrategy(concurrencyStrategy)); - HystrixPlugins.getInstance().registerEventNotifier(eventNotifier); - HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher); - HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy); - HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook); - } - - private HystrixConcurrencyStrategy detectRegisteredConcurrencyStrategy() { - HystrixConcurrencyStrategy registeredStrategy = HystrixPlugins.getInstance() - .getConcurrencyStrategy(); - if (existingConcurrencyStrategy == null) { - return registeredStrategy; - } - // Hystrix registered a default Strategy. - if (registeredStrategy instanceof HystrixConcurrencyStrategyDefault) { - return existingConcurrencyStrategy; - } - // If registeredStrategy not the default and not some use bean of - // existingConcurrencyStrategy. - if (!existingConcurrencyStrategy.equals(registeredStrategy)) { - LOGGER.warn( - "Multiple HystrixConcurrencyStrategy detected. Bean of HystrixConcurrencyStrategy was used."); - } - return existingConcurrencyStrategy; - } - - static class HystrixSecurityCondition extends AllNestedConditions { - - HystrixSecurityCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @ConditionalOnProperty(name = "hystrix.shareSecurityContext") - static class ShareSecurityContext { - - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/security/SecurityContextConcurrencyStrategy.java b/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/security/SecurityContextConcurrencyStrategy.java deleted file mode 100644 index 56235f0b5..000000000 --- a/spring-cloud-netflix-hystrix/src/main/java/org/springframework/cloud/netflix/hystrix/security/SecurityContextConcurrencyStrategy.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.security; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.Callable; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -import com.netflix.hystrix.HystrixThreadPoolKey; -import com.netflix.hystrix.HystrixThreadPoolProperties; -import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy; -import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable; -import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle; -import com.netflix.hystrix.strategy.properties.HystrixProperty; - -import org.springframework.security.concurrent.DelegatingSecurityContextCallable; - -/** - * @author Daniel Lavoie - */ -public class SecurityContextConcurrencyStrategy extends HystrixConcurrencyStrategy { - - private HystrixConcurrencyStrategy existingConcurrencyStrategy; - - public SecurityContextConcurrencyStrategy( - HystrixConcurrencyStrategy existingConcurrencyStrategy) { - this.existingConcurrencyStrategy = existingConcurrencyStrategy; - } - - @Override - public BlockingQueue getBlockingQueue(int maxQueueSize) { - return existingConcurrencyStrategy != null - ? existingConcurrencyStrategy.getBlockingQueue(maxQueueSize) - : super.getBlockingQueue(maxQueueSize); - } - - @Override - public HystrixRequestVariable getRequestVariable( - HystrixRequestVariableLifecycle rv) { - return existingConcurrencyStrategy != null - ? existingConcurrencyStrategy.getRequestVariable(rv) - : super.getRequestVariable(rv); - } - - @Override - public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, - HystrixProperty corePoolSize, - HystrixProperty maximumPoolSize, - HystrixProperty keepAliveTime, TimeUnit unit, - BlockingQueue workQueue) { - return existingConcurrencyStrategy != null - ? existingConcurrencyStrategy.getThreadPool(threadPoolKey, corePoolSize, - maximumPoolSize, keepAliveTime, unit, workQueue) - : super.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, - keepAliveTime, unit, workQueue); - } - - @Override - public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, - HystrixThreadPoolProperties threadPoolProperties) { - return existingConcurrencyStrategy != null - ? existingConcurrencyStrategy.getThreadPool(threadPoolKey, - threadPoolProperties) - : super.getThreadPool(threadPoolKey, threadPoolProperties); - } - - @Override - public Callable wrapCallable(Callable callable) { - return existingConcurrencyStrategy != null - ? existingConcurrencyStrategy - .wrapCallable(new DelegatingSecurityContextCallable(callable)) - : super.wrapCallable(new DelegatingSecurityContextCallable(callable)); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-netflix-hystrix/src/main/resources/META-INF/additional-spring-configuration-metadata.json deleted file mode 100644 index 216f5dfd8..000000000 --- a/spring-cloud-netflix-hystrix/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "properties": [ - { - "defaultValue": "true", - "name": "management.metrics.binders.hystrix.enabled", - "description": "Enables creation of OK Http Client factory beans.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": false, - "name": "hystrix.shareSecurityContext", - "description": "Enables auto-configuration of the Hystrix concurrency strategy plugin hook who will transfer the `SecurityContext` from your main thread to the one used by the Hystrix command.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": true, - "name": "spring.cloud.circuitbreaker.hystrix.enabled", - "description": "Enables auto-configuration of the Hystrix Spring Cloud CircuitBreaker API implementation.", - "type": "java.lang.Boolean" - } - ] -} \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-hystrix/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 929e0a746..000000000 --- a/spring-cloud-netflix-hystrix/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,8 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.hystrix.HystrixAutoConfiguration,\ -org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerAutoConfiguration,\ -org.springframework.cloud.netflix.hystrix.ReactiveHystrixCircuitBreakerAutoConfiguration,\ -org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfiguration - -org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker=\ -org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/AdhocTestSuite.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/AdhocTestSuite.java deleted file mode 100644 index 172b59509..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/AdhocTestSuite.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2012-2013 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 - * - * https://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; - -import org.junit.Ignore; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -/** - * A test suite for probing weird ordering problems in the tests. - * - * @author Dave Syer - */ -@RunWith(Suite.class) -@SuiteClasses({ - // org.springframework.cloud.netflix.test.OkHttpClientConfigurationTests.class, - // org.springframework.cloud.netflix.test.ApacheHttpClientConfigurationTests.class, - // org.springframework.cloud.netflix.hystrix.HystrixCommandsTests.class, - // org.springframework.cloud.netflix.hystrix.HystrixOnlyTests.class, - // org.springframework.cloud.netflix.hystrix.security.HystrixSecurityTests.class, - // org.springframework.cloud.netflix.hystrix.security.HystrixSecurityNoFeignTests.class, - // org.springframework.cloud.netflix.hystrix.HystrixStreamEndpointTests.class, - // org.springframework.cloud.netflix.hystrix.HystrixConfigurationTests.class, - // org.springframework.cloud.netflix.resttemplate.RestTemplateRetryTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessorOverridesRetryTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonUtilsTests.class, - // org.springframework.cloud.netflix.ribbon.test.RibbonClientDefaultConfigurationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientConfigurationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientHttpRequestFactoryTests.class, - // org.springframework.cloud.netflix.ribbon.SpringRetryEnabledTests.class, - // org.springframework.cloud.netflix.ribbon.PlainRibbonClientPreprocessorIntegrationTests.class, - // org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClientTests.class, - // org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpRequestTests.class, - // org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpResponseTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessorIntegrationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientsPreprocessorIntegrationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientsEagerInitializationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonInterceptorTests.class, - // org.springframework.cloud.netflix.ribbon.support.ContextAwareRequestTests.class, - // org.springframework.cloud.netflix.ribbon.support.RibbonCommandContextTest.class, - // org.springframework.cloud.netflix.ribbon.support.RetryableStatusCodeExceptionTests.class, - // org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilterTests.class, - // org.springframework.cloud.netflix.ribbon.DefaultServerIntrospectorDefaultTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessorPropertiesOverridesIntegrationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactoryTests.class, - // org.springframework.cloud.netflix.ribbon.SpringClientFactoryTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonAutoConfigurationIntegrationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClientTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessorOverridesIntegrationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonApplicationContextInitializerTests.class, - // org.springframework.cloud.netflix.ribbon.okhttp.SpringRetryDisableOkHttpClientTests.class, - // org.springframework.cloud.netflix.ribbon.okhttp.OkHttpRibbonResponseTests.class, - // org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClientTests.class, - // org.springframework.cloud.netflix.ribbon.okhttp.OkHttpRibbonRequestTests.class, - // org.springframework.cloud.netflix.ribbon.okhttp.SpringRetryEnabledOkHttpClientTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonClientConfigurationIntegrationTests.class, - // org.springframework.cloud.netflix.ribbon.RibbonDisabledTests.class, - // org.springframework.cloud.netflix.ribbon.DefaultServerIntrospectorTests.class, - // org.springframework.cloud.netflix.ribbon.SpringRetryDisabledTests.class, - // org.springframework.cloud.netflix.feign.beans.FeignClientTests.class, - // org.springframework.cloud.netflix.feign.FeignClientsRegistrarTests.class, - // org.springframework.cloud.netflix.feign.encoding.FeignAcceptEncodingTests.class, - // org.springframework.cloud.netflix.feign.encoding.FeignContentEncodingTests.class, - // org.springframework.cloud.netflix.feign.FeignLoggerFactoryTests.class, - // org.springframework.cloud.netflix.feign.FeignCompressionTests.class, - // org.springframework.cloud.netflix.feign.EnableFeignClientsTests.class, - // org.springframework.cloud.netflix.feign.SpringDecoderTests.class, - // org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests.class, - // org.springframework.cloud.netflix.feign.FeignHttpClientUrlTests.class, - // org.springframework.cloud.netflix.feign.invalid.FeignClientValidationTests.class, - // org.springframework.cloud.netflix.feign.support.FeignHttpClientPropertiesTests.class, - // org.springframework.cloud.netflix.feign.support.SpringMvcContractTests.class, - // org.springframework.cloud.netflix.feign.support.SpringEncoderTests.class, - // org.springframework.cloud.netflix.feign.FeignClientOverrideDefaultsTests.class, - // org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClientOverrideTests.class, - // org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientPathTests.class, - // org.springframework.cloud.netflix.feign.ribbon.RetryableFeignLoadBalancerTests.class, - // org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientRetryTests.class, - // org.springframework.cloud.netflix.feign.ribbon.FeignLoadBalancerTests.class, - // org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientTests.class, - // org.springframework.cloud.netflix.feign.ribbon.CachingSpringLoadBalancerFactoryTests.class, - // org.springframework.cloud.netflix.feign.valid.scanning.FeignClientEnvVarTests.class, - // org.springframework.cloud.netflix.feign.valid.scanning.FeignClientScanningTests.class, - // org.springframework.cloud.netflix.feign.valid.FeignOkHttpTests.class, - // org.springframework.cloud.netflix.feign.valid.FeignClientValidationTests.class, - // org.springframework.cloud.netflix.feign.valid.FeignClientTests.class, - // org.springframework.cloud.netflix.feign.valid.FeignHttpClientTests.class, - // org.springframework.cloud.netflix.feign.valid.FeignClientNotPrimaryTests.class, - // org.springframework.cloud.netflix.feign.FeignClientFactoryTests.class, - -}) -@Ignore -public class AdhocTestSuite { - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfigurationTests.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfigurationTests.java deleted file mode 100644 index c16111be4..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixAutoConfigurationTests.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.cloud.test.ModifiedClassPathRunner; -import org.springframework.context.ConfigurableApplicationContext; - -import static org.assertj.core.api.Assertions.fail; - -@RunWith(ModifiedClassPathRunner.class) -@ClassPathExclusions({ "micrometer-core-*" }) -public class HystrixAutoConfigurationTests { - - @Test - @Ignore // TODO: why does this test fail in maven, but not in IDE? - public void contextStarts() { - try (ConfigurableApplicationContext context = new SpringApplicationBuilder() - .web(WebApplicationType.NONE).sources(TestApp.class).run()) { - try { - context.getBean("hystrixMetricsBinder"); - fail("HystrixMetricsBinder class should not be found"); - } - catch (NoSuchBeanDefinitionException e) { - // this is the correct case - } - } - } - - @EnableCircuitBreaker - @SpringBootConfiguration - @EnableAutoConfiguration - protected static class TestApp { - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerIntegrationTest.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerIntegrationTest.java deleted file mode 100644 index ddd432793..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerIntegrationTest.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2013-2018 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 - * - * https://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.hystrix; - -import com.netflix.hystrix.HystrixCommand; -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandProperties; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.cloud.client.circuitbreaker.CircuitBreaker; -import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; -import org.springframework.cloud.client.circuitbreaker.Customizer; -import org.springframework.cloud.netflix.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.stereotype.Service; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - classes = HystrixCircuitBreakerIntegrationTest.Application.class) -@DirtiesContext -@Import(NoSecurityConfiguration.class) -public class HystrixCircuitBreakerIntegrationTest { - - @Autowired - Application.DemoControllerService service; - - @Test - public void testSlow() { - assertThat(service.slow()).isEqualTo("fallback"); - } - - @Test - public void testNormal() { - assertThat(service.normal()).isEqualTo("normal"); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - protected static class Application { - - @RequestMapping("/slow") - public String slow() throws InterruptedException { - Thread.sleep(3000); - return "slow"; - } - - @GetMapping("/normal") - public String normal() { - return "normal"; - } - - @Bean - public Customizer customizer() { - return factory -> factory - .configure( - builder -> builder.commandProperties(HystrixCommandProperties - .Setter().withExecutionTimeoutInMilliseconds(2000)), - "slow"); - } - - @Bean - public Customizer defaultConfig() { - return factory -> factory.configureDefault(id -> HystrixCommand.Setter - .withGroupKey(HystrixCommandGroupKey.Factory.asKey(id)) - .andCommandPropertiesDefaults(HystrixCommandProperties.Setter() - .withExecutionTimeoutInMilliseconds(4000))); - } - - @Service - public static class DemoControllerService { - - private TestRestTemplate rest; - - private final CircuitBreakerFactory cbFactory; - - private final CircuitBreaker circuitBreakerSlow; - - DemoControllerService(TestRestTemplate rest, - CircuitBreakerFactory cbBuilder) { - this.rest = rest; - this.cbFactory = cbBuilder; - this.circuitBreakerSlow = cbBuilder.create("slow"); - } - - public String slow() { - return circuitBreakerSlow.run( - () -> rest.getForObject("/slow", String.class), t -> "fallback"); - } - - public String normal() { - return cbFactory.create("normal").run( - () -> rest.getForObject("/normal", String.class), - t -> "fallback"); - } - - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerTest.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerTest.java deleted file mode 100644 index 1a974c249..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCircuitBreakerTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2013-2018 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 - * - * https://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.hystrix; - -import org.junit.Test; - -import org.springframework.cloud.client.circuitbreaker.CircuitBreaker; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - */ -public class HystrixCircuitBreakerTest { - - @Test - public void run() { - CircuitBreaker cb = new HystrixCircuitBreakerFactory().create("foo"); - String s = cb.run(() -> "foobar", t -> "fallback"); - assertThat(cb.run(() -> "foobar", t -> "fallback")).isEqualTo("foobar"); - } - - @Test - public void fallback() { - CircuitBreaker cb = new HystrixCircuitBreakerFactory().create("foo"); - assertThat((String) cb.run(() -> { - throw new RuntimeException("Boom"); - }, t -> "fallback")).isEqualTo("fallback"); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCommandsTests.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCommandsTests.java deleted file mode 100644 index e92691093..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixCommandsTests.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -import java.time.Duration; - -import com.netflix.hystrix.exception.HystrixRuntimeException; -import org.junit.Test; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -public class HystrixCommandsTests { - - @Test - public void monoWorks() { - StepVerifier.create(HystrixCommands.from(Flux.just("works")) - .commandName("testworks").toMono()).expectNext("works").verifyComplete(); - } - - @Test - public void eagerMonoWorks() { - StepVerifier - .create(HystrixCommands.from(Mono.just("works")).eager() - .commandName("testworks").toMono()) - .expectNext("works").verifyComplete(); - } - - @Test - public void monoTimesOut() { - StepVerifier.create(HystrixCommands.from(Mono.fromCallable(() -> { - Thread.sleep(1500); - return "timeout"; - })).commandName("failcmd").toMono()).verifyError(HystrixRuntimeException.class); - } - - @Test - public void monoFallbackWorks() { - StepVerifier - .create(HystrixCommands.from(Mono.error(new Exception())) - .commandName("failcmd").fallback(Mono.just("fallback")).toMono()) - .expectNext("fallback").verifyComplete(); - } - - @Test - public void monoFallbackWithExceptionWorks() { - StepVerifier.create( - HystrixCommands.from(Mono.error(new IllegalStateException())) - .commandName("failcmd").fallback(throwable -> { - if (throwable instanceof IllegalStateException) { - return Mono.just("specificfallback"); - } - return Mono.just("genericfallback"); - }).toMono()) - .expectNext("specificfallback").verifyComplete(); - } - - @Test - public void fluxWorks() { - StepVerifier.create(HystrixCommands.from(Flux.just("1", "2")) - .commandName("multiflux").toFlux()).expectNext("1").expectNext("2") - .verifyComplete(); - } - - @Test - public void fluxWorksDeferredRequest() { - StepVerifier - .create(HystrixCommands.from(Flux.just("1", "2")).commandName("multiflux") - .build(), 1) - .expectNext("1").thenAwait(Duration.ofSeconds(1)).thenRequest(1) - .expectNext("2").verifyComplete(); - } - - @Test - public void toObservableFunctionWorks() { - StepVerifier - .create(HystrixCommands.from(Flux.just("1", "2")).commandName("multiflux") - .toObservable(cmd -> cmd.toObservable()).build(), 1) - .expectNext("1").thenAwait(Duration.ofSeconds(1)).thenRequest(1) - .verifyError(); - } - - @Test - public void eagerFluxWorks() { - StepVerifier - .create(HystrixCommands.from(Flux.just("1", "2")).commandName("multiflux") - .eager().toFlux()) - .expectNext("1").expectNext("2").verifyComplete(); - } - - @Test - public void fluxTimesOut() { - StepVerifier.create(HystrixCommands.from(Flux.from(s -> { - try { - Thread.sleep(1500); - } - catch (InterruptedException e) { - throw new RuntimeException(e); - } - })).commandName("failcmd").toFlux()).verifyError(HystrixRuntimeException.class); - } - - @Test - public void fluxFallbackWorks() { - StepVerifier - .create(HystrixCommands.from(Flux.error(new Exception())) - .commandName("multiflux").fallback(Flux.just("a", "b")).toFlux()) - .expectNext("a").expectNext("b").verifyComplete(); - } - - @Test - public void extendTimeout() { - StepVerifier.create(HystrixCommands.from(Mono.fromCallable(() -> { - Thread.sleep(1500); - return "works"; - })).commandName("extendTimeout") - .commandProperties( - setter -> setter.withExecutionTimeoutInMilliseconds(2000)) - .toMono()).expectNext("works").verifyComplete(); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixConfigurationTests.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixConfigurationTests.java deleted file mode 100644 index ccfa7be77..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixConfigurationTests.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect; -import io.micrometer.core.instrument.binder.MeterBinder; -import io.micrometer.core.instrument.binder.hystrix.HystrixMetricsBinder; -import org.junit.Test; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * @author Biju Kunjummen - */ -public class HystrixConfigurationTests { - - @Test - public void nonWebAppStartsUp() { - new ApplicationContextRunner() - .withUserConfiguration(HystrixCircuitBreakerConfiguration.class) - .run(c -> { - assertThat(c).hasSingleBean(HystrixCommandAspect.class); - }); - } - - @Test - public void hystrixMetricsConfigured() { - new WebApplicationContextRunner().withUserConfiguration(TestApp.class).run(c -> { - assertThat(c.getBeansOfType(MeterBinder.class).values()) - .hasAtLeastOneElementOfType(HystrixMetricsBinder.class); - }); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - protected static class TestApp { - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixOnlyTests.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixOnlyTests.java deleted file mode 100644 index 7a1ad2732..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixOnlyTests.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -import java.util.Base64; -import java.util.List; -import java.util.Map; - -import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; -import org.springframework.cloud.netflix.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; -import static org.springframework.cloud.netflix.test.TestAutoConfiguration.PASSWORD; -import static org.springframework.cloud.netflix.test.TestAutoConfiguration.USER; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = HystrixOnlyApplication.class, webEnvironment = RANDOM_PORT, - properties = { "management.endpoint.health.show-details=ALWAYS" }) -@DirtiesContext -@ActiveProfiles("proxysecurity") -public class HystrixOnlyTests { - - private static final String BASE_PATH = new WebEndpointProperties().getBasePath(); - - @LocalServerPort - private int port; - - @Test - public void testNormalExecution() { - ResponseEntity res = new TestRestTemplate() - .getForEntity("http://localhost:" + this.port + "/", String.class); - assertThat(res.getBody()).as("incorrect response").isEqualTo("Hello world"); - } - - @Test - public void testFailureFallback() { - ResponseEntity res = new TestRestTemplate() - .getForEntity("http://localhost:" + this.port + "/fail", String.class); - assertThat(res.getBody()).as("incorrect fallback") - .isEqualTo("Fallback Hello world"); - } - - @Test - @SuppressWarnings("unchecked") - public void testHystrixHealth() { - Map map = getHealth(); - // https://github.com/spring-projects/spring-boot/issues/17929 - // if the default changes back, this will need to be reverted. - assertThat(map).containsKeys("components"); - Map details = (Map) map.get("components"); - assertThat(details).containsKeys("hystrix"); - Map hystrix = (Map) details.get("hystrix"); - assertThat(hystrix).containsEntry("status", "UP"); - } - - @Test - public void testNoDiscoveryHealth() { - Map map = getHealth(); - // There is explicitly no discovery, so there should be no discovery health key - assertThat(map.containsKey("discovery")) - .as("Incorrect existing discovery health key").isFalse(); - } - - @Test - public void testHystrixInnerMapMetrics() { - // We have to hit any Hystrix command before Hystrix metrics to be populated - String url = "http://localhost:" + this.port; - ResponseEntity response = new TestRestTemplate().getForEntity(url, - String.class); - assertThat(response.getStatusCode()).as("bad response code") - .isEqualTo(HttpStatus.OK); - - // Poller takes some time to realize for new metrics - try { - Thread.sleep(2000); - } - catch (InterruptedException e) { - } - - Map> map = (Map>) getMetrics(); - - assertThat(map.get("names").contains("hystrix.latency.total")) - .as("There is no latencyTotal group key specified").isTrue(); - assertThat(map.get("names").contains("hystrix.latency.execution")) - .as("There is no latencyExecute group key specified").isTrue(); - } - - private Map getMetrics() { - return getAuthenticatedEndpoint("/metrics"); - } - - private Map getHealth() { - return getAuthenticatedEndpoint("/health"); - } - - private Map getAuthenticatedEndpoint(String endpoint) { - return new TestRestTemplate().exchange( - "http://localhost:" + this.port + BASE_PATH + endpoint, HttpMethod.GET, - new HttpEntity(createBasicAuthHeader(USER, PASSWORD)), Map.class) - .getBody(); - } - - public static HttpHeaders createBasicAuthHeader(final String username, - final String password) { - return new HttpHeaders() { - private static final long serialVersionUID = 1766341693637204893L; - - { - String auth = username + ":" + password; - byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes()); - String authHeader = "Basic " + new String(encodedAuth); - this.set("Authorization", authHeader); - } - }; - } - -} - -class Service { - - @HystrixCommand - public String hello() { - return "Hello world"; - } - - @HystrixCommand(fallbackMethod = "fallback") - public String fail() { - throw new RuntimeException("Always fail"); - } - - public String fallback() { - return "Fallback Hello world"; - } - -} - -// Don't use @SpringBootApplication because we don't want to component scan -@Configuration(proxyBeanMethods = false) -@EnableAutoConfiguration -@EnableCircuitBreaker -@RestController -@Import(NoSecurityConfiguration.class) -class HystrixOnlyApplication { - - @Bean - public Service service() { - return new Service(); - } - - @Autowired - private Service service; - - @RequestMapping("/") - public String home() { - return this.service.hello(); - } - - @RequestMapping("/fail") - public String fail() { - return this.service.fail(); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpointTests.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpointTests.java deleted file mode 100644 index bc0edf471..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixStreamEndpointTests.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; - -import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; -import org.springframework.cloud.netflix.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; - -/** - * @author Dave Syer - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = HystrixStreamEndpointTests.Application.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "spring.application.name=hystrixstreamtest" }) -@DirtiesContext -public class HystrixStreamEndpointTests { - - private static final String BASE_PATH = new WebEndpointProperties().getBasePath(); - - private static final Log log = LogFactory.getLog(HystrixStreamEndpointTests.class); - - @LocalServerPort - private int port = 0; - - @Test - public void hystrixStreamWorks() throws Exception { - String url = "http://localhost:" + port; - // you have to hit a Hystrix circuit breaker before the stream sends anything - ResponseEntity response = new TestRestTemplate().getForEntity(url, - String.class); - assertThat(response.getStatusCode()).as("bad response code") - .isEqualTo(HttpStatus.OK); - - URL hystrixUrl = new URL(url + BASE_PATH + "/hystrix.stream"); - - List data = new ArrayList<>(); - for (int i = 0; i < 5; i++) { - try (InputStream in = hystrixUrl.openStream()) { - byte[] buffer = new byte[1024]; - in.read(buffer); - data.add(new String(buffer)); - } - catch (Exception e) { - log.error("Error getting hystrix stream, try " + i, e); - } - } - - for (String item : data) { - if (item.contains("data:")) { - return; // test passed - } - } - fail("/hystrix.stream didn't contain 'data:' was " + data); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableCircuitBreaker - @Import(NoSecurityConfiguration.class) - protected static class Application { - - @Autowired - Service service; - - @Bean - Service service() { - return new Service(); - } - - @RequestMapping("/") - public String hello() { - return service.hello(); - } - - } - - protected static class Service { - - @HystrixCommand - public String hello() { - return "Hello World"; - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixWebfluxEndpointTests.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixWebfluxEndpointTests.java deleted file mode 100644 index 82f68fcd3..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/HystrixWebfluxEndpointTests.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix; - -import java.util.Map; - -import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Test; -import org.junit.runner.RunWith; -import reactor.core.publisher.Flux; -import reactor.test.StepVerifier; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; -import org.springframework.cloud.netflix.test.TestAutoConfiguration; -import org.springframework.http.MediaType; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Dave Syer - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - properties = { "spring.main.web-application-type=reactive", - "spring.application.name=hystrixstreamwebfluxtest" /* "debug=true" */ }) -@DirtiesContext -public class HystrixWebfluxEndpointTests { - - private static final String BASE_PATH = new WebEndpointProperties().getBasePath(); - - private static final Log log = LogFactory.getLog(HystrixWebfluxEndpointTests.class); - - @LocalServerPort - private int port; - - @Test - public void hystrixStreamWorks() { - String url = "http://localhost:" + port; - // you have to hit a Hystrix circuit breaker before the stream sends anything - WebTestClient testClient = WebTestClient.bindToServer().baseUrl(url).build(); - testClient.get().uri("/").exchange().expectStatus().isOk(); - - WebClient client = WebClient.create(url); - - Flux result = client.get().uri(BASE_PATH + "/hystrix.stream") - .accept(MediaType.TEXT_EVENT_STREAM).exchange() - .flatMapMany(res -> res.bodyToFlux(Map.class)).take(5) - .filter(map -> "HystrixCommand".equals(map.get("type"))) - .map(map -> (String) map.get("type")); - - StepVerifier.create(result).expectNext("HystrixCommand").thenCancel().verify(); - } - - @RestController - @EnableCircuitBreaker - @EnableAutoConfiguration(exclude = TestAutoConfiguration.class, excludeName = { - "org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration", - "org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration", - "org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration" }) - @SpringBootConfiguration - protected static class Config { - - @HystrixCommand - @RequestMapping("/") - public String hi() { - return "hi"; - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerIntegrationTest.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerIntegrationTest.java deleted file mode 100644 index 4cd3ebeb4..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerIntegrationTest.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2013-2018 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 - * - * https://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.hystrix; - -import java.time.Duration; - -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.HystrixObservableCommand; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.client.circuitbreaker.Customizer; -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker; -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory; -import org.springframework.cloud.netflix.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.stereotype.Service; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - classes = ReactiveHystrixCircuitBreakerIntegrationTest.Application.class) -@DirtiesContext -@Import(NoSecurityConfiguration.class) -public class ReactiveHystrixCircuitBreakerIntegrationTest { - - @LocalServerPort - int port = 0; - - @Autowired - ReactiveHystrixCircuitBreakerIntegrationTest.Application.DemoControllerService service; - - @Before - public void setup() { - service.setPort(port); - } - - @Test - public void testSlow() { - assertThat(service.slow().block()).isEqualTo("fallback"); - } - - @Test - public void testNormal() { - assertThat(service.normal().block()).isEqualTo("normal"); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - protected static class Application { - - @RequestMapping("/slow") - public Mono slow() { - return Mono.just("slow").delayElement(Duration.ofSeconds(3)); - } - - @GetMapping("/normal") - public Mono normal() { - return Mono.just("normal"); - } - - @Bean - public Customizer customizer() { - return factory -> factory - .configure( - builder -> builder.commandProperties(HystrixCommandProperties - .Setter().withExecutionTimeoutInMilliseconds(2000)), - "slow"); - } - - @Bean - public Customizer defaultConfig() { - return factory -> factory - .configureDefault(id -> HystrixObservableCommand.Setter - .withGroupKey(HystrixCommandGroupKey.Factory.asKey(id)) - .andCommandPropertiesDefaults(HystrixCommandProperties - .Setter().withExecutionTimeoutInMilliseconds(4000))); - } - - @Service - public static class DemoControllerService { - - private int port = 0; - - private final ReactiveCircuitBreakerFactory cbFactory; - - private final ReactiveCircuitBreaker circuitBreakerSlow; - - DemoControllerService(ReactiveCircuitBreakerFactory cbBuilder) { - this.cbFactory = cbBuilder; - this.circuitBreakerSlow = cbBuilder.create("slow"); - } - - public Mono slow() { - return WebClient.builder().baseUrl("http://localhost:" + port).build() - .get().uri("/slow").retrieve().bodyToMono(String.class) - .transform(it -> circuitBreakerSlow.run(it, t -> { - t.printStackTrace(); - return Mono.just("fallback"); - })); - } - - public Mono normal() { - return WebClient.builder().baseUrl("http://localhost:" + port).build() - .get().uri("/normal").retrieve().bodyToMono(String.class) - .transform(it -> cbFactory.create("normal").run(it, t -> { - t.printStackTrace(); - return Mono.just("fallback"); - })); - } - - public void setPort(int port) { - this.port = port; - } - - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerTest.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerTest.java deleted file mode 100644 index f14c47131..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/ReactiveHystrixCircuitBreakerTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2013-2018 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 - * - * https://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.hystrix; - -import org.assertj.core.util.Arrays; -import org.junit.Test; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - */ -public class ReactiveHystrixCircuitBreakerTest { - - @Test - public void monoRun() { - ReactiveCircuitBreaker cb = new ReactiveHystrixCircuitBreakerFactory() - .create("foo"); - Mono s = Mono.just("foobar") - .transform(it -> cb.run(it, t -> Mono.just("fallback"))); - assertThat(s.block()).isEqualTo("foobar"); - } - - @Test - public void monoFallback() { - ReactiveCircuitBreaker cb = new ReactiveHystrixCircuitBreakerFactory() - .create("foo"); - assertThat(Mono.error(new RuntimeException("boom")) - .transform(it -> cb.run(it, t -> Mono.just("fallback"))).block()) - .isEqualTo("fallback"); - } - - @Test - public void fluxRun() { - ReactiveCircuitBreaker cb = new ReactiveHystrixCircuitBreakerFactory() - .create("foo"); - Flux s = Flux.just("foobar", "hello world") - .transform(it -> cb.run(it, t -> Flux.just("fallback"))); - assertThat(s.collectList().block()) - .isEqualTo(Arrays.asList(new String[] { "foobar", "hello world" })); - } - - @Test - public void fluxFallback() { - ReactiveCircuitBreaker cb = new ReactiveHystrixCircuitBreakerFactory() - .create("foo"); - assertThat(Flux.error(new RuntimeException("boom")) - .transform(it -> cb.run(it, t -> Flux.just("fallback"))).collectList() - .block()).isEqualTo(Arrays.asList(new String[] { "fallback" })); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityApplication.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityApplication.java deleted file mode 100644 index ff2904ca6..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityApplication.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2013-2016 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 - * - * https://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.hystrix.security; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Configuration; - -/** - * @author Daniel Lavoie - */ -@Configuration(proxyBeanMethods = false) -@SpringBootApplication -public class HystrixSecurityApplication { - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityAutoConfigurationTest.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityAutoConfigurationTest.java deleted file mode 100644 index b1d0cf982..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityAutoConfigurationTest.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.security; - -import java.lang.reflect.Field; - -import com.netflix.hystrix.strategy.HystrixPlugins; -import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy; -import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategyDefault; -import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; -import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook; -import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher; -import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy; -import org.junit.Test; -import org.mockito.internal.util.reflection.FieldSetter; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author : ailin.zhou - */ -public class HystrixSecurityAutoConfigurationTest { - - @Test - public void testInit() throws NoSuchFieldException, IllegalAccessException { - - // save test context - HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance() - .getEventNotifier(); - HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance() - .getMetricsPublisher(); - HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance() - .getPropertiesStrategy(); - HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance() - .getCommandExecutionHook(); - HystrixConcurrencyStrategy concurrencyStrategy = HystrixPlugins.getInstance() - .getConcurrencyStrategy(); - - // test - testForMultiConcurrentStrategy(); - - // recover test context - HystrixPlugins.reset(); - HystrixPlugins.getInstance().registerConcurrencyStrategy(concurrencyStrategy); - HystrixPlugins.getInstance().registerEventNotifier(eventNotifier); - HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher); - HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy); - HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook); - - } - - private void testForMultiConcurrentStrategy() - throws IllegalAccessException, NoSuchFieldException { - HystrixSecurityAutoConfiguration securityStrategy = new HystrixSecurityAutoConfiguration(); - - // 1.existingConcurrencyStrategy is null, registeredStrategy is default - HystrixPlugins.reset(); - securityStrategy.init(); - // result is default - assertThat(getOriginalInSecurityConcurrencyStrategy()) - .isEqualTo(HystrixConcurrencyStrategyDefault.getInstance()); - - // 2.existingConcurrencyStrategy is null, registered strategy is customized - HystrixPlugins.reset(); - HystrixConcurrencyStrategy customized = new HystrixConcurrencyStrategy() { - }; - HystrixPlugins.getInstance().registerConcurrencyStrategy(customized); - securityStrategy.init(); - // result is customized - assertThat(getOriginalInSecurityConcurrencyStrategy()).isEqualTo(customized); - - // 3.existingConcurrencyStrategy is not null, registeredStrategy is default. - HystrixPlugins.reset(); - HystrixConcurrencyStrategy existingConcurrencyStrategy = new HystrixConcurrencyStrategy() { - }; - FieldSetter - .setField(securityStrategy, - securityStrategy.getClass() - .getDeclaredField("existingConcurrencyStrategy"), - existingConcurrencyStrategy); - securityStrategy.init(); - // result is existingConcurrencyStrategy - assertThat(getOriginalInSecurityConcurrencyStrategy()) - .isEqualTo(existingConcurrencyStrategy); - - // 4.existingConcurrencyStrategy is not null, registeredStrategy is customized. - HystrixPlugins.reset(); - HystrixPlugins.getInstance().registerConcurrencyStrategy(customized); - FieldSetter - .setField(securityStrategy, - securityStrategy.getClass() - .getDeclaredField("existingConcurrencyStrategy"), - existingConcurrencyStrategy); - securityStrategy.init(); - assertThat(getOriginalInSecurityConcurrencyStrategy()) - .isEqualTo(existingConcurrencyStrategy); - } - - private HystrixConcurrencyStrategy getOriginalInSecurityConcurrencyStrategy() - throws IllegalAccessException, NoSuchFieldException { - HystrixConcurrencyStrategy concurrencyStrategy = HystrixPlugins.getInstance() - .getConcurrencyStrategy(); - Field existingConcurrencyStrategy = concurrencyStrategy.getClass() - .getDeclaredField("existingConcurrencyStrategy"); - existingConcurrencyStrategy.setAccessible(true); - HystrixConcurrencyStrategy strategyInSecurityStrategy = (HystrixConcurrencyStrategy) existingConcurrencyStrategy - .get(concurrencyStrategy); - return strategyInSecurityStrategy; - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityNoFeignTests.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityNoFeignTests.java deleted file mode 100644 index e79b80333..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/HystrixSecurityNoFeignTests.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.security; - -import com.netflix.hystrix.strategy.HystrixPlugins; -import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringRunner.class) -@DirtiesContext -@SpringBootTest(classes = HystrixSecurityApplication.class) -public class HystrixSecurityNoFeignTests { - - @Test - public void testSecurityConcurrencyStrategyInstalled() { - HystrixConcurrencyStrategy concurrencyStrategy = HystrixPlugins.getInstance() - .getConcurrencyStrategy(); - assertThat(concurrencyStrategy) - .isInstanceOf(SecurityContextConcurrencyStrategy.class); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/CustomConcurrenyStrategy.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/CustomConcurrenyStrategy.java deleted file mode 100644 index 5884ffcb5..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/CustomConcurrenyStrategy.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2016-2019 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 - * - * https://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.hystrix.security.app; - -import java.util.concurrent.Callable; - -import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy; - -import org.springframework.stereotype.Component; - -@Component -public class CustomConcurrenyStrategy extends HystrixConcurrencyStrategy { - - private boolean hookCalled; - - @Override - public Callable wrapCallable(Callable callable) { - this.hookCalled = true; - - return super.wrapCallable(callable); - } - - public boolean isHookCalled() { - return hookCalled; - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/UsernameController.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/UsernameController.java deleted file mode 100644 index 91806236f..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/hystrix/security/app/UsernameController.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.hystrix.security.app; - -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * @author Daniel Lavoie - */ -@RestController -@RequestMapping("/username") -public class UsernameController { - - @RequestMapping - public String getUsername(@RequestHeader String username) { - return username; - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/resttemplate/RestTemplateRetryTests.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/resttemplate/RestTemplateRetryTests.java deleted file mode 100644 index 9b990457f..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/resttemplate/RestTemplateRetryTests.java +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.resttemplate; - -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.concurrent.atomic.AtomicInteger; - -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.AvailabilityFilteringRule; -import com.netflix.loadbalancer.BaseLoadBalancer; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.IPing; -import com.netflix.loadbalancer.IRule; -import com.netflix.loadbalancer.LoadBalancerBuilder; -import com.netflix.loadbalancer.LoadBalancerStats; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.loadbalancer.ServerStats; -import com.netflix.niws.client.http.HttpClientLoadBalancerErrorHandler; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.loadbalancer.LoadBalanced; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.SocketUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = RestTemplateRetryTests.Application.class, - webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=resttemplatetest", - "logging.level.com.netflix=DEBUG", - "logging.level.org.springframework.cloud.netflix.resttemplate=DEBUG", - "logging.level.com.netflix=DEBUG", "badClients.ribbon.MaxAutoRetries=25", - "badClients.ribbon.OkToRetryOnAllOperations=true", - "ribbon.http.client.enabled" }) -@DirtiesContext -public class RestTemplateRetryTests { - - private static final Log logger = LogFactory.getLog(RestTemplateRetryTests.class); - - @Autowired - private RestTemplate testClient; - - @Before - public void setup() throws Exception { - // Force Ribbon configuration by making one call. - this.testClient.getForObject("http://badClients/ping", Integer.class); - } - - @Test - public void testNullPointer() throws Exception { - - LoadBalancerStats stats = LocalBadClientConfiguration.balancer - .getLoadBalancerStats(); - ServerStats badServer1Stats = stats - .getSingleServerStat(LocalBadClientConfiguration.badServer); - ServerStats badServer2Stats = stats - .getSingleServerStat(LocalBadClientConfiguration.badServer2); - ServerStats goodServerStats = stats - .getSingleServerStat(LocalBadClientConfiguration.goodServer); - - badServer1Stats.clearSuccessiveConnectionFailureCount(); - badServer2Stats.clearSuccessiveConnectionFailureCount(); - int numCalls = 10; - long targetConnectionCount = goodServerStats.getTotalRequestsCount() + numCalls; - - // A null pointer should NOT trigger a circuit breaker. - for (int index = 0; index < numCalls; index++) { - try { - this.testClient.getForObject("http://badClients/null", Integer.class); - } - catch (Exception exception) { - } - } - logServerStats(LocalBadClientConfiguration.badServer); - logServerStats(LocalBadClientConfiguration.badServer2); - logServerStats(LocalBadClientConfiguration.goodServer); - - assertThat(badServer1Stats.isCircuitBreakerTripped()).isTrue(); - assertThat(badServer2Stats.isCircuitBreakerTripped()).isTrue(); - assertThat(targetConnectionCount) - .isLessThanOrEqualTo(goodServerStats.getTotalRequestsCount()); - - // Wait for any timeout thread to finish. - - } - - private void logServerStats(Server server) { - LoadBalancerStats stats = LocalBadClientConfiguration.balancer - .getLoadBalancerStats(); - ServerStats serverStats = stats.getSingleServerStat(server); - logger.debug("Server : " + server.toString() + " : Total Count == " - + serverStats.getTotalRequestsCount() + ", Failure Count == " - + serverStats.getFailureCount() + ", Successive Connection Failure == " - + serverStats.getSuccessiveConnectionFailureCount() - + ", Circuit Breaker ? == " + serverStats.isCircuitBreakerTripped()); - } - - @Test - public void testRestRetries() { - - LoadBalancerStats stats = LocalBadClientConfiguration.balancer - .getLoadBalancerStats(); - ServerStats badServer1Stats = stats - .getSingleServerStat(LocalBadClientConfiguration.badServer); - ServerStats badServer2Stats = stats - .getSingleServerStat(LocalBadClientConfiguration.badServer2); - ServerStats goodServerStats = stats - .getSingleServerStat(LocalBadClientConfiguration.goodServer); - - badServer1Stats.clearSuccessiveConnectionFailureCount(); - badServer2Stats.clearSuccessiveConnectionFailureCount(); - int numCalls = 20; - long targetConnectionCount = goodServerStats.getTotalRequestsCount() + numCalls; - - int hits = 0; - - for (int index = 0; index < numCalls; index++) { - hits = this.testClient.getForObject("http://badClients/good", Integer.class); - } - - logServerStats(LocalBadClientConfiguration.badServer); - logServerStats(LocalBadClientConfiguration.badServer2); - logServerStats(LocalBadClientConfiguration.goodServer); - - assertThat(badServer1Stats.isCircuitBreakerTripped()).isTrue(); - assertThat(badServer2Stats.isCircuitBreakerTripped()).isTrue(); - assertThat(targetConnectionCount) - .isLessThanOrEqualTo(goodServerStats.getTotalRequestsCount()); - assertThat(hits).isGreaterThanOrEqualTo(numCalls); - logger.debug("Retry Hits: " + hits); - } - - @Test - public void testRestRetriesWithReadTimeout() throws Exception { - - LoadBalancerStats stats = LocalBadClientConfiguration.balancer - .getLoadBalancerStats(); - ServerStats badServer1Stats = stats - .getSingleServerStat(LocalBadClientConfiguration.badServer); - ServerStats badServer2Stats = stats - .getSingleServerStat(LocalBadClientConfiguration.badServer2); - ServerStats goodServerStats = stats - .getSingleServerStat(LocalBadClientConfiguration.goodServer); - - badServer1Stats.clearSuccessiveConnectionFailureCount(); - badServer2Stats.clearSuccessiveConnectionFailureCount(); - assertThat(!badServer1Stats.isCircuitBreakerTripped()).isTrue(); - assertThat(!badServer2Stats.isCircuitBreakerTripped()).isTrue(); - - int hits = 0; - - int numCalls = 15; - for (int index = 0; index < numCalls; index++) { - hits = this.testClient.getForObject("http://badClients/timeout", - Integer.class); - } - logServerStats(LocalBadClientConfiguration.badServer); - logServerStats(LocalBadClientConfiguration.badServer2); - logServerStats(LocalBadClientConfiguration.goodServer); - - assertThat(badServer1Stats.isCircuitBreakerTripped()).isTrue(); - assertThat(badServer2Stats.isCircuitBreakerTripped()).isTrue(); - assertThat(!goodServerStats.isCircuitBreakerTripped()).isTrue(); - - // 15 + 4 timeouts. See the endpoint for timeout conditions. - assertThat(hits).isGreaterThanOrEqualTo(numCalls + 4); - - // Wait for any timeout thread to finish. - Thread.sleep(600); - - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @RibbonClient(name = "badClients", configuration = LocalBadClientConfiguration.class) - @Import(NoSecurityConfiguration.class) - public static class Application { - - private AtomicInteger hits = new AtomicInteger(1); - - private AtomicInteger retryHits = new AtomicInteger(1); - - @RequestMapping(method = RequestMethod.GET, value = "/ping") - public int ping() { - return 0; - } - - @RequestMapping(method = RequestMethod.GET, value = "/good") - public int good() { - int lValue = this.hits.getAndIncrement(); - return lValue; - } - - @RequestMapping(method = RequestMethod.GET, value = "/timeout") - public int timeout() throws Exception { - int lValue = this.retryHits.getAndIncrement(); - - // Force the good server to have 2 consecutive errors a couple of times. - if (lValue == 2 || lValue == 3 || lValue == 5 || lValue == 6) { - Thread.sleep(500); - } - return lValue; - } - - @RequestMapping(method = RequestMethod.GET, value = "/null") - public int isNull() throws Exception { - throw new NullPointerException("Null"); - } - - @LoadBalanced - @Bean - RestTemplate restTemplate() { - return new RestTemplate(); - } - - } - - // Load balancer with fixed server list for "local" pointing to localhost - // and some bogus servers are thrown in to test retry - @Configuration(proxyBeanMethods = false) - static class LocalBadClientConfiguration { - - static BaseLoadBalancer balancer; - static Server goodServer; - static Server badServer; - static Server badServer2; - - LocalBadClientConfiguration() { - } - - @Value("${local.server.port}") - private int port = 0; - - @Bean - public IRule loadBalancerRule() { - // This is a good place to try different load balancing rules and how those - // rules - // behave in failure states: BestAvailableRule, WeightedResponseTimeRule, etc - - // This rule just uses a round robin and will skip servers that are in circuit - // breaker state. - return new AvailabilityFilteringRule(); - - } - - @Bean - public ILoadBalancer ribbonLoadBalancer(IClientConfig config, - ServerList serverList, IRule rule, IPing ping) { - - goodServer = new Server("localhost", this.port); - badServer = new Server("mybadhost", 10001); - badServer2 = new Server("localhost", SocketUtils.findAvailableTcpPort()); - - balancer = LoadBalancerBuilder.newBuilder().withClientConfig(config) - .withRule(rule).withPing(ping).buildFixedServerListLoadBalancer( - Arrays.asList(badServer, badServer2, goodServer)); - return balancer; - } - - @Bean - public RetryHandler retryHandler() { - return new OverrideRetryHandler(); - } - - static class OverrideRetryHandler extends HttpClientLoadBalancerErrorHandler { - - OverrideRetryHandler() { - this.circuitRelated.add(UnknownHostException.class); - this.retriable.add(UnknownHostException.class); - } - - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientStatusCodeExceptionTest.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientStatusCodeExceptionTest.java deleted file mode 100644 index 8a5778754..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientStatusCodeExceptionTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.apache; - -import java.io.ByteArrayInputStream; -import java.net.URI; -import java.util.Locale; - -import org.apache.http.Header; -import org.apache.http.HttpEntity; -import org.apache.http.ProtocolVersion; -import org.apache.http.StatusLine; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.entity.BasicHttpEntity; -import org.apache.http.message.BasicHeader; -import org.apache.http.message.BasicStatusLine; -import org.apache.http.util.EntityUtils; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -/** - * @author Ryan Baxter - */ -@RunWith(MockitoJUnitRunner.class) -public class HttpClientStatusCodeExceptionTest { - - @Test - public void getResponse() throws Exception { - CloseableHttpResponse response = mock(CloseableHttpResponse.class); - doReturn(new Locale("en")).when(response).getLocale(); - Header foo = new BasicHeader("foo", "bar"); - Header[] headers = new Header[] { foo }; - doReturn(headers).when(response).getAllHeaders(); - StatusLine statusLine = new BasicStatusLine(new ProtocolVersion("http", 1, 1), - 200, "Success"); - doReturn(statusLine).when(response).getStatusLine(); - BasicHttpEntity entity = new BasicHttpEntity(); - entity.setContent(new ByteArrayInputStream("foo".getBytes())); - entity.setContentLength(3); - doReturn(entity).when(response).getEntity(); - HttpEntity copiedEntity = HttpClientUtils.createEntity(response); - HttpClientStatusCodeException ex = new HttpClientStatusCodeException("service", - response, copiedEntity, new URI("https://service.com")); - assertThat(ex.getResponse().getLocale().toString()).isEqualTo("en"); - assertThat(ex.getResponse().getAllHeaders()).isEqualTo(headers); - assertThat(ex.getResponse().getStatusLine().getReasonPhrase()) - .isEqualTo("Success"); - assertThat(ex.getResponse().getStatusLine().getStatusCode()).isEqualTo(200); - assertThat(ex.getResponse().getStatusLine().getProtocolVersion().getProtocol()) - .isEqualTo("http"); - assertThat(ex.getResponse().getStatusLine().getProtocolVersion().getMajor()) - .isEqualTo(1); - assertThat(ex.getResponse().getStatusLine().getProtocolVersion().getMinor()) - .isEqualTo(1); - assertThat(EntityUtils.toString(ex.getResponse().getEntity())).isEqualTo("foo"); - verify(response, times(1)).close(); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpStatusCodeExceptionTest.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpStatusCodeExceptionTest.java deleted file mode 100644 index 31a231462..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpStatusCodeExceptionTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.okhttp; - -import java.net.URI; - -import okhttp3.Headers; -import okhttp3.MediaType; -import okhttp3.Protocol; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.ResponseBody; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - */ -@RunWith(MockitoJUnitRunner.class) -public class OkHttpStatusCodeExceptionTest { - - @Test - public void getResponse() throws Exception { - Headers headers = new Headers.Builder().add("foo", "bar").build(); - Response response = new Response.Builder().code(200).headers(headers).code(200) - .message("Success") - .body(ResponseBody.create(MediaType.parse("text/plain"), "foo")) - .protocol(Protocol.HTTP_1_1) - .request(new Request.Builder().url("https://service.com").build()) - .build(); - ResponseBody body = response.peekBody(Integer.MAX_VALUE); - OkHttpStatusCodeException ex = new OkHttpStatusCodeException("service", response, - body, new URI("https://service.com")); - assertThat(ex.getResponse().headers()).isEqualTo(headers); - assertThat(ex.getResponse().code()).isEqualTo(200); - assertThat(ex.getResponse().message()).isEqualTo("Success"); - assertThat(ex.getResponse().body().string()).isEqualTo("foo"); - assertThat(ex.getResponse().protocol()).isEqualTo(Protocol.HTTP_1_1); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/test/NoSecurityConfiguration.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/test/NoSecurityConfiguration.java deleted file mode 100644 index 889476863..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/test/NoSecurityConfiguration.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.test; - -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration(proxyBeanMethods = false) -public class NoSecurityConfiguration extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.authorizeRequests().anyRequest().permitAll().and().csrf().disable(); - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/test/TestAutoConfiguration.java b/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/test/TestAutoConfiguration.java deleted file mode 100644 index 3b56a87b9..000000000 --- a/spring-cloud-netflix-hystrix/src/test/java/org/springframework/cloud/netflix/test/TestAutoConfiguration.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.test; - -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@Import({ NoopDiscoveryClientAutoConfiguration.class }) -@AutoConfigureBefore(SecurityAutoConfiguration.class) -public class TestAutoConfiguration { - - public static final String USER = "user"; - - public static final String PASSWORD = "{noop}password"; - - @Configuration(proxyBeanMethods = false) - @Order(Ordered.HIGHEST_PRECEDENCE) - protected static class TestSecurityConfiguration - extends WebSecurityConfigurerAdapter { - - TestSecurityConfiguration() { - super(true); - } - - @Bean - public UserDetailsService userDetailsService() { - InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); - manager.createUser( - User.withUsername(USER).password(PASSWORD).roles("USER").build()); - return manager; - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - // super.configure(http); - http.antMatcher("/proxy-username").httpBasic().and().authorizeRequests() - .antMatchers("/**").permitAll(); - } - - } - -} diff --git a/spring-cloud-netflix-hystrix/src/test/resources/META-INF/spring.factories b/spring-cloud-netflix-hystrix/src/test/resources/META-INF/spring.factories deleted file mode 100644 index 60ea354e8..000000000 --- a/spring-cloud-netflix-hystrix/src/test/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.test.TestAutoConfiguration diff --git a/spring-cloud-netflix-hystrix/src/test/resources/application.yml b/spring-cloud-netflix-hystrix/src/test/resources/application.yml deleted file mode 100644 index 82d37798a..000000000 --- a/spring-cloud-netflix-hystrix/src/test/resources/application.yml +++ /dev/null @@ -1,35 +0,0 @@ -server: - port: 9999 - compression: - enabled: true - min-response-size: 1024 - mime-types: application/xml,application/json -spring: - application: - name: testclient -eureka: - server: - enabled: false - client: - registerWithEureka: false - fetchRegistry: false -#error: -# path: /myerror -hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000 -ribbon: - ConnectTimeout: 3001 - ReadTimeout: 60001 -foo: - ribbon: - ConnectTimeout: 7 - ReadTimeout: 17 -badClients: - ribbon: - MaxAutoRetriesNextServer: 10 - ReadTimeout: 200 -endpoints: - health: - sensitive: false -hystrix: - shareSecurityContext: true -management.endpoints.web.exposure.include: '*' diff --git a/spring-cloud-netflix-hystrix/src/test/resources/archaius_db_store.sql b/spring-cloud-netflix-hystrix/src/test/resources/archaius_db_store.sql deleted file mode 100644 index 6b914cb50..000000000 --- a/spring-cloud-netflix-hystrix/src/test/resources/archaius_db_store.sql +++ /dev/null @@ -1,8 +0,0 @@ -create table if not exists properties ( - property_key VARCHAR(40) NOT NULL PRIMARY KEY, - property_value VARCHAR(255) NOT NULL, -); - -insert into properties(property_key, property_value) values ('db.property','this is a db property'); -insert into properties(property_key, property_value) values ('db.second.property','this is another db property'); - diff --git a/spring-cloud-netflix-hystrix/src/test/resources/config.properties.bak b/spring-cloud-netflix-hystrix/src/test/resources/config.properties.bak deleted file mode 100644 index 1e9c021f4..000000000 --- a/spring-cloud-netflix-hystrix/src/test/resources/config.properties.bak +++ /dev/null @@ -1,2 +0,0 @@ -archaius.file.property=Static config file property -db.second.property=It should be overridden diff --git a/spring-cloud-netflix-hystrix/src/test/resources/static/index.html b/spring-cloud-netflix-hystrix/src/test/resources/static/index.html deleted file mode 100644 index 27f581907..000000000 --- a/spring-cloud-netflix-hystrix/src/test/resources/static/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - -

- File to upload:
Name:

Press here to upload the file via ribbon proxy! -
-
- File to upload:
Name:

Press here to upload the file via direct proxy! -
-
- File to upload:
Name:

Press here to upload the file via proxy servlet! -
-
- File to upload:
Name:

Press here to upload the file directly! -
- - \ No newline at end of file diff --git a/spring-cloud-netflix-ribbon/pom.xml b/spring-cloud-netflix-ribbon/pom.xml deleted file mode 100644 index fa9d6440c..000000000 --- a/spring-cloud-netflix-ribbon/pom.xml +++ /dev/null @@ -1,128 +0,0 @@ - - - - spring-cloud-netflix - org.springframework.cloud - 2.2.2.BUILD-SNAPSHOT - .. - - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix-ribbon - - - - org.springframework.boot - spring-boot-starter-web - true - - - org.springframework.boot - spring-boot - true - - - org.springframework.boot - spring-boot-autoconfigure - true - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.cloud - spring-cloud-commons - true - - - org.springframework.cloud - spring-cloud-context - true - - - org.springframework.cloud - spring-cloud-netflix-archaius - - - com.netflix.ribbon - ribbon - true - - - com.netflix.ribbon - ribbon-core - true - - - com.netflix.ribbon - ribbon-httpclient - true - - - com.netflix.ribbon - ribbon-loadbalancer - true - - - - com.sun.jersey.contribs - jersey-apache-client4 - true - - - com.squareup.okhttp3 - okhttp - true - - - org.springframework.retry - spring-retry - true - - - commons-configuration - commons-configuration - true - - - com.netflix.servo - servo-core - true - - - com.netflix.netflix-commons - netflix-commons-util - true - - - com.netflix.hystrix - hystrix-javanica - true - - - org.springframework.cloud - spring-cloud-test-support - test - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.boot - spring-boot-starter-security - test - - - org.springframework.boot - spring-boot-starter-actuator - test - - - \ No newline at end of file diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospector.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospector.java deleted file mode 100644 index 222a832a2..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospector.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.util.Collections; -import java.util.Map; - -import com.netflix.loadbalancer.Server; - -import org.springframework.beans.factory.annotation.Autowired; - -/** - * @author Spencer Gibb - */ -public class DefaultServerIntrospector implements ServerIntrospector { - - private ServerIntrospectorProperties serverIntrospectorProperties = new ServerIntrospectorProperties(); - - @Autowired(required = false) - public void setServerIntrospectorProperties( - ServerIntrospectorProperties serverIntrospectorProperties) { - this.serverIntrospectorProperties = serverIntrospectorProperties; - } - - @Override - public boolean isSecure(Server server) { - return serverIntrospectorProperties.getSecurePorts().contains(server.getPort()); - } - - @Override - public Map getMetadata(Server server) { - return Collections.emptyMap(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/PropertiesFactory.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/PropertiesFactory.java deleted file mode 100644 index 9786a4e55..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/PropertiesFactory.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2016-2019 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 - * - * https://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.ribbon; - -import java.util.HashMap; -import java.util.Map; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.IPing; -import com.netflix.loadbalancer.IRule; -import com.netflix.loadbalancer.ServerList; -import com.netflix.loadbalancer.ServerListFilter; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.env.Environment; -import org.springframework.util.StringUtils; - -import static org.springframework.cloud.netflix.ribbon.SpringClientFactory.NAMESPACE; - -/** - * @author Spencer Gibb - */ -public class PropertiesFactory { - - @Autowired - private Environment environment; - - private Map classToProperty = new HashMap<>(); - - public PropertiesFactory() { - classToProperty.put(ILoadBalancer.class, "NFLoadBalancerClassName"); - classToProperty.put(IPing.class, "NFLoadBalancerPingClassName"); - classToProperty.put(IRule.class, "NFLoadBalancerRuleClassName"); - classToProperty.put(ServerList.class, "NIWSServerListClassName"); - classToProperty.put(ServerListFilter.class, "NIWSServerListFilterClassName"); - } - - public boolean isSet(Class clazz, String name) { - return StringUtils.hasText(getClassName(clazz, name)); - } - - public String getClassName(Class clazz, String name) { - if (this.classToProperty.containsKey(clazz)) { - String classNameProperty = this.classToProperty.get(clazz); - String className = environment - .getProperty(name + "." + NAMESPACE + "." + classNameProperty); - return className; - } - return null; - } - - @SuppressWarnings("unchecked") - public C get(Class clazz, IClientConfig config, String name) { - String className = getClassName(clazz, name); - if (StringUtils.hasText(className)) { - try { - Class toInstantiate = Class.forName(className); - return (C) SpringClientFactory.instantiateWithConfig(toInstantiate, - config); - } - catch (ClassNotFoundException e) { - throw new IllegalArgumentException("Unknown class to load " + className - + " for class " + clazz + " named " + name); - } - } - return null; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RestClientRibbonConfiguration.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RestClientRibbonConfiguration.java deleted file mode 100644 index 4260027e6..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RestClientRibbonConfiguration.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.niws.client.http.RestClient; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; - -/** - * @author Spencer Gibb - */ -@SuppressWarnings("deprecation") -@Configuration(proxyBeanMethods = false) -@RibbonAutoConfiguration.ConditionalOnRibbonRestClient -class RestClientRibbonConfiguration { - - @RibbonClientName - private String name = "client"; - - /** - * Create a Netflix {@link RestClient} integrated with Ribbon if none already exists - * in the application context. It is not required for Ribbon to work properly and is - * therefore created lazily if ever another component requires it. - * @param config the configuration to use by the underlying Ribbon instance - * @param loadBalancer the load balancer to use by the underlying Ribbon instance - * @param serverIntrospector server introspector to use by the underlying Ribbon - * instance - * @param retryHandler retry handler to use by the underlying Ribbon instance - * @return a {@link RestClient} instances backed by Ribbon - */ - @Bean - @Lazy - @ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class) - public RestClient ribbonRestClient(IClientConfig config, ILoadBalancer loadBalancer, - ServerIntrospector serverIntrospector, RetryHandler retryHandler) { - RestClient client = new RibbonClientConfiguration.OverrideRestClient(config, - serverIntrospector); - client.setLoadBalancer(loadBalancer); - client.setRetryHandler(retryHandler); - return client; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonApplicationContextInitializer.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonApplicationContextInitializer.java deleted file mode 100644 index 1a54530a4..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonApplicationContextInitializer.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.ribbon; - -import java.util.List; - -import org.springframework.boot.context.event.ApplicationReadyEvent; -import org.springframework.context.ApplicationListener; - -/** - * Responsible for eagerly creating the child application context holding the Ribbon - * related configuration. - * - * @author Biju Kunjummen - */ -public class RibbonApplicationContextInitializer - implements ApplicationListener { - - private final SpringClientFactory springClientFactory; - - // List of Ribbon client names - private final List clientNames; - - public RibbonApplicationContextInitializer(SpringClientFactory springClientFactory, - List clientNames) { - this.springClientFactory = springClientFactory; - this.clientNames = clientNames; - } - - protected void initialize() { - if (clientNames != null) { - for (String clientName : clientNames) { - this.springClientFactory.getContext(clientName); - } - } - } - - @Override - public void onApplicationEvent(ApplicationReadyEvent event) { - initialize(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java deleted file mode 100644 index 3755b8750..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.ArrayList; -import java.util.List; - -import com.netflix.client.IClient; -import com.netflix.client.http.HttpRequest; -import com.netflix.ribbon.Ribbon; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.AllNestedConditions; -import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.loadbalancer.AsyncLoadBalancerAutoConfiguration; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; -import org.springframework.cloud.client.loadbalancer.RestTemplateCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.client.AsyncRestTemplate; -import org.springframework.web.client.RestTemplate; - -/** - * Auto configuration for Ribbon (client side load balancing). - * - * @author Spencer Gibb - * @author Dave Syer - * @author Biju Kunjummen - */ -@Configuration -@Conditional(RibbonAutoConfiguration.RibbonClassesConditions.class) -@RibbonClients -@AutoConfigureAfter( - name = "org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration") -@AutoConfigureBefore({ LoadBalancerAutoConfiguration.class, - AsyncLoadBalancerAutoConfiguration.class }) -@EnableConfigurationProperties({ RibbonEagerLoadProperties.class, - ServerIntrospectorProperties.class }) -public class RibbonAutoConfiguration { - - @Autowired(required = false) - private List configurations = new ArrayList<>(); - - @Autowired - private RibbonEagerLoadProperties ribbonEagerLoadProperties; - - @Bean - public HasFeatures ribbonFeature() { - return HasFeatures.namedFeature("Ribbon", Ribbon.class); - } - - @Bean - public SpringClientFactory springClientFactory() { - SpringClientFactory factory = new SpringClientFactory(); - factory.setConfigurations(this.configurations); - return factory; - } - - @Bean - @ConditionalOnMissingBean(LoadBalancerClient.class) - public LoadBalancerClient loadBalancerClient() { - return new RibbonLoadBalancerClient(springClientFactory()); - } - - @Bean - @ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate") - @ConditionalOnMissingBean - public LoadBalancedRetryFactory loadBalancedRetryPolicyFactory( - final SpringClientFactory clientFactory) { - return new RibbonLoadBalancedRetryFactory(clientFactory); - } - - @Bean - @ConditionalOnMissingBean - public PropertiesFactory propertiesFactory() { - return new PropertiesFactory(); - } - - @Bean - @ConditionalOnProperty("ribbon.eager-load.enabled") - public RibbonApplicationContextInitializer ribbonApplicationContextInitializer() { - return new RibbonApplicationContextInitializer(springClientFactory(), - ribbonEagerLoadProperties.getClients()); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(HttpRequest.class) - @ConditionalOnRibbonRestClient - protected static class RibbonClientHttpRequestFactoryConfiguration { - - @Autowired - private SpringClientFactory springClientFactory; - - @Bean - public RestTemplateCustomizer restTemplateCustomizer( - final RibbonClientHttpRequestFactory ribbonClientHttpRequestFactory) { - return restTemplate -> restTemplate - .setRequestFactory(ribbonClientHttpRequestFactory); - } - - @Bean - public RibbonClientHttpRequestFactory ribbonClientHttpRequestFactory() { - return new RibbonClientHttpRequestFactory(this.springClientFactory); - } - - } - - // TODO: support for autoconfiguring restemplate to use apache http client or okhttp - - @Target({ ElementType.TYPE, ElementType.METHOD }) - @Retention(RetentionPolicy.RUNTIME) - @Documented - @Conditional(OnRibbonRestClientCondition.class) - @interface ConditionalOnRibbonRestClient { - - } - - private static class OnRibbonRestClientCondition extends AnyNestedCondition { - - OnRibbonRestClientCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @Deprecated // remove in Edgware" - @ConditionalOnProperty("ribbon.http.client.enabled") - static class ZuulProperty { - - } - - @ConditionalOnProperty("ribbon.restclient.enabled") - static class RibbonProperty { - - } - - } - - /** - * {@link AllNestedConditions} that checks that either multiple classes are present. - */ - static class RibbonClassesConditions extends AllNestedConditions { - - RibbonClassesConditions() { - super(ConfigurationPhase.PARSE_CONFIGURATION); - } - - @ConditionalOnClass(IClient.class) - static class IClientPresent { - - } - - @ConditionalOnClass(RestTemplate.class) - static class RestTemplatePresent { - - } - - @SuppressWarnings("deprecation") - @ConditionalOnClass(AsyncRestTemplate.class) - static class AsyncRestTemplatePresent { - - } - - @ConditionalOnClass(Ribbon.class) - static class RibbonPresent { - - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClient.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClient.java deleted file mode 100644 index d2da7ae58..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClient.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.IRule; -import com.netflix.loadbalancer.ServerListFilter; - -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * Declarative configuration for a ribbon client. Add this annotation to any - * @Configuration and then inject a {@link SpringClientFactory} to access the - * client that is created. - * - * @author Dave Syer - */ -@Configuration(proxyBeanMethods = false) -@Import(RibbonClientConfigurationRegistrar.class) -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface RibbonClient { - - /** - * Synonym for name (the name of the client). - * - * @see #name() - * @return name of the Ribbon client - */ - String value() default ""; - - /** - * The name of the ribbon client, uniquely identifying a set of client resources, - * including a load balancer. - * @return name of the Ribbon client - */ - String name() default ""; - - /** - * A custom @Configuration for the ribbon client. Can contain override - * @Bean definition for the pieces that make up the client, for instance - * {@link ILoadBalancer}, {@link ServerListFilter}, {@link IRule}. - * - * @see RibbonClientConfiguration for the defaults - * @return the custom Ribbon client configuration - */ - Class[] configuration() default {}; - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java deleted file mode 100644 index 91198a8f4..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.net.URI; - -import javax.annotation.PostConstruct; - -import com.netflix.client.DefaultLoadBalancerRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ConfigurationBasedServerList; -import com.netflix.loadbalancer.DummyPing; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.IPing; -import com.netflix.loadbalancer.IRule; -import com.netflix.loadbalancer.PollingServerListUpdater; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.loadbalancer.ServerListFilter; -import com.netflix.loadbalancer.ServerListUpdater; -import com.netflix.loadbalancer.ZoneAvoidanceRule; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import com.netflix.niws.client.http.RestClient; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.client.apache4.ApacheHttpClient4; -import org.apache.http.client.params.ClientPNames; -import org.apache.http.client.params.CookiePolicy; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.ribbon.apache.HttpClientRibbonConfiguration; -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpRibbonConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -import static com.netflix.client.config.CommonClientConfigKey.DeploymentContextBasedVipAddresses; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.setRibbonProperty; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToSecureConnectionIfNeeded; - -/** - * @author Dave Syer - * @author Tim Ysewyn - */ -@SuppressWarnings("deprecation") -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties -// Order is important here, last should be the default, first should be optional -// see -// https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653 -@Import({ HttpClientConfiguration.class, OkHttpRibbonConfiguration.class, - RestClientRibbonConfiguration.class, HttpClientRibbonConfiguration.class }) -public class RibbonClientConfiguration { - - /** - * Ribbon client default connect timeout. - */ - public static final int DEFAULT_CONNECT_TIMEOUT = 1000; - - /** - * Ribbon client default read timeout. - */ - public static final int DEFAULT_READ_TIMEOUT = 1000; - - /** - * Ribbon client default Gzip Payload flag. - */ - public static final boolean DEFAULT_GZIP_PAYLOAD = true; - - @RibbonClientName - private String name = "client"; - - // TODO: maybe re-instate autowired load balancers: identified by name they could be - // associated with ribbon clients - - @Autowired - private PropertiesFactory propertiesFactory; - - @Bean - @ConditionalOnMissingBean - public IClientConfig ribbonClientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.loadProperties(this.name); - config.set(CommonClientConfigKey.ConnectTimeout, DEFAULT_CONNECT_TIMEOUT); - config.set(CommonClientConfigKey.ReadTimeout, DEFAULT_READ_TIMEOUT); - config.set(CommonClientConfigKey.GZipPayload, DEFAULT_GZIP_PAYLOAD); - return config; - } - - @Bean - @ConditionalOnMissingBean - public IRule ribbonRule(IClientConfig config) { - if (this.propertiesFactory.isSet(IRule.class, name)) { - return this.propertiesFactory.get(IRule.class, config, name); - } - ZoneAvoidanceRule rule = new ZoneAvoidanceRule(); - rule.initWithNiwsConfig(config); - return rule; - } - - @Bean - @ConditionalOnMissingBean - public IPing ribbonPing(IClientConfig config) { - if (this.propertiesFactory.isSet(IPing.class, name)) { - return this.propertiesFactory.get(IPing.class, config, name); - } - return new DummyPing(); - } - - @Bean - @ConditionalOnMissingBean - @SuppressWarnings("unchecked") - public ServerList ribbonServerList(IClientConfig config) { - if (this.propertiesFactory.isSet(ServerList.class, name)) { - return this.propertiesFactory.get(ServerList.class, config, name); - } - ConfigurationBasedServerList serverList = new ConfigurationBasedServerList(); - serverList.initWithNiwsConfig(config); - return serverList; - } - - @Bean - @ConditionalOnMissingBean - public ServerListUpdater ribbonServerListUpdater(IClientConfig config) { - return new PollingServerListUpdater(config); - } - - @Bean - @ConditionalOnMissingBean - public ILoadBalancer ribbonLoadBalancer(IClientConfig config, - ServerList serverList, ServerListFilter serverListFilter, - IRule rule, IPing ping, ServerListUpdater serverListUpdater) { - if (this.propertiesFactory.isSet(ILoadBalancer.class, name)) { - return this.propertiesFactory.get(ILoadBalancer.class, config, name); - } - return new ZoneAwareLoadBalancer<>(config, rule, ping, serverList, - serverListFilter, serverListUpdater); - } - - @Bean - @ConditionalOnMissingBean - @SuppressWarnings("unchecked") - public ServerListFilter ribbonServerListFilter(IClientConfig config) { - if (this.propertiesFactory.isSet(ServerListFilter.class, name)) { - return this.propertiesFactory.get(ServerListFilter.class, config, name); - } - ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - filter.initWithNiwsConfig(config); - return filter; - } - - @Bean - @ConditionalOnMissingBean - public RibbonLoadBalancerContext ribbonLoadBalancerContext(ILoadBalancer loadBalancer, - IClientConfig config, RetryHandler retryHandler) { - return new RibbonLoadBalancerContext(loadBalancer, config, retryHandler); - } - - @Bean - @ConditionalOnMissingBean - public RetryHandler retryHandler(IClientConfig config) { - return new DefaultLoadBalancerRetryHandler(config); - } - - @Bean - @ConditionalOnMissingBean - public ServerIntrospector serverIntrospector() { - return new DefaultServerIntrospector(); - } - - @PostConstruct - public void preprocess() { - setRibbonProperty(name, DeploymentContextBasedVipAddresses.key(), name); - } - - static class OverrideRestClient extends RestClient { - - private IClientConfig config; - - private ServerIntrospector serverIntrospector; - - protected OverrideRestClient(IClientConfig config, - ServerIntrospector serverIntrospector) { - super(); - this.config = config; - this.serverIntrospector = serverIntrospector; - initWithNiwsConfig(this.config); - } - - @Override - public URI reconstructURIWithServer(Server server, URI original) { - URI uri = updateToSecureConnectionIfNeeded(original, this.config, - this.serverIntrospector, server); - return super.reconstructURIWithServer(server, uri); - } - - @Override - protected Client apacheHttpClientSpecificInitialization() { - ApacheHttpClient4 apache = (ApacheHttpClient4) super.apacheHttpClientSpecificInitialization(); - apache.getClientHandler().getHttpClient().getParams().setParameter( - ClientPNames.COOKIE_POLICY, CookiePolicy.IGNORE_COOKIES); - return apache; - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationRegistrar.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationRegistrar.java deleted file mode 100644 index e58ba0a22..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationRegistrar.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.util.Map; - -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; -import org.springframework.core.annotation.AnnotationAttributes; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.util.StringUtils; - -/** - * @author Dave Syer - */ -public class RibbonClientConfigurationRegistrar implements ImportBeanDefinitionRegistrar { - - @Override - public void registerBeanDefinitions(AnnotationMetadata metadata, - BeanDefinitionRegistry registry) { - Map attrs = metadata - .getAnnotationAttributes(RibbonClients.class.getName(), true); - if (attrs != null && attrs.containsKey("value")) { - AnnotationAttributes[] clients = (AnnotationAttributes[]) attrs.get("value"); - for (AnnotationAttributes client : clients) { - registerClientConfiguration(registry, getClientName(client), - client.get("configuration")); - } - } - if (attrs != null && attrs.containsKey("defaultConfiguration")) { - String name; - if (metadata.hasEnclosingClass()) { - name = "default." + metadata.getEnclosingClassName(); - } - else { - name = "default." + metadata.getClassName(); - } - registerClientConfiguration(registry, name, - attrs.get("defaultConfiguration")); - } - Map client = metadata - .getAnnotationAttributes(RibbonClient.class.getName(), true); - String name = getClientName(client); - if (name != null) { - registerClientConfiguration(registry, name, client.get("configuration")); - } - } - - private String getClientName(Map client) { - if (client == null) { - return null; - } - String value = (String) client.get("value"); - if (!StringUtils.hasText(value)) { - value = (String) client.get("name"); - } - if (StringUtils.hasText(value)) { - return value; - } - throw new IllegalStateException( - "Either 'name' or 'value' must be provided in @RibbonClient"); - } - - private void registerClientConfiguration(BeanDefinitionRegistry registry, Object name, - Object configuration) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder - .genericBeanDefinition(RibbonClientSpecification.class); - builder.addConstructorArgValue(name); - builder.addConstructorArgValue(configuration); - registry.registerBeanDefinition(name + ".RibbonClientSpecification", - builder.getBeanDefinition()); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactory.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactory.java deleted file mode 100644 index 2974cd130..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactory.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.io.IOException; -import java.net.URI; - -import com.netflix.client.config.IClientConfig; -import com.netflix.client.http.HttpRequest; -import com.netflix.niws.client.http.RestClient; - -import org.springframework.http.HttpMethod; -import org.springframework.http.client.ClientHttpRequest; -import org.springframework.http.client.ClientHttpRequestFactory; - -/** - * @author Spencer Gibb - */ -public class RibbonClientHttpRequestFactory implements ClientHttpRequestFactory { - - private final SpringClientFactory clientFactory; - - public RibbonClientHttpRequestFactory(SpringClientFactory clientFactory) { - this.clientFactory = clientFactory; - } - - @Override - @SuppressWarnings("deprecation") - public ClientHttpRequest createRequest(URI originalUri, HttpMethod httpMethod) - throws IOException { - String serviceId = originalUri.getHost(); - if (serviceId == null) { - throw new IOException( - "Invalid hostname in the URI [" + originalUri.toASCIIString() + "]"); - } - IClientConfig clientConfig = this.clientFactory.getClientConfig(serviceId); - RestClient client = this.clientFactory.getClient(serviceId, RestClient.class); - HttpRequest.Verb verb = HttpRequest.Verb.valueOf(httpMethod.name()); - - return new RibbonHttpRequest(originalUri, verb, client, clientConfig); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientName.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientName.java deleted file mode 100644 index 4ed945ed8..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientName.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2018-2019 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 - * - * https://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.ribbon; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.beans.factory.annotation.Value; - -/** - * Annotation at the field or method/constructor parameter level that injects the Ribbon - * Client Name that got allocated at runtime. Provides a convenient alternative for - * @Value("${ribbon.client.name}"). - * - * @author Spencer Gibb - * @since 2.0.0 - */ -@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, - ElementType.ANNOTATION_TYPE }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Value("${ribbon.client.name}") -public @interface RibbonClientName { - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientSpecification.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientSpecification.java deleted file mode 100644 index c092ea006..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientSpecification.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2013-2014 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 - * - * https://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.ribbon; - -import java.util.Arrays; -import java.util.Objects; - -import org.springframework.cloud.context.named.NamedContextFactory; - -/** - * @author Dave Syer - */ -public class RibbonClientSpecification implements NamedContextFactory.Specification { - - private String name; - - private Class[] configuration; - - public RibbonClientSpecification() { - } - - public RibbonClientSpecification(String name, Class[] configuration) { - this.name = name; - this.configuration = configuration; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Class[] getConfiguration() { - return configuration; - } - - public void setConfiguration(Class[] configuration) { - this.configuration = configuration; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RibbonClientSpecification that = (RibbonClientSpecification) o; - return Arrays.equals(configuration, that.configuration) - && Objects.equals(name, that.name); - } - - @Override - public int hashCode() { - return Objects.hash(configuration, name); - } - - @Override - public String toString() { - return new StringBuilder("RibbonClientSpecification{").append("name='") - .append(name).append("', ").append("configuration=") - .append(Arrays.toString(configuration)).append("}").toString(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClients.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClients.java deleted file mode 100644 index 8843d4e3f..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClients.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * Convenience annotation that allows user to combine multiple @RibbonClient - * annotations on a single class (including in Java 7). - * - * @author Dave Syer - */ -@Configuration(proxyBeanMethods = false) -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE }) -@Documented -@Import(RibbonClientConfigurationRegistrar.class) -public @interface RibbonClients { - - RibbonClient[] value() default {}; - - Class[] defaultConfiguration() default {}; - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonEagerLoadProperties.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonEagerLoadProperties.java deleted file mode 100644 index 453e1db5e..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonEagerLoadProperties.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.ribbon; - -import java.util.List; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Configuration Properties to indicate which Ribbon configurations should be eagerly - * loaded up. - * - * @author Biju Kunjummen - */ -@ConfigurationProperties(prefix = "ribbon.eager-load") -public class RibbonEagerLoadProperties { - - private boolean enabled = false; - - private List clients; - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public List getClients() { - return clients; - } - - public void setClients(List clients) { - this.clients = clients; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonHttpRequest.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonHttpRequest.java deleted file mode 100644 index b321c9c17..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonHttpRequest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.net.URI; -import java.util.List; - -import com.netflix.client.config.IClientConfig; -import com.netflix.client.http.HttpRequest; -import com.netflix.client.http.HttpResponse; -import com.netflix.niws.client.http.RestClient; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.client.AbstractClientHttpRequest; -import org.springframework.http.client.ClientHttpResponse; - -/** - * @author Spencer Gibb - */ -@SuppressWarnings("deprecation") -public class RibbonHttpRequest extends AbstractClientHttpRequest { - - private HttpRequest.Builder builder; - - private URI uri; - - private HttpRequest.Verb verb; - - private RestClient client; - - private IClientConfig config; - - private ByteArrayOutputStream outputStream = null; - - public RibbonHttpRequest(URI uri, HttpRequest.Verb verb, RestClient client, - IClientConfig config) { - this.uri = uri; - this.verb = verb; - this.client = client; - this.config = config; - this.builder = HttpRequest.newBuilder().uri(uri).verb(verb); - } - - @Override - public HttpMethod getMethod() { - return HttpMethod.valueOf(verb.name()); - } - - @Override - public String getMethodValue() { - return getMethod().name(); - } - - @Override - public URI getURI() { - return uri; - } - - @Override - protected OutputStream getBodyInternal(HttpHeaders headers) throws IOException { - if (outputStream == null) { - outputStream = new ByteArrayOutputStream(); - } - return outputStream; - } - - @Override - protected ClientHttpResponse executeInternal(HttpHeaders headers) throws IOException { - try { - addHeaders(headers); - if (outputStream != null) { - outputStream.close(); - builder.entity(outputStream.toByteArray()); - } - HttpRequest request = builder.build(); - HttpResponse response = client.executeWithLoadBalancer(request, config); - return new RibbonHttpResponse(response); - } - catch (Exception e) { - throw new IOException(e); - } - } - - private void addHeaders(HttpHeaders headers) { - for (String name : headers.keySet()) { - // apache http RequestContent pukes if there is a body and - // the dynamic headers are already present - if (isDynamic(name) && outputStream != null) { - continue; - } - // Don't add content-length if the output stream is null. The RibbonClient - // does this for us. - if (name.equals("Content-Length") && outputStream == null) { - continue; - } - List values = headers.get(name); - for (String value : values) { - builder.header(name, value); - } - } - } - - private boolean isDynamic(String name) { - return "Content-Length".equalsIgnoreCase(name) - || "Transfer-Encoding".equalsIgnoreCase(name); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonHttpResponse.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonHttpResponse.java deleted file mode 100644 index 27b1e7302..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonHttpResponse.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.Map; - -import com.netflix.client.http.HttpResponse; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.client.AbstractClientHttpResponse; - -/** - * @author Spencer Gibb - */ -public class RibbonHttpResponse extends AbstractClientHttpResponse { - - private HttpResponse response; - - private HttpHeaders httpHeaders; - - public RibbonHttpResponse(HttpResponse response) { - this.response = response; - this.httpHeaders = new HttpHeaders(); - List> headers = response.getHttpHeaders() - .getAllHeaders(); - for (Map.Entry header : headers) { - this.httpHeaders.add(header.getKey(), header.getValue()); - } - } - - @Override - public InputStream getBody() throws IOException { - return response.getInputStream(); - } - - @Override - public HttpHeaders getHeaders() { - return this.httpHeaders; - } - - @Override - public int getRawStatusCode() throws IOException { - return response.getStatus(); - } - - @Override - public String getStatusText() throws IOException { - return HttpStatus.valueOf(response.getStatus()).name(); - } - - @Override - public void close() { - response.close(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryFactory.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryFactory.java deleted file mode 100644 index 6e069f97d..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryFactory.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.retry.RetryListener; -import org.springframework.retry.backoff.BackOffPolicy; - -/** - * @author Ryan Baxter - */ -public class RibbonLoadBalancedRetryFactory implements LoadBalancedRetryFactory { - - private SpringClientFactory clientFactory; - - public RibbonLoadBalancedRetryFactory(SpringClientFactory clientFactory) { - this.clientFactory = clientFactory; - } - - @Override - public LoadBalancedRetryPolicy createRetryPolicy(String service, - ServiceInstanceChooser serviceInstanceChooser) { - RibbonLoadBalancerContext lbContext = this.clientFactory - .getLoadBalancerContext(service); - return new RibbonLoadBalancedRetryPolicy(service, lbContext, - serviceInstanceChooser, clientFactory.getClientConfig(service)); - } - - @Override - public RetryListener[] createRetryListeners(String service) { - return new RetryListener[0]; - } - - @Override - public BackOffPolicy createBackOffPolicy(String service) { - return null; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicy.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicy.java deleted file mode 100644 index d04872891..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicy.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.util.ArrayList; -import java.util.List; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; -import com.netflix.client.config.IClientConfigKey; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerStats; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.RibbonServer; -import org.springframework.http.HttpMethod; -import org.springframework.util.StringUtils; - -/** - * {@link LoadBalancedRetryPolicy} for Ribbon clients. - * - * @author Ryan Baxter - */ -public class RibbonLoadBalancedRetryPolicy implements LoadBalancedRetryPolicy { - - /** - * Retrayable status codes config key. - */ - public static final IClientConfigKey RETRYABLE_STATUS_CODES = new CommonClientConfigKey( - "retryableStatusCodes") { - }; - - private static final Log log = LogFactory.getLog(RibbonLoadBalancedRetryPolicy.class); - - private int sameServerCount = 0; - - private int nextServerCount = 0; - - private String serviceId; - - private RibbonLoadBalancerContext lbContext; - - private ServiceInstanceChooser loadBalanceChooser; - - List retryableStatusCodes = new ArrayList<>(); - - private static final Log LOGGER = LogFactory - .getLog(RibbonLoadBalancedRetryPolicy.class); - - public RibbonLoadBalancedRetryPolicy(String serviceId, - RibbonLoadBalancerContext context, - ServiceInstanceChooser loadBalanceChooser) { - this.serviceId = serviceId; - this.lbContext = context; - this.loadBalanceChooser = loadBalanceChooser; - } - - public RibbonLoadBalancedRetryPolicy(String serviceId, - RibbonLoadBalancerContext context, ServiceInstanceChooser loadBalanceChooser, - IClientConfig clientConfig) { - this.serviceId = serviceId; - this.lbContext = context; - this.loadBalanceChooser = loadBalanceChooser; - String retryableStatusCodesProp = clientConfig - .getPropertyAsString(RETRYABLE_STATUS_CODES, ""); - String[] retryableStatusCodesArray = retryableStatusCodesProp.split(","); - for (String code : retryableStatusCodesArray) { - if (!StringUtils.isEmpty(code)) { - try { - retryableStatusCodes.add(Integer.valueOf(code.trim())); - } - catch (NumberFormatException e) { - log.warn("We cant add the status code because the code [ " + code - + " ] could not be converted to an integer. ", e); - } - } - } - } - - public boolean canRetry(LoadBalancedRetryContext context) { - HttpMethod method = context.getRequest().getMethod(); - return HttpMethod.GET == method || lbContext.isOkToRetryOnAllOperations(); - } - - @Override - public boolean canRetrySameServer(LoadBalancedRetryContext context) { - return sameServerCount < lbContext.getRetryHandler().getMaxRetriesOnSameServer() - && canRetry(context); - } - - @Override - public boolean canRetryNextServer(LoadBalancedRetryContext context) { - // this will be called after a failure occurs and we increment the counter - // so we check that the count is less than or equals to too make sure - // we try the next server the right number of times - return nextServerCount <= lbContext.getRetryHandler().getMaxRetriesOnNextServer() - && canRetry(context); - } - - @Override - public void close(LoadBalancedRetryContext context) { - - } - - @Override - public void registerThrowable(LoadBalancedRetryContext context, Throwable throwable) { - // if this is a circuit tripping exception then notify the load balancer - if (lbContext.getRetryHandler().isCircuitTrippingException(throwable)) { - updateServerInstanceStats(context); - } - - // Check if we need to ask the load balancer for a new server. - // Do this before we increment the counters because the first call to this method - // is not a retry it is just an initial failure. - if (!canRetrySameServer(context) && canRetryNextServer(context)) { - context.setServiceInstance(loadBalanceChooser.choose(serviceId)); - } - // This method is called regardless of whether we are retrying or making the first - // request. - // Since we do not count the initial request in the retry count we don't reset the - // counter - // until we actually equal the same server count limit. This will allow us to make - // the initial - // request plus the right number of retries. - if (sameServerCount >= lbContext.getRetryHandler().getMaxRetriesOnSameServer() - && canRetry(context)) { - // reset same server since we are moving to a new server - sameServerCount = 0; - nextServerCount++; - if (!canRetryNextServer(context)) { - context.setExhaustedOnly(); - } - } - else { - sameServerCount++; - } - - } - - private void updateServerInstanceStats(LoadBalancedRetryContext context) { - ServiceInstance serviceInstance = context.getServiceInstance(); - if (serviceInstance instanceof RibbonServer) { - Server lbServer = ((RibbonServer) serviceInstance).getServer(); - ServerStats serverStats = lbContext.getServerStats(lbServer); - serverStats.incrementSuccessiveConnectionFailureCount(); - serverStats.addToFailureCount(); - LOGGER.debug(lbServer.getHostPort() + " RetryCount: " - + context.getRetryCount() + " Successive Failures: " - + serverStats.getSuccessiveConnectionFailureCount() - + " CircuitBreakerTripped:" + serverStats.isCircuitBreakerTripped()); - } - } - - @Override - public boolean retryableStatusCode(int statusCode) { - return retryableStatusCodes.contains(statusCode); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java deleted file mode 100644 index 27006ab09..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.io.IOException; -import java.net.URI; -import java.util.Collections; -import java.util.Map; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.Server; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; -import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; - -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToSecureConnectionIfNeeded; - -/** - * @author Spencer Gibb - * @author Dave Syer - * @author Ryan Baxter - * @author Tim Ysewyn - */ -public class RibbonLoadBalancerClient implements LoadBalancerClient { - - private SpringClientFactory clientFactory; - - public RibbonLoadBalancerClient(SpringClientFactory clientFactory) { - this.clientFactory = clientFactory; - } - - @Override - public URI reconstructURI(ServiceInstance instance, URI original) { - Assert.notNull(instance, "instance can not be null"); - String serviceId = instance.getServiceId(); - RibbonLoadBalancerContext context = this.clientFactory - .getLoadBalancerContext(serviceId); - - URI uri; - Server server; - if (instance instanceof RibbonServer) { - RibbonServer ribbonServer = (RibbonServer) instance; - server = ribbonServer.getServer(); - uri = updateToSecureConnectionIfNeeded(original, ribbonServer); - } - else { - server = new Server(instance.getScheme(), instance.getHost(), - instance.getPort()); - IClientConfig clientConfig = clientFactory.getClientConfig(serviceId); - ServerIntrospector serverIntrospector = serverIntrospector(serviceId); - uri = updateToSecureConnectionIfNeeded(original, clientConfig, - serverIntrospector, server); - } - return context.reconstructURIWithServer(server, uri); - } - - @Override - public ServiceInstance choose(String serviceId) { - return choose(serviceId, null); - } - - /** - * New: Select a server using a 'key'. - * @param serviceId of the service to choose an instance for - * @param hint to specify the service instance - * @return the selected {@link ServiceInstance} - */ - public ServiceInstance choose(String serviceId, Object hint) { - Server server = getServer(getLoadBalancer(serviceId), hint); - if (server == null) { - return null; - } - return new RibbonServer(serviceId, server, isSecure(server, serviceId), - serverIntrospector(serviceId).getMetadata(server)); - } - - @Override - public T execute(String serviceId, LoadBalancerRequest request) - throws IOException { - return execute(serviceId, request, null); - } - - /** - * New: Execute a request by selecting server using a 'key'. The hint will have to be - * the last parameter to not mess with the `execute(serviceId, ServiceInstance, - * request)` method. This somewhat breaks the fluent coding style when using a lambda - * to define the LoadBalancerRequest. - * @param returned request execution result type - * @param serviceId id of the service to execute the request to - * @param request to be executed - * @param hint used to choose appropriate {@link Server} instance - * @return request execution result - * @throws IOException executing the request may result in an {@link IOException} - */ - public T execute(String serviceId, LoadBalancerRequest request, Object hint) - throws IOException { - ILoadBalancer loadBalancer = getLoadBalancer(serviceId); - Server server = getServer(loadBalancer, hint); - if (server == null) { - throw new IllegalStateException("No instances available for " + serviceId); - } - RibbonServer ribbonServer = new RibbonServer(serviceId, server, - isSecure(server, serviceId), - serverIntrospector(serviceId).getMetadata(server)); - - return execute(serviceId, ribbonServer, request); - } - - @Override - public T execute(String serviceId, ServiceInstance serviceInstance, - LoadBalancerRequest request) throws IOException { - Server server = null; - if (serviceInstance instanceof RibbonServer) { - server = ((RibbonServer) serviceInstance).getServer(); - } - if (server == null) { - throw new IllegalStateException("No instances available for " + serviceId); - } - - RibbonLoadBalancerContext context = this.clientFactory - .getLoadBalancerContext(serviceId); - RibbonStatsRecorder statsRecorder = new RibbonStatsRecorder(context, server); - - try { - T returnVal = request.apply(serviceInstance); - statsRecorder.recordStats(returnVal); - return returnVal; - } - // catch IOException and rethrow so RestTemplate behaves correctly - catch (IOException ex) { - statsRecorder.recordStats(ex); - throw ex; - } - catch (Exception ex) { - statsRecorder.recordStats(ex); - ReflectionUtils.rethrowRuntimeException(ex); - } - return null; - } - - private ServerIntrospector serverIntrospector(String serviceId) { - ServerIntrospector serverIntrospector = this.clientFactory.getInstance(serviceId, - ServerIntrospector.class); - if (serverIntrospector == null) { - serverIntrospector = new DefaultServerIntrospector(); - } - return serverIntrospector; - } - - private boolean isSecure(Server server, String serviceId) { - IClientConfig config = this.clientFactory.getClientConfig(serviceId); - ServerIntrospector serverIntrospector = serverIntrospector(serviceId); - return RibbonUtils.isSecure(config, serverIntrospector, server); - } - - // Note: This method could be removed? - protected Server getServer(String serviceId) { - return getServer(getLoadBalancer(serviceId), null); - } - - protected Server getServer(ILoadBalancer loadBalancer) { - return getServer(loadBalancer, null); - } - - protected Server getServer(ILoadBalancer loadBalancer, Object hint) { - if (loadBalancer == null) { - return null; - } - // Use 'default' on a null hint, or just pass it on? - return loadBalancer.chooseServer(hint != null ? hint : "default"); - } - - protected ILoadBalancer getLoadBalancer(String serviceId) { - return this.clientFactory.getLoadBalancer(serviceId); - } - - /** - * Ribbon-server-specific {@link ServiceInstance} implementation. - */ - public static class RibbonServer implements ServiceInstance { - - private final String serviceId; - - private final Server server; - - private final boolean secure; - - private Map metadata; - - public RibbonServer(String serviceId, Server server) { - this(serviceId, server, false, Collections.emptyMap()); - } - - public RibbonServer(String serviceId, Server server, boolean secure, - Map metadata) { - this.serviceId = serviceId; - this.server = server; - this.secure = secure; - this.metadata = metadata; - } - - @Override - public String getInstanceId() { - return this.server.getId(); - } - - @Override - public String getServiceId() { - return this.serviceId; - } - - @Override - public String getHost() { - return this.server.getHost(); - } - - @Override - public int getPort() { - return this.server.getPort(); - } - - @Override - public boolean isSecure() { - return this.secure; - } - - @Override - public URI getUri() { - return DefaultServiceInstance.getUri(this); - } - - @Override - public Map getMetadata() { - return this.metadata; - } - - public Server getServer() { - return this.server; - } - - @Override - public String getScheme() { - return this.server.getScheme(); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("RibbonServer{"); - sb.append("serviceId='").append(serviceId).append('\''); - sb.append(", server=").append(server); - sb.append(", secure=").append(secure); - sb.append(", metadata=").append(metadata); - sb.append('}'); - return sb.toString(); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerContext.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerContext.java deleted file mode 100644 index 08138a111..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerContext.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.LoadBalancerContext; -import com.netflix.loadbalancer.ServerStats; -import com.netflix.servo.monitor.Timer; - -/** - * @author Spencer Gibb - */ -public class RibbonLoadBalancerContext extends LoadBalancerContext { - - public RibbonLoadBalancerContext(ILoadBalancer lb) { - super(lb); - } - - public RibbonLoadBalancerContext(ILoadBalancer lb, IClientConfig clientConfig) { - super(lb, clientConfig); - } - - public RibbonLoadBalancerContext(ILoadBalancer lb, IClientConfig clientConfig, - RetryHandler handler) { - super(lb, clientConfig, handler); - } - - @Override - public void noteOpenConnection(ServerStats serverStats) { - super.noteOpenConnection(serverStats); - } - - @Override - public Timer getExecuteTracer() { - return super.getExecuteTracer(); - } - - @Override - public void noteRequestCompletion(ServerStats stats, Object response, Throwable e, - long responseTime) { - super.noteRequestCompletion(stats, response, e, responseTime); - } - - @Override - public void noteRequestCompletion(ServerStats stats, Object response, Throwable e, - long responseTime, RetryHandler errorHandler) { - super.noteRequestCompletion(stats, response, e, responseTime, errorHandler); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonProperties.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonProperties.java deleted file mode 100644 index 5e6437996..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonProperties.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright 2018-2019 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 - * - * https://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.ribbon; - -import java.util.concurrent.TimeUnit; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; -import com.netflix.client.config.IClientConfigKey; - -import static com.netflix.client.config.CommonClientConfigKey.PoolKeepAliveTime; -import static com.netflix.client.config.CommonClientConfigKey.PoolKeepAliveTimeUnits; -import static com.netflix.client.config.CommonClientConfigKey.Port; -import static com.netflix.client.config.CommonClientConfigKey.SecurePort; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_CONNECTION_IDLE_TIMERTASK_REPEAT_IN_MSECS; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_CONNECT_TIMEOUT; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_FOLLOW_REDIRECTS; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_MAX_CONNECTIONS_PER_HOST; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_MAX_TOTAL_CONNECTIONS; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_OK_TO_RETRY_ON_ALL_OPERATIONS; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_POOL_KEEP_ALIVE_TIME; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_POOL_KEEP_ALIVE_TIME_UNITS; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_PORT; -import static com.netflix.client.config.DefaultClientConfigImpl.DEFAULT_READ_TIMEOUT; - -/** - * Stores and allows the access to Ribbon {@link IClientConfig}. - * - * @author Spencer Gibb - * @author Tomasz Juchniewicz - */ -public class RibbonProperties { - - private final IClientConfig config; - - public static RibbonProperties from(IClientConfig config) { - return new RibbonProperties(config); - } - - RibbonProperties(IClientConfig config) { - this.config = config; - } - - public Integer getConnectionCleanerRepeatInterval() { - return get(CommonClientConfigKey.ConnectionCleanerRepeatInterval); - } - - public int connectionCleanerRepeatInterval() { - return get(CommonClientConfigKey.ConnectionCleanerRepeatInterval, - DEFAULT_CONNECTION_IDLE_TIMERTASK_REPEAT_IN_MSECS); - } - - public Integer getConnectTimeout() { - return get(CommonClientConfigKey.ConnectTimeout); - } - - public int connectTimeout() { - return connectTimeout(DEFAULT_CONNECT_TIMEOUT); - } - - public int connectTimeout(int defaultValue) { - return get(CommonClientConfigKey.ConnectTimeout, defaultValue); - } - - public Boolean getFollowRedirects() { - return get(CommonClientConfigKey.FollowRedirects); - } - - public boolean isFollowRedirects() { - return isFollowRedirects(DEFAULT_FOLLOW_REDIRECTS); - } - - public boolean isFollowRedirects(boolean defaultValue) { - return get(CommonClientConfigKey.FollowRedirects, defaultValue); - } - - public boolean isGZipPayload() { - return isGZipPayload(RibbonClientConfiguration.DEFAULT_GZIP_PAYLOAD); - } - - public boolean isGZipPayload(boolean defaultValue) { - return get(CommonClientConfigKey.GZipPayload, defaultValue); - } - - public Integer getMaxConnectionsPerHost() { - return get(CommonClientConfigKey.MaxConnectionsPerHost); - } - - public int maxConnectionsPerHost() { - return maxConnectionsPerHost(DEFAULT_MAX_CONNECTIONS_PER_HOST); - } - - public int maxConnectionsPerHost(int defaultValue) { - return get(CommonClientConfigKey.MaxConnectionsPerHost, defaultValue); - } - - public Integer getMaxTotalConnections() { - return get(CommonClientConfigKey.MaxTotalConnections); - } - - public int maxTotalConnections() { - return maxTotalConnections(DEFAULT_MAX_TOTAL_CONNECTIONS); - } - - public int maxTotalConnections(int defaultValue) { - return get(CommonClientConfigKey.MaxTotalConnections, defaultValue); - } - - public Boolean getOkToRetryOnAllOperations() { - return get(CommonClientConfigKey.OkToRetryOnAllOperations); - } - - public boolean isOkToRetryOnAllOperations() { - return get(CommonClientConfigKey.OkToRetryOnAllOperations, - DEFAULT_OK_TO_RETRY_ON_ALL_OPERATIONS); - } - - @SuppressWarnings("deprecation") - public Long getPoolKeepAliveTime() { - Object property = this.config.getProperty(PoolKeepAliveTime); - if (property instanceof Long) { - return (Long) property; - } - else if (property instanceof String) { - return Long.valueOf((String) property); - } - return null; - } - - public long poolKeepAliveTime() { - Long poolKeepAliveTime = getPoolKeepAliveTime(); - if (poolKeepAliveTime != null) { - return poolKeepAliveTime; - } - - return DEFAULT_POOL_KEEP_ALIVE_TIME; - } - - @SuppressWarnings("deprecation") - public TimeUnit getPoolKeepAliveTimeUnits() { - Object property = this.config.getProperty(PoolKeepAliveTimeUnits); - if (property instanceof TimeUnit) { - return (TimeUnit) property; - } - return DEFAULT_POOL_KEEP_ALIVE_TIME_UNITS; - } - - public Integer getPort() { - return get(Port); - } - - public int port() { - return get(Port, DEFAULT_PORT); - } - - public Integer getReadTimeout() { - return get(CommonClientConfigKey.ReadTimeout); - } - - public int readTimeout() { - return readTimeout(DEFAULT_READ_TIMEOUT); - } - - public int readTimeout(int defaultValue) { - return get(CommonClientConfigKey.ReadTimeout, defaultValue); - } - - public Boolean getSecure() { - return get(CommonClientConfigKey.IsSecure); - } - - public boolean isSecure() { - return isSecure(false); - } - - public boolean isSecure(boolean defaultValue) { - return get(CommonClientConfigKey.IsSecure, defaultValue); - } - - public Integer getSecurePort() { - return this.config.get(SecurePort); - } - - public Boolean getUseIPAddrForServer() { - return get(CommonClientConfigKey.UseIPAddrForServer); - } - - public boolean isUseIPAddrForServer() { - return isUseIPAddrForServer(false); - } - - public boolean isUseIPAddrForServer(boolean defaultValue) { - return get(CommonClientConfigKey.UseIPAddrForServer, defaultValue); - } - - public boolean has(IClientConfigKey key) { - return this.config.containsProperty(key); - } - - public T get(IClientConfigKey key) { - return this.config.get(key); - } - - public T get(IClientConfigKey key, T defaultValue) { - return this.config.get(key, defaultValue); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonStatsRecorder.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonStatsRecorder.java deleted file mode 100644 index 73859f27d..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonStatsRecorder.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2016-2019 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 - * - * https://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.ribbon; - -import java.util.concurrent.TimeUnit; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerStats; -import com.netflix.servo.monitor.Stopwatch; - -/** - * @author Spencer Gibb - */ -public class RibbonStatsRecorder { - - private RibbonLoadBalancerContext context; - - private ServerStats serverStats; - - private Stopwatch tracer; - - public RibbonStatsRecorder(RibbonLoadBalancerContext context, Server server) { - this.context = context; - if (server != null) { - serverStats = context.getServerStats(server); - context.noteOpenConnection(serverStats); - tracer = context.getExecuteTracer().start(); - } - } - - public void recordStats(Object entity) { - this.recordStats(entity, null); - } - - public void recordStats(Throwable t) { - this.recordStats(null, t); - } - - protected void recordStats(Object entity, Throwable exception) { - if (this.tracer != null && this.serverStats != null) { - this.tracer.stop(); - long duration = this.tracer.getDuration(TimeUnit.MILLISECONDS); - this.context.noteRequestCompletion(serverStats, entity, exception, duration, - null/* errorHandler */); - } - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonUtils.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonUtils.java deleted file mode 100644 index c29fd07fa..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonUtils.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2016-2019 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 - * - * https://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.ribbon; - -import java.net.URI; -import java.util.HashMap; -import java.util.Map; - -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; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.util.StringUtils; -import org.springframework.web.util.UriComponentsBuilder; - -import static com.netflix.client.config.CommonClientConfigKey.DeploymentContextBasedVipAddresses; -import static com.netflix.client.config.CommonClientConfigKey.EnableZoneAffinity; - -/** - * @author Spencer Gibb - * @author Jacques-Etienne Beaudet - * @author Tim Ysewyn - */ -public final class RibbonUtils { - - /** - * Used to verify if property value is set. - */ - public static final String VALUE_NOT_SET = "__not__set__"; - - /** - * Default Ribbon namespace. - */ - public static final String DEFAULT_NAMESPACE = "ribbon"; - - private static final Map unsecureSchemeMapping; - - static { - unsecureSchemeMapping = new HashMap<>(); - unsecureSchemeMapping.put("http", "https"); - unsecureSchemeMapping.put("ws", "wss"); - } - - private RibbonUtils() { - throw new AssertionError("Must not instantiate utility class."); - } - - public static void initializeRibbonDefaults(String serviceId) { - setRibbonProperty(serviceId, DeploymentContextBasedVipAddresses.key(), serviceId); - setRibbonProperty(serviceId, EnableZoneAffinity.key(), "true"); - } - - 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 used to verify if the server provides secure connections - * @param server to verify - * @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 to modify if required - * @param config Ribbon {@link IClientConfig} configuration - * @param serverIntrospector used to verify if the server provides secure connections - * @param server to verify - * @return {@link URI} updated to https if necessary - * @deprecated use {@link #updateToSecureConnectionIfNeeded} - */ - public static URI updateToHttpsIfNeeded(URI uri, IClientConfig config, - ServerIntrospector serverIntrospector, Server server) { - return updateToSecureConnectionIfNeeded(uri, config, serverIntrospector, server); - } - - /** - * Replace the scheme to the secure variant if needed. If the - * {@link #unsecureSchemeMapping} map contains the uri scheme and - * {@link #isSecure(IClientConfig, ServerIntrospector, Server)} is true, update the - * scheme. This assumes the uri is already encoded to avoid double encoding. - * @param uri to modify if required - * @param ribbonServer to verify if it provides secure connections - * @return {@link URI} updated if required - */ - static URI updateToSecureConnectionIfNeeded(URI uri, ServiceInstance ribbonServer) { - String scheme = uri.getScheme(); - - if (StringUtils.isEmpty(scheme)) { - scheme = "http"; - } - - if (!StringUtils.isEmpty(uri.toString()) - && unsecureSchemeMapping.containsKey(scheme) && ribbonServer.isSecure()) { - return upgradeConnection(uri, unsecureSchemeMapping.get(scheme)); - } - return uri; - } - - /** - * Replace the scheme to the secure variant if needed. If the - * {@link #unsecureSchemeMapping} map contains the uri scheme and - * {@link #isSecure(IClientConfig, ServerIntrospector, Server)} is true, update the - * scheme. This assumes the uri is already encoded to avoid double encoding. - * @param uri to modify if required - * @param config the supplied client configuration - * @param serverIntrospector used to verify if the server provides secure connections - * @param server to verify - * @return {@link URI} updated if required - */ - public static URI updateToSecureConnectionIfNeeded(URI uri, IClientConfig config, - ServerIntrospector serverIntrospector, Server server) { - String scheme = uri.getScheme(); - - if (StringUtils.isEmpty(scheme)) { - scheme = "http"; - } - - if (!StringUtils.isEmpty(uri.toString()) - && unsecureSchemeMapping.containsKey(scheme) - && isSecure(config, serverIntrospector, server)) { - return upgradeConnection(uri, unsecureSchemeMapping.get(scheme)); - } - return uri; - } - - private static URI upgradeConnection(URI uri, String scheme) { - UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUri(uri) - .scheme(scheme); - 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(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospector.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospector.java deleted file mode 100644 index 463453a3e..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospector.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.util.Map; - -import com.netflix.loadbalancer.Server; - -/** - * @author Spencer Gibb - */ -public interface ServerIntrospector { - - boolean isSecure(Server server); - - Map getMetadata(Server server); - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospectorProperties.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospectorProperties.java deleted file mode 100644 index 111750e65..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospectorProperties.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.util.Arrays; -import java.util.List; -import java.util.Objects; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * @author Rico Pahlisch - * @author Gregor Zurowski - */ -@ConfigurationProperties("ribbon") -public class ServerIntrospectorProperties { - - private List securePorts = Arrays.asList(443, 8443); - - public List getSecurePorts() { - return securePorts; - } - - public void setSecurePorts(List securePorts) { - this.securePorts = securePorts; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ServerIntrospectorProperties that = (ServerIntrospectorProperties) o; - return Objects.equals(securePorts, that.securePorts); - } - - @Override - public int hashCode() { - return Objects.hash(securePorts); - } - - @Override - public String toString() { - return new StringBuilder("ServerIntrospectorProperties{").append("securePorts=") - .append(securePorts).append("}").toString(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java deleted file mode 100644 index f0b6b7c0e..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.lang.reflect.Constructor; - -import com.netflix.client.IClient; -import com.netflix.client.IClientConfigAware; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; - -import org.springframework.beans.BeanUtils; -import org.springframework.cloud.context.named.NamedContextFactory; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; - -/** - * A factory that creates client, load balancer and client configuration instances. It - * creates a Spring ApplicationContext per client name, and extracts the beans that it - * needs from there. - * - * @author Spencer Gibb - * @author Dave Syer - */ -public class SpringClientFactory extends NamedContextFactory { - - static final String NAMESPACE = "ribbon"; - - public SpringClientFactory() { - super(RibbonClientConfiguration.class, NAMESPACE, "ribbon.client.name"); - } - - /** - * Get the rest client associated with the name. - * @param name name to search by - * @param clientClass the class of the client bean - * @param {@link IClient} subtype - * @return {@link IClient} instance - * @throws RuntimeException if any error occurs - */ - public > C getClient(String name, Class clientClass) { - return getInstance(name, clientClass); - } - - /** - * Get the load balancer associated with the name. - * @param name name to search by - * @return {@link ILoadBalancer} instance - * @throws RuntimeException if any error occurs - */ - public ILoadBalancer getLoadBalancer(String name) { - return getInstance(name, ILoadBalancer.class); - } - - /** - * Get the client config associated with the name. - * @param name name to search by - * @return {@link IClientConfig} instance - * @throws RuntimeException if any error occurs - */ - public IClientConfig getClientConfig(String name) { - return getInstance(name, IClientConfig.class); - } - - /** - * Get the load balancer context associated with the name. - * @param serviceId id of the service to search by - * @return {@link RibbonLoadBalancerContext} instance - * @throws RuntimeException if any error occurs - */ - public RibbonLoadBalancerContext getLoadBalancerContext(String serviceId) { - return getInstance(serviceId, RibbonLoadBalancerContext.class); - } - - static C instantiateWithConfig(Class clazz, IClientConfig config) { - return instantiateWithConfig(null, clazz, config); - } - - static C instantiateWithConfig(AnnotationConfigApplicationContext context, - Class clazz, IClientConfig config) { - C result = null; - - try { - Constructor constructor = clazz.getConstructor(IClientConfig.class); - result = constructor.newInstance(config); - } - catch (Throwable e) { - // Ignored - } - - if (result == null) { - result = BeanUtils.instantiateClass(clazz); - - if (result instanceof IClientConfigAware) { - ((IClientConfigAware) result).initWithNiwsConfig(config); - } - - if (context != null) { - context.getAutowireCapableBeanFactory().autowireBean(result); - } - } - - return result; - } - - @Override - public C getInstance(String name, Class type) { - C instance = super.getInstance(name, type); - if (instance != null) { - return instance; - } - IClientConfig config = getInstance(name, IClientConfig.class); - return instantiateWithConfig(getContext(name), type, config); - } - - @Override - protected AnnotationConfigApplicationContext getContext(String name) { - return super.getContext(name); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/StaticServerList.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/StaticServerList.java deleted file mode 100644 index 42f585f85..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/StaticServerList.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.util.Arrays; -import java.util.List; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; - -/** - * Represents list of servers used by Ribbon. - * - * @param {@link Server} subtype - * @author Spencer Gibb - */ -public class StaticServerList implements ServerList { - - private final List servers; - - public StaticServerList(T... servers) { - this.servers = Arrays.asList(servers); - } - - @Override - public List getInitialListOfServers() { - return servers; - } - - @Override - public List getUpdatedListOfServers() { - return servers; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ZonePreferenceServerListFilter.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ZonePreferenceServerListFilter.java deleted file mode 100644 index c57c06f13..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/ZonePreferenceServerListFilter.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import com.netflix.client.config.IClientConfig; -import com.netflix.config.ConfigurationManager; -import com.netflix.config.DeploymentContext.ContextKey; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAffinityServerListFilter; - -/** - * A filter that actively prefers the local zone (as defined by the deployment context, or - * the Eureka instance metadata). - * - * @author Dave Syer - */ -public class ZonePreferenceServerListFilter extends ZoneAffinityServerListFilter { - - private String zone; - - @Override - public void initWithNiwsConfig(IClientConfig niwsClientConfig) { - super.initWithNiwsConfig(niwsClientConfig); - if (ConfigurationManager.getDeploymentContext() != null) { - this.zone = ConfigurationManager.getDeploymentContext() - .getValue(ContextKey.zone); - } - } - - @Override - public List getFilteredListOfServers(List servers) { - List output = super.getFilteredListOfServers(servers); - if (this.zone != null && output.size() == servers.size()) { - List local = new ArrayList<>(); - for (Server server : output) { - if (this.zone.equalsIgnoreCase(server.getZone())) { - local.add(server); - } - } - if (!local.isEmpty()) { - return local; - } - } - return output; - } - - public String getZone() { - return zone; - } - - public void setZone(String zone) { - this.zone = zone; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ZonePreferenceServerListFilter that = (ZonePreferenceServerListFilter) o; - return Objects.equals(zone, that.zone); - } - - @Override - public int hashCode() { - return Objects.hash(zone); - } - - @Override - public String toString() { - return new StringBuilder("ZonePreferenceServerListFilter{").append("zone='") - .append(zone).append("'").append("}").toString(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientRibbonConfiguration.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientRibbonConfiguration.java deleted file mode 100644 index cb1d8438f..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientRibbonConfiguration.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.apache; - -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.TimeUnit; - -import javax.annotation.PreDestroy; - -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.servo.monitor.Monitors; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.config.RegistryBuilder; -import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.impl.client.CloseableHttpClient; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; -import org.springframework.cloud.netflix.ribbon.RibbonClientName; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext; -import org.springframework.cloud.netflix.ribbon.RibbonProperties; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(name = "org.apache.http.client.HttpClient") -@ConditionalOnProperty(name = "ribbon.httpclient.enabled", matchIfMissing = true) -public class HttpClientRibbonConfiguration { - - @RibbonClientName - private String name = "client"; - - @Bean - @ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class) - @ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate") - public RibbonLoadBalancingHttpClient ribbonLoadBalancingHttpClient( - IClientConfig config, ServerIntrospector serverIntrospector, - ILoadBalancer loadBalancer, RetryHandler retryHandler, - CloseableHttpClient httpClient) { - RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient( - httpClient, config, serverIntrospector); - client.setLoadBalancer(loadBalancer); - client.setRetryHandler(retryHandler); - Monitors.registerObject("Client_" + this.name, client); - return client; - } - - @Bean - @ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class) - @ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate") - public RetryableRibbonLoadBalancingHttpClient retryableRibbonLoadBalancingHttpClient( - IClientConfig config, ServerIntrospector serverIntrospector, - ILoadBalancer loadBalancer, RetryHandler retryHandler, - LoadBalancedRetryFactory loadBalancedRetryFactory, - CloseableHttpClient httpClient, - RibbonLoadBalancerContext ribbonLoadBalancerContext) { - RetryableRibbonLoadBalancingHttpClient client = new RetryableRibbonLoadBalancingHttpClient( - httpClient, config, serverIntrospector, loadBalancedRetryFactory); - client.setLoadBalancer(loadBalancer); - client.setRetryHandler(retryHandler); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - Monitors.registerObject("Client_" + this.name, client); - return client; - } - - @Configuration(proxyBeanMethods = false) - protected static class ApacheHttpClientConfiguration { - - private final Timer connectionManagerTimer = new Timer( - "RibbonApacheHttpClientConfiguration.connectionManagerTimer", true); - - private CloseableHttpClient httpClient; - - @Autowired(required = false) - private RegistryBuilder registryBuilder; - - @Bean - @ConditionalOnMissingBean(HttpClientConnectionManager.class) - public HttpClientConnectionManager httpClientConnectionManager( - IClientConfig config, - ApacheHttpClientConnectionManagerFactory connectionManagerFactory) { - RibbonProperties ribbon = RibbonProperties.from(config); - int maxTotalConnections = ribbon.maxTotalConnections(); - int maxConnectionsPerHost = ribbon.maxConnectionsPerHost(); - int timerRepeat = ribbon.connectionCleanerRepeatInterval(); - long timeToLive = ribbon.poolKeepAliveTime(); - TimeUnit ttlUnit = ribbon.getPoolKeepAliveTimeUnits(); - final HttpClientConnectionManager connectionManager = connectionManagerFactory - .newConnectionManager(false, maxTotalConnections, - maxConnectionsPerHost, timeToLive, ttlUnit, registryBuilder); - this.connectionManagerTimer.schedule(new TimerTask() { - @Override - public void run() { - connectionManager.closeExpiredConnections(); - } - }, 30000, timerRepeat); - return connectionManager; - } - - @Bean - @ConditionalOnMissingBean(CloseableHttpClient.class) - public CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory, - HttpClientConnectionManager connectionManager, IClientConfig config) { - RibbonProperties ribbon = RibbonProperties.from(config); - Boolean followRedirects = ribbon.isFollowRedirects(); - Integer connectTimeout = ribbon.connectTimeout(); - RequestConfig defaultRequestConfig = RequestConfig.custom() - .setConnectTimeout(connectTimeout) - .setRedirectsEnabled(followRedirects).build(); - this.httpClient = httpClientFactory.createBuilder() - .setDefaultRequestConfig(defaultRequestConfig) - .setConnectionManager(connectionManager).build(); - return httpClient; - } - - @PreDestroy - public void destroy() throws Exception { - connectionManagerTimer.cancel(); - if (httpClient != null) { - httpClient.close(); - } - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientStatusCodeException.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientStatusCodeException.java deleted file mode 100644 index 54cb28598..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientStatusCodeException.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.apache; - -import java.io.IOException; -import java.net.URI; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.message.BasicHttpResponse; -import org.apache.http.util.EntityUtils; - -import org.springframework.cloud.client.loadbalancer.RetryableStatusCodeException; - -/** - * A {@link RetryableStatusCodeException} for {@link HttpResponse}s. - * - * @author Ryan Baxter - */ -public class HttpClientStatusCodeException extends RetryableStatusCodeException { - - private final BasicHttpResponse response; - - public HttpClientStatusCodeException(String serviceId, HttpResponse response, - HttpEntity entity, URI uri) throws IOException { - super(serviceId, response.getStatusLine().getStatusCode(), response, uri); - this.response = new BasicHttpResponse(response.getStatusLine()); - this.response.setLocale(response.getLocale()); - this.response.setStatusCode(response.getStatusLine().getStatusCode()); - this.response.setReasonPhrase(response.getStatusLine().getReasonPhrase()); - this.response.setHeaders(response.getAllHeaders()); - EntityUtils.updateEntity(this.response, entity); - } - - @Override - public HttpResponse getResponse() { - return this.response; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientUtils.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientUtils.java deleted file mode 100644 index 05e757cf1..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/HttpClientUtils.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.apache; - -import java.io.ByteArrayInputStream; -import java.io.IOException; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.entity.BasicHttpEntity; -import org.apache.http.util.EntityUtils; - -/** - * Provides basic utilities for {@link org.apache.http.client.HttpClient}. - * - * @author Ryan Baxter - */ -public final class HttpClientUtils { - - private HttpClientUtils() { - throw new AssertionError("Must not instantiate utility class."); - } - - /** - * Creates an new {@link HttpEntity} by copying the {@link HttpEntity} from the - * {@link HttpResponse}. This method will close the response after copying the entity. - * @param response The response to create the {@link HttpEntity} from - * @return A new {@link HttpEntity} - * @throws IOException thrown if there is a problem closing the response. - */ - public static HttpEntity createEntity(HttpResponse response) throws IOException { - ByteArrayInputStream is = new ByteArrayInputStream( - EntityUtils.toByteArray(response.getEntity())); - BasicHttpEntity entity = new BasicHttpEntity(); - entity.setContent(is); - entity.setContentLength(response.getEntity().getContentLength()); - if (CloseableHttpResponse.class.isInstance(response)) { - ((CloseableHttpResponse) response).close(); - } - return entity; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RetryableRibbonLoadBalancingHttpClient.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RetryableRibbonLoadBalancingHttpClient.java deleted file mode 100644 index ec1016137..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RetryableRibbonLoadBalancingHttpClient.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.apache; - -import java.net.URI; - -import com.netflix.client.RequestSpecificRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.HttpResponse; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.impl.client.CloseableHttpClient; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.InterceptorRetryPolicy; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRecoveryCallback; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.RibbonServer; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext; -import org.springframework.cloud.netflix.ribbon.RibbonProperties; -import org.springframework.cloud.netflix.ribbon.RibbonStatsRecorder; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.support.ContextAwareRequest; -import org.springframework.http.HttpRequest; -import org.springframework.retry.RecoveryCallback; -import org.springframework.retry.RetryCallback; -import org.springframework.retry.RetryListener; -import org.springframework.retry.backoff.BackOffPolicy; -import org.springframework.retry.backoff.NoBackOffPolicy; -import org.springframework.retry.policy.NeverRetryPolicy; -import org.springframework.retry.support.RetryTemplate; -import org.springframework.web.util.UriComponentsBuilder; - -/** - * An Apache HTTP client which leverages Spring Retry to retry failed requests. - * - * @author Ryan Baxter - * @author Gang Li - */ -public class RetryableRibbonLoadBalancingHttpClient - extends RibbonLoadBalancingHttpClient { - - private static final Log LOGGER = LogFactory - .getLog(RetryableRibbonLoadBalancingHttpClient.class); - - private LoadBalancedRetryFactory loadBalancedRetryFactory; - - private RibbonLoadBalancerContext ribbonLoadBalancerContext; - - public RetryableRibbonLoadBalancingHttpClient(CloseableHttpClient delegate, - IClientConfig config, ServerIntrospector serverIntrospector, - LoadBalancedRetryFactory loadBalancedRetryFactory) { - super(delegate, config, serverIntrospector); - this.loadBalancedRetryFactory = loadBalancedRetryFactory; - } - - @Override - public RibbonApacheHttpResponse execute(final RibbonApacheHttpRequest request, - final IClientConfig configOverride) throws Exception { - final RequestConfig.Builder builder = RequestConfig.custom(); - IClientConfig config = configOverride != null ? configOverride : this.config; - RibbonProperties ribbon = RibbonProperties.from(config); - builder.setConnectTimeout(ribbon.connectTimeout(this.connectTimeout)); - builder.setSocketTimeout(ribbon.readTimeout(this.readTimeout)); - builder.setRedirectsEnabled(ribbon.isFollowRedirects(this.followRedirects)); - builder.setContentCompressionEnabled(ribbon.isGZipPayload(this.gzipPayload)); - - final RequestConfig requestConfig = builder.build(); - final LoadBalancedRetryPolicy retryPolicy = loadBalancedRetryFactory - .createRetryPolicy(this.getClientName(), this); - - RetryCallback retryCallback = context -> { - // on retries the policy will choose the server and set it in the context - // extract the server and update the request being made - RibbonApacheHttpRequest newRequest = request; - RibbonStatsRecorder statsRecorder = null; - if (context instanceof LoadBalancedRetryContext) { - ServiceInstance service = ((LoadBalancedRetryContext) context) - .getServiceInstance(); - validateServiceInstance(service); - if (service != null) { - // Reconstruct the request URI using the host and port set in the - // retry context - newRequest = newRequest.withNewUri(UriComponentsBuilder.newInstance() - .host(service.getHost()).scheme(service.getUri().getScheme()) - .userInfo(newRequest.getURI().getUserInfo()) - .port(service.getPort()) - .path(newRequest.getURI().getRawPath()) - .query(newRequest.getURI().getQuery()) - .fragment(newRequest.getURI().getFragment()).build(true) - .encode().toUri()); - if (ribbonLoadBalancerContext == null) { - LOGGER.error( - "RibbonLoadBalancerContext is null. Unable to update load balancer stats"); - } - else if (service instanceof RibbonServer) { - statsRecorder = new RibbonStatsRecorder(ribbonLoadBalancerContext, - ((RibbonServer) service).getServer()); - } - } - } - newRequest = getSecureRequest(newRequest, configOverride); - HttpUriRequest httpUriRequest = newRequest.toRequest(requestConfig); - final HttpResponse httpResponse = RetryableRibbonLoadBalancingHttpClient.this.delegate - .execute(httpUriRequest); - if (retryPolicy - .retryableStatusCode(httpResponse.getStatusLine().getStatusCode())) { - throw new HttpClientStatusCodeException( - RetryableRibbonLoadBalancingHttpClient.this.clientName, - httpResponse, HttpClientUtils.createEntity(httpResponse), - httpUriRequest.getURI()); - } - if (statsRecorder != null) { - statsRecorder.recordStats(httpResponse); - } - return new RibbonApacheHttpResponse(httpResponse, httpUriRequest.getURI()); - }; - LoadBalancedRecoveryCallback recoveryCallback = new LoadBalancedRecoveryCallback() { - @Override - protected RibbonApacheHttpResponse createResponse(HttpResponse response, - URI uri) { - return new RibbonApacheHttpResponse(response, uri); - } - }; - return this.executeWithRetry(request, retryPolicy, retryCallback, - recoveryCallback); - } - - @Override - public boolean isClientRetryable(ContextAwareRequest request) { - return request != null && isRequestRetryable(request); - } - - private boolean isRequestRetryable(ContextAwareRequest request) { - if (request.getContext() == null || request.getContext().getRetryable() == null) { - return true; - } - return request.getContext().getRetryable(); - } - - private RibbonApacheHttpResponse executeWithRetry(RibbonApacheHttpRequest request, - LoadBalancedRetryPolicy retryPolicy, - RetryCallback callback, - RecoveryCallback recoveryCallback) - throws Exception { - RetryTemplate retryTemplate = new RetryTemplate(); - boolean retryable = isRequestRetryable(request); - retryTemplate.setRetryPolicy(retryPolicy == null || !retryable - ? new NeverRetryPolicy() - : new RetryPolicy(request, retryPolicy, this, this.getClientName())); - BackOffPolicy backOffPolicy = loadBalancedRetryFactory - .createBackOffPolicy(this.getClientName()); - retryTemplate.setBackOffPolicy( - backOffPolicy == null ? new NoBackOffPolicy() : backOffPolicy); - RetryListener[] retryListeners = this.loadBalancedRetryFactory - .createRetryListeners(this.getClientName()); - if (retryListeners != null && retryListeners.length != 0) { - retryTemplate.setListeners(retryListeners); - } - return retryTemplate.execute(callback, recoveryCallback); - } - - @Override - public RequestSpecificRetryHandler getRequestSpecificRetryHandler( - RibbonApacheHttpRequest request, IClientConfig requestConfig) { - return new RequestSpecificRetryHandler(false, false, RetryHandler.DEFAULT, null); - } - - public void setRibbonLoadBalancerContext( - RibbonLoadBalancerContext ribbonLoadBalancerContext) { - this.ribbonLoadBalancerContext = ribbonLoadBalancerContext; - } - - static class RetryPolicy extends InterceptorRetryPolicy { - - RetryPolicy(HttpRequest request, LoadBalancedRetryPolicy policy, - ServiceInstanceChooser serviceInstanceChooser, String serviceName) { - super(request, policy, serviceInstanceChooser, serviceName); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpRequest.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpRequest.java deleted file mode 100644 index ac51d6252..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpRequest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.apache; - -import java.net.URI; -import java.util.List; - -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.methods.RequestBuilder; -import org.apache.http.entity.BasicHttpEntity; - -import org.springframework.cloud.netflix.ribbon.support.ContextAwareRequest; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; - -import static org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer.Runner.customize; - -/** - * @author Christian Lohmann - */ -public class RibbonApacheHttpRequest extends ContextAwareRequest implements Cloneable { - - public RibbonApacheHttpRequest(RibbonCommandContext context) { - super(context); - } - - public HttpUriRequest toRequest(final RequestConfig requestConfig) { - final RequestBuilder builder = RequestBuilder.create(this.context.getMethod()); - builder.setUri(this.uri); - for (final String name : this.context.getHeaders().keySet()) { - final List values = this.context.getHeaders().get(name); - for (final String value : values) { - builder.addHeader(name, value); - } - } - - for (final String name : this.context.getParams().keySet()) { - final List values = this.context.getParams().get(name); - for (final String value : values) { - builder.addParameter(name, value); - } - } - - if (this.context.getRequestEntity() != null) { - final BasicHttpEntity entity; - entity = new BasicHttpEntity(); - entity.setContent(this.context.getRequestEntity()); - // if the entity contentLength isn't set, transfer-encoding will be set - // to chunked in org.apache.http.protocol.RequestContent. See gh-1042 - Long contentLength = this.context.getContentLength(); - if ("GET".equals(this.context.getMethod()) - && (contentLength == null || contentLength < 0)) { - entity.setContentLength(0); - } - else if (contentLength != null) { - entity.setContentLength(contentLength); - } - builder.setEntity(entity); - } - - customize(this.context.getRequestCustomizers(), builder); - - builder.setConfig(requestConfig); - return builder.build(); - } - - public RibbonApacheHttpRequest withNewUri(URI uri) { - return new RibbonApacheHttpRequest(newContext(uri)); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpResponse.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpResponse.java deleted file mode 100644 index ac7c10518..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpResponse.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.apache; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Type; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.google.common.reflect.TypeToken; -import com.netflix.client.ClientException; -import com.netflix.client.http.CaseInsensitiveMultiMap; -import com.netflix.client.http.HttpHeaders; -import org.apache.http.Header; -import org.apache.http.HttpResponse; - -import org.springframework.http.HttpStatus; -import org.springframework.util.Assert; - -/** - * @author Christian Lohmann - */ -public class RibbonApacheHttpResponse implements com.netflix.client.http.HttpResponse { - - private HttpResponse httpResponse; - - private URI uri; - - public RibbonApacheHttpResponse(final HttpResponse httpResponse, final URI uri) { - Assert.notNull(httpResponse, "httpResponse can not be null"); - this.httpResponse = httpResponse; - this.uri = uri; - } - - @Override - public Object getPayload() throws ClientException { - try { - if (!hasPayload()) { - return null; - } - return this.httpResponse.getEntity().getContent(); - } - catch (final IOException e) { - throw new ClientException(e.getMessage(), e); - } - } - - @Override - public boolean hasPayload() { - return this.httpResponse.getEntity() != null; - } - - @Override - public boolean isSuccess() { - return HttpStatus.valueOf(this.httpResponse.getStatusLine().getStatusCode()) - .is2xxSuccessful(); - } - - @Override - public URI getRequestedURI() { - return this.uri; - } - - public int getStatus() { - return httpResponse.getStatusLine().getStatusCode(); - } - - public String getStatusLine() { - return httpResponse.getStatusLine().toString(); - } - - @Override - public Map> getHeaders() { - final Map> headers = new HashMap<>(); - for (final Header header : this.httpResponse.getAllHeaders()) { - if (headers.containsKey(header.getName())) { - headers.get(header.getName()).add(header.getValue()); - } - else { - final List values = new ArrayList<>(); - values.add(header.getValue()); - headers.put(header.getName(), values); - } - } - - return headers; - } - - @Override - public HttpHeaders getHttpHeaders() { - final CaseInsensitiveMultiMap headers = new CaseInsensitiveMultiMap(); - for (final Header header : httpResponse.getAllHeaders()) { - headers.addHeader(header.getName(), header.getValue()); - } - - return headers; - } - - @Override - public void close() { - if (this.httpResponse != null && this.httpResponse.getEntity() != null) { - try { - this.httpResponse.getEntity().getContent().close(); - } - catch (final IOException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - - } - - @Override - public InputStream getInputStream() { - try { - if (!hasPayload()) { - return null; - } - return this.httpResponse.getEntity().getContent(); - } - catch (final IOException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - - @Override - public boolean hasEntity() { - return hasPayload(); - } - - /** - * Not used. - */ - @Override - public T getEntity(final Class type) throws Exception { - return null; - } - - /** - * Not used. - */ - @Override - public T getEntity(final Type type) throws Exception { - return null; - } - - /** - * Not used. - */ - @Override - public T getEntity(final TypeToken type) throws Exception { - return null; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClient.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClient.java deleted file mode 100644 index c13181165..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClient.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.apache; - -import java.net.URI; - -import com.netflix.client.RequestSpecificRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.Server; -import org.apache.http.HttpResponse; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; - -import org.springframework.cloud.netflix.ribbon.RibbonProperties; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.support.AbstractLoadBalancingClient; -import org.springframework.web.util.UriComponentsBuilder; - -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToSecureConnectionIfNeeded; - -/** - * @author Christian Lohmann - * @author Ryan Baxter - * @author Tim Ysewyn - */ -// TODO: rename (ie new class that extends this in Dalston) to -// ApacheHttpLoadBalancingClient -public class RibbonLoadBalancingHttpClient extends - AbstractLoadBalancingClient { - - public RibbonLoadBalancingHttpClient(IClientConfig config, - ServerIntrospector serverIntrospector) { - super(config, serverIntrospector); - } - - public RibbonLoadBalancingHttpClient(CloseableHttpClient delegate, - IClientConfig config, ServerIntrospector serverIntrospector) { - super(delegate, config, serverIntrospector); - } - - protected CloseableHttpClient createDelegate(IClientConfig config) { - RibbonProperties ribbon = RibbonProperties.from(config); - return HttpClientBuilder.create() - // already defaults to 0 in builder, so resetting to 0 won't hurt - .setMaxConnTotal(ribbon.maxTotalConnections(0)) - // already defaults to 0 in builder, so resetting to 0 won't hurt - .setMaxConnPerRoute(ribbon.maxConnectionsPerHost(0)) - .disableCookieManagement().useSystemProperties() // for proxy - .build(); - } - - @Override - public RibbonApacheHttpResponse execute(RibbonApacheHttpRequest request, - final IClientConfig configOverride) throws Exception { - IClientConfig config = configOverride != null ? configOverride : this.config; - RibbonProperties ribbon = RibbonProperties.from(config); - RequestConfig requestConfig = RequestConfig.custom() - .setConnectTimeout(ribbon.connectTimeout(this.connectTimeout)) - .setSocketTimeout(ribbon.readTimeout(this.readTimeout)) - .setRedirectsEnabled(ribbon.isFollowRedirects(this.followRedirects)) - .setContentCompressionEnabled(ribbon.isGZipPayload(this.gzipPayload)) - .build(); - - request = getSecureRequest(request, configOverride); - final HttpUriRequest httpUriRequest = request.toRequest(requestConfig); - final HttpResponse httpResponse = this.delegate.execute(httpUriRequest); - return new RibbonApacheHttpResponse(httpResponse, httpUriRequest.getURI()); - } - - @Override - public URI reconstructURIWithServer(Server server, URI original) { - URI uri = updateToSecureConnectionIfNeeded(original, this.config, - this.serverIntrospector, server); - return super.reconstructURIWithServer(server, uri); - } - - @Override - public RequestSpecificRetryHandler getRequestSpecificRetryHandler( - RibbonApacheHttpRequest request, IClientConfig requestConfig) { - return new RequestSpecificRetryHandler(false, false, RetryHandler.DEFAULT, - requestConfig); - } - - protected RibbonApacheHttpRequest getSecureRequest(RibbonApacheHttpRequest request, - IClientConfig configOverride) { - if (isSecure(configOverride)) { - final URI secureUri = UriComponentsBuilder.fromUri(request.getUri()) - .scheme("https").build(true).toUri(); - return request.withNewUri(secureUri); - } - return request; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClient.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClient.java deleted file mode 100644 index 784b40e4d..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClient.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.okhttp; - -import java.net.URI; -import java.util.concurrent.TimeUnit; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.Server; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; - -import org.springframework.cloud.netflix.ribbon.RibbonProperties; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.support.AbstractLoadBalancingClient; -import org.springframework.web.util.UriComponentsBuilder; - -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToSecureConnectionIfNeeded; - -/** - * @author Spencer Gibb - * @author Ryan Baxter - * @author Tim Ysewyn - */ -public class OkHttpLoadBalancingClient extends - AbstractLoadBalancingClient { - - public OkHttpLoadBalancingClient(IClientConfig config, - ServerIntrospector serverIntrospector) { - super(config, serverIntrospector); - } - - public OkHttpLoadBalancingClient(OkHttpClient delegate, IClientConfig config, - ServerIntrospector serverIntrospector) { - super(delegate, config, serverIntrospector); - } - - @Override - protected OkHttpClient createDelegate(IClientConfig config) { - return new OkHttpClient(); - } - - @Override - public OkHttpRibbonResponse execute(OkHttpRibbonRequest ribbonRequest, - final IClientConfig configOverride) throws Exception { - boolean secure = isSecure(configOverride); - if (secure) { - final URI secureUri = UriComponentsBuilder.fromUri(ribbonRequest.getUri()) - .scheme("https").build().toUri(); - ribbonRequest = ribbonRequest.withNewUri(secureUri); - } - - OkHttpClient httpClient = getOkHttpClient(configOverride, secure); - final Request request = ribbonRequest.toRequest(); - Response response = httpClient.newCall(request).execute(); - return new OkHttpRibbonResponse(response, ribbonRequest.getUri()); - } - - OkHttpClient getOkHttpClient(IClientConfig configOverride, boolean secure) { - IClientConfig config = configOverride != null ? configOverride : this.config; - RibbonProperties ribbon = RibbonProperties.from(config); - OkHttpClient.Builder builder = this.delegate.newBuilder() - .connectTimeout(ribbon.connectTimeout(this.connectTimeout), - TimeUnit.MILLISECONDS) - .readTimeout(ribbon.readTimeout(this.readTimeout), TimeUnit.MILLISECONDS) - .followRedirects(ribbon.isFollowRedirects(this.followRedirects)); - if (secure) { - builder.followSslRedirects(ribbon.isFollowRedirects(this.followRedirects)); - } - - return builder.build(); - } - - @Override - public URI reconstructURIWithServer(Server server, URI original) { - URI uri = updateToSecureConnectionIfNeeded(original, this.config, - this.serverIntrospector, server); - return super.reconstructURIWithServer(server, uri); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonConfiguration.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonConfiguration.java deleted file mode 100644 index c67857a65..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonConfiguration.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.okhttp; - -import java.util.concurrent.TimeUnit; - -import javax.annotation.PreDestroy; - -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.servo.monitor.Monitors; -import okhttp3.ConnectionPool; -import okhttp3.OkHttpClient; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory; -import org.springframework.cloud.commons.httpclient.OkHttpClientFactory; -import org.springframework.cloud.netflix.ribbon.RibbonClientName; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext; -import org.springframework.cloud.netflix.ribbon.RibbonProperties; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnProperty("ribbon.okhttp.enabled") -@ConditionalOnClass(name = "okhttp3.OkHttpClient") -public class OkHttpRibbonConfiguration { - - @RibbonClientName - private String name = "client"; - - @Bean - @ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class) - @ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate") - public RetryableOkHttpLoadBalancingClient retryableOkHttpLoadBalancingClient( - IClientConfig config, ServerIntrospector serverIntrospector, - ILoadBalancer loadBalancer, RetryHandler retryHandler, - LoadBalancedRetryFactory loadBalancedRetryFactory, OkHttpClient delegate, - RibbonLoadBalancerContext ribbonLoadBalancerContext) { - RetryableOkHttpLoadBalancingClient client = new RetryableOkHttpLoadBalancingClient( - delegate, config, serverIntrospector, loadBalancedRetryFactory); - client.setLoadBalancer(loadBalancer); - client.setRetryHandler(retryHandler); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - Monitors.registerObject("Client_" + this.name, client); - return client; - } - - @Bean - @ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class) - @ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate") - public OkHttpLoadBalancingClient okHttpLoadBalancingClient(IClientConfig config, - ServerIntrospector serverIntrospector, ILoadBalancer loadBalancer, - RetryHandler retryHandler, OkHttpClient delegate) { - OkHttpLoadBalancingClient client = new OkHttpLoadBalancingClient(delegate, config, - serverIntrospector); - client.setLoadBalancer(loadBalancer); - client.setRetryHandler(retryHandler); - Monitors.registerObject("Client_" + this.name, client); - return client; - } - - @Configuration(proxyBeanMethods = false) - protected static class OkHttpClientConfiguration { - - private OkHttpClient httpClient; - - @Bean - @ConditionalOnMissingBean(ConnectionPool.class) - public ConnectionPool httpClientConnectionPool(IClientConfig config, - OkHttpClientConnectionPoolFactory connectionPoolFactory) { - RibbonProperties ribbon = RibbonProperties.from(config); - int maxTotalConnections = ribbon.maxTotalConnections(); - long timeToLive = ribbon.poolKeepAliveTime(); - TimeUnit ttlUnit = ribbon.getPoolKeepAliveTimeUnits(); - return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit); - } - - @Bean - @ConditionalOnMissingBean(OkHttpClient.class) - public OkHttpClient client(OkHttpClientFactory httpClientFactory, - ConnectionPool connectionPool, IClientConfig config) { - RibbonProperties ribbon = RibbonProperties.from(config); - this.httpClient = httpClientFactory.createBuilder(false) - .connectTimeout(ribbon.connectTimeout(), TimeUnit.MILLISECONDS) - .readTimeout(ribbon.readTimeout(), TimeUnit.MILLISECONDS) - .followRedirects(ribbon.isFollowRedirects()) - .connectionPool(connectionPool).build(); - return this.httpClient; - } - - @PreDestroy - public void destroy() { - if (httpClient != null) { - httpClient.dispatcher().executorService().shutdown(); - httpClient.connectionPool().evictAll(); - } - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonRequest.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonRequest.java deleted file mode 100644 index 5fcc545e8..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonRequest.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.okhttp; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.util.List; - -import okhttp3.Headers; -import okhttp3.HttpUrl; -import okhttp3.MediaType; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.internal.http.HttpMethod; -import okio.BufferedSink; -import okio.Okio; -import okio.Source; - -import org.springframework.cloud.netflix.ribbon.support.ContextAwareRequest; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; - -import static org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer.Runner.customize; - -/** - * @author Spencer Gibb - */ -public class OkHttpRibbonRequest extends ContextAwareRequest implements Cloneable { - - public OkHttpRibbonRequest(RibbonCommandContext context) { - super(context); - } - - public Request toRequest() { - Headers.Builder headers = new Headers.Builder(); - for (String name : this.context.getHeaders().keySet()) { - List values = this.context.getHeaders().get(name); - for (String value : values) { - headers.add(name, value); - } - } - - HttpUrl.Builder url = HttpUrl.get(this.uri).newBuilder(); - for (String name : this.context.getParams().keySet()) { - List values = this.context.getParams().get(name); - for (String value : values) { - url.addQueryParameter(name, value); - } - } - - RequestBody requestBody = null; - - if (this.context.getRequestEntity() != null - && HttpMethod.permitsRequestBody(this.context.getMethod())) { - MediaType mediaType = null; - if (headers.get("Content-Type") != null) { - mediaType = MediaType.parse(headers.get("Content-Type")); - } - requestBody = new InputStreamRequestBody(this.context.getRequestEntity(), - mediaType, this.context.getContentLength()); - } - - Request.Builder builder = new Request.Builder().url(url.build()) - .headers(headers.build()).method(this.context.getMethod(), requestBody); - - customize(this.context.getRequestCustomizers(), builder); - - return builder.build(); - } - - public OkHttpRibbonRequest withNewUri(final URI uri) { - return new OkHttpRibbonRequest(newContext(uri)); - } - - static class InputStreamRequestBody extends RequestBody { - - private InputStream inputStream; - - private MediaType mediaType; - - private Long contentLength; - - InputStreamRequestBody(InputStream inputStream, MediaType mediaType, - Long contentLength) { - this.inputStream = inputStream; - this.mediaType = mediaType; - this.contentLength = contentLength; - } - - @Override - public MediaType contentType() { - return mediaType; - } - - @Override - public long contentLength() { - if (contentLength != null) { - return contentLength; - } - try { - return inputStream.available(); - } - catch (IOException e) { - return 0; - } - } - - @Override - public void writeTo(BufferedSink sink) throws IOException { - Source source = null; - try { - source = Okio.source(inputStream); - sink.writeAll(source); - } - finally { - if (source != null) { - source.close(); - } - } - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonResponse.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonResponse.java deleted file mode 100644 index 227fa37a7..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonResponse.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.okhttp; - -import java.io.InputStream; -import java.lang.reflect.Type; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.google.common.reflect.TypeToken; -import com.netflix.client.ClientException; -import com.netflix.client.http.CaseInsensitiveMultiMap; -import com.netflix.client.http.HttpHeaders; -import okhttp3.Response; -import okhttp3.ResponseBody; - -import org.springframework.util.Assert; - -/** - * @author Spencer Gibb - */ -public class OkHttpRibbonResponse implements com.netflix.client.http.HttpResponse { - - private final ResponseBody body; - - private URI uri; - - private Response response; - - public OkHttpRibbonResponse(Response response, URI uri) { - Assert.notNull(response, "response can not be null"); - this.response = response; - this.body = response.body(); - this.uri = uri; - } - - @Override - public int getStatus() { - return this.response.code(); - } - - @Override - public String getStatusLine() { - return this.response.message(); - } - - @Override - public Object getPayload() throws ClientException { - if (!hasPayload()) { - return null; - } - return this.body.byteStream(); - } - - @Override - public boolean hasPayload() { - return this.body != null; - } - - @Override - public boolean isSuccess() { - return this.response.isSuccessful(); - } - - @Override - public URI getRequestedURI() { - return this.uri; - } - - @Override - public Map> getHeaders() { - final Map> headers = new HashMap<>(); - for (Map.Entry> entry : this.response.headers().toMultimap() - .entrySet()) { - String name = entry.getKey(); - for (String value : entry.getValue()) { - if (headers.containsKey(name)) { - headers.get(name).add(value); - } - else { - final List values = new ArrayList<>(); - values.add(value); - headers.put(name, values); - } - } - } - - return headers; - } - - @Override - public HttpHeaders getHttpHeaders() { - final CaseInsensitiveMultiMap headers = new CaseInsensitiveMultiMap(); - for (Map.Entry> entry : this.response.headers().toMultimap() - .entrySet()) { - for (String value : entry.getValue()) { - headers.addHeader(entry.getKey(), value); - } - } - - return headers; - } - - @Override - public void close() { - this.response.close(); - } - - @Override - public InputStream getInputStream() { - if (this.body == null) { - return null; - } - return this.body.byteStream(); - } - - @Override - public boolean hasEntity() { - return hasPayload(); - } - - @Override - public T getEntity(Class type) throws Exception { - return null; - } - - @Override - public T getEntity(Type type) throws Exception { - return null; - } - - @Override - public T getEntity(TypeToken type) throws Exception { - return null; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpStatusCodeException.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpStatusCodeException.java deleted file mode 100644 index ef11b6b22..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpStatusCodeException.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.okhttp; - -import java.net.URI; - -import okhttp3.Response; -import okhttp3.ResponseBody; - -import org.springframework.cloud.client.loadbalancer.RetryableStatusCodeException; - -/** - * An {@link RetryableStatusCodeException} that captures a {@link Response}. - * - * @author Ryan Baxter - */ -public class OkHttpStatusCodeException extends RetryableStatusCodeException { - - private final Response response; - - public OkHttpStatusCodeException(String serviceId, Response response, - ResponseBody responseBody, URI uri) { - super(serviceId, response.code(), response, uri); - this.response = new Response.Builder().code(response.code()) - .message(response.message()).protocol(response.protocol()) - .request(response.request()).headers(response.headers()) - .handshake(response.handshake()).cacheResponse(response.cacheResponse()) - .networkResponse(response.networkResponse()) - .priorResponse(response.priorResponse()) - .sentRequestAtMillis(response.sentRequestAtMillis()).body(responseBody) - .build(); - } - - @Override - public Response getResponse() { - return response; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/RetryableOkHttpLoadBalancingClient.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/RetryableOkHttpLoadBalancingClient.java deleted file mode 100644 index d972b2bc7..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/RetryableOkHttpLoadBalancingClient.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.okhttp; - -import java.net.URI; - -import com.netflix.client.RequestSpecificRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.ResponseBody; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.InterceptorRetryPolicy; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRecoveryCallback; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.RibbonServer; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext; -import org.springframework.cloud.netflix.ribbon.RibbonStatsRecorder; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.support.ContextAwareRequest; -import org.springframework.http.HttpRequest; -import org.springframework.retry.RecoveryCallback; -import org.springframework.retry.RetryCallback; -import org.springframework.retry.RetryContext; -import org.springframework.retry.RetryListener; -import org.springframework.retry.backoff.BackOffPolicy; -import org.springframework.retry.backoff.NoBackOffPolicy; -import org.springframework.retry.policy.NeverRetryPolicy; -import org.springframework.retry.support.RetryTemplate; -import org.springframework.web.util.UriComponentsBuilder; - -/** - * An OK HTTP client which leverages Spring Retry to retry failed request. - * - * @author Ryan Baxter - * @author Gang Li - */ -public class RetryableOkHttpLoadBalancingClient extends OkHttpLoadBalancingClient { - - private static final Log LOGGER = LogFactory - .getLog(RetryableOkHttpLoadBalancingClient.class); - - private LoadBalancedRetryFactory loadBalancedRetryFactory; - - private RibbonLoadBalancerContext ribbonLoadBalancerContext; - - public RetryableOkHttpLoadBalancingClient(OkHttpClient delegate, IClientConfig config, - ServerIntrospector serverIntrospector, - LoadBalancedRetryFactory loadBalancedRetryPolicyFactory) { - super(delegate, config, serverIntrospector); - this.loadBalancedRetryFactory = loadBalancedRetryPolicyFactory; - } - - @Override - public boolean isClientRetryable(ContextAwareRequest request) { - return request != null && isRequestRetryable(request); - } - - private boolean isRequestRetryable(ContextAwareRequest request) { - if (request.getContext() == null || request.getContext().getRetryable() == null) { - return true; - } - return request.getContext().getRetryable(); - } - - private OkHttpRibbonResponse executeWithRetry(OkHttpRibbonRequest request, - LoadBalancedRetryPolicy retryPolicy, - RetryCallback callback, - RecoveryCallback recoveryCallback) throws Exception { - RetryTemplate retryTemplate = new RetryTemplate(); - BackOffPolicy backOffPolicy = loadBalancedRetryFactory - .createBackOffPolicy(this.getClientName()); - retryTemplate.setBackOffPolicy( - backOffPolicy == null ? new NoBackOffPolicy() : backOffPolicy); - RetryListener[] retryListeners = this.loadBalancedRetryFactory - .createRetryListeners(this.getClientName()); - if (retryListeners != null && retryListeners.length != 0) { - retryTemplate.setListeners(retryListeners); - } - boolean retryable = isRequestRetryable(request); - retryTemplate.setRetryPolicy(retryPolicy == null || !retryable - ? new NeverRetryPolicy() - : new RetryPolicy(request, retryPolicy, this, this.getClientName())); - return retryTemplate.execute(callback, recoveryCallback); - } - - @Override - public OkHttpRibbonResponse execute(final OkHttpRibbonRequest ribbonRequest, - final IClientConfig configOverride) throws Exception { - final LoadBalancedRetryPolicy retryPolicy = loadBalancedRetryFactory - .createRetryPolicy(this.getClientName(), this); - RetryCallback retryCallback = new RetryCallback() { - @Override - public OkHttpRibbonResponse doWithRetry(RetryContext context) - throws Exception { - // on retries the policy will choose the server and set it in the context - // extract the server and update the request being made - OkHttpRibbonRequest newRequest = ribbonRequest; - RibbonStatsRecorder statsRecorder = null; - - if (context instanceof LoadBalancedRetryContext) { - ServiceInstance service = ((LoadBalancedRetryContext) context) - .getServiceInstance(); - validateServiceInstance(service); - // Reconstruct the request URI using the host and port set in the - // retry context - newRequest = newRequest - .withNewUri(new URI(service.getUri().getScheme(), - newRequest.getURI().getUserInfo(), service.getHost(), - service.getPort(), newRequest.getURI().getPath(), - newRequest.getURI().getQuery(), - newRequest.getURI().getFragment())); - - if (ribbonLoadBalancerContext == null) { - LOGGER.error( - "RibbonLoadBalancerContext is null. Unable to update load balancer stats"); - } - else if (service instanceof RibbonServer) { - statsRecorder = new RibbonStatsRecorder(ribbonLoadBalancerContext, - ((RibbonServer) service).getServer()); - } - } - if (isSecure(configOverride)) { - final URI secureUri = UriComponentsBuilder - .fromUri(newRequest.getUri()).scheme("https").build().toUri(); - newRequest = newRequest.withNewUri(secureUri); - } - OkHttpClient httpClient = getOkHttpClient(configOverride, secure); - - final Request request = newRequest.toRequest(); - Response response = httpClient.newCall(request).execute(); - if (retryPolicy.retryableStatusCode(response.code())) { - ResponseBody responseBody = response.peekBody(Integer.MAX_VALUE); - response.close(); - throw new OkHttpStatusCodeException( - RetryableOkHttpLoadBalancingClient.this.clientName, response, - responseBody, newRequest.getURI()); - } - if (statsRecorder != null) { - statsRecorder.recordStats(response); - } - return new OkHttpRibbonResponse(response, newRequest.getUri()); - } - }; - return this.executeWithRetry(ribbonRequest, retryPolicy, retryCallback, - new LoadBalancedRecoveryCallback() { - - @Override - protected OkHttpRibbonResponse createResponse(Response response, - URI uri) { - return new OkHttpRibbonResponse(response, uri); - } - }); - } - - @Override - public RequestSpecificRetryHandler getRequestSpecificRetryHandler( - OkHttpRibbonRequest request, IClientConfig requestConfig) { - return new RequestSpecificRetryHandler(false, false, RetryHandler.DEFAULT, null); - } - - public void setRibbonLoadBalancerContext( - RibbonLoadBalancerContext ribbonLoadBalancerContext) { - this.ribbonLoadBalancerContext = ribbonLoadBalancerContext; - } - - static class RetryPolicy extends InterceptorRetryPolicy { - - RetryPolicy(HttpRequest request, LoadBalancedRetryPolicy policy, - ServiceInstanceChooser serviceInstanceChooser, String serviceName) { - super(request, policy, serviceInstanceChooser, serviceName); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/AbstractLoadBalancingClient.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/AbstractLoadBalancingClient.java deleted file mode 100644 index f61bfa586..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/AbstractLoadBalancingClient.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.support; - -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.ClientException; -import com.netflix.client.IResponse; -import com.netflix.client.RequestSpecificRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.reactive.LoadBalancerCommand; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient; -import org.springframework.cloud.netflix.ribbon.RibbonProperties; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; - -import static org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration.DEFAULT_CONNECT_TIMEOUT; -import static org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration.DEFAULT_GZIP_PAYLOAD; -import static org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration.DEFAULT_READ_TIMEOUT; - -/** - * @param delegate - * @param {@link ContextAwareRequest} subtype - * @param {@link ServiceInstanceChooser} subtype - * @author Spencer Gibb - * - */ -public abstract class AbstractLoadBalancingClient - extends AbstractLoadBalancerAwareClient implements ServiceInstanceChooser { - - protected int connectTimeout; - - protected int readTimeout; - - protected boolean secure; - - protected boolean followRedirects; - - protected boolean gzipPayload; - - protected boolean okToRetryOnAllOperations; - - protected final D delegate; - - protected final IClientConfig config; - - protected final ServerIntrospector serverIntrospector; - - public boolean isClientRetryable(ContextAwareRequest request) { - return false; - } - - protected AbstractLoadBalancingClient(IClientConfig config, - ServerIntrospector serverIntrospector) { - super(null); - this.delegate = createDelegate(config); - this.config = config; - this.serverIntrospector = serverIntrospector; - this.setRetryHandler(RetryHandler.DEFAULT); - initWithNiwsConfig(config); - } - - protected AbstractLoadBalancingClient(D delegate, IClientConfig config, - ServerIntrospector serverIntrospector) { - super(null); - this.delegate = delegate; - this.config = config; - this.serverIntrospector = serverIntrospector; - this.setRetryHandler(RetryHandler.DEFAULT); - initWithNiwsConfig(config); - } - - @Override - public void initWithNiwsConfig(IClientConfig clientConfig) { - super.initWithNiwsConfig(clientConfig); - RibbonProperties ribbon = RibbonProperties.from(clientConfig); - this.connectTimeout = ribbon.connectTimeout(DEFAULT_CONNECT_TIMEOUT); - this.readTimeout = ribbon.readTimeout(DEFAULT_READ_TIMEOUT); - this.secure = ribbon.isSecure(); - this.followRedirects = ribbon.isFollowRedirects(); - this.okToRetryOnAllOperations = ribbon.isOkToRetryOnAllOperations(); - this.gzipPayload = ribbon.isGZipPayload(DEFAULT_GZIP_PAYLOAD); - } - - protected abstract D createDelegate(IClientConfig config); - - public D getDelegate() { - return this.delegate; - } - - @Override - public RequestSpecificRetryHandler getRequestSpecificRetryHandler(final S request, - final IClientConfig requestConfig) { - if (this.okToRetryOnAllOperations) { - return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(), - requestConfig); - } - - if (!request.getContext().getMethod().equals("GET")) { - return new RequestSpecificRetryHandler(true, false, this.getRetryHandler(), - requestConfig); - } - else { - return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(), - requestConfig); - } - } - - protected boolean isSecure(final IClientConfig config) { - if (config != null) { - return RibbonProperties.from(config).isSecure(this.secure); - } - return this.secure; - } - - @Override - protected void customizeLoadBalancerCommandBuilder(S request, IClientConfig config, - LoadBalancerCommand.Builder builder) { - if (request.getLoadBalancerKey() != null) { - builder.withServerLocator(request.getLoadBalancerKey()); - } - } - - @Override - public ServiceInstance choose(String serviceId) { - Server server = this.getLoadBalancer().chooseServer(serviceId); - if (server != null) { - return new RibbonLoadBalancerClient.RibbonServer(serviceId, server); - } - return null; - } - - public void validateServiceInstance(ServiceInstance serviceInstance) - throws ClientException { - if (serviceInstance == null) { - throw new ClientException( - "Load balancer does not have available server for client: " - + clientName); - } - else if (serviceInstance.getHost() == null) { - throw new ClientException("Invalid Server for: " - + serviceInstance.getServiceId() + " null Host"); - } - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/ContextAwareRequest.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/ContextAwareRequest.java deleted file mode 100644 index 08cf65c16..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/ContextAwareRequest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.support; - -import java.net.URI; - -import com.netflix.client.ClientRequest; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpRequest; -import org.springframework.util.MultiValueMap; - -/** - * @author Spencer Gibb - * @author Ryan Baxter - */ -public abstract class ContextAwareRequest extends ClientRequest implements HttpRequest { - - protected final RibbonCommandContext context; - - private HttpHeaders httpHeaders; - - public ContextAwareRequest(RibbonCommandContext context) { - this.context = context; - MultiValueMap headers = context.getHeaders(); - this.httpHeaders = new HttpHeaders(); - for (String key : headers.keySet()) { - this.httpHeaders.put(key, headers.get(key)); - } - this.uri = context.uri(); - this.isRetriable = context.getRetryable(); - this.loadBalancerKey = context.getLoadBalancerKey(); - } - - public RibbonCommandContext getContext() { - return context; - } - - @Override - public HttpMethod getMethod() { - return HttpMethod.valueOf(context.getMethod()); - } - - @Override - public String getMethodValue() { - return getMethod().name(); - } - - @Override - public URI getURI() { - return this.getUri(); - } - - @Override - public HttpHeaders getHeaders() { - return httpHeaders; - } - - protected RibbonCommandContext newContext(URI uri) { - RibbonCommandContext commandContext = new RibbonCommandContext( - this.context.getServiceId(), this.context.getMethod(), uri.toString(), - this.context.getRetryable(), this.context.getHeaders(), - this.context.getParams(), this.context.getRequestEntity(), - this.context.getRequestCustomizers(), this.context.getContentLength(), - this.context.getLoadBalancerKey()); - return commandContext; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/ResettableServletInputStreamWrapper.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/ResettableServletInputStreamWrapper.java deleted file mode 100644 index a521332b3..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/ResettableServletInputStreamWrapper.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.support; - -import java.io.ByteArrayInputStream; -import java.io.IOException; - -import javax.servlet.ReadListener; -import javax.servlet.ServletInputStream; - -/** - * A wrapper for {@link ServletInputStream} providing additional capabilities to allow for - * resetting. - * - * @author Arne Dörnbrack - * @author Spencer Gibb - */ -public class ResettableServletInputStreamWrapper extends ServletInputStream { - - private final ByteArrayInputStream input; - - public ResettableServletInputStreamWrapper(byte[] data) { - this.input = new ByteArrayInputStream(data); - } - - @Override - public boolean isFinished() { - return false; - } - - @Override - public boolean isReady() { - return false; - } - - @Override - public void setReadListener(ReadListener listener) { - } - - @Override - public int read() throws IOException { - return input.read(); - } - - @Override - public synchronized void reset() throws IOException { - input.reset(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonCommandContext.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonCommandContext.java deleted file mode 100644 index 2aed0098c..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonCommandContext.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.support; - -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import org.springframework.util.Assert; -import org.springframework.util.MultiValueMap; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StreamUtils; - -/** - * @author Spencer Gibb - * @author Yongsung Yoon - */ -public class RibbonCommandContext { - - private final String serviceId; - - private final String method; - - private final String uri; - - private final Boolean retryable; - - private final MultiValueMap headers; - - private final MultiValueMap params; - - private final List requestCustomizers; - - private InputStream requestEntity; - - private Long contentLength; - - private Object loadBalancerKey; - - /** - * Kept for backwards compatibility with Spring Cloud Sleuth 1.x versions. - * @param serviceId to be used with Ribbon request - * @param method to be used with Ribbon request - * @param uri {@link String} value of the uri to be used with Ribbon request - * @param retryable determines whether the requests should be retried - * @param headers to pass to the Ribbon request - * @param params parameters to pass to the Ribbon request - * @param requestEntity request content {@link InputStream} - */ - @Deprecated - public RibbonCommandContext(String serviceId, String method, String uri, - Boolean retryable, MultiValueMap headers, - MultiValueMap params, InputStream requestEntity) { - this(serviceId, method, uri, retryable, headers, params, requestEntity, - new ArrayList(), null, null); - } - - public RibbonCommandContext(String serviceId, String method, String uri, - Boolean retryable, MultiValueMap headers, - MultiValueMap params, InputStream requestEntity, - List requestCustomizers) { - this(serviceId, method, uri, retryable, headers, params, requestEntity, - requestCustomizers, null, null); - } - - public RibbonCommandContext(String serviceId, String method, String uri, - Boolean retryable, MultiValueMap headers, - MultiValueMap params, InputStream requestEntity, - List requestCustomizers, Long contentLength) { - this(serviceId, method, uri, retryable, headers, params, requestEntity, - requestCustomizers, contentLength, null); - } - - public RibbonCommandContext(String serviceId, String method, String uri, - Boolean retryable, MultiValueMap headers, - MultiValueMap params, InputStream requestEntity, - List requestCustomizers, Long contentLength, - Object loadBalancerKey) { - Assert.notNull(serviceId, "serviceId may not be null"); - Assert.notNull(method, "method may not be null"); - Assert.notNull(uri, "uri may not be null"); - Assert.notNull(headers, "headers may not be null"); - Assert.notNull(params, "params may not be null"); - Assert.notNull(requestCustomizers, "requestCustomizers may not be null"); - this.serviceId = serviceId; - this.method = method; - this.uri = uri; - this.retryable = retryable; - this.headers = headers; - this.params = params; - this.requestEntity = requestEntity; - this.requestCustomizers = requestCustomizers; - this.contentLength = contentLength; - this.loadBalancerKey = loadBalancerKey; - } - - public URI uri() { - try { - return new URI(this.uri); - } - catch (URISyntaxException e) { - ReflectionUtils.rethrowRuntimeException(e); - } - return null; - } - - /** - * Use {@link #getMethod()}. - * @return request method - */ - @Deprecated - public String getVerb() { - return this.method; - } - - public String getServiceId() { - return serviceId; - } - - public String getMethod() { - return method; - } - - public String getUri() { - return uri; - } - - public Boolean getRetryable() { - return retryable; - } - - public MultiValueMap getHeaders() { - return headers; - } - - public MultiValueMap getParams() { - return params; - } - - public InputStream getRequestEntity() { - if (requestEntity == null) { - return null; - } - // If the route is not retryable there is no point in copying the RequestEntity. - // This - // has memory implications in all cases but especially when uploading large files - // through - // Zuul - if (!retryable) { - return requestEntity; - } - - try { - if (!(requestEntity instanceof ResettableServletInputStreamWrapper)) { - requestEntity = new ResettableServletInputStreamWrapper( - StreamUtils.copyToByteArray(requestEntity)); - } - requestEntity.reset(); - } - finally { - return requestEntity; - } - } - - public List getRequestCustomizers() { - return requestCustomizers; - } - - public Long getContentLength() { - return contentLength; - } - - public void setContentLength(Long contentLength) { - this.contentLength = contentLength; - } - - public Object getLoadBalancerKey() { - return loadBalancerKey; - } - - public void setLoadBalancerKey(Object loadBalancerKey) { - this.loadBalancerKey = loadBalancerKey; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RibbonCommandContext that = (RibbonCommandContext) o; - return Objects.equals(serviceId, that.serviceId) - && Objects.equals(method, that.method) && Objects.equals(uri, that.uri) - && Objects.equals(retryable, that.retryable) - && Objects.equals(headers, that.headers) - && Objects.equals(params, that.params) - && Objects.equals(requestEntity, that.requestEntity) - && Objects.equals(requestCustomizers, that.requestCustomizers) - && Objects.equals(contentLength, that.contentLength) - && Objects.equals(loadBalancerKey, that.loadBalancerKey); - } - - @Override - public int hashCode() { - return Objects.hash(serviceId, method, uri, retryable, headers, params, - requestEntity, requestCustomizers, contentLength, loadBalancerKey); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("RibbonCommandContext{"); - sb.append("serviceId='").append(serviceId).append('\''); - sb.append(", method='").append(method).append('\''); - sb.append(", uri='").append(uri).append('\''); - sb.append(", retryable=").append(retryable); - sb.append(", headers=").append(headers); - sb.append(", params=").append(params); - sb.append(", requestEntity=").append(requestEntity); - sb.append(", requestCustomizers=").append(requestCustomizers); - sb.append(", contentLength=").append(contentLength); - sb.append(", loadBalancerKey=").append(loadBalancerKey); - sb.append('}'); - return sb.toString(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonRequestCustomizer.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonRequestCustomizer.java deleted file mode 100644 index 1a51b6867..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonRequestCustomizer.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.support; - -import java.util.List; - -/** - * Interface providing methods for customizing Ribbon requests. - * - * @param Request builder type - * @author Spencer Gibb - */ -public interface RibbonRequestCustomizer { - - boolean accepts(Class builderClass); - - void customize(B builder); - - class Runner { - - private Runner() { - throw new AssertionError("Must not instantiate utility class."); - } - - @SuppressWarnings("unchecked") - public static void customize(List customizers, - Object builder) { - for (RibbonRequestCustomizer customizer : customizers) { - if (customizer.accepts(builder.getClass())) { - customizer.customize(builder); - } - } - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonRetryPolicy.java b/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonRetryPolicy.java deleted file mode 100644 index 766c9fcd8..000000000 --- a/spring-cloud-netflix-ribbon/src/main/java/org/springframework/cloud/netflix/ribbon/support/RibbonRetryPolicy.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2018-2019 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 - * - * https://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.ribbon.support; - -import java.net.URI; -import java.util.HashMap; -import java.util.Map; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.InterceptorRetryPolicy; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.http.HttpRequest; -import org.springframework.retry.RetryContext; - -/** - * @author Ryan Baxter - */ -public class RibbonRetryPolicy extends InterceptorRetryPolicy { - - private HttpRequest request; - - private String serviceId; - - public RibbonRetryPolicy(HttpRequest request, LoadBalancedRetryPolicy policy, - ServiceInstanceChooser serviceInstanceChooser, String serviceName) { - super(request, policy, serviceInstanceChooser, serviceName); - this.request = request; - this.serviceId = serviceName; - } - - @Override - public boolean canRetry(RetryContext context) { - /* - * In InterceptorRetryPolicy.canRetry we ask the LoadBalancer to choose a server - * if one is not set in the retry context and then return true. RetryTemplat calls - * the canRetry method of the policy even on its first execution. So the fact that - * we didnt have a service instance set in the RetryContext signaled that it was - * the first execution and we should return true. - * - */ - if (context.getRetryCount() == 0) { - return true; - } - return super.canRetry(context); - } - - @Override - public RetryContext open(RetryContext parent) { - LoadBalancedRetryContext context = new LoadBalancedRetryContext(parent, - this.request); - context.setServiceInstance( - new RibbonRetryPolicyServiceInstance(serviceId, request)); - return context; - } - - class RibbonRetryPolicyServiceInstance implements ServiceInstance { - - private String serviceId; - - private HttpRequest request; - - private Map metadata; - - RibbonRetryPolicyServiceInstance(String serviceId, HttpRequest request) { - this.serviceId = serviceId; - this.request = request; - this.metadata = new HashMap<>(); - } - - @Override - public String getServiceId() { - return serviceId; - } - - @Override - public String getHost() { - return request.getURI().getHost(); - } - - @Override - public int getPort() { - return request.getURI().getPort(); - } - - @Override - public boolean isSecure() { - return "https".equals(request.getURI().getScheme()); - } - - @Override - public URI getUri() { - return request.getURI(); - } - - @Override - public Map getMetadata() { - return metadata; - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-netflix-ribbon/src/main/resources/META-INF/additional-spring-configuration-metadata.json deleted file mode 100644 index a98ad55cf..000000000 --- a/spring-cloud-netflix-ribbon/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "properties": [ - { - "defaultValue": true, - "name": "eureka.client.healthcheck.enabled", - "description": "Enables the Eureka health check handler.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": false, - "name": "ribbon.restclient.enabled", - "description": "Enables the use of the deprecated Ribbon RestClient.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": false, - "name": "ribbon.http.client.enabled", - "description": "Deprecated property to enable Ribbon RestClient.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": false, - "name": "ribbon.okhttp.enabled", - "description": "Enables the use of the OK HTTP Client with Ribbon.", - "type": "java.lang.Boolean" - } - ] -} \ No newline at end of file diff --git a/spring-cloud-netflix-ribbon/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-ribbon/src/main/resources/META-INF/spring.factories deleted file mode 100644 index be8c8c7bd..000000000 --- a/spring-cloud-netflix-ribbon/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration \ No newline at end of file diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospectorDefaultTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospectorDefaultTests.java deleted file mode 100644 index 878c90d67..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospectorDefaultTests.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import com.netflix.loadbalancer.Server; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * @author Rico Pahlisch - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = DefaultServerIntrospectorDefaultTests.TestConfiguration.class) -public class DefaultServerIntrospectorDefaultTests { - - @Autowired - private ServerIntrospector serverIntrospector; - - @Test - public void testDefaultSslPorts() { - Server serverMock = mock(Server.class); - when(serverMock.getPort()).thenReturn(443); - assertThat(serverIntrospector.isSecure(serverMock)).isTrue(); - when(serverMock.getPort()).thenReturn(8443); - assertThat(serverIntrospector.isSecure(serverMock)).isTrue(); - - when(serverMock.getPort()).thenReturn(16443); - assertThat(serverIntrospector.isSecure(serverMock)).isFalse(); - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(ServerIntrospectorProperties.class) - protected static class TestConfiguration { - - @Bean - public DefaultServerIntrospector defaultServerIntrospector() { - return new DefaultServerIntrospector(); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospectorTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospectorTests.java deleted file mode 100644 index c8f290c4e..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospectorTests.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import com.netflix.loadbalancer.Server; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * @author Rico Pahlisch - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = DefaultServerIntrospectorTests.TestConfiguration.class) -@TestPropertySource(properties = { "ribbon.securePorts=12345,556" }) -public class DefaultServerIntrospectorTests { - - @Autowired - private ServerIntrospector serverIntrospector; - - @Test - public void testSecurePortConfiguration() { - Server serverMock = mock(Server.class); - when(serverMock.getPort()).thenReturn(12345); - assertThat(serverIntrospector.isSecure(serverMock)).isTrue(); - when(serverMock.getPort()).thenReturn(556); - assertThat(serverIntrospector.isSecure(serverMock)).isTrue(); - when(serverMock.getPort()).thenReturn(443); - assertThat(serverIntrospector.isSecure(serverMock)).isFalse(); - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(ServerIntrospectorProperties.class) - protected static class TestConfiguration { - - @Bean - public DefaultServerIntrospector defaultServerIntrospector() { - return new DefaultServerIntrospector(); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/PlainRibbonClientPreprocessorIntegrationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/PlainRibbonClientPreprocessorIntegrationTests.java deleted file mode 100644 index be38fb5aa..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/PlainRibbonClientPreprocessorIntegrationTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import com.netflix.loadbalancer.ConfigurationBasedServerList; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.PlainRibbonClientPreprocessorIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = TestConfiguration.class) -@DirtiesContext -public class PlainRibbonClientPreprocessorIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void serverListIsConfigured() throws Exception { - @SuppressWarnings("unchecked") - ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) this.factory - .getLoadBalancer("foo"); - ConfigurationBasedServerList.class.cast(loadBalancer.getServerListImpl()); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient("foo") - @Import({ PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class, - RibbonAutoConfiguration.class }) - protected static class TestConfiguration { - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonApplicationContextInitializerTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonApplicationContextInitializerTests.java deleted file mode 100644 index 29e841bd8..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonApplicationContextInitializerTests.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.ribbon; - -import java.util.Arrays; -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Biju Kunjummen - */ - -@RunWith(SpringRunner.class) -@SpringBootTest( - classes = { RibbonAutoConfiguration.class, ArchaiusAutoConfiguration.class, - RibbonApplicationContextInitializerTests.RibbonInitializerConfig.class }) -@DirtiesContext -public class RibbonApplicationContextInitializerTests { - - @Autowired - private SpringClientFactory springClientFactory; - - @Test - public void testContextShouldInitalizeChildContexts() { - - // Context should have been initialized and an instance of Foo created - assertThat(Foo.getInstanceCount()).isEqualTo(1); - ApplicationContext ctx = springClientFactory.getContext("testspec"); - - assertThat(Foo.getInstanceCount()).isEqualTo(1); - Foo foo = ctx.getBean("foo", Foo.class); - assertThat(foo).isNotNull(); - } - - static class FooConfig { - - @Bean - public Foo foo() { - return new Foo(); - } - - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient(name = "testspec", configuration = FooConfig.class) - static class RibbonInitializerConfig { - - @Bean - public RibbonApplicationContextInitializer ribbonApplicationContextInitializer( - SpringClientFactory springClientFactory) { - return new RibbonApplicationContextInitializer(springClientFactory, - Arrays.asList("testspec")); - } - - } - - static class Foo { - - private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger(); - - Foo() { - INSTANCE_COUNT.incrementAndGet(); - } - - public static int getInstanceCount() { - return INSTANCE_COUNT.get(); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfigurationIntegrationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfigurationIntegrationTests.java deleted file mode 100644 index cdaccfc2e..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfigurationIntegrationTests.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfigurationIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = TestConfiguration.class, - value = { "ribbon.ConnectTimeout=25000" }) -@DirtiesContext -public class RibbonAutoConfigurationIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void serverListIsConfigured() throws Exception { - IClientConfig config = this.factory.getClientConfig("client"); - assertThat( - config.getPropertyAsInteger(CommonClientConfigKey.ConnectTimeout, 3000)) - .isEqualTo(25000); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient("client") - @Import({ PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class, - RibbonAutoConfiguration.class }) - protected static class TestConfiguration { - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationIntegrationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationIntegrationTests.java deleted file mode 100644 index 82220fe25..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationIntegrationTests.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.PollingServerListUpdater; -import com.netflix.loadbalancer.ServerListUpdater; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = RibbonClientConfigurationIntegrationTests.TestLBConfig.class, - properties = "test.ribbon.ServerListRefreshInterval=999") -@DirtiesContext -public class RibbonClientConfigurationIntegrationTests { - - @Autowired - private SpringClientFactory clientFactory; - - @Test - public void testLoadBalancerConstruction() { - ILoadBalancer loadBalancer = clientFactory.getInstance("test", - ILoadBalancer.class); - assertThat(loadBalancer).isInstanceOf(ZoneAwareLoadBalancer.class); - ZoneAwareLoadBalancer lb = (ZoneAwareLoadBalancer) loadBalancer; - ServerListUpdater serverListUpdater = (PollingServerListUpdater) ReflectionTestUtils - .getField(loadBalancer, "serverListUpdater"); - Long refreshIntervalMs = (Long) ReflectionTestUtils.getField(serverListUpdater, - "refreshIntervalMs"); - // assertThat(refreshIntervalMs, equalTo(999L)); - - ServerListUpdater updater = clientFactory.getInstance("test", - ServerListUpdater.class); - assertThat(updater).isSameAs(serverListUpdater); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - protected static class TestLBConfig { - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationTests.java deleted file mode 100644 index a34cfd8c0..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationTests.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.Server; -import com.netflix.niws.client.http.RestClient; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration.OverrideRestClient; -import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; - -/** - * @author Spencer Gibb - */ -public class RibbonClientConfigurationTests { - - private CountingConfig config; - - @Mock - private ServerIntrospector inspector; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - this.config = new CountingConfig(); - this.config.setProperty(CommonClientConfigKey.ConnectTimeout, "1"); - this.config.setProperty(CommonClientConfigKey.ReadTimeout, "1"); - this.config.setProperty(CommonClientConfigKey.MaxHttpConnectionsPerHost, "1"); - this.config.setClientName("testClient"); - } - - @Test - public void restClientInitCalledOnce() { - new TestRestClient(this.config); - assertThat(this.config.count).isEqualTo(1); - } - - @Test - public void restClientWithSecureServer() throws Exception { - CountingConfig config = new CountingConfig(); - config.setProperty(CommonClientConfigKey.ConnectTimeout, "1"); - config.setProperty(CommonClientConfigKey.ReadTimeout, "1"); - config.setProperty(CommonClientConfigKey.MaxHttpConnectionsPerHost, "1"); - config.setClientName("bar"); - Server server = new Server("example.com", 443); - URI uri = new TestRestClient(config).reconstructURIWithServer(server, - new URI("/foo")); - assertThat(uri.getScheme()).isEqualTo("https"); - assertThat(uri.getHost()).isEqualTo("example.com"); - } - - @Test - public void testSecureUriFromClientConfig() throws Exception { - Server server = new Server("foo", 7777); - when(this.inspector.isSecure(server)).thenReturn(true); - - for (AbstractLoadBalancerAwareClient client : clients()) { - URI uri = client.reconstructURIWithServer(server, new URI("https://foo/")); - assertThat(uri).as(getReason(client)).isEqualTo(new URI("https://foo:7777/")); - } - } - - @Test - public void testInSecureUriFromClientConfig() throws Exception { - Server server = new Server("foo", 7777); - when(this.inspector.isSecure(server)).thenReturn(false); - - for (AbstractLoadBalancerAwareClient client : clients()) { - URI uri = client.reconstructURIWithServer(server, new URI("https://foo/")); - assertThat(uri).as(getReason(client)).isEqualTo(new URI("https://foo:7777/")); - } - } - - String getReason(AbstractLoadBalancerAwareClient client) { - return client.getClass().getSimpleName() + " failed"; - } - - @Test - public void testNotDoubleEncodedWhenSecure() throws Exception { - Server server = new Server("foo", 7777); - when(this.inspector.isSecure(server)).thenReturn(true); - - for (AbstractLoadBalancerAwareClient client : clients()) { - URI uri = client.reconstructURIWithServer(server, - new URI("https://foo/%20bar")); - assertThat(uri).as(getReason(client)) - .isEqualTo(new URI("https://foo:7777/%20bar")); - } - } - - @Test - public void testPlusInQueryStringGetsRewrittenWhenServerIsSecure() throws Exception { - Server server = new Server("foo", 7777); - when(this.inspector.isSecure(server)).thenReturn(true); - - for (AbstractLoadBalancerAwareClient client : clients()) { - URI uri = client.reconstructURIWithServer(server, - new URI("http://foo/%20bar?hello=1+2")); - assertThat(uri).isEqualTo(new URI("https://foo:7777/%20bar?hello=1%202")); - } - } - - private List clients() { - ArrayList clients = new ArrayList<>(); - clients.add(new OverrideRestClient(this.config, this.inspector)); - clients.add(new RibbonLoadBalancingHttpClient(this.config, this.inspector)); - clients.add(new OkHttpLoadBalancingClient(this.config, this.inspector)); - return clients; - } - - @SuppressWarnings("deprecation") - @Test - public void testDefaultsToApacheHttpClient() { - testClient(RibbonLoadBalancingHttpClient.class, null, RestClient.class, - OkHttpLoadBalancingClient.class); - testClient(RibbonLoadBalancingHttpClient.class, - new String[] { "ribbon.httpclient.enabled" }, RestClient.class, - OkHttpLoadBalancingClient.class); - } - - @SuppressWarnings("deprecation") - @Test - public void testEnableRestClient() { - testClient(RestClient.class, new String[] { "ribbon.restclient.enabled" }, - RibbonLoadBalancingHttpClient.class, OkHttpLoadBalancingClient.class); - } - - @SuppressWarnings("deprecation") - @Test - public void testEnableOkHttpClient() { - testClient(OkHttpLoadBalancingClient.class, - new String[] { "ribbon.okhttp.enabled" }, - RibbonLoadBalancingHttpClient.class, RestClient.class); - } - - void testClient(Class clientType, String[] properties, Class... excludedTypes) { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - context.register(HttpClientConfiguration.class, RibbonAutoConfiguration.class, - RibbonClientConfiguration.class); - if (properties != null) { - TestPropertyValues.of(properties).applyTo(context); - } - context.refresh(); - context.getBean(clientType); - for (Class excludedType : excludedTypes) { - assertThat(hasInstance(context, excludedType)) - .as("has " + excludedType.getSimpleName() + " instance").isFalse(); - } - context.close(); - } - - private boolean hasInstance(ListableBeanFactory lbf, Class requiredType) { - return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(lbf, - requiredType).length > 0; - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - protected static class TestLBConfig { - - } - - static class CountingConfig extends DefaultClientConfigImpl { - - int count = 0; - - } - - static final class TestRestClient extends OverrideRestClient { - - private TestRestClient(IClientConfig ncc) { - super(ncc, new DefaultServerIntrospector()); - } - - @Override - public void initWithNiwsConfig(IClientConfig clientConfig) { - ((CountingConfig) clientConfig).count++; - super.initWithNiwsConfig(clientConfig); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactoryTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactoryTests.java deleted file mode 100644 index 5307a7c4a..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactoryTests.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.net.URI; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.loadbalancer.LoadBalanced; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpStatus; -import org.springframework.http.RequestEntity; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.ResourceAccessException; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = RibbonClientHttpRequestFactoryTests.App.class, - webEnvironment = RANDOM_PORT, - value = { "spring.application.name=ribbonclienttest", "spring.jmx.enabled=true", - "spring.cloud.netflix.metrics.enabled=false", - "ribbon.restclient.enabled=true", "debug=true" }) -@DirtiesContext -public class RibbonClientHttpRequestFactoryTests { - - @Rule - /** - * JUnit rule - */ - public final ExpectedException exceptionRule = ExpectedException.none(); - - @LoadBalanced - @Autowired - protected RestTemplate restTemplate; - - @Test - public void requestFactoryIsRibbon() { - ClientHttpRequestFactory requestFactory = this.restTemplate.getRequestFactory(); - assertThat(requestFactory).isInstanceOf(RibbonClientHttpRequestFactory.class); - } - - @Test - public void vanillaRequestWorks() { - ResponseEntity response = this.restTemplate.getForEntity("http://simple/", - String.class); - assertThat(response.getStatusCode()).as("wrong response code") - .isEqualTo(HttpStatus.OK); - assertThat(response.getBody()).as("wrong response body").isEqualTo("hello"); - } - - @Test - public void requestWithPathParamWorks() { - ResponseEntity response = this.restTemplate - .getForEntity("http://simple/path/{param}", String.class, "world"); - assertThat(response.getStatusCode()).as("wrong response code") - .isEqualTo(HttpStatus.OK); - assertThat(response.getBody()).as("wrong response body").isEqualTo("hello world"); - } - - @Test - public void requestWithEncodedPathParamWorks() { - ResponseEntity response = this.restTemplate.getForEntity( - "http://simple/path/{param}", String.class, "world & everyone else"); - assertThat(response.getStatusCode()).as("wrong response code") - .isEqualTo(HttpStatus.OK); - assertThat(response.getBody()).as("wrong response body") - .isEqualTo("hello world & everyone else"); - } - - @Test - public void requestWithRequestParamWorks() { - ResponseEntity response = this.restTemplate.getForEntity( - "http://simple/request?param={param}", String.class, "world"); - assertThat(response.getStatusCode()).as("wrong response code") - .isEqualTo(HttpStatus.OK); - assertThat(response.getBody()).as("wrong response body").isEqualTo("hello world"); - } - - @Test - public void requestWithPostWorks() { - ResponseEntity response = this.restTemplate - .postForEntity("http://simple/post", "world", String.class); - assertThat(response.getStatusCode()).as("wrong response code") - .isEqualTo(HttpStatus.OK); - assertThat(response.getBody()).as("wrong response body").isEqualTo("hello world"); - } - - @Test - public void requestWithEmptyPostWorks() { - ResponseEntity response = this.restTemplate - .postForEntity("http://simple/emptypost", "", String.class); - assertThat(response.getStatusCode()).as("wrong response code") - .isEqualTo(HttpStatus.OK); - assertThat(response.getBody()).as("wrong response body").isEqualTo("hello empty"); - } - - @Test - public void requestWithHeaderWorks() throws Exception { - RequestEntity entity = RequestEntity.get(new URI("http://simple/header")) - .header("X-Param", "world").build(); - ResponseEntity response = this.restTemplate.exchange(entity, - String.class); - assertThat(response.getStatusCode()).as("wrong response code") - .isEqualTo(HttpStatus.OK); - assertThat(response.getBody()).as("wrong response body").isEqualTo("hello world"); - } - - @Test - public void invalidHostNameError() { - this.exceptionRule.expect(ResourceAccessException.class); - this.exceptionRule.expectMessage("Invalid hostname"); - this.restTemplate.getForEntity("https://simple_bad", String.class); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @RibbonClient(value = "simple", configuration = SimpleRibbonClientConfiguration.class) - public static class App extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.authorizeRequests().anyRequest().permitAll().and().csrf().disable(); - } - - @LoadBalanced - @Bean - RestTemplate restTemplate() { - return new RestTemplate(); - } - - @RequestMapping("/") - public String hi() { - return "hello"; - } - - @RequestMapping("/path/{param}") - public String hiParam(@PathVariable("param") String param) { - return "hello " + param; - } - - @RequestMapping("/request") - public String hiRequest(@RequestParam("param") String param) { - return "hello " + param; - } - - @RequestMapping(value = "/post", method = RequestMethod.POST) - public String hiPost(@RequestBody String param) { - return "hello " + param; - } - - @RequestMapping(value = "/emptypost", method = RequestMethod.POST) - public String hiPostEmpty() { - return "hello empty"; - } - - @RequestMapping("/header") - public String hiHeader(@RequestHeader("X-Param") String param) { - return "hello " + param; - } - - } - - @Configuration(proxyBeanMethods = false) - static class SimpleRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port = 0; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorIntegrationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorIntegrationTests.java deleted file mode 100644 index 28818327d..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorIntegrationTests.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import com.netflix.loadbalancer.ConfigurationBasedServerList; -import com.netflix.loadbalancer.DummyPing; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAvoidanceRule; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessorIntegrationTests.PlainConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = PlainConfiguration.class) -@DirtiesContext -public class RibbonClientPreprocessorIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void ruleDefaultsToZoneAvoidance() throws Exception { - ZoneAvoidanceRule.class.cast(getLoadBalancer().getRule()); - } - - @Test - public void serverListFilterDefaultsToZonePreference() throws Exception { - ZonePreferenceServerListFilter.class.cast(getLoadBalancer().getFilter()); - } - - @Test - public void pingDefaultsToDummy() throws Exception { - DummyPing.class.cast(getLoadBalancer().getPing()); - } - - @Test - public void serverListDefaultsToConfigurationBased() throws Exception { - ConfigurationBasedServerList.class.cast(getLoadBalancer().getServerListImpl()); - } - - @SuppressWarnings("unchecked") - private ZoneAwareLoadBalancer getLoadBalancer() { - return (ZoneAwareLoadBalancer) this.factory.getLoadBalancer("foo"); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient(name = "foo") - @Import({ PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class, - RibbonAutoConfiguration.class }) - protected static class PlainConfiguration { - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorOverridesIntegrationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorOverridesIntegrationTests.java deleted file mode 100644 index a8df3d2a1..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorOverridesIntegrationTests.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ConfigurationBasedServerList; -import com.netflix.loadbalancer.DummyPing; -import com.netflix.loadbalancer.IPing; -import com.netflix.loadbalancer.IRule; -import com.netflix.loadbalancer.PingConstant; -import com.netflix.loadbalancer.RandomRule; -import com.netflix.loadbalancer.RoundRobinRule; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.loadbalancer.ServerListFilter; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest( - classes = RibbonClientPreprocessorOverridesIntegrationTests.TestConfiguration.class) -@DirtiesContext -public class RibbonClientPreprocessorOverridesIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void ruleOverridesToRandom() throws Exception { - RandomRule.class.cast(getLoadBalancer("foo").getRule()); - RoundRobinRule.class.cast(getLoadBalancer("bar").getRule()); - } - - @Test - public void pingOverridesToDummy() throws Exception { - DummyPing.class.cast(getLoadBalancer("foo").getPing()); - PingConstant.class.cast(getLoadBalancer("bar").getPing()); - } - - @Test - public void serverListOverridesToMy() throws Exception { - FooServiceList.class.cast(getLoadBalancer("foo").getServerListImpl()); - BarServiceList.class.cast(getLoadBalancer("bar").getServerListImpl()); - } - - @SuppressWarnings("unchecked") - private ZoneAwareLoadBalancer getLoadBalancer(String name) { - return (ZoneAwareLoadBalancer) this.factory.getLoadBalancer(name); - } - - @Test - public void serverListFilterOverride() throws Exception { - ServerListFilter filter = getLoadBalancer("foo").getFilter(); - assertThat(ZonePreferenceServerListFilter.class.cast(filter).getZone()) - .isEqualTo("FooTestZone"); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClients({ @RibbonClient(name = "foo", configuration = FooConfiguration.class), - @RibbonClient(name = "bar", configuration = BarConfiguration.class) }) - @Import({ UtilAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, - ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class }) - protected static class TestConfiguration { - - } - - @Configuration(proxyBeanMethods = false) - public static class FooConfiguration { - - @Bean - public IRule ribbonRule() { - return new RandomRule(); - } - - @Bean - public IPing ribbonPing() { - return new DummyPing(); - } - - @Bean - public ServerList ribbonServerList(IClientConfig config) { - return new FooServiceList(config); - } - - @Bean - public ZonePreferenceServerListFilter serverListFilter() { - ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - filter.setZone("FooTestZone"); - return filter; - } - - } - - public static class FooServiceList extends ConfigurationBasedServerList { - - public FooServiceList(IClientConfig config) { - super.initWithNiwsConfig(config); - } - - } - - @Configuration(proxyBeanMethods = false) - public static class BarConfiguration { - - @Bean - public IRule ribbonRule() { - return new RoundRobinRule(); - } - - @Bean - public IPing ribbonPing() { - return new PingConstant(); - } - - @Bean - public ServerList ribbonServerList(IClientConfig config) { - return new BarServiceList(config); - } - - @Bean - public ZonePreferenceServerListFilter serverListFilter() { - ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - filter.setZone("BarTestZone"); - return filter; - } - - } - - public static class BarServiceList extends ConfigurationBasedServerList { - - public BarServiceList(IClientConfig config) { - super.initWithNiwsConfig(config); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorOverridesRetryTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorOverridesRetryTests.java deleted file mode 100644 index 85fe76559..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorOverridesRetryTests.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.net.ConnectException; -import java.net.SocketException; -import java.net.SocketTimeoutException; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.List; - -import com.netflix.client.DefaultLoadBalancerRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Tyler Van Gorder - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest( - classes = RibbonClientPreprocessorOverridesRetryTests.TestConfiguration.class, - value = { "customRetry.ribbon.MaxAutoRetries=0", - "customRetry.ribbon.MaxAutoRetriesNextServer=1", - "customRetry.ribbon.OkToRetryOnAllOperations=true" }) -@DirtiesContext -public class RibbonClientPreprocessorOverridesRetryTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void customRetryIsConfigured() throws Exception { - RibbonLoadBalancerContext context = (RibbonLoadBalancerContext) this.factory - .getLoadBalancerContext("customRetry"); - assertThat(context.getRetryHandler()) - .isInstanceOf(RetryRibbonConfiguration.CustomRetryHandler.class); - assertThat(context.getRetryHandler().getMaxRetriesOnSameServer()).isEqualTo(0); - assertThat(context.getRetryHandler().getMaxRetriesOnNextServer()).isEqualTo(1); - assertThat(context.getRetryHandler() - .isCircuitTrippingException(new UnknownHostException("Unknown Host"))) - .isTrue(); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClient(name = "customRetry", configuration = RetryRibbonConfiguration.class) - @Import({ PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class, - RibbonAutoConfiguration.class }) - protected static class TestConfiguration { - - } - -} - -@Configuration(proxyBeanMethods = false) -class RetryRibbonConfiguration { - - @Bean - public RetryHandler retryHandler(IClientConfig config) { - return new CustomRetryHandler(config); - } - - class CustomRetryHandler extends DefaultLoadBalancerRetryHandler { - - @SuppressWarnings("unchecked") - private List> retriable = new ArrayList() { - { - add(UnknownHostException.class); - add(ConnectException.class); - add(SocketTimeoutException.class); - } - }; - - @SuppressWarnings("unchecked") - private List> circuitRelated = new ArrayList() { - { - add(UnknownHostException.class); - add(SocketException.class); - add(SocketTimeoutException.class); - } - }; - - CustomRetryHandler(IClientConfig config) { - super(config); - } - - @Override - protected List> getRetriableExceptions() { - return retriable; - } - - @Override - protected List> getCircuitRelatedExceptions() { - return circuitRelated; - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorPropertiesOverridesIntegrationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorPropertiesOverridesIntegrationTests.java deleted file mode 100644 index 8420225bc..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientPreprocessorPropertiesOverridesIntegrationTests.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import com.netflix.loadbalancer.ConfigurationBasedServerList; -import com.netflix.loadbalancer.DummyPing; -import com.netflix.loadbalancer.NoOpPing; -import com.netflix.loadbalancer.RandomRule; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerListSubsetFilter; -import com.netflix.loadbalancer.ZoneAvoidanceRule; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.test.TestLoadBalancer; -import org.springframework.cloud.netflix.ribbon.test.TestServerList; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.junit.Assume.assumeThat; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest( - classes = RibbonClientPreprocessorPropertiesOverridesIntegrationTests.TestConfiguration.class) -@DirtiesContext -public class RibbonClientPreprocessorPropertiesOverridesIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void ruleOverridesToRandom() throws Exception { - assumeNotTravis(); - RandomRule.class.cast(getLoadBalancer("foo2").getRule()); - ZoneAvoidanceRule.class.cast(getLoadBalancer("bar").getRule()); - } - - // TODO: why do these tests fail in travis? - void assumeNotTravis() { - assumeThat("running in travis, skipping", System.getenv("TRAVIS"), - is(not(equalTo("true")))); - } - - @Test - public void pingOverridesToNoOp() throws Exception { - NoOpPing.class.cast(getLoadBalancer("foo2").getPing()); - DummyPing.class.cast(getLoadBalancer("bar").getPing()); - } - - @Test - public void serverListOverridesToTest() throws Exception { - assumeNotTravis(); - TestServerList.class.cast(getLoadBalancer("foo2").getServerListImpl()); - ConfigurationBasedServerList.class - .cast(getLoadBalancer("bar").getServerListImpl()); - } - - @Test - public void loadBalancerOverridesToTest() throws Exception { - TestLoadBalancer.class.cast(getLoadBalancer("foo2")); - ZoneAwareLoadBalancer.class.cast(getLoadBalancer("bar")); - } - - @Test - public void serverListFilterOverride() throws Exception { - assumeNotTravis(); - ServerListSubsetFilter.class.cast(getLoadBalancer("foo2").getFilter()); - ZonePreferenceServerListFilter.class.cast(getLoadBalancer("bar").getFilter()); - } - - @SuppressWarnings("unchecked") - private ZoneAwareLoadBalancer getLoadBalancer(String name) { - return (ZoneAwareLoadBalancer) this.factory.getLoadBalancer(name); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClients - @Import({ UtilAutoConfiguration.class, HttpClientConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class, - RibbonAutoConfiguration.class }) - protected static class TestConfiguration { - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsEagerInitializationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsEagerInitializationTests.java deleted file mode 100644 index d615f29da..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsEagerInitializationTests.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.ribbon; - -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Biju Kunjummen - */ - -@RunWith(SpringRunner.class) -@SpringBootTest(properties = { "ribbon.eager-load.enabled=true", - "ribbon.eager-load.clients=testspec1,testspec2" }) -@DirtiesContext -public class RibbonClientsEagerInitializationTests { - - @Test - public void contextsShouldBeInitialized() { - assertThat(Foo1.getInstanceCount()).isEqualTo(2); - } - - static class FooConfig { - - @Bean - public Foo1 foo() { - return new Foo1(); - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RibbonClients({ @RibbonClient(name = "testspec1", configuration = FooConfig.class), - @RibbonClient(name = "testspec2", configuration = FooConfig.class), - @RibbonClient(name = "testspec3", configuration = FooConfig.class) }) - static class RibbonConfig { - - } - - static class Foo1 { - - private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger(); - - Foo1() { - INSTANCE_COUNT.incrementAndGet(); - } - - public static int getInstanceCount() { - return INSTANCE_COUNT.get(); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsPreprocessorIntegrationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsPreprocessorIntegrationTests.java deleted file mode 100644 index ea58ac6f4..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsPreprocessorIntegrationTests.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import com.netflix.loadbalancer.IPing; -import com.netflix.loadbalancer.PingUrl; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAvoidanceRule; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClientsPreprocessorIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = TestConfiguration.class) -@DirtiesContext -public class RibbonClientsPreprocessorIntegrationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void ruleDefaultsToZoneAvoidance() throws Exception { - ZoneAvoidanceRule.class.cast(getLoadBalancer().getRule()); - } - - @SuppressWarnings("unchecked") - private ZoneAwareLoadBalancer getLoadBalancer() { - return (ZoneAwareLoadBalancer) this.factory.getLoadBalancer("foo"); - } - - @Test - public void serverListFilterOverride() throws Exception { - assertThat(ZonePreferenceServerListFilter.class - .cast(getLoadBalancer().getFilter()).getZone()).isEqualTo("myTestZone"); - } - - @Test - public void pingOverride() throws Exception { - assertThat(getLoadBalancer().getPing()).isInstanceOf(PingUrl.class); - } - - @Configuration(proxyBeanMethods = false) - @RibbonClients(@RibbonClient(name = "foo", configuration = FooConfiguration.class)) - @Import({ UtilAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, - ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class, - HttpClientConfiguration.class }) - protected static class TestConfiguration { - - } - - // tag::sample_override_ribbon_config[] - @Configuration(proxyBeanMethods = false) - protected static class FooConfiguration { - - @Bean - public ZonePreferenceServerListFilter serverListFilter() { - ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - filter.setZone("myTestZone"); - return filter; - } - - @Bean - public IPing ribbonPing() { - return new PingUrl(); - } - - } - // end::sample_override_ribbon_config[] - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonDisabledTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonDisabledTests.java deleted file mode 100644 index 82bcce37b..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonDisabledTests.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.cloud.test.ModifiedClassPathRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - * @author Biju Kunjummen - */ -@RunWith(ModifiedClassPathRunner.class) -@ClassPathExclusions({ "ribbon-{version:\\d.*}.jar" }) -public class RibbonDisabledTests { - - @Test - public void testRibbonDisabled() { - new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(RibbonAutoConfiguration.class)) - .run(context -> { - assertThat(context.getBeanNamesForType(SpringClientFactory.class)) - .hasSize(0); - }); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptorTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptorTests.java deleted file mode 100644 index 26303ccf3..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptorTests.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.io.IOException; -import java.net.URI; -import java.net.URL; - -import com.netflix.loadbalancer.Server; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; -import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor; -import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.RibbonServer; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.client.support.HttpRequestWrapper; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.util.UriComponentsBuilder; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.verify; - -/** - * @author Spencer Gibb - */ -public class RibbonInterceptorTests { - - @Mock - private HttpRequest request; - - @Mock - private ClientHttpRequestExecution execution; - - @Mock - private ClientHttpResponse response; - - @Before - public void init() { - MockitoAnnotations.initMocks(this); - } - - @Test - public void testIntercept() throws Exception { - RibbonServer server = new RibbonServer("myservice", new Server("myhost", 8080)); - LoadBalancerInterceptor interceptor = new LoadBalancerInterceptor( - new MyClient(server)); - given(this.request.getURI()).willReturn(new URL("https://myservice").toURI()); - given(this.execution.execute(isA(HttpRequest.class), isA(byte[].class))) - .willReturn(this.response); - ArgumentCaptor argument = ArgumentCaptor - .forClass(HttpRequestWrapper.class); - ClientHttpResponse response = interceptor.intercept(this.request, new byte[0], - this.execution); - assertThat(response).as("response was null").isNotNull(); - verify(this.execution).execute(argument.capture(), isA(byte[].class)); - HttpRequestWrapper wrapper = argument.getValue(); - assertThat(wrapper.getURI()).as("wrong constructed uri") - .isEqualTo(new URL("https://myhost:8080").toURI()); - } - - protected static class MyClient implements LoadBalancerClient { - - private ServiceInstance instance; - - public MyClient(ServiceInstance instance) { - this.instance = instance; - } - - @Override - public ServiceInstance choose(String serviceId) { - return this.instance; - } - - @Override - public T execute(String serviceId, LoadBalancerRequest request) { - try { - return request.apply(this.instance); - } - catch (Exception ex) { - ReflectionUtils.rethrowRuntimeException(ex); - } - return null; - } - - @Override - public T execute(String s, ServiceInstance serviceInstance, - LoadBalancerRequest request) throws IOException { - try { - return request.apply(this.instance); - } - catch (Exception ex) { - ReflectionUtils.rethrowRuntimeException(ex); - } - return null; - } - - @Override - public URI reconstructURI(ServiceInstance instance, URI original) { - return UriComponentsBuilder.fromUri(original).host(instance.getHost()) - .port(instance.getPort()).build().toUri(); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryFactoryTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryFactoryTests.java deleted file mode 100644 index 15e9cf65f..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryFactoryTests.java +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.io.IOException; -import java.net.SocketException; -import java.util.Collections; -import java.util.Map; - -import com.netflix.client.DefaultLoadBalancerRetryHandler; -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.BaseLoadBalancer; -import com.netflix.loadbalancer.LoadBalancerStats; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerStats; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.RibbonServer; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpRequest; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -/** - * @author Ryan Baxter - */ -public class RibbonLoadBalancedRetryFactoryTests { - - @Mock - private SpringClientFactory clientFactory; - - @Mock - private BaseLoadBalancer loadBalancer; - - @Mock - private LoadBalancerStats loadBalancerStats; - - @Mock - private ServerStats serverStats; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - given(this.clientFactory.getLoadBalancerContext(anyString())) - .willReturn(new RibbonLoadBalancerContext(this.loadBalancer)); - given(this.clientFactory.getInstance(anyString(), eq(ServerIntrospector.class))) - .willReturn(new DefaultServerIntrospector() { - @Override - public Map getMetadata(Server server) { - return Collections.singletonMap("mykey", "myvalue"); - } - }); - - } - - @After - public void tearDown() throws Exception { - } - - @Test - public void testGetRetryPolicyNoRetry() throws Exception { - int sameServer = 0; - int nextServer = 0; - boolean retryOnAllOps = false; - RibbonServer server = getRibbonServer(); - IClientConfig config = mock(IClientConfig.class); - doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), - anyInt()); - doReturn(sameServer).when(config) - .getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetries), anyInt()); - doReturn(nextServer).when(config) - .get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(nextServer).when(config).getPropertyAsInteger( - eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(retryOnAllOps).when(config) - .get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean()); - doReturn(retryOnAllOps).when(config).getPropertyAsBoolean( - eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean()); - doReturn("").when(config).getPropertyAsString( - eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq("")); - doReturn(server.getServiceId()).when(config).getClientName(); - doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId())); - clientFactory.getLoadBalancerContext(server.getServiceId()) - .setRetryHandler(new DefaultLoadBalancerRetryHandler(config)); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - RibbonLoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory); - LoadBalancedRetryPolicy policy = factory.createRetryPolicy(server.getServiceId(), - client); - HttpRequest request = mock(HttpRequest.class); - doReturn(HttpMethod.GET).when(request).getMethod(); - LoadBalancedRetryContext context = new LoadBalancedRetryContext(null, request); - assertThat(policy.canRetryNextServer(context)).isTrue(); - assertThat(policy.canRetrySameServer(context)).isFalse(); - assertThat(policy.retryableStatusCode(400)).isFalse(); - } - - @Test - public void testGetRetryPolicyNotGet() throws Exception { - int sameServer = 3; - int nextServer = 3; - boolean retryOnAllOps = false; - RibbonServer server = getRibbonServer(); - IClientConfig config = mock(IClientConfig.class); - doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), - anyInt()); - doReturn(sameServer).when(config) - .getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetries), anyInt()); - doReturn(nextServer).when(config) - .get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(nextServer).when(config).getPropertyAsInteger( - eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(retryOnAllOps).when(config) - .get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean()); - doReturn(retryOnAllOps).when(config).getPropertyAsBoolean( - eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean()); - doReturn("").when(config).getPropertyAsString( - eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq("")); - doReturn(server.getServiceId()).when(config).getClientName(); - doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId())); - clientFactory.getLoadBalancerContext(server.getServiceId()) - .setRetryHandler(new DefaultLoadBalancerRetryHandler(config)); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - RibbonLoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory); - LoadBalancedRetryPolicy policy = factory.createRetryPolicy(server.getServiceId(), - client); - HttpRequest request = mock(HttpRequest.class); - doReturn(HttpMethod.POST).when(request).getMethod(); - LoadBalancedRetryContext context = new LoadBalancedRetryContext(null, request); - assertThat(policy.canRetryNextServer(context)).isFalse(); - assertThat(policy.canRetrySameServer(context)).isFalse(); - assertThat(policy.retryableStatusCode(400)).isFalse(); - } - - @Test - public void testGetRetryPolicyRetryOnNonGet() throws Exception { - int sameServer = 3; - int nextServer = 3; - boolean retryOnAllOps = true; - RibbonServer server = getRibbonServer(); - IClientConfig config = mock(IClientConfig.class); - doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), - anyInt()); - doReturn(sameServer).when(config) - .getPropertyAsInteger(eq(CommonClientConfigKey.MaxAutoRetries), anyInt()); - doReturn(nextServer).when(config) - .get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(nextServer).when(config).getPropertyAsInteger( - eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(retryOnAllOps).when(config) - .get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean()); - doReturn(retryOnAllOps).when(config).getPropertyAsBoolean( - eq(CommonClientConfigKey.OkToRetryOnAllOperations), anyBoolean()); - doReturn("").when(config).getPropertyAsString( - eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq("")); - doReturn(server.getServiceId()).when(config).getClientName(); - doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId())); - clientFactory.getLoadBalancerContext(server.getServiceId()) - .initWithNiwsConfig(config); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - RibbonLoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory); - LoadBalancedRetryPolicy policy = factory.createRetryPolicy(server.getServiceId(), - client); - HttpRequest request = mock(HttpRequest.class); - doReturn(HttpMethod.POST).when(request).getMethod(); - LoadBalancedRetryContext context = new LoadBalancedRetryContext(null, request); - assertThat(policy.canRetryNextServer(context)).isTrue(); - assertThat(policy.canRetrySameServer(context)).isTrue(); - assertThat(policy.retryableStatusCode(400)).isFalse(); - } - - @Test - public void testGetRetryPolicyRetryCount() throws Exception { - int sameServer = 3; - int nextServer = 3; - RibbonServer server = getRibbonServer(); - IClientConfig config = mock(IClientConfig.class); - doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), - anyInt()); - doReturn(nextServer).when(config) - .get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(false).when(config) - .get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false)); - doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId())); - doReturn("").when(config).getPropertyAsString( - eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq("")); - clientFactory.getLoadBalancerContext(server.getServiceId()) - .setRetryHandler(new DefaultLoadBalancerRetryHandler(config)); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - RibbonLoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory); - LoadBalancedRetryPolicy policy = factory.createRetryPolicy(server.getServiceId(), - client); - HttpRequest request = mock(HttpRequest.class); - doReturn(HttpMethod.GET).when(request).getMethod(); - LoadBalancedRetryContext context = spy( - new LoadBalancedRetryContext(null, request)); - // Loop through as if we are retrying a request until we exhaust the number of - // retries - // outer loop is for next server retries - // inner loop is for same server retries - for (int i = 0; i < nextServer + 1; i++) { - // iterate once time beyond the same server retry limit to cause us to reset - // the same sever counter and increment the next server counter - for (int j = 0; j < sameServer + 1; j++) { - if (j < 3) { - assertThat(policy.canRetrySameServer(context)).isTrue(); - } - else { - assertThat(policy.canRetrySameServer(context)).isFalse(); - } - policy.registerThrowable(context, new IOException()); - } - if (i < 3) { - assertThat(policy.canRetryNextServer(context)).isTrue(); - } - else { - assertThat(policy.canRetryNextServer(context)).isFalse(); - } - } - assertThat(context.isExhaustedOnly()).isTrue(); - assertThat(policy.retryableStatusCode(400)).isFalse(); - verify(context, times(4)).setServiceInstance(any(ServiceInstance.class)); - } - - @Test - public void testCiruitRelatedExceptionsUpdateServerStats() throws Exception { - int sameServer = 3; - int nextServer = 3; - - RibbonServer server = getRibbonServer(); - IClientConfig config = mock(IClientConfig.class); - - doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), - anyInt()); - doReturn(nextServer).when(config) - .get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(false).when(config) - .get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false)); - doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId())); - doReturn("").when(config).getPropertyAsString( - eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq("")); - clientFactory.getLoadBalancerContext(server.getServiceId()) - .setRetryHandler(new DefaultLoadBalancerRetryHandler(config)); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - - RibbonLoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory); - LoadBalancedRetryPolicy policy = factory.createRetryPolicy(server.getServiceId(), - client); - HttpRequest request = mock(HttpRequest.class); - - LoadBalancedRetryContext context = spy( - new LoadBalancedRetryContext(null, request)); - doReturn(server).when(context).getServiceInstance(); - - policy.registerThrowable(context, new IOException()); - verify(serverStats, times(0)).incrementSuccessiveConnectionFailureCount(); - - // Circuit Related should increment failure count - policy.registerThrowable(context, new SocketException()); - verify(serverStats, times(1)).incrementSuccessiveConnectionFailureCount(); - } - - @Test - public void testRetryableStatusCodes() throws Exception { - int sameServer = 3; - int nextServer = 3; - RibbonServer server = getRibbonServer(); - IClientConfig config = mock(IClientConfig.class); - doReturn(sameServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), - anyInt()); - doReturn(nextServer).when(config) - .get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); - doReturn(false).when(config) - .get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false)); - doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId())); - doReturn("404, 418,502,foo, ,").when(config).getPropertyAsString( - eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq("")); - clientFactory.getLoadBalancerContext(server.getServiceId()) - .setRetryHandler(new DefaultLoadBalancerRetryHandler(config)); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - RibbonLoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory); - LoadBalancedRetryPolicy policy = factory.createRetryPolicy(server.getServiceId(), - client); - HttpRequest request = mock(HttpRequest.class); - doReturn(HttpMethod.GET).when(request).getMethod(); - assertThat(policy.retryableStatusCode(400)).isFalse(); - assertThat(policy.retryableStatusCode(404)).isTrue(); - assertThat(policy.retryableStatusCode(418)).isTrue(); - assertThat(policy.retryableStatusCode(502)).isTrue(); - } - - protected RibbonLoadBalancerClient getRibbonLoadBalancerClient( - RibbonServer ribbonServer) { - given(this.loadBalancer.getName()).willReturn(ribbonServer.getServiceId()); - given(this.loadBalancer.chooseServer(any())).willReturn(ribbonServer.getServer()); - given(this.loadBalancer.getLoadBalancerStats()) - .willReturn(this.loadBalancerStats); - given(this.loadBalancerStats.getSingleServerStat(ribbonServer.getServer())) - .willReturn(this.serverStats); - given(this.clientFactory.getLoadBalancer(this.loadBalancer.getName())) - .willReturn(this.loadBalancer); - return new RibbonLoadBalancerClient(this.clientFactory); - } - - protected RibbonServer getRibbonServer() { - return new RibbonServer("testService", new Server("myhost", 9080), false, - Collections.singletonMap("mykey", "myvalue")); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClientTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClientTests.java deleted file mode 100644 index 83db9b2c7..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClientTests.java +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.io.IOException; -import java.net.URI; -import java.net.URL; -import java.util.Collections; -import java.util.Map; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.BaseLoadBalancer; -import com.netflix.loadbalancer.LoadBalancerStats; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerStats; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.RibbonServer; -import org.springframework.web.util.DefaultUriBuilderFactory; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyDouble; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.same; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * @author Spencer Gibb - * @author Tim Ysewyn - */ -public class RibbonLoadBalancerClientTests { - - @Mock - private SpringClientFactory clientFactory; - - @Mock - private BaseLoadBalancer loadBalancer; - - @Mock - private LoadBalancerStats loadBalancerStats; - - @Mock - private ServerStats serverStats; - - private Server server = null; - - @Before - public void init() { - server = null; - MockitoAnnotations.initMocks(this); - given(this.clientFactory.getLoadBalancerContext(anyString())) - .willReturn(new RibbonLoadBalancerContext(this.loadBalancer)); - given(this.clientFactory.getInstance(anyString(), eq(ServerIntrospector.class))) - .willReturn(new DefaultServerIntrospector() { - - @Override - public boolean isSecure(Server server) { - RibbonLoadBalancerClientTests.this.server = server; - return super.isSecure(server); - } - - @Override - public Map getMetadata(Server server) { - return Collections.singletonMap("mykey", "myvalue"); - } - }); - } - - @Test - public void reconstructURI() throws Exception { - testReconstructURI("http"); - } - - @Test - public void reconstructSecureURI() throws Exception { - testReconstructURI("https"); - } - - private void testReconstructURI(String scheme) throws Exception { - RibbonServer server = getRibbonServer(); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - ServiceInstance serviceInstance = client.choose(server.getServiceId()); - URI uri = client.reconstructURI(serviceInstance, - new URL(scheme + "://" + server.getServiceId()).toURI()); - assertThat(uri).hasScheme(scheme).hasHost(serviceInstance.getHost()) - .hasPort(serviceInstance.getPort()); - assertThat(this.server).isNotNull().isInstanceOf(MyServer.class); - } - - @Test - public void testReconstructSecureUriWithSpecialCharsPath() { - testReconstructUriWithPath("https", "/foo=|"); - } - - @Test - public void testReconstructUnsecureUriWithSpecialCharsPath() { - testReconstructUriWithPath("http", "/foo=|"); - } - - private void testReconstructUriWithPath(String scheme, String path) { - RibbonServer server = getRibbonServer(); - IClientConfig config = mock(IClientConfig.class); - when(config.get(CommonClientConfigKey.IsSecure)).thenReturn(true); - when(clientFactory.getClientConfig(server.getServiceId())).thenReturn(config); - - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - ServiceInstance serviceInstance = client.choose(server.getServiceId()); - - URI expanded = new DefaultUriBuilderFactory() - .expand(scheme + "://" + server.getServiceId() + path); - URI reconstructed = client.reconstructURI(serviceInstance, expanded); - assertThat(reconstructed).hasPath(path); - } - - @Test - public void testReconstructHonorsRibbonServerScheme() { - RibbonServer server = new RibbonServer("testService", - new Server("ws", "myhost", 9080), false, - Collections.singletonMap("mykey", "myvalue")); - - IClientConfig config = mock(IClientConfig.class); - when(config.get(CommonClientConfigKey.IsSecure)).thenReturn(false); - when(clientFactory.getClientConfig(server.getServiceId())).thenReturn(config); - - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - ServiceInstance serviceInstance = client.choose(server.getServiceId()); - URI uri = client.reconstructURI(serviceInstance, - URI.create("http://testService")); - - assertThat(uri).hasScheme("ws").hasHost("myhost").hasPort(9080); - } - - @Test - public void testReconstructUriWithSecureClientConfig() throws Exception { - RibbonServer server = getRibbonServer(); - IClientConfig config = mock(IClientConfig.class); - when(config.get(CommonClientConfigKey.IsSecure)).thenReturn(true); - when(clientFactory.getClientConfig(server.getServiceId())).thenReturn(config); - - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - ServiceInstance serviceInstance = client.choose(server.getServiceId()); - URI uri = client.reconstructURI(serviceInstance, - new URL("http://" + server.getServiceId()).toURI()); - assertThat(uri.getHost()).isEqualTo(server.getHost()); - assertThat(uri.getPort()).isEqualTo(server.getPort()); - assertThat(uri.getScheme()).isEqualTo("https"); - } - - @Test - public void testReconstructSecureUriWithoutScheme() throws Exception { - testReconstructSchemelessUriWithoutClientConfig(getSecureRibbonServer(), "https"); - } - - @Test - public void testReconstructUnsecureSchemelessUri() throws Exception { - testReconstructSchemelessUriWithoutClientConfig(getRibbonServer(), "http"); - } - - public void testReconstructSchemelessUriWithoutClientConfig(RibbonServer server, - String expectedScheme) throws Exception { - IClientConfig config = mock(IClientConfig.class); - when(config.get(CommonClientConfigKey.IsSecure)).thenReturn(null); - when(clientFactory.getClientConfig(server.getServiceId())).thenReturn(config); - - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - ServiceInstance serviceInstance = client.choose(server.getServiceId()); - URI uri = client.reconstructURI(serviceInstance, - new URI("//" + server.getServiceId())); - assertThat(uri.getHost()).isEqualTo(server.getHost()); - assertThat(uri.getPort()).isEqualTo(server.getPort()); - assertThat(uri.getScheme()).isEqualTo(expectedScheme); - } - - @Test - public void testChoose() { - RibbonServer server = getRibbonServer(); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - ServiceInstance serviceInstance = client.choose(server.getServiceId()); - assertServiceInstance(server, serviceInstance); - verify(this.loadBalancer).chooseServer(eq("default")); - } - - @Test - public void testChooseWithHint() { - Object hint = new Object(); - RibbonServer server = getRibbonServer(); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - ServiceInstance serviceInstance = client.choose(server.getServiceId(), hint); - assertServiceInstance(server, serviceInstance); - verify(this.loadBalancer).chooseServer(same(hint)); - } - - @Test - public void testChooseMissing() { - given(this.clientFactory.getLoadBalancer(this.loadBalancer.getName())) - .willReturn(null); - given(this.loadBalancer.getName()).willReturn("missingservice"); - RibbonLoadBalancerClient client = new RibbonLoadBalancerClient( - this.clientFactory); - ServiceInstance instance = client.choose("missingservice"); - assertThat(instance).as("instance wasn't null").isNull(); - } - - @Test - public void testExecute() throws IOException { - final RibbonServer server = getRibbonServer(); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - final String returnVal = "myval"; - Object actualReturn = client.execute(server.getServiceId(), - (LoadBalancerRequest) instance -> { - assertServiceInstance(server, instance); - return returnVal; - }); - verifyServerStats(); - verify(this.loadBalancer).chooseServer(eq("default")); - assertThat(actualReturn).as("retVal was wrong").isEqualTo(returnVal); - } - - @Test - public void testExecuteWithHint() throws IOException { - Object hint = new Object(); - final RibbonServer server = getRibbonServer(); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); - final String returnVal = "myval"; - Object actualReturn = client.execute(server.getServiceId(), - (LoadBalancerRequest) instance -> { - assertServiceInstance(server, instance); - return returnVal; - }, hint); - verifyServerStats(); - verify(this.loadBalancer).chooseServer(same(hint)); - assertThat(actualReturn).as("retVal was wrong").isEqualTo(returnVal); - } - - @Test - public void testExecuteException() { - final RibbonServer ribbonServer = getRibbonServer(); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(ribbonServer); - try { - client.execute(ribbonServer.getServiceId(), instance -> { - assertServiceInstance(ribbonServer, instance); - throw new RuntimeException(); - }); - fail("Should have thrown exception"); - } - catch (Exception ex) { - assertThat(ex).isNotNull(); - } - verifyServerStats(); - } - - @Test - public void testExecuteIOException() { - final RibbonServer ribbonServer = getRibbonServer(); - RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(ribbonServer); - try { - client.execute(ribbonServer.getServiceId(), instance -> { - assertServiceInstance(ribbonServer, instance); - throw new IOException(); - }); - fail("Should have thrown exception"); - } - catch (Exception ex) { - assertThat(ex).isInstanceOf(IOException.class); - } - verifyServerStats(); - } - - protected RibbonServer getRibbonServer() { - return new RibbonServer("testService", new MyServer("myhost", 9080), false, - Collections.singletonMap("mykey", "myvalue")); - } - - protected RibbonServer getSecureRibbonServer() { - return new RibbonServer("testService", new MyServer("myhost", 8443), false, - Collections.singletonMap("mykey", "myvalue")); - } - - protected void verifyServerStats() { - verify(this.serverStats).incrementActiveRequestsCount(); - verify(this.serverStats).decrementActiveRequestsCount(); - verify(this.serverStats).incrementNumRequests(); - verify(this.serverStats).noteResponseTime(anyDouble()); - } - - protected void assertServiceInstance(RibbonServer ribbonServer, - ServiceInstance instance) { - assertThat(instance).as("instance was null").isNotNull(); - assertThat(instance.getInstanceId()).as("instanceId was wrong") - .isEqualTo(ribbonServer.getInstanceId()); - assertThat(instance.getServiceId()).as("serviceId was wrong") - .isEqualTo(ribbonServer.getServiceId()); - assertThat(instance.getHost()).as("host was wrong") - .isEqualTo(ribbonServer.getHost()); - assertThat(instance.getPort()).as("port was wrong") - .isEqualTo(ribbonServer.getPort()); - assertThat(instance.getMetadata().get("mykey")).as("missing metadata") - .isEqualTo(ribbonServer.getMetadata().get("mykey")); - } - - protected RibbonLoadBalancerClient getRibbonLoadBalancerClient( - RibbonServer ribbonServer) { - given(this.loadBalancer.getName()).willReturn(ribbonServer.getServiceId()); - given(this.loadBalancer.chooseServer(any())).willReturn(ribbonServer.getServer()); - given(this.loadBalancer.getLoadBalancerStats()) - .willReturn(this.loadBalancerStats); - given(this.loadBalancerStats.getSingleServerStat(ribbonServer.getServer())) - .willReturn(this.serverStats); - given(this.clientFactory.getLoadBalancer(this.loadBalancer.getName())) - .willReturn(this.loadBalancer); - return new RibbonLoadBalancerClient(this.clientFactory); - } - - protected static class MyServer extends Server { - - public MyServer(String host, int port) { - super(host, port); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonPropertiesTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonPropertiesTests.java deleted file mode 100644 index eedb037bc..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonPropertiesTests.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -public class RibbonPropertiesTests { - - @Test - public void poolKeepAliveWorksWithString() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.setProperty(CommonClientConfigKey.PoolKeepAliveTime, "714"); - RibbonProperties properties = new RibbonProperties(config); - assertThat(properties.poolKeepAliveTime()).isEqualTo(714L); - assertThat(properties.getPoolKeepAliveTime()).isEqualTo(714L); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonUtilsTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonUtilsTests.java deleted file mode 100644 index 6f893fb85..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonUtilsTests.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Map; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.loadbalancer.Server; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.isSecure; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToSecureConnectionIfNeeded; - -/** - * @author Spencer Gibb - * @author Jacques-Etienne Beaudet - * @author Tim Ysewyn - */ -public class RibbonUtilsTests { - - private static final ServerIntrospector NON_SECURE_INTROSPECTOR = new StaticServerIntrospector( - false); - - private static final ServerIntrospector SECURE_INTROSPECTOR = new StaticServerIntrospector( - true); - - private static final Server SERVER = new Server("localhost", 8080); - - private static final DefaultClientConfigImpl SECURE_CONFIG = getConfig(true); - - private static final DefaultClientConfigImpl NON_SECURE_CONFIG = getConfig(false); - - private static final DefaultClientConfigImpl NO_IS_SECURE_CONFIG = new DefaultClientConfigImpl(); - - @Test - public void noRibbonPropSecureIntrospector() { - boolean secure = isSecure(NO_IS_SECURE_CONFIG, SECURE_INTROSPECTOR, SERVER); - assertThat(secure).as("isSecure was wrong").isTrue(); - } - - @Test - public void noRibbonPropNonSecureIntrospector() { - boolean secure = isSecure(NO_IS_SECURE_CONFIG, NON_SECURE_INTROSPECTOR, SERVER); - assertThat(secure).as("isSecure was wrong").isFalse(); - } - - @Test - public void isSecureRibbonPropSecureIntrospector() { - boolean secure = isSecure(SECURE_CONFIG, SECURE_INTROSPECTOR, SERVER); - assertThat(secure).as("isSecure was wrong").isTrue(); - } - - @Test - public void nonSecureRibbonPropNonSecureIntrospector() { - boolean secure = isSecure(NON_SECURE_CONFIG, NON_SECURE_INTROSPECTOR, SERVER); - assertThat(secure).as("isSecure was wrong").isFalse(); - } - - @Test - public void isSecureRibbonPropNonSecureIntrospector() { - boolean secure = isSecure(SECURE_CONFIG, NON_SECURE_INTROSPECTOR, SERVER); - assertThat(secure).as("isSecure was wrong").isTrue(); - } - - @Test - public void nonSecureRibbonPropSecureIntrospector() { - boolean secure = isSecure(NON_SECURE_CONFIG, SECURE_INTROSPECTOR, SERVER); - assertThat(secure).as("isSecure was wrong").isFalse(); - } - - @Test - public void uriIsNotChangedWhenServerIsNotSecured() throws URISyntaxException { - URI original = new URI("https://foo"); - URI updated = updateToSecureConnectionIfNeeded(original, NON_SECURE_CONFIG, - NON_SECURE_INTROSPECTOR, SERVER); - assertThat(original) - .as("URI should not have been updated since server is not secured.") - .isEqualTo(updated); - } - - @Test - public void uriIsNotChangedWhenServerIsSecuredAndUriAlreadyInHttps() - throws URISyntaxException { - URI original = new URI("https://foo"); - URI updated = updateToSecureConnectionIfNeeded(original, SECURE_CONFIG, - SECURE_INTROSPECTOR, SERVER); - assertThat(original) - .as("URI should not have been updated since uri is already in https.") - .isEqualTo(updated); - } - - @Test - public void shouldUpgradeUriToHttpsWhenServerIsSecureAndUriNotInHttps() - throws URISyntaxException { - URI original = new URI("https://foo"); - URI updated = updateToSecureConnectionIfNeeded(original, SECURE_CONFIG, - SECURE_INTROSPECTOR, SERVER); - assertThat(updated).as("URI should have been updated to https.") - .isEqualTo(new URI("https://foo")); - } - - @Test - public void shouldUpgradeUriToWssWhenServerIsSecureAndUriNotInWss() - throws URISyntaxException { - URI original = new URI("ws://foo"); - URI updated = updateToSecureConnectionIfNeeded(original, SECURE_CONFIG, - SECURE_INTROSPECTOR, SERVER); - assertThat(updated).as("URI should have been updated to wss.") - .isEqualTo(new URI("wss://foo")); - } - - @Test - public void shouldSubstitutePlusInQueryParam() throws URISyntaxException { - URI original = new URI("http://foo/%20bar?hello=1+2"); - URI updated = updateToSecureConnectionIfNeeded(original, SECURE_CONFIG, - SECURE_INTROSPECTOR, SERVER); - assertThat(updated) - .as("URI should have had its plus sign replaced in query string.") - .isEqualTo(new URI("https://foo/%20bar?hello=1%202")); - } - - @Test - public void emptyStringUri() throws URISyntaxException { - URI original = new URI(""); - URI updated = updateToSecureConnectionIfNeeded(original, SECURE_CONFIG, - SECURE_INTROSPECTOR, SERVER); - assertThat(updated).as("URI should be the emptry string").isEqualTo(new URI("")); - } - - static DefaultClientConfigImpl getConfig(boolean value) { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.setProperty(CommonClientConfigKey.IsSecure, value); - return config; - } - - static class StaticServerIntrospector implements ServerIntrospector { - - final boolean secure; - - StaticServerIntrospector(boolean secure) { - this.secure = secure; - } - - @Override - public boolean isSecure(Server server) { - return this.secure; - } - - @Override - public Map getMetadata(Server server) { - return null; - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringClientFactoryTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringClientFactoryTests.java deleted file mode 100644 index 6e34d41af..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringClientFactoryTests.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import com.netflix.client.DefaultLoadBalancerRetryHandler; -import com.netflix.client.IClientConfigAware; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.niws.client.http.RestClient; -import com.sun.jersey.client.apache4.ApacheHttpClient4; -import org.apache.http.client.params.ClientPNames; -import org.apache.http.client.params.CookiePolicy; -import org.junit.Test; - -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * - */ -public class SpringClientFactoryTests { - - @Test - public void testConfigureRetry() { - SpringClientFactory factory = new SpringClientFactory(); - AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext( - RibbonAutoConfiguration.class, ArchaiusAutoConfiguration.class, - HttpClientConfiguration.class); - TestPropertyValues.of("foo.ribbon.MaxAutoRetries:2").applyTo(parent); - factory.setApplicationContext(parent); - DefaultLoadBalancerRetryHandler retryHandler = (DefaultLoadBalancerRetryHandler) factory - .getLoadBalancerContext("foo").getRetryHandler(); - assertThat(retryHandler.getMaxRetriesOnSameServer()).isEqualTo(2); - parent.close(); - factory.destroy(); - } - - @SuppressWarnings("deprecation") - @Test - public void testCookiePolicy() { - SpringClientFactory factory = new SpringClientFactory(); - AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("ribbon.restclient.enabled=true").applyTo(parent); - parent.register(RibbonAutoConfiguration.class, ArchaiusAutoConfiguration.class); - parent.refresh(); - factory.setApplicationContext(parent); - RestClient client = factory.getClient("foo", RestClient.class); - ApacheHttpClient4 jerseyClient = (ApacheHttpClient4) client.getJerseyClient(); - assertThat(jerseyClient.getClientHandler().getHttpClient().getParams() - .getParameter(ClientPNames.COOKIE_POLICY)) - .isEqualTo(CookiePolicy.IGNORE_COOKIES); - parent.close(); - factory.destroy(); - } - - @Test - public void testInstantiateWithConfigInjectByConstructor() { - IClientConfig clientConfig = new DefaultClientConfigImpl(); - ClientConfigInjectedByConstructor instance = SpringClientFactory - .instantiateWithConfig(ClientConfigInjectedByConstructor.class, - clientConfig); - assertThat(instance.clientConfig).isSameAs(clientConfig); - } - - @Test - public void testInstantiateWithConfigInjectedByInitMethod() { - IClientConfig clientConfig = new DefaultClientConfigImpl(); - ClientConfigInjectedByInitMethod instance = SpringClientFactory - .instantiateWithConfig(ClientConfigInjectedByInitMethod.class, - clientConfig); - assertThat(instance.clientConfig).isSameAs(clientConfig); - } - - @Test - public void testInstantiateWithoutConfig() { - IClientConfig clientConfig = new DefaultClientConfigImpl(); - NoClientConfigAware instance = SpringClientFactory - .instantiateWithConfig(NoClientConfigAware.class, clientConfig); - assertThat(instance).isNotNull(); - } - - public static class ClientConfigInjectedByConstructor { - - private IClientConfig clientConfig; - - public ClientConfigInjectedByConstructor(IClientConfig clientConfig) { - this.clientConfig = clientConfig; - } - - } - - public static class ClientConfigInjectedByInitMethod implements IClientConfigAware { - - private IClientConfig clientConfig; - - @Override - public void initWithNiwsConfig(IClientConfig clientConfig) { - this.clientConfig = clientConfig; - } - - } - - public static class NoClientConfigAware { - - public NoClientConfigAware() { - // no client config - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringRetryDisabledTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringRetryDisabledTests.java deleted file mode 100644 index eb990737a..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringRetryDisabledTests.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.cloud.test.ModifiedClassPathRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - * @author Biju Kunjummen - */ -@RunWith(ModifiedClassPathRunner.class) -@ClassPathExclusions({ "spring-retry-*.jar", "spring-boot-starter-aop-*.jar" }) -public class SpringRetryDisabledTests { - - @Test - public void testLoadBalancedRetryFactoryBean() { - new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(RibbonAutoConfiguration.class, - LoadBalancerAutoConfiguration.class, - RibbonClientConfiguration.class)) - .run(context -> { - Map factories = context - .getBeansOfType(LoadBalancedRetryFactory.class); - assertThat(factories.values()).hasSize(0); - Map clients = context - .getBeansOfType(RibbonLoadBalancingHttpClient.class); - assertThat(clients.values()).hasSize(1); - assertThat(clients.values().toArray()[0]) - .isInstanceOf(RibbonLoadBalancingHttpClient.class); - }); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringRetryEnabledTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringRetryEnabledTests.java deleted file mode 100644 index fbb588742..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/SpringRetryEnabledTests.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.BeansException; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.ribbon.apache.RetryableRibbonLoadBalancingHttpClient; -import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration( - classes = { RibbonAutoConfiguration.class, RibbonClientConfiguration.class, - LoadBalancerAutoConfiguration.class, HttpClientConfiguration.class }) -public class SpringRetryEnabledTests implements ApplicationContextAware { - - private ApplicationContext context; - - @Test - public void testLoadBalancedRetryFactoryBean() throws Exception { - Map factories = context - .getBeansOfType(LoadBalancedRetryFactory.class); - assertThat(factories.values()).hasSize(1); - assertThat(factories.values().toArray()[0]) - .isInstanceOf(RibbonLoadBalancedRetryFactory.class); - Map clients = context - .getBeansOfType(RibbonLoadBalancingHttpClient.class); - assertThat(clients.values()).hasSize(1); - assertThat(clients.values().toArray()[0]) - .isInstanceOf(RetryableRibbonLoadBalancingHttpClient.class); - } - - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - this.context = context; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/ZonePreferenceServerListFilterTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/ZonePreferenceServerListFilterTests.java deleted file mode 100644 index fdb9d77a9..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/ZonePreferenceServerListFilterTests.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon; - -import java.util.Arrays; -import java.util.List; - -import com.netflix.loadbalancer.Server; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - */ -public class ZonePreferenceServerListFilterTests { - - private Server dsyer = new Server("dsyer", 8080); - - private Server localhost = new Server("localhost", 8080); - - @Before - public void init() { - this.dsyer.setZone("dsyer"); - this.localhost.setZone("localhost"); - } - - @Test - public void noZoneSet() { - ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - List result = filter - .getFilteredListOfServers(Arrays.asList(this.localhost)); - assertThat(result.size()).isEqualTo(1); - } - - @Test - public void withZoneSetAndNoMatches() { - ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - ReflectionTestUtils.setField(filter, "zone", "dsyer"); - List result = filter - .getFilteredListOfServers(Arrays.asList(this.localhost)); - assertThat(result.size()).isEqualTo(1); - } - - @Test - public void withZoneSetAndMatches() { - ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); - ReflectionTestUtils.setField(filter, "zone", "dsyer"); - List result = filter - .getFilteredListOfServers(Arrays.asList(this.dsyer, this.localhost)); - assertThat(result.size()).isEqualTo(1); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpRequestTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpRequestTests.java deleted file mode 100644 index 95e38ef74..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpRequestTests.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.apache; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.net.URI; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Collections; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpEntityEnclosingRequest; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.methods.RequestBuilder; -import org.junit.Test; - -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.StreamUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -public class RibbonApacheHttpRequestTests { - - @Test - public void testNullEntity() throws Exception { - String uri = "https://example.com"; - LinkedMultiValueMap headers = new LinkedMultiValueMap<>(); - headers.add("my-header", "my-value"); - headers.add("content-length", "5192"); - LinkedMultiValueMap params = new LinkedMultiValueMap<>(); - params.add("myparam", "myparamval"); - RibbonApacheHttpRequest httpRequest = new RibbonApacheHttpRequest( - new RibbonCommandContext("example", "GET", uri, false, headers, params, - null, new ArrayList())); - - HttpUriRequest request = httpRequest.toRequest(RequestConfig.custom().build()); - - assertThat(request).as("request is wrong type") - .isNotInstanceOf(HttpEntityEnclosingRequest.class); - assertThat(request.getURI().toString()).as("uri is wrong").startsWith(uri); - assertThat(request.getFirstHeader("my-header")).as("my-header is missing") - .isNotNull(); - assertThat(request.getFirstHeader("my-header").getValue()) - .as("my-header is wrong").isEqualTo("my-value"); - assertThat(request.getFirstHeader("content-length").getValue()) - .as("Content-Length is wrong").isEqualTo("5192"); - assertThat(request.getURI().getQuery()).as("myparam is missing") - .isEqualTo("myparam=myparamval"); - - } - - @Test - // this situation happens, see - // https://github.com/spring-cloud/spring-cloud-netflix/issues/1042#issuecomment-227723877 - public void testEmptyEntityGet() throws Exception { - String entityValue = ""; - testEntity(entityValue, new ByteArrayInputStream(entityValue.getBytes()), false, - "GET"); - } - - @Test - public void testNonEmptyEntityPost() throws Exception { - String entityValue = "abcd"; - testEntity(entityValue, new ByteArrayInputStream(entityValue.getBytes()), true, - "POST"); - } - - void testEntity(String entityValue, ByteArrayInputStream requestEntity, - boolean addContentLengthHeader, String method) throws IOException { - String lengthString = String.valueOf(entityValue.length()); - Long length = null; - URI uri = URI.create("https://example.com"); - LinkedMultiValueMap headers = new LinkedMultiValueMap<>(); - if (addContentLengthHeader) { - headers.add("Content-Length", lengthString); - length = (long) entityValue.length(); - } - - RibbonRequestCustomizer requestCustomizer = new RibbonRequestCustomizer() { - @Override - public boolean accepts(Class builderClass) { - return builderClass == RequestBuilder.class; - } - - @Override - public void customize(RequestBuilder builder) { - builder.addHeader("from-customizer", "foo"); - } - }; - RibbonCommandContext context = new RibbonCommandContext("example", method, - uri.toString(), false, headers, new LinkedMultiValueMap(), - requestEntity, Collections.singletonList(requestCustomizer)); - context.setContentLength(length); - RibbonApacheHttpRequest httpRequest = new RibbonApacheHttpRequest(context); - - HttpUriRequest request = httpRequest.toRequest(RequestConfig.custom().build()); - - assertThat(request).as("request is wrong type") - .isInstanceOf(HttpEntityEnclosingRequest.class); - assertThat(request.getURI().toString()).as("uri is wrong") - .startsWith(uri.toString()); - if (addContentLengthHeader) { - assertThat(request.getFirstHeader("Content-Length")) - .as("Content-Length is missing").isNotNull(); - assertThat(request.getFirstHeader("Content-Length").getValue()) - .as("Content-Length is wrong").isEqualTo(lengthString); - } - assertThat(request.getFirstHeader("from-customizer")) - .as("from-customizer is missing").isNotNull(); - assertThat(request.getFirstHeader("from-customizer").getValue()) - .as("from-customizer is wrong").isEqualTo("foo"); - - HttpEntityEnclosingRequest entityRequest = (HttpEntityEnclosingRequest) request; - assertThat(entityRequest.getEntity()).as("entity is missing").isNotNull(); - HttpEntity entity = entityRequest.getEntity(); - assertThat(entity.getContentLength()).as("contentLength is wrong") - .isEqualTo((long) entityValue.length()); - assertThat(entity.getContent()).as("content is missing").isNotNull(); - String string = StreamUtils.copyToString(entity.getContent(), - Charset.forName("UTF-8")); - assertThat(string).as("content is wrong").isEqualTo(entityValue); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpResponseTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpResponseTests.java deleted file mode 100644 index af86f4f01..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonApacheHttpResponseTests.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.apache; - -import java.io.ByteArrayInputStream; -import java.net.URI; - -import org.apache.http.HttpResponse; -import org.apache.http.StatusLine; -import org.apache.http.entity.BasicHttpEntity; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.mock; - -/** - * @author Spencer Gibb - */ -public class RibbonApacheHttpResponseTests { - - @Test - public void testNullEntity() throws Exception { - StatusLine statusLine = mock(StatusLine.class); - given(statusLine.getStatusCode()).willReturn(204); - HttpResponse response = mock(HttpResponse.class); - given(response.getStatusLine()).willReturn(statusLine); - - RibbonApacheHttpResponse httpResponse = new RibbonApacheHttpResponse(response, - URI.create("https://example.com")); - - assertThat(httpResponse.isSuccess()).isTrue(); - assertThat(httpResponse.hasPayload()).isFalse(); - assertThat(httpResponse.getPayload()).isNull(); - assertThat(httpResponse.getInputStream()).isNull(); - } - - @Test - public void testNotNullEntity() throws Exception { - StatusLine statusLine = mock(StatusLine.class); - given(statusLine.getStatusCode()).willReturn(204); - HttpResponse response = mock(HttpResponse.class); - given(response.getStatusLine()).willReturn(statusLine); - BasicHttpEntity entity = new BasicHttpEntity(); - entity.setContent(new ByteArrayInputStream(new byte[0])); - given(response.getEntity()).willReturn(entity); - - RibbonApacheHttpResponse httpResponse = new RibbonApacheHttpResponse(response, - URI.create("https://example.com")); - - assertThat(httpResponse.isSuccess()).isTrue(); - assertThat(httpResponse.hasPayload()).isTrue(); - assertThat(httpResponse.getPayload()).isNotNull(); - assertThat(httpResponse.getInputStream()).isNotNull(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClientTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClientTests.java deleted file mode 100644 index f8761d0db..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClientTests.java +++ /dev/null @@ -1,1109 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.apache; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.util.ArrayList; -import java.util.Locale; -import java.util.concurrent.TimeUnit; - -import com.netflix.client.ClientException; -import com.netflix.client.DefaultLoadBalancerRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.AbstractLoadBalancer; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.LoadBalancerStats; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerStats; -import com.netflix.servo.monitor.Monitors; -import org.apache.http.HttpEntity; -import org.apache.http.StatusLine; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.entity.BasicHttpEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatcher; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryFactory; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicy; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpMethod; -import org.springframework.retry.RetryCallback; -import org.springframework.retry.RetryContext; -import org.springframework.retry.RetryListener; -import org.springframework.retry.TerminatedRetryException; -import org.springframework.retry.backoff.BackOffContext; -import org.springframework.retry.backoff.BackOffInterruptedException; -import org.springframework.retry.backoff.BackOffPolicy; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.util.LinkedMultiValueMap; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * @author Sébastien Nussbaumer - * @author Ryan Baxter - * @author Gang Li - */ -public class RibbonLoadBalancingHttpClientTests { - - private ILoadBalancer loadBalancer; - - @Before - public void setup() { - loadBalancer = mock(AbstractLoadBalancer.class); - doReturn(new Server("foo.com", 8000)).when(loadBalancer) - .chooseServer(eq("default")); - doReturn(new Server("foo.com", 8000)).when(loadBalancer) - .chooseServer(eq("service")); - } - - @After - public void teardown() { - loadBalancer = null; - } - - @Test - public void testRequestConfigUseDefaultsNoOverride() throws Exception { - RequestConfig result = getBuiltRequestConfig(UseDefaults.class, null); - - assertThat(result.isRedirectsEnabled()).isFalse(); - - } - - @Test - public void testRequestConfigDoNotFollowRedirectsNoOverride() throws Exception { - RequestConfig result = getBuiltRequestConfig(DoNotFollowRedirects.class, null); - - assertThat(result.isRedirectsEnabled()).isFalse(); - } - - @Test - public void testRequestConfigFollowRedirectsNoOverride() throws Exception { - RequestConfig result = getBuiltRequestConfig(FollowRedirects.class, null); - - assertThat(result.isRedirectsEnabled()).isTrue(); - } - - @Test - public void testTimeouts() throws Exception { - RequestConfig result = getBuiltRequestConfig(Timeouts.class, null); - assertThat(result.getConnectTimeout()).isEqualTo(60000); - assertThat(result.getSocketTimeout()).isEqualTo(50000); - } - - @Test - public void testDefaultTimeouts() throws Exception { - RequestConfig result = getBuiltRequestConfig(UseDefaults.class, null); - assertThat(result.getConnectTimeout()).isEqualTo(1000); - assertThat(result.getSocketTimeout()).isEqualTo(1000); - } - - @Test - public void testCompressionDefault() throws Exception { - RequestConfig result = getBuiltRequestConfig(UseDefaults.class, null); - assertThat(result.isContentCompressionEnabled()).isTrue(); - } - - @Test - public void testCompressionDisabled() throws Exception { - IClientConfig configOverride = DefaultClientConfigImpl - .getClientConfigWithDefaultValues(); - configOverride.set(CommonClientConfigKey.GZipPayload, false); - RequestConfig result = getBuiltRequestConfig(UseDefaults.class, configOverride); - assertThat(result.isContentCompressionEnabled()).isFalse(); - } - - @Test - public void testConnections() throws Exception { - SpringClientFactory factory = new SpringClientFactory(); - factory.setApplicationContext(new AnnotationConfigApplicationContext( - RibbonAutoConfiguration.class, Connections.class)); - RetryableRibbonLoadBalancingHttpClient client = factory.getClient("service", - RetryableRibbonLoadBalancingHttpClient.class); - - HttpClient delegate = client.getDelegate(); - PoolingHttpClientConnectionManager connManager = (PoolingHttpClientConnectionManager) ReflectionTestUtils - .getField(delegate, "connManager"); - assertThat(connManager.getMaxTotal()).isEqualTo(101); - assertThat(connManager.getDefaultMaxPerRoute()).isEqualTo(201); - } - - @Test - public void testRequestConfigDoNotFollowRedirectsOverrideWithFollowRedirects() - throws Exception { - - DefaultClientConfigImpl override = new DefaultClientConfigImpl(); - override.set(CommonClientConfigKey.FollowRedirects, true); - override.set(CommonClientConfigKey.IsSecure, false); - - RequestConfig result = getBuiltRequestConfig(DoNotFollowRedirects.class, - override); - - assertThat(result.isRedirectsEnabled()).isTrue(); - } - - @Test - public void testRequestConfigFollowRedirectsOverrideWithDoNotFollowRedirects() - throws Exception { - - DefaultClientConfigImpl override = new DefaultClientConfigImpl(); - override.set(CommonClientConfigKey.FollowRedirects, false); - override.set(CommonClientConfigKey.IsSecure, false); - - RequestConfig result = getBuiltRequestConfig(FollowRedirects.class, override); - - assertThat(result.isRedirectsEnabled()).isFalse(); - } - - @Test - public void testUpdatedTimeouts() throws Exception { - SpringClientFactory factory = new SpringClientFactory(); - RequestConfig result = getBuiltRequestConfig(Timeouts.class, null, factory); - assertThat(result.getConnectTimeout()).isEqualTo(60000); - assertThat(result.getSocketTimeout()).isEqualTo(50000); - IClientConfig config = factory.getClientConfig("service"); - config.set(CommonClientConfigKey.ConnectTimeout, 60); - config.set(CommonClientConfigKey.ReadTimeout, 50); - result = getBuiltRequestConfig(Timeouts.class, null, factory); - assertThat(result.getConnectTimeout()).isEqualTo(60); - assertThat(result.getSocketTimeout()).isEqualTo(50); - } - - @Test - public void testNeverRetry() throws Exception { - ServerIntrospector introspector = mock(ServerIntrospector.class); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - doThrow(new IOException("boom")).when(delegate) - .execute(any(HttpUriRequest.class)); - DefaultClientConfigImpl clientConfig = new DefaultClientConfigImpl(); - clientConfig.setClientName("foo"); - RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient(delegate, - clientConfig, introspector); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - when(request.toRequest(any(RequestConfig.class))) - .thenReturn(mock(HttpUriRequest.class)); - try { - client.execute(request, null); - fail("Expected IOException"); - } - catch (IOException e) { - } - finally { - verify(delegate, times(1)).execute(any(HttpUriRequest.class)); - } - } - - @Test - public void testRetryFail() throws Exception { - int retriesNextServer = 0; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = false; - String serviceName = "foo"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.GET; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - StatusLine fourOFourStatusLine = mock(StatusLine.class); - CloseableHttpResponse fourOFourResponse = mock(CloseableHttpResponse.class); - Locale locale = new Locale("en"); - doReturn(locale).when(fourOFourResponse).getLocale(); - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocationOnMock) throws Throwable { - HttpEntity entity = mock(HttpEntity.class); - doReturn(new ByteArrayInputStream("test".getBytes())).when(entity) - .getContent(); - return entity; - } - }).when(fourOFourResponse).getEntity(); - doReturn(404).when(fourOFourStatusLine).getStatusCode(); - doReturn(fourOFourStatusLine).when(fourOFourResponse).getStatusLine(); - doReturn(locale).when(fourOFourResponse).getLocale(); - doReturn(fourOFourResponse).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - MyBackOffPolicy myBackOffPolicy = new MyBackOffPolicy(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "404", myBackOffPolicy); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(uri).when(request).getURI(); - doReturn(method).when(request).getMethod(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uri).when(uriRequest).getURI(); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - RibbonApacheHttpResponse returnedResponse = client.execute(request, null); - verify(delegate, times(2)).execute(any(HttpUriRequest.class)); - byte[] buf = new byte[100]; - InputStream inputStream = returnedResponse.getInputStream(); - int read = inputStream.read(buf); - assertThat(new String(buf, 0, read)).isEqualTo("test"); - } - - private RetryableRibbonLoadBalancingHttpClient setupClientForRetry( - int retriesNextServer, int retriesSameServer, boolean retryable, - boolean retryOnAllOps, String serviceName, String host, int port, - CloseableHttpClient delegate, ILoadBalancer lb, String statusCodes, - BackOffPolicy backOffPolicy) throws Exception { - return setupClientForRetry(retriesNextServer, retriesSameServer, retryable, - retryOnAllOps, serviceName, host, port, delegate, lb, statusCodes, - backOffPolicy, false); - } - - private RetryableRibbonLoadBalancingHttpClient setupClientForRetry( - int retriesNextServer, int retriesSameServer, boolean retryable, - boolean retryOnAllOps, String serviceName, String host, int port, - CloseableHttpClient delegate, ILoadBalancer lb, String statusCodes, - BackOffPolicy backOffPolicy, boolean isSecure) throws Exception { - ServerIntrospector introspector = mock(ServerIntrospector.class); - RetryHandler retryHandler = new DefaultLoadBalancerRetryHandler(retriesSameServer, - retriesNextServer, retryable); - doReturn(new Server(host, port)).when(lb).chooseServer(eq(serviceName)); - DefaultClientConfigImpl clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(CommonClientConfigKey.OkToRetryOnAllOperations, retryOnAllOps); - clientConfig.set(CommonClientConfigKey.MaxAutoRetriesNextServer, - retriesNextServer); - clientConfig.set(CommonClientConfigKey.MaxAutoRetries, retriesSameServer); - clientConfig.set(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES, - statusCodes); - clientConfig.set(CommonClientConfigKey.IsSecure, isSecure); - clientConfig.setClientName(serviceName); - RibbonLoadBalancerContext context = new RibbonLoadBalancerContext(lb, - clientConfig, retryHandler); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - doReturn(context).when(clientFactory).getLoadBalancerContext(eq(serviceName)); - doReturn(clientConfig).when(clientFactory).getClientConfig(eq(serviceName)); - LoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory) { - @Override - public BackOffPolicy createBackOffPolicy(String service) { - return backOffPolicy; - } - }; - RetryableRibbonLoadBalancingHttpClient client = new RetryableRibbonLoadBalancingHttpClient( - delegate, clientConfig, introspector, factory); - client.setLoadBalancer(lb); - ReflectionTestUtils.setField(client, "delegate", delegate); - return client; - } - - private RetryableRibbonLoadBalancingHttpClient setupClientForRetry( - int retriesNextServer, int retriesSameServer, boolean retryable, - boolean retryOnAllOps, String serviceName, String host, int port, - CloseableHttpClient delegate, ILoadBalancer lb, String statusCodes, - BackOffPolicy backOffPolicy, boolean isSecure, RetryListener[] retryListeners) - throws Exception { - ServerIntrospector introspector = mock(ServerIntrospector.class); - RetryHandler retryHandler = new DefaultLoadBalancerRetryHandler(retriesSameServer, - retriesNextServer, retryable); - doReturn(new Server(host, port)).when(lb).chooseServer(eq(serviceName)); - DefaultClientConfigImpl clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(CommonClientConfigKey.OkToRetryOnAllOperations, retryOnAllOps); - clientConfig.set(CommonClientConfigKey.MaxAutoRetriesNextServer, - retriesNextServer); - clientConfig.set(CommonClientConfigKey.MaxAutoRetries, retriesSameServer); - clientConfig.set(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES, - statusCodes); - clientConfig.set(CommonClientConfigKey.IsSecure, isSecure); - clientConfig.setClientName(serviceName); - RibbonLoadBalancerContext context = new RibbonLoadBalancerContext(lb, - clientConfig, retryHandler); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - doReturn(context).when(clientFactory).getLoadBalancerContext(eq(serviceName)); - doReturn(clientConfig).when(clientFactory).getClientConfig(eq(serviceName)); - LoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory) { - @Override - public RetryListener[] createRetryListeners(String service) { - return retryListeners; - } - - @Override - public BackOffPolicy createBackOffPolicy(String service) { - return backOffPolicy; - } - }; - RetryableRibbonLoadBalancingHttpClient client = new RetryableRibbonLoadBalancingHttpClient( - delegate, clientConfig, introspector, factory); - client.setLoadBalancer(lb); - ReflectionTestUtils.setField(client, "delegate", delegate); - return client; - } - - @Test - public void testRetrySameServerOnly() throws Exception { - int retriesNextServer = 0; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = false; - String serviceName = "foo"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.GET; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doThrow(new IOException("boom")).doReturn(response).when(delegate) - .execute(any(HttpUriRequest.class)); - AbstractLoadBalancer lb = mock(AbstractLoadBalancer.class); - LoadBalancerStats lbStats = mock(LoadBalancerStats.class); - doReturn(lbStats).when(lb).getLoadBalancerStats(); - ServerStats serverStats = mock(ServerStats.class); - doReturn(serverStats).when(lbStats).getSingleServerStat(any(Server.class)); - RibbonLoadBalancerContext ribbonLoadBalancerContext = mock( - RibbonLoadBalancerContext.class); - doReturn(lb).when(ribbonLoadBalancerContext).getLoadBalancer(); - doReturn(Monitors.newTimer("_LoadBalancerExecutionTimer", TimeUnit.MILLISECONDS)) - .when(ribbonLoadBalancerContext).getExecuteTracer(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", null); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(uri).when(request).getURI(); - doReturn(method).when(request).getMethod(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uri).when(uriRequest).getURI(); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - RibbonApacheHttpResponse returnedResponse = client.execute(request, null); - verify(delegate, times(2)).execute(any(HttpUriRequest.class)); - verify(lb, times(1)).chooseServer(eq(serviceName)); - verify(ribbonLoadBalancerContext, times(1)).noteRequestCompletion(serverStats, - response, null, 0, null); - } - - @Test - public void testRetryNextServer() throws Exception { - int retriesNextServer = 1; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = false; - String serviceName = "foo"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.GET; - URI uri = new URI("http://" + host + ":" + port + "/a%2Bb"); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doThrow(new IOException("boom")).doThrow(new IOException("boom again")) - .doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - MyBackOffPolicy myBackOffPolicy = new MyBackOffPolicy(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", myBackOffPolicy); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(uri).when(request).getURI(); - doReturn(method).when(request).getMethod(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uri).when(uriRequest).getURI(); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - client.execute(request, null); - verify(delegate, times(3)).execute(any(HttpUriRequest.class)); - verify(lb, times(2)).chooseServer(eq(serviceName)); - assertThat(myBackOffPolicy.getCount()).isEqualTo(2); - verify(request, times(3)).withNewUri(argThat(new ArgumentMatcher() { - @Override - public boolean matches(URI argument) { - if (argument.equals(uri)) { - return true; - } - return false; - } - })); - } - - @Test - public void testRetryOnPost() throws Exception { - int retriesNextServer = 1; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = true; - String serviceName = "foo"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doThrow(new IOException("boom")).doThrow(new IOException("boom again")) - .doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - MyBackOffPolicy myBackOffPolicy = new MyBackOffPolicy(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", myBackOffPolicy); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - RibbonApacheHttpResponse returnedResponse = client.execute(request, null); - verify(response, times(0)).close(); - verify(delegate, times(3)).execute(any(HttpUriRequest.class)); - verify(lb, times(2)).chooseServer(eq(serviceName)); - assertThat(myBackOffPolicy.getCount()).isEqualTo(2); - } - - @Test - public void testDoubleEncoding() throws Exception { - String serviceName = "foo"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.GET; - final URI uri = new URI("https://" + host + ":" + port + "/a%2Bb"); - DefaultClientConfigImpl clientConfig = new DefaultClientConfigImpl(); - clientConfig.setClientName(serviceName); - ServerIntrospector introspector = mock(ServerIntrospector.class); - RibbonCommandContext context = new RibbonCommandContext(serviceName, - method.toString(), uri.toString(), false, - new LinkedMultiValueMap(), - new LinkedMultiValueMap(), - new ByteArrayInputStream("bar".getBytes()), - new ArrayList()); - RibbonApacheHttpRequest request = new RibbonApacheHttpRequest(context); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient(delegate, - clientConfig, introspector); - client.execute(request, null); - verify(response, times(0)).close(); - verify(delegate, times(1)).execute(argThat(new ArgumentMatcher() { - @Override - public boolean matches(HttpUriRequest argument) { - if (argument instanceof HttpUriRequest) { - HttpUriRequest arg = (HttpUriRequest) argument; - return arg.getURI().equals(uri); - } - return false; - } - })); - } - - @Test - public void testDoubleEncodingWithRetry() throws Exception { - int retriesNextServer = 0; - int retriesSameServer = 0; - boolean retryable = true; - boolean retryOnAllOps = true; - String serviceName = "foo"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.GET; - final URI uri = new URI("https://" + host + ":" + port + "/a%20b"); - RibbonCommandContext context = new RibbonCommandContext(serviceName, - method.toString(), uri.toString(), true, - new LinkedMultiValueMap(), - new LinkedMultiValueMap(), - new ByteArrayInputStream(new String("bar").getBytes()), - new ArrayList()); - RibbonApacheHttpRequest request = new RibbonApacheHttpRequest(context); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", null, true); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - client.execute(request, null); - verify(response, times(0)).close(); - verify(delegate, times(1)).execute(argThat(new ArgumentMatcher() { - @Override - public boolean matches(HttpUriRequest argument) { - if (argument instanceof HttpUriRequest) { - HttpUriRequest arg = (HttpUriRequest) argument; - return arg.getURI().equals(uri); - } - return false; - } - })); - } - - @Test - public void testNoRetryOnPost() throws Exception { - int retriesNextServer = 1; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = false; - String serviceName = "foo"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - doThrow(new IOException("boom")).doThrow(new IOException("boom again")) - .doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", null); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uri).when(uriRequest).getURI(); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - try { - client.execute(request, null); - fail("Expected IOException"); - } - catch (IOException e) { - } - finally { - verify(response, times(0)).close(); - verify(delegate, times(1)).execute(any(HttpUriRequest.class)); - verify(lb, times(1)).chooseServer(eq(serviceName)); - } - } - - @Test - public void testRetryOnStatusCode() throws Exception { - int retriesNextServer = 0; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = false; - String serviceName = "foo"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.GET; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - Locale locale = new Locale("en"); - doReturn(locale).when(response).getLocale(); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - final CloseableHttpResponse fourOFourResponse = mock(CloseableHttpResponse.class); - doReturn(locale).when(fourOFourResponse).getLocale(); - BasicHttpEntity entity = new BasicHttpEntity(); - entity.setContentLength(5); - entity.setContent(new ByteArrayInputStream("error".getBytes())); - doReturn(entity).when(fourOFourResponse).getEntity(); - StatusLine fourOFourStatusLine = mock(StatusLine.class); - doReturn(404).when(fourOFourStatusLine).getStatusCode(); - doReturn(fourOFourStatusLine).when(fourOFourResponse).getStatusLine(); - doReturn(fourOFourResponse).doReturn(response).when(delegate) - .execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - MyBackOffPolicy myBackOffPolicy = new MyBackOffPolicy(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "404", myBackOffPolicy); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(uri).when(request).getURI(); - doReturn(method).when(request).getMethod(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uri).when(uriRequest).getURI(); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - client.execute(request, null); - verify(fourOFourResponse, times(1)).close(); - verify(delegate, times(2)).execute(any(HttpUriRequest.class)); - verify(lb, times(1)).chooseServer(eq(serviceName)); - assertThat(myBackOffPolicy.getCount()).isEqualTo(1); - } - - @Test - public void retryListenerTest() throws Exception { - int retriesNextServer = 1; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = true; - String serviceName = "listener"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doThrow(new IOException("boom")).doThrow(new IOException("boom again")) - .doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - MyBackOffPolicy myBackOffPolicy = new MyBackOffPolicy(); - MyRetryListener myRetryListener = new MyRetryListener(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", myBackOffPolicy, false, - new RetryListener[] { myRetryListener }); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - RibbonApacheHttpResponse returnedResponse = client.execute(request, null); - verify(response, times(0)).close(); - verify(delegate, times(3)).execute(any(HttpUriRequest.class)); - verify(lb, times(2)).chooseServer(eq(serviceName)); - assertThat(myBackOffPolicy.getCount()).isEqualTo(2); - assertThat(myRetryListener.getOnError()).isEqualTo(2); - } - - @Test - public void retryDefaultListenerTest() throws Exception { - int retriesNextServer = 1; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = true; - String serviceName = "listener"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doThrow(new IOException("boom")).doThrow(new IOException("boom again")) - .doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - MyBackOffPolicy myBackOffPolicy = new MyBackOffPolicy(); - MyRetryListener myRetryListener = new MyRetryListener(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", myBackOffPolicy, false, - new RetryListener[] {}); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - RibbonApacheHttpResponse returnedResponse = client.execute(request, null); - verify(response, times(0)).close(); - verify(delegate, times(3)).execute(any(HttpUriRequest.class)); - verify(lb, times(2)).chooseServer(eq(serviceName)); - assertThat(myBackOffPolicy.getCount()).isEqualTo(2); - assertThat(myRetryListener.getOnError()).isEqualTo(0); - } - - @Test(expected = TerminatedRetryException.class) - public void retryListenerTestNoRetry() throws Exception { - int retriesNextServer = 1; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = true; - String serviceName = "listener"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doThrow(new IOException("boom")).doThrow(new IOException("boom again")) - .doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - MyBackOffPolicy myBackOffPolicy = new MyBackOffPolicy(); - MyRetryListenerNotRetry myRetryListenerNotRetry = new MyRetryListenerNotRetry(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", myBackOffPolicy, false, - new RetryListener[] { myRetryListenerNotRetry }); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - RibbonApacheHttpResponse returnedResponse = client.execute(request, null); - - } - - @Test - public void retryWithOriginalConstructorTest() throws Exception { - int retriesNextServer = 1; - int retriesSameServer = 1; - boolean retryable = true; - boolean retryOnAllOps = true; - String serviceName = "listener"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - final CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(response).getStatusLine(); - doThrow(new IOException("boom")).doThrow(new IOException("boom again")) - .doReturn(response).when(delegate).execute(any(HttpUriRequest.class)); - ILoadBalancer lb = mock(ILoadBalancer.class); - RibbonLoadBalancerContext ribbonLoadBalancerContext = new RibbonLoadBalancerContext( - lb); - MyBackOffPolicy myBackOffPolicy = new MyBackOffPolicy(); - RetryableRibbonLoadBalancingHttpClient client = setupClientForRetry( - retriesNextServer, retriesSameServer, retryable, retryOnAllOps, - serviceName, host, port, delegate, lb, "", myBackOffPolicy, false); - client.setRibbonLoadBalancerContext(ribbonLoadBalancerContext); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - RibbonApacheHttpResponse returnedResponse = client.execute(request, null); - verify(response, times(0)).close(); - verify(delegate, times(3)).execute(any(HttpUriRequest.class)); - verify(lb, times(2)).chooseServer(eq(serviceName)); - assertThat(myBackOffPolicy.getCount()).isEqualTo(2); - } - - private RetryableRibbonLoadBalancingHttpClient setupClientForServerValidation( - String serviceName, String host, int port, CloseableHttpClient delegate, - ILoadBalancer lb) throws Exception { - ServerIntrospector introspector = mock(ServerIntrospector.class); - RetryHandler retryHandler = new DefaultLoadBalancerRetryHandler(1, 1, true); - DefaultClientConfigImpl clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(CommonClientConfigKey.OkToRetryOnAllOperations, true); - clientConfig.set(CommonClientConfigKey.MaxAutoRetriesNextServer, 0); - clientConfig.set(CommonClientConfigKey.MaxAutoRetries, 1); - clientConfig.set(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES, ""); - clientConfig.set(CommonClientConfigKey.IsSecure, false); - clientConfig.setClientName(serviceName); - RibbonLoadBalancerContext context = new RibbonLoadBalancerContext(lb, - clientConfig, retryHandler); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - doReturn(context).when(clientFactory).getLoadBalancerContext(eq(serviceName)); - doReturn(clientConfig).when(clientFactory).getClientConfig(eq(serviceName)); - LoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory); - RetryableRibbonLoadBalancingHttpClient client = new RetryableRibbonLoadBalancingHttpClient( - delegate, clientConfig, introspector, factory); - client.setLoadBalancer(lb); - client.setRibbonLoadBalancerContext(context); - ReflectionTestUtils.setField(client, "delegate", delegate); - return client; - } - - @Test - public void noServersFoundTest() throws Exception { - String serviceName = "noservers"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - ILoadBalancer lb = mock(ILoadBalancer.class); - - RetryableRibbonLoadBalancingHttpClient client = setupClientForServerValidation( - serviceName, host, port, delegate, lb); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(null).when(lb).chooseServer(eq(serviceName)); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - try { - client.execute(request, null); - fail("Expected IOException for no servers available"); - } - catch (ClientException ex) { - assertThat(ex.getMessage()) - .contains("Load balancer does not have available server for client"); - } - } - - @Test - public void invalidServerTest() throws Exception { - String serviceName = "noservers"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - ILoadBalancer lb = mock(ILoadBalancer.class); - - RetryableRibbonLoadBalancingHttpClient client = setupClientForServerValidation( - serviceName, host, port, delegate, lb); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(new Server(null, 8000)).when(lb).chooseServer(eq(serviceName)); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - HttpUriRequest uriRequest = mock(HttpUriRequest.class); - doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); - try { - client.execute(request, null); - fail("Expected IOException for no servers available"); - } - catch (ClientException ex) { - assertThat(ex.getMessage()).contains("Invalid Server for: "); - } - } - - private RequestConfig getBuiltRequestConfig(Class defaultConfigurationClass, - IClientConfig configOverride) throws Exception { - return getBuiltRequestConfig(defaultConfigurationClass, configOverride, - new SpringClientFactory()); - } - - private RequestConfig getBuiltRequestConfig(Class defaultConfigurationClass, - IClientConfig configOverride, SpringClientFactory factory) throws Exception { - - factory.setApplicationContext( - new AnnotationConfigApplicationContext(HttpClientConfiguration.class, - RibbonAutoConfiguration.class, defaultConfigurationClass)); - String serviceName = "foo"; - String host = serviceName; - int port = 80; - URI uri = new URI("http://" + host + ":" + port); - CloseableHttpClient delegate = mock(CloseableHttpClient.class); - RibbonLoadBalancingHttpClient client = factory.getClient("service", - RibbonLoadBalancingHttpClient.class); - - ReflectionTestUtils.setField(client, "delegate", delegate); - ReflectionTestUtils.setField(client, "lb", loadBalancer); - CloseableHttpResponse httpResponse = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - doReturn(statusLine).when(httpResponse).getStatusLine(); - given(delegate.execute(any(HttpUriRequest.class))).willReturn(httpResponse); - RibbonApacheHttpRequest request = mock(RibbonApacheHttpRequest.class); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - given(request.toRequest(any(RequestConfig.class))) - .willReturn(mock(HttpUriRequest.class)); - - client.execute(request, configOverride); - - ArgumentCaptor requestConfigCaptor = ArgumentCaptor - .forClass(RequestConfig.class); - verify(request, times(1)).toRequest(requestConfigCaptor.capture()); - return requestConfigCaptor.getValue(); - } - - class MyBackOffPolicy implements BackOffPolicy { - - private int count = 0; - - @Override - public BackOffContext start(RetryContext retryContext) { - return null; - } - - @Override - public void backOff(BackOffContext backOffContext) - throws BackOffInterruptedException { - count++; - } - - int getCount() { - return count; - } - - } - - class MyRetryListener implements RetryListener { - - private int onError = 0; - - int getOnError() { - return onError; - } - - @Override - public boolean open(RetryContext context, - RetryCallback callback) { - return true; - } - - @Override - public void close(RetryContext context, - RetryCallback callback, Throwable throwable) { - - } - - @Override - public void onError(RetryContext context, - RetryCallback callback, Throwable throwable) { - onError++; - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class DoNotFollowRedirects { - - @Bean - public IClientConfig clientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.FollowRedirects, false); - return config; - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class Connections { - - @Bean - public IClientConfig clientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.MaxTotalConnections, 101); - config.set(CommonClientConfigKey.MaxConnectionsPerHost, 201); - return config; - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class Timeouts { - - @Bean - public IClientConfig clientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.ConnectTimeout, 60000); - config.set(CommonClientConfigKey.ReadTimeout, 50000); - return config; - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class UseDefaults { - - } - - @Configuration(proxyBeanMethods = false) - protected static class FollowRedirects { - - @Bean - public IClientConfig clientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.FollowRedirects, true); - return config; - } - - } - - class MyRetryListenerNotRetry implements RetryListener { - - @Override - public boolean open(RetryContext context, - RetryCallback callback) { - return false; - } - - @Override - public void close(RetryContext context, - RetryCallback callback, Throwable throwable) { - - } - - @Override - public void onError(RetryContext context, - RetryCallback callback, Throwable throwable) { - - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClientTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClientTests.java deleted file mode 100644 index 6c142c9bc..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClientTests.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.okhttp; - -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import okhttp3.OkHttpClient; -import org.junit.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -public class OkHttpLoadBalancingClientTests { - - @Test - public void testOkHttpClientUseDefaultsNoOverride() throws Exception { - OkHttpClient result = getHttpClient(UseDefaults.class, null); - - assertThat(result.followRedirects()).isFalse(); - } - - @Test - public void testOkHttpClientDoNotFollowRedirectsNoOverride() throws Exception { - OkHttpClient result = getHttpClient(DoNotFollowRedirects.class, null); - - assertThat(result.followRedirects()).isFalse(); - } - - @Test - public void testOkHttpClientFollowRedirectsNoOverride() throws Exception { - OkHttpClient result = getHttpClient(FollowRedirects.class, null); - - assertThat(result.followRedirects()).isTrue(); - } - - @Test - public void testOkHttpClientDoNotFollowRedirectsOverrideWithFollowRedirects() - throws Exception { - - DefaultClientConfigImpl override = new DefaultClientConfigImpl(); - override.set(CommonClientConfigKey.FollowRedirects, true); - override.set(CommonClientConfigKey.IsSecure, false); - - OkHttpClient result = getHttpClient(DoNotFollowRedirects.class, override); - - assertThat(result.followRedirects()).isTrue(); - } - - @Test - public void testOkHttpClientFollowRedirectsOverrideWithDoNotFollowRedirects() - throws Exception { - - DefaultClientConfigImpl override = new DefaultClientConfigImpl(); - override.set(CommonClientConfigKey.FollowRedirects, false); - override.set(CommonClientConfigKey.IsSecure, false); - - OkHttpClient result = getHttpClient(FollowRedirects.class, override); - - assertThat(result.followRedirects()).isFalse(); - } - - @Test - public void testTimeouts() throws Exception { - OkHttpClient result = getHttpClient(Timeouts.class, null); - assertThat(result.readTimeoutMillis()).isEqualTo(50000); - assertThat(result.connectTimeoutMillis()).isEqualTo(60000); - } - - @Test - public void testDefaultTimeouts() throws Exception { - OkHttpClient result = getHttpClient(UseDefaults.class, null); - assertThat(result.readTimeoutMillis()).isEqualTo(1000); - assertThat(result.connectTimeoutMillis()).isEqualTo(1000); - } - - @Test - public void testTimeoutsOverride() throws Exception { - DefaultClientConfigImpl override = new DefaultClientConfigImpl(); - override.set(CommonClientConfigKey.ConnectTimeout, 60); - override.set(CommonClientConfigKey.ReadTimeout, 50); - OkHttpClient result = getHttpClient(Timeouts.class, override); - assertThat(result.readTimeoutMillis()).isEqualTo(50); - assertThat(result.connectTimeoutMillis()).isEqualTo(60); - } - - @Test - public void testUpdatedTimeouts() throws Exception { - SpringClientFactory factory = new SpringClientFactory(); - OkHttpClient result = getHttpClient(Timeouts.class, null, factory); - assertThat(result.readTimeoutMillis()).isEqualTo(50000); - assertThat(result.connectTimeoutMillis()).isEqualTo(60000); - IClientConfig config = factory.getClientConfig("service"); - config.set(CommonClientConfigKey.ConnectTimeout, 60); - config.set(CommonClientConfigKey.ReadTimeout, 50); - result = getHttpClient(Timeouts.class, null, factory); - assertThat(result.readTimeoutMillis()).isEqualTo(50); - assertThat(result.connectTimeoutMillis()).isEqualTo(60); - } - - private OkHttpClient getHttpClient(Class defaultConfigurationClass, - IClientConfig configOverride) throws Exception { - return getHttpClient(defaultConfigurationClass, configOverride, - new SpringClientFactory()); - } - - private OkHttpClient getHttpClient(Class defaultConfigurationClass, - IClientConfig configOverride, SpringClientFactory factory) throws Exception { - factory.setApplicationContext( - new AnnotationConfigApplicationContext(RibbonAutoConfiguration.class, - OkHttpClientConfiguration.class, defaultConfigurationClass)); - - OkHttpLoadBalancingClient client = factory.getClient("service", - OkHttpLoadBalancingClient.class); - - return client.getOkHttpClient(configOverride, false); - } - - @Configuration(proxyBeanMethods = false) - protected static class OkHttpClientConfiguration { - - @Autowired(required = false) - IClientConfig clientConfig; - - @Bean - public OkHttpLoadBalancingClient okHttpLoadBalancingClient() { - if (clientConfig == null) { - clientConfig = new DefaultClientConfigImpl(); - } - return new OkHttpLoadBalancingClient(new OkHttpClient(), clientConfig, - new DefaultServerIntrospector()); - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class UseDefaults { - - } - - @Configuration(proxyBeanMethods = false) - protected static class FollowRedirects { - - @Bean - public IClientConfig clientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.FollowRedirects, true); - return config; - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class DoNotFollowRedirects { - - @Bean - public IClientConfig clientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.FollowRedirects, false); - return config; - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class Timeouts { - - @Bean - public IClientConfig clientConfig() { - DefaultClientConfigImpl config = new DefaultClientConfigImpl(); - config.set(CommonClientConfigKey.ConnectTimeout, 60000); - config.set(CommonClientConfigKey.ReadTimeout, 50000); - return config; - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonRequestTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonRequestTests.java deleted file mode 100644 index 857fd7ccf..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonRequestTests.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.okhttp; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; - -import okhttp3.Request; -import okhttp3.RequestBody; -import okio.Buffer; -import org.junit.Test; - -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer; -import org.springframework.util.LinkedMultiValueMap; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -public class OkHttpRibbonRequestTests { - - @Test - public void testNullEntity() throws Exception { - String uri = "https://example.com"; - LinkedMultiValueMap headers = new LinkedMultiValueMap<>(); - headers.add("my-header", "my-value"); - // headers.add(HttpEncoding.CONTENT_LENGTH, "5192"); - LinkedMultiValueMap params = new LinkedMultiValueMap<>(); - params.add("myparam", "myparamval"); - RibbonCommandContext context = new RibbonCommandContext("example", "GET", uri, - false, headers, params, null, new ArrayList()); - OkHttpRibbonRequest httpRequest = new OkHttpRibbonRequest(context); - - Request request = httpRequest.toRequest(); - - assertThat(request.body()).as("body is not null").isNull(); - assertThat(request.url().toString()).as("uri is wrong").startsWith(uri); - assertThat(request.header("my-header")).as("my-header is wrong") - .isEqualTo("my-value"); - assertThat(request.url().queryParameter("myparam")).as("myparam is missing") - .isEqualTo("myparamval"); - } - - @Test - // this situation happens, see - // https://github.com/spring-cloud/spring-cloud-netflix/issues/1042#issuecomment-227723877 - public void testEmptyEntityGet() throws Exception { - String entityValue = ""; - testEntity(entityValue, new ByteArrayInputStream(entityValue.getBytes()), false, - "GET"); - } - - @Test - public void testNonEmptyEntityPost() throws Exception { - String entityValue = "abcd"; - testEntity(entityValue, new ByteArrayInputStream(entityValue.getBytes()), true, - "POST"); - } - - void testEntity(String entityValue, ByteArrayInputStream requestEntity, - boolean addContentLengthHeader, String method) throws IOException { - String lengthString = String.valueOf(entityValue.length()); - Long length = null; - String uri = "https://example.com"; - LinkedMultiValueMap headers = new LinkedMultiValueMap<>(); - if (addContentLengthHeader) { - headers.add("Content-Length", lengthString); - length = (long) entityValue.length(); - } - - RibbonRequestCustomizer requestCustomizer = new RibbonRequestCustomizer() { - @Override - public boolean accepts(Class builderClass) { - return builderClass == Request.Builder.class; - } - - @Override - public void customize(Request.Builder builder) { - builder.addHeader("from-customizer", "foo"); - } - }; - RibbonCommandContext context = new RibbonCommandContext("example", method, uri, - false, headers, new LinkedMultiValueMap(), requestEntity, - Collections.singletonList(requestCustomizer)); - context.setContentLength(length); - OkHttpRibbonRequest httpRequest = new OkHttpRibbonRequest(context); - - Request request = httpRequest.toRequest(); - - assertThat(request.url().toString()).as("uri is wrong").startsWith(uri); - if (addContentLengthHeader) { - assertThat(request.header("Content-Length")).as("Content-Length is wrong") - .isEqualTo(lengthString); - } - assertThat(request.header("from-customizer")).as("from-customizer is wrong") - .isEqualTo("foo"); - - if (!method.equalsIgnoreCase("get")) { - assertThat(request.body()).as("body is null").isNotNull(); - RequestBody body = request.body(); - assertThat(body.contentLength()).as("contentLength is wrong") - .isEqualTo((long) entityValue.length()); - Buffer content = new Buffer(); - body.writeTo(content); - String string = content.readByteString().utf8(); - assertThat(string).as("content is wrong").isEqualTo(entityValue); - } - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonResponseTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonResponseTests.java deleted file mode 100644 index 91b0144d3..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpRibbonResponseTests.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.okhttp; - -import java.net.URI; - -import okhttp3.HttpUrl; -import okhttp3.MediaType; -import okhttp3.Protocol; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.ResponseBody; -import org.junit.Test; - -import org.springframework.http.HttpStatus; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -public class OkHttpRibbonResponseTests { - - @Test - public void testNullEntity() throws Exception { - URI uri = URI.create("https://example.com"); - Response response = response(uri).build(); - - OkHttpRibbonResponse httpResponse = new OkHttpRibbonResponse(response, uri); - - assertThat(httpResponse.isSuccess()).isTrue(); - assertThat(httpResponse.hasPayload()).isFalse(); - assertThat(httpResponse.getPayload()).isNull(); - assertThat(httpResponse.getInputStream()).isNull(); - } - - @Test - public void testNotNullEntity() throws Exception { - URI uri = URI.create("https://example.com"); - Response response = response(uri) - .body(ResponseBody.create(MediaType.parse("text/plain"), "abcd")).build(); - - OkHttpRibbonResponse httpResponse = new OkHttpRibbonResponse(response, uri); - - assertThat(httpResponse.isSuccess()).isTrue(); - assertThat(httpResponse.hasPayload()).isTrue(); - assertThat(httpResponse.getPayload()).isNotNull(); - assertThat(httpResponse.getInputStream()).isNotNull(); - } - - Response.Builder response(URI uri) { - return new Response.Builder() - .request(new Request.Builder().url(HttpUrl.get(uri)).build()) - .protocol(Protocol.HTTP_1_1).code(HttpStatus.OK.value()) - .message(HttpStatus.OK.getReasonPhrase()); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryDisableOkHttpClientTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryDisableOkHttpClientTests.java deleted file mode 100644 index f1ac67ff7..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryDisableOkHttpClientTests.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.okhttp; - -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.cloud.test.ModifiedClassPathRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - * @author Biju Kunjummen - */ -@RunWith(ModifiedClassPathRunner.class) -@ClassPathExclusions({ "spring-retry-*.jar", "spring-boot-starter-aop-*.jar" }) -public class SpringRetryDisableOkHttpClientTests { - - @Test - public void testLoadBalancedRetryFactoryBean() { - new ApplicationContextRunner().withPropertyValues("ribbon.okhttp.enabled=true") - .withConfiguration(AutoConfigurations.of(RibbonAutoConfiguration.class, - LoadBalancerAutoConfiguration.class, - HttpClientConfiguration.class, RibbonClientConfiguration.class)) - .withUserConfiguration( - OkHttpLoadBalancingClientTests.OkHttpClientConfiguration.class) - .run(context -> { - Map factories = context - .getBeansOfType(LoadBalancedRetryFactory.class); - assertThat(factories.values()).hasSize(0); - Map clients = context - .getBeansOfType(OkHttpLoadBalancingClient.class); - assertThat(clients.values()).hasSize(1); - assertThat(clients.values().toArray()[0]) - .isInstanceOf(OkHttpLoadBalancingClient.class); - }); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryEnabledOkHttpClientTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryEnabledOkHttpClientTests.java deleted file mode 100644 index 211367785..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/okhttp/SpringRetryEnabledOkHttpClientTests.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.okhttp; - -import java.net.URI; -import java.util.Map; - -import com.netflix.client.ClientException; -import com.netflix.client.DefaultLoadBalancerRetryHandler; -import com.netflix.client.RetryHandler; -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.Server; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.BeansException; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryFactory; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicy; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext; -import org.springframework.cloud.netflix.ribbon.ServerIntrospector; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.http.HttpMethod; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest({ "ribbon.okhttp.enabled: true", "ribbon.httpclient.enabled: false" }) -@ContextConfiguration( - classes = { RibbonAutoConfiguration.class, HttpClientConfiguration.class, - RibbonClientConfiguration.class, LoadBalancerAutoConfiguration.class }) -public class SpringRetryEnabledOkHttpClientTests implements ApplicationContextAware { - - private ApplicationContext context; - - private ILoadBalancer loadBalancer; - - @Test - public void testLoadBalancedRetryFactoryBean() throws Exception { - Map factories = context - .getBeansOfType(LoadBalancedRetryFactory.class); - assertThat(factories.values()).hasSize(1); - assertThat(factories.values().toArray()[0]) - .isInstanceOf(RibbonLoadBalancedRetryFactory.class); - Map clients = context - .getBeansOfType(OkHttpLoadBalancingClient.class); - assertThat(clients.values()).hasSize(1); - assertThat(clients.values().toArray()[0]) - .isInstanceOf(RetryableOkHttpLoadBalancingClient.class); - - RibbonLoadBalancerContext ribbonLoadBalancerContext = (RibbonLoadBalancerContext) ReflectionTestUtils - .getField(clients.values().toArray()[0], - RetryableOkHttpLoadBalancingClient.class, - "ribbonLoadBalancerContext"); - assertThat(ribbonLoadBalancerContext).as( - "RetryableOkHttpLoadBalancingClient.ribbonLoadBalancerContext should not be null") - .isNotNull(); - - } - - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - this.context = context; - } - - private RetryableOkHttpLoadBalancingClient setupClientForServerValidation( - String serviceName, String host, int port, OkHttpClient delegate, - ILoadBalancer lb) throws Exception { - ServerIntrospector introspector = mock(ServerIntrospector.class); - RetryHandler retryHandler = new DefaultLoadBalancerRetryHandler(1, 1, true); - DefaultClientConfigImpl clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(CommonClientConfigKey.OkToRetryOnAllOperations, true); - clientConfig.set(CommonClientConfigKey.MaxAutoRetriesNextServer, 0); - clientConfig.set(CommonClientConfigKey.MaxAutoRetries, 1); - clientConfig.set(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES, ""); - clientConfig.set(CommonClientConfigKey.IsSecure, false); - clientConfig.setClientName(serviceName); - RibbonLoadBalancerContext context = new RibbonLoadBalancerContext(lb, - clientConfig, retryHandler); - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - doReturn(context).when(clientFactory).getLoadBalancerContext(eq(serviceName)); - doReturn(clientConfig).when(clientFactory).getClientConfig(eq(serviceName)); - LoadBalancedRetryFactory factory = new RibbonLoadBalancedRetryFactory( - clientFactory); - RetryableOkHttpLoadBalancingClient client = new RetryableOkHttpLoadBalancingClient( - delegate, clientConfig, introspector, factory); - client.setLoadBalancer(lb); - ReflectionTestUtils.setField(client, "delegate", delegate); - return client; - } - - @Test - public void noServersFoundTest() throws Exception { - String serviceName = "noservers"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - OkHttpClient delegate = mock(OkHttpClient.class); - ILoadBalancer lb = mock(ILoadBalancer.class); - - RetryableOkHttpLoadBalancingClient client = setupClientForServerValidation( - serviceName, host, port, delegate, lb); - OkHttpRibbonRequest request = mock(OkHttpRibbonRequest.class); - doReturn(null).when(lb).chooseServer(eq(serviceName)); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - Request okRequest = new Request.Builder().url("ws:testerror.sc").build(); - doReturn(okRequest).when(request).toRequest(); - try { - client.execute(request, null); - fail("Expected ClientException for no servers available"); - } - catch (ClientException ex) { - assertThat(ex.getMessage()) - .contains("Load balancer does not have available server for client"); - } - } - - @Test - public void invalidServerTest() throws Exception { - String serviceName = "noservers"; - String host = serviceName; - int port = 80; - HttpMethod method = HttpMethod.POST; - URI uri = new URI("http://" + host + ":" + port); - OkHttpClient delegate = mock(OkHttpClient.class); - ILoadBalancer lb = mock(ILoadBalancer.class); - - RetryableOkHttpLoadBalancingClient client = setupClientForServerValidation( - serviceName, host, port, delegate, lb); - OkHttpRibbonRequest request = mock(OkHttpRibbonRequest.class); - doReturn(new Server(null, 8000)).when(lb).chooseServer(eq(serviceName)); - doReturn(method).when(request).getMethod(); - doReturn(uri).when(request).getURI(); - doReturn(request).when(request).withNewUri(any(URI.class)); - Request okRequest = new Request.Builder().url("ws:testerror.sc").build(); - doReturn(okRequest).when(request).toRequest(); - - try { - client.execute(request, null); - fail("Expected ClientException for no Invalid Host"); - } - catch (ClientException ex) { - assertThat(ex.getMessage()).contains("Invalid Server for: "); - } - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/support/ContextAwareRequestTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/support/ContextAwareRequestTests.java deleted file mode 100644 index 9e534b8ef..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/support/ContextAwareRequestTests.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.support; - -import java.net.URI; -import java.util.Arrays; -import java.util.Collections; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * @author Ryan Baxter - */ -public class ContextAwareRequestTests { - - private RibbonCommandContext context; - - private ContextAwareRequest request; - - @Before - public void setUp() throws Exception { - context = mock(RibbonCommandContext.class); - doReturn("GET").when(context).getMethod(); - MultiValueMap headers = new LinkedMultiValueMap<>(); - headers.put("header1", Collections.emptyList()); - headers.put("header2", Arrays.asList("value1", "value2")); - headers.put("header3", Arrays.asList("value1")); - doReturn(headers).when(context).getHeaders(); - doReturn(new URI("https://foo")).when(context).uri(); - doReturn("foo").when(context).getServiceId(); - doReturn(new LinkedMultiValueMap<>()).when(context).getParams(); - doReturn("testLoadBalancerKey").when(context).getLoadBalancerKey(); - request = new TestContextAwareRequest(context); - } - - @After - public void tearDown() throws Exception { - context = null; - request = null; - } - - @Test - public void getContext() throws Exception { - assertThat(request.getContext()).isEqualTo(context); - } - - @Test - public void getMethod() throws Exception { - assertThat(request.getMethod()).isEqualTo(HttpMethod.GET); - } - - @Test - public void getURI() throws Exception { - assertThat(request.getURI()).isEqualTo(new URI("https://foo")); - - RibbonCommandContext badUriContext = mock(RibbonCommandContext.class); - doReturn(new LinkedMultiValueMap()).when(badUriContext).getHeaders(); - doReturn("foobar").when(badUriContext).getUri(); - ContextAwareRequest badUriRequest = new TestContextAwareRequest(badUriContext); - - assertThat(badUriRequest.getURI()).isNull(); - - } - - @Test - public void getHeaders() throws Exception { - HttpHeaders headers = new HttpHeaders(); - headers.put("header1", Collections.emptyList()); - headers.put("header2", Arrays.asList("value1", "value2")); - headers.put("header3", Arrays.asList("value1")); - assertThat(request.getHeaders()).isEqualTo(headers); - } - - @Test - public void getLoadBalancerKey() throws Exception { - assertThat(request.getLoadBalancerKey()).isEqualTo("testLoadBalancerKey"); - - RibbonCommandContext defaultContext = mock(RibbonCommandContext.class); - doReturn(new LinkedMultiValueMap()).when(defaultContext).getHeaders(); - doReturn(null).when(defaultContext).getLoadBalancerKey(); - ContextAwareRequest defaultRequest = new TestContextAwareRequest(defaultContext); - - assertThat(defaultRequest.getLoadBalancerKey()).isNull(); - } - - static class TestContextAwareRequest extends ContextAwareRequest { - - TestContextAwareRequest(RibbonCommandContext context) { - super(context); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/support/RibbonCommandContextTest.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/support/RibbonCommandContextTest.java deleted file mode 100644 index d6c1a671b..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/support/RibbonCommandContextTest.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.support; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collections; - -import okhttp3.Request; -import org.junit.Test; - -import org.springframework.http.HttpMethod; -import org.springframework.util.LinkedMultiValueMap; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Andre Dörnbrack - */ -public class RibbonCommandContextTest { - - private static final byte[] TEST_CONTENT = { 42, 42, 42, 42, 42 }; - - private RibbonCommandContext ribbonCommandContext; - - @Test - public void testMultipleReadsOnRequestEntity() throws Exception { - givenRibbonCommandContextIsSetup(); - - InputStream requestEntity = ribbonCommandContext.getRequestEntity(); - assertThat(requestEntity instanceof ResettableServletInputStreamWrapper).isTrue(); - - whenInputStreamIsConsumed(requestEntity); - assertThat(requestEntity.read()).isEqualTo(-1); - - requestEntity.reset(); - assertThat(requestEntity.read()).isNotEqualTo(-1); - - whenInputStreamIsConsumed(requestEntity); - assertThat(requestEntity.read()).isEqualTo(-1); - - requestEntity.reset(); - assertThat(requestEntity.read()).isNotEqualTo(-1); - - whenInputStreamIsConsumed(requestEntity); - assertThat(requestEntity.read()).isEqualTo(-1); - } - - private void whenInputStreamIsConsumed(InputStream requestEntity) throws IOException { - while (requestEntity.read() != -1) { - requestEntity.read(); - } - } - - private void givenRibbonCommandContextIsSetup() { - LinkedMultiValueMap headers = new LinkedMultiValueMap(); - LinkedMultiValueMap params = new LinkedMultiValueMap(); - - RibbonRequestCustomizer requestCustomizer = new RibbonRequestCustomizer() { - @Override - public boolean accepts(Class builderClass) { - return builderClass == Request.Builder.class; - } - - @Override - public void customize(Request.Builder builder) { - builder.addHeader("from-customizer", "foo"); - } - }; - - ribbonCommandContext = new RibbonCommandContext("serviceId", - HttpMethod.POST.toString(), "/my/route", true, headers, params, - new ByteArrayInputStream(TEST_CONTENT), - Collections.singletonList(requestCustomizer)); - } - - @Test - public void testNullSafetyWithNullableParameters() throws Exception { - LinkedMultiValueMap headers = new LinkedMultiValueMap(); - LinkedMultiValueMap params = new LinkedMultiValueMap(); - - RibbonCommandContext testContext = new RibbonCommandContext("serviceId", - HttpMethod.POST.toString(), "/my/route", true, headers, params, - new ByteArrayInputStream(TEST_CONTENT), - Collections.emptyList(), null, null); - - assertThat(testContext.hashCode()).isNotEqualTo(0); - assertThat(testContext.toString()).isNotNull(); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/RibbonClientDefaultConfigurationTests.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/RibbonClientDefaultConfigurationTests.java deleted file mode 100644 index 9a4aa2623..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/RibbonClientDefaultConfigurationTests.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.test; - -import com.netflix.loadbalancer.BestAvailableRule; -import com.netflix.loadbalancer.PingUrl; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerListSubsetFilter; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.test.RibbonClientDefaultConfigurationTestsConfig.BazServiceList; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = RibbonClientDefaultConfigurationTestsConfig.class, - value = "ribbon.eureka.enabled=true") -@DirtiesContext -public class RibbonClientDefaultConfigurationTests { - - @Autowired - private SpringClientFactory factory; - - @Test - public void ruleOverridesDefault() throws Exception { - assertThat(getLoadBalancer("baz").getRule()).as("wrong rule type") - .isInstanceOf(BestAvailableRule.class); - } - - @Test - public void pingOverridesDefault() throws Exception { - assertThat(getLoadBalancer("baz").getPing()).as("wrong ping type") - .isInstanceOf(PingUrl.class); - } - - @Test - public void serverListOverridesDefault() throws Exception { - assertThat(getLoadBalancer("baz").getServerListImpl()) - .as("wrong server list type").isInstanceOf(BazServiceList.class); - } - - @SuppressWarnings("unchecked") - private ZoneAwareLoadBalancer getLoadBalancer(String name) { - return (ZoneAwareLoadBalancer) this.factory.getLoadBalancer(name); - } - - @Test - public void serverListFilterOverride() throws Exception { - assertThat(getLoadBalancer("baz").getFilter()).as("wrong filter type") - .isInstanceOf(ServerListSubsetFilter.class); - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/RibbonClientDefaultConfigurationTestsConfig.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/RibbonClientDefaultConfigurationTestsConfig.java deleted file mode 100644 index 2c062223c..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/RibbonClientDefaultConfigurationTestsConfig.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.test; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.BestAvailableRule; -import com.netflix.loadbalancer.ConfigurationBasedServerList; -import com.netflix.loadbalancer.IPing; -import com.netflix.loadbalancer.IRule; -import com.netflix.loadbalancer.PingUrl; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.loadbalancer.ServerListSubsetFilter; - -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@Import({ PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class, - UtilAutoConfiguration.class, RibbonAutoConfiguration.class, - HttpClientConfiguration.class }) -// tag::sample_default_ribbon_config[] -@RibbonClients(defaultConfiguration = DefaultRibbonConfig.class) -public class RibbonClientDefaultConfigurationTestsConfig { - - public static class BazServiceList extends ConfigurationBasedServerList { - - public BazServiceList(IClientConfig config) { - super.initWithNiwsConfig(config); - } - - } - -} - -@Configuration(proxyBeanMethods = false) -class DefaultRibbonConfig { - - @Bean - public IRule ribbonRule() { - return new BestAvailableRule(); - } - - @Bean - public IPing ribbonPing() { - return new PingUrl(); - } - - @Bean - public ServerList ribbonServerList(IClientConfig config) { - return new RibbonClientDefaultConfigurationTestsConfig.BazServiceList(config); - } - - @Bean - public ServerListSubsetFilter serverListFilter() { - ServerListSubsetFilter filter = new ServerListSubsetFilter(); - return filter; - } - -} -// end::sample_default_ribbon_config[] diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestAutoConfiguration.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestAutoConfiguration.java deleted file mode 100644 index b03118c97..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestAutoConfiguration.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.test; - -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@Import({ NoopDiscoveryClientAutoConfiguration.class }) -@AutoConfigureBefore(SecurityAutoConfiguration.class) -public class TestAutoConfiguration { - - /** - * User name - */ - public static final String USER = "user"; - - /** - * Password - */ - public static final String PASSWORD = "{noop}password"; - - @Configuration(proxyBeanMethods = false) - @Order(Ordered.HIGHEST_PRECEDENCE) - static class TestSecurityConfiguration extends WebSecurityConfigurerAdapter { - - TestSecurityConfiguration() { - super(true); - } - - @Bean - public UserDetailsService userDetailsService() { - InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); - manager.createUser( - User.withUsername(USER).password(PASSWORD).roles("USER").build()); - return manager; - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - // super.configure(http); - http.antMatcher("/proxy-username").httpBasic().and().authorizeRequests() - .antMatchers("/**").permitAll(); - } - - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestLoadBalancer.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestLoadBalancer.java deleted file mode 100644 index ab73e5309..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestLoadBalancer.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.test; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; - -/** - * @author Spencer Gibb - */ -public class TestLoadBalancer extends ZoneAwareLoadBalancer { - -} diff --git a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestServerList.java b/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestServerList.java deleted file mode 100644 index 4595dc197..000000000 --- a/spring-cloud-netflix-ribbon/src/test/java/org/springframework/cloud/netflix/ribbon/test/TestServerList.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.ribbon.test; - -import java.util.ArrayList; -import java.util.List; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; - -/** - * @author Spencer Gibb - */ -public class TestServerList implements ServerList { - - private final List servers; - - public TestServerList() { - this.servers = new ArrayList<>(); - } - - public void add(T server) { - this.servers.add(server); - } - - @Override - public List getInitialListOfServers() { - return servers; - } - - @Override - public List getUpdatedListOfServers() { - return servers; - } - -} diff --git a/spring-cloud-netflix-ribbon/src/test/resources/META-INF/spring.factories b/spring-cloud-netflix-ribbon/src/test/resources/META-INF/spring.factories deleted file mode 100644 index 8e405ed6e..000000000 --- a/spring-cloud-netflix-ribbon/src/test/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.ribbon.test.TestAutoConfiguration diff --git a/spring-cloud-netflix-ribbon/src/test/resources/application.yml b/spring-cloud-netflix-ribbon/src/test/resources/application.yml deleted file mode 100644 index 30a3f68a6..000000000 --- a/spring-cloud-netflix-ribbon/src/test/resources/application.yml +++ /dev/null @@ -1,8 +0,0 @@ -# for RibbonClientPreprocessorPropertiesOverridesIntegrationTests -foo2: - ribbon: - NFLoadBalancerPingClassName: com.netflix.loadbalancer.NoOpPing - NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule - NIWSServerListClassName: org.springframework.cloud.netflix.ribbon.test.TestServerList - NIWSServerListFilterClassName: com.netflix.loadbalancer.ServerListSubsetFilter - NFLoadBalancerClassName: org.springframework.cloud.netflix.ribbon.test.TestLoadBalancer diff --git a/spring-cloud-netflix-sidecar/pom.xml b/spring-cloud-netflix-sidecar/pom.xml deleted file mode 100644 index 5b616a3b8..000000000 --- a/spring-cloud-netflix-sidecar/pom.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT - .. - - spring-cloud-netflix-sidecar - jar - Spring Cloud Netflix Sidecar - https://projects.spring.io/spring-cloud/ - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework.cloud - spring-cloud-context - - - org.springframework.cloud - spring-cloud-netflix-zuul - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework - spring-web - - - org.springframework.cloud - spring-cloud-netflix-hystrix - - - org.springframework.cloud - spring-cloud-netflix-eureka-client - - - com.netflix.eureka - eureka-client - - - com.netflix.hystrix - hystrix-core - - - com.netflix.hystrix - hystrix-metrics-event-stream - - - com.netflix.hystrix - hystrix-javanica - - - com.netflix.ribbon - ribbon - - - com.netflix.ribbon - ribbon-core - - - com.netflix.ribbon - ribbon-eureka - - - com.netflix.ribbon - ribbon-httpclient - - - com.netflix.zuul - zuul-core - - - org.apache.tomcat.embed - tomcat-embed-el - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.cloud - spring-cloud-config-client - test - - - diff --git a/spring-cloud-netflix-sidecar/run-server.sh b/spring-cloud-netflix-sidecar/run-server.sh deleted file mode 100755 index 8bacc042a..000000000 --- a/spring-cloud-netflix-sidecar/run-server.sh +++ /dev/null @@ -1 +0,0 @@ -python -m SimpleHTTPServer diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/EnableSidecar.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/EnableSidecar.java deleted file mode 100644 index 255de4239..000000000 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/EnableSidecar.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 - * - * https://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.sidecar; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.context.annotation.Import; - -/** - * @author Spencer Gibb - */ -@EnableCircuitBreaker -@EnableZuulProxy -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Import(SidecarMarkerConfiguration.class) -public @interface EnableSidecar { - -} diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandler.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandler.java deleted file mode 100644 index cd525bc7e..000000000 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandler.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.sidecar; - -import com.netflix.appinfo.HealthCheckHandler; -import com.netflix.appinfo.InstanceInfo.InstanceStatus; - -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; - -import static com.netflix.appinfo.InstanceInfo.InstanceStatus.DOWN; -import static com.netflix.appinfo.InstanceInfo.InstanceStatus.OUT_OF_SERVICE; -import static com.netflix.appinfo.InstanceInfo.InstanceStatus.UNKNOWN; -import static com.netflix.appinfo.InstanceInfo.InstanceStatus.UP; - -/** - * Eureka HealthCheckHandler that translates boot health status to InstanceStatus so the - * proper status of the non-JVM app is sent to Eureka. - * - * @author Spencer Gibb - */ -class LocalApplicationHealthCheckHandler implements HealthCheckHandler { - - private final HealthIndicator healthIndicator; - - LocalApplicationHealthCheckHandler(HealthIndicator healthIndicator) { - this.healthIndicator = healthIndicator; - } - - @Override - public InstanceStatus getStatus(InstanceStatus currentStatus) { - Status status = healthIndicator.health().getStatus(); - if (status.equals(Status.UP)) { - return UP; - } - else if (status.equals(Status.OUT_OF_SERVICE)) { - return OUT_OF_SERVICE; - } - else if (status.equals(Status.DOWN)) { - return DOWN; - } - return UNKNOWN; - } - -} diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthIndicator.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthIndicator.java deleted file mode 100644 index 947b29b9e..000000000 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthIndicator.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.sidecar; - -import java.net.URI; -import java.util.Map; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.web.client.RestTemplate; - -/** - * @author Spencer Gibb - * @author Fabrizio Di Napoli - */ -public class LocalApplicationHealthIndicator extends AbstractHealthIndicator { - - @Autowired - private SidecarProperties properties; - - @Autowired - private RestTemplate restTemplate; - - @SuppressWarnings("unchecked") - @Override - protected void doHealthCheck(Health.Builder builder) throws Exception { - URI uri = this.properties.getHealthUri(); - if (uri == null) { - builder.up(); - return; - } - - Map map = restTemplate.getForObject(uri, Map.class); - Object status = map.get("status"); - if (status instanceof String) { - builder.status(status.toString()); - } - else if (status instanceof Map) { - Map statusMap = (Map) status; - Object code = statusMap.get("code"); - if (code != null) { - builder.status(code.toString()); - } - else { - getWarning(builder); - } - } - else { - getWarning(builder); - } - } - - private Health.Builder getWarning(Health.Builder builder) { - return builder.unknown().withDetail("warning", "no status field in response"); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarAutoConfiguration.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarAutoConfiguration.java deleted file mode 100644 index 4211e06a8..000000000 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarAutoConfiguration.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.sidecar; - -import java.util.Map; - -import com.netflix.appinfo.HealthCheckHandler; -import com.netflix.discovery.EurekaClientConfig; -import org.apache.http.client.HttpClient; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.commons.util.InetUtils; -import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.cloud.netflix.eureka.metadata.DefaultManagementMetadataProvider; -import org.springframework.cloud.netflix.eureka.metadata.ManagementMetadata; -import org.springframework.cloud.netflix.eureka.metadata.ManagementMetadataProvider; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.util.StringUtils; -import org.springframework.web.client.RestTemplate; - -import static org.springframework.cloud.commons.util.IdUtils.getDefaultInstanceId; - -/** - * Sidecar Configuration that setting up {@link com.netflix.appinfo.EurekaInstanceConfig}. - *

- * Depends on {@link SidecarProperties} and {@code eureka.instance.hostname} property. - * Since there is two way to configure hostname: - *

    - *
  1. {@code eureka.instance.hostname} property
  2. - *
  3. {@link SidecarProperties#hostname}
  4. - *
- * {@code eureka.instance.hostname} will always win against - * {@link SidecarProperties#hostname} due to - * {@code @ConfigurationProperties("eureka.instance")} on - * {@link EurekaInstanceConfigBeanConfiguration}. - * - * @author Spencer Gibb - * @author Ryan Baxter - * @author Fabrizio Di Napoli - * @see EurekaInstanceConfigBeanConfiguration - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnBean(SidecarMarkerConfiguration.Marker.class) -@EnableConfigurationProperties(SidecarProperties.class) -@AutoConfigureBefore(EurekaClientAutoConfiguration.class) -@ConditionalOnProperty(value = "spring.cloud.netflix.sidecar.enabled", - matchIfMissing = true) -public class SidecarAutoConfiguration { - - @Bean - public HasFeatures Feature() { - return HasFeatures.namedFeature("Netflix Sidecar", - SidecarAutoConfiguration.class); - } - - @Bean - @ConditionalOnMissingClass("org.apache.http.client.HttpClient") - public RestTemplate restTemplate() { - return new RestTemplateBuilder().build(); - } - - @Bean - @ConditionalOnClass(HttpClient.class) - public RestTemplate sslRestTemplate(SidecarProperties properties) { - RestTemplateBuilder builder = new RestTemplateBuilder(); - if (properties.acceptAllSslCertificates()) { - CloseableHttpClient httpClient = HttpClients.custom() - .setSSLHostnameVerifier(new NoopHostnameVerifier()).build(); - HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); - requestFactory.setHttpClient(httpClient); - builder = builder.requestFactory(() -> requestFactory); - } - return builder.build(); - } - - @Bean - public LocalApplicationHealthIndicator localApplicationHealthIndicator() { - return new LocalApplicationHealthIndicator(); - } - - @Bean - public SidecarController sidecarController() { - return new SidecarController(); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(EurekaClientConfig.class) - protected static class EurekaInstanceConfigBeanConfiguration { - - @Autowired - private SidecarProperties sidecarProperties; - - @Autowired - private InetUtils inetUtils; - - @Value("${management.server.port:${MANAGEMENT_PORT:#{null}}}") - private Integer managementPort; - - @Value("${server.port:${SERVER_PORT:${PORT:8080}}}") - private int serverPort = 8080; - - @Value("${management.server.servlet.context-path:${MANAGEMENT_CONTEXT_PATH:#{null}}}") - private String managementContextPath; - - @Value("${server.servlet.context-path:${SERVER_CONTEXT_PATH:/}}") - private String serverContextPath = "/"; - - @Value("${eureka.instance.hostname:${EUREKA_INSTANCE_HOSTNAME:}}") - private String hostname; - - @Autowired - private ConfigurableEnvironment env; - - @Bean - @ConditionalOnMissingBean - public ManagementMetadataProvider serviceManagementMetadataProvider() { - return new DefaultManagementMetadataProvider(); - } - - @Bean - @ConditionalOnMissingBean - public EurekaInstanceConfigBean eurekaInstanceConfigBean( - ManagementMetadataProvider managementMetadataProvider) { - EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(inetUtils); - String springAppName = this.env.getProperty("spring.application.name", ""); - int port = this.sidecarProperties.getPort(); - config.setNonSecurePort(port); - config.setSecurePortEnabled(this.sidecarProperties.isSecurePortEnabled()); - config.setInstanceId(getDefaultInstanceId(this.env)); - if (StringUtils.hasText(springAppName)) { - config.setAppname(springAppName); - config.setVirtualHostName(springAppName); - config.setSecureVirtualHostName(springAppName); - } - String hostname = this.sidecarProperties.getHostname(); - String ipAddress = this.sidecarProperties.getIpAddress(); - if (!StringUtils.hasText(hostname) && StringUtils.hasText(this.hostname)) { - hostname = this.hostname; - } - if (StringUtils.hasText(hostname)) { - config.setHostname(hostname); - } - if (StringUtils.hasText(ipAddress)) { - config.setIpAddress(ipAddress); - } - String scheme = config.getSecurePortEnabled() ? "https" : "http"; - ManagementMetadata metadata = managementMetadataProvider.get(config, - serverPort, serverContextPath, managementContextPath, managementPort); - - if (metadata != null) { - config.setStatusPageUrl(metadata.getStatusPageUrl()); - config.setHealthCheckUrl(metadata.getHealthCheckUrl()); - if (config.isSecurePortEnabled()) { - config.setSecureHealthCheckUrl(metadata.getSecureHealthCheckUrl()); - } - Map metadataMap = config.getMetadataMap(); - metadataMap.computeIfAbsent("management.port", - k -> String.valueOf(metadata.getManagementPort())); - } - config.setHomePageUrl(scheme + "://" + config.getHostname() + ":" + port - + config.getHomePageUrlPath()); - return config; - } - - @Bean - public HealthCheckHandler healthCheckHandler( - final LocalApplicationHealthIndicator healthIndicator) { - return new LocalApplicationHealthCheckHandler(healthIndicator); - } - - } - -} diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarController.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarController.java deleted file mode 100644 index d5dbe3cdd..000000000 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarController.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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 - * - * https://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.sidecar; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -/** - * @author Spencer Gibb - */ -@RestController -public class SidecarController { - - @Autowired - private DiscoveryClient discovery; - - @Value("${spring.application.name}") - private String appName; - - @RequestMapping("/ping") - public String ping() { - return "OK"; - } - - @RequestMapping("/hosts/{appName}") - public List hosts(@PathVariable("appName") String appName) { - return hosts2(appName); - } - - @RequestMapping("/hosts") - public List hosts2(@RequestParam("appName") String appName) { - List instances = this.discovery.getInstances(appName); - return instances; - } - - @RequestMapping(value = "/", produces = "text/html") - public String home() { - return "Sidecar\n" - + "ping
\n" - + "health
\n" + "hosts/" + this.appName + "
\n" + ""; - } - -} diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarMarkerConfiguration.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarMarkerConfiguration.java deleted file mode 100644 index 0c1fb02d1..000000000 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarMarkerConfiguration.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.sidecar; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Annotation to activate Eureka Server related configuration. - * {@link SidecarAutoConfiguration} - * - * @author Greg Adams - */ -@Configuration(proxyBeanMethods = false) -public class SidecarMarkerConfiguration { - - @Bean - public Marker sidecarMarkerBean() { - return new Marker(); - } - - class Marker { - - } - -} diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarProperties.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarProperties.java deleted file mode 100644 index 7968e7670..000000000 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarProperties.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.sidecar; - -import java.net.URI; -import java.util.Objects; - -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * @author Spencer Gibb - * @author Gregor Zurowski - * @author Fabrizio Di Napoli - */ -@ConfigurationProperties("sidecar") -public class SidecarProperties { - - private URI healthUri; - - private URI homePageUri; - - @Max(65535) - @Min(1) - private int port; - - private String hostname; - - private String ipAddress; - - private boolean acceptAllSslCertificates; - - private boolean securePortEnabled; - - public boolean isSecurePortEnabled() { - return securePortEnabled; - } - - public void setSecurePortEnabled(boolean securePortEnabled) { - this.securePortEnabled = securePortEnabled; - } - - public URI getHealthUri() { - return healthUri; - } - - public void setHealthUri(URI healthUri) { - this.healthUri = healthUri; - } - - public URI getHomePageUri() { - return homePageUri; - } - - public void setHomePageUri(URI homePageUri) { - this.homePageUri = homePageUri; - } - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - public String getHostname() { - return hostname; - } - - public void setHostname(String hostname) { - this.hostname = hostname; - } - - public String getIpAddress() { - return ipAddress; - } - - public void setIpAddress(String ipAddress) { - this.ipAddress = ipAddress; - } - - public boolean acceptAllSslCertificates() { - return acceptAllSslCertificates; - } - - public void setAcceptAllSslCertificates(boolean acceptAllSslCertificates) { - this.acceptAllSslCertificates = acceptAllSslCertificates; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SidecarProperties that = (SidecarProperties) o; - return Objects.equals(healthUri, that.healthUri) - && Objects.equals(homePageUri, that.homePageUri) && port == that.port - && Objects.equals(securePortEnabled, that.securePortEnabled) - && Objects.equals(hostname, that.hostname) - && Objects.equals(ipAddress, that.ipAddress) && Objects - .equals(acceptAllSslCertificates, that.acceptAllSslCertificates); - } - - @Override - public int hashCode() { - return Objects.hash(healthUri, homePageUri, port, hostname, ipAddress, - acceptAllSslCertificates, securePortEnabled); - } - - @Override - public String toString() { - return new StringBuilder("SidecarProperties{").append("healthUri=") - .append(healthUri).append(", ").append("homePageUri=").append(homePageUri) - .append(", ").append("port=").append(port).append(", ") - .append("hostname='").append(hostname).append("', ").append("ipAddress='") - .append(ipAddress).append("', ").append("securePortEnabled='") - .append(securePortEnabled).append("', ") - .append("acceptAllSslCertificates='").append(acceptAllSslCertificates) - .append("'}").toString(); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-sidecar/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 17e18fd22..000000000 --- a/spring-cloud-netflix-sidecar/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - org.springframework.cloud.netflix.sidecar.SidecarAutoConfiguration \ No newline at end of file diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/AcceptAllSslCertificatesContextTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/AcceptAllSslCertificatesContextTests.java deleted file mode 100644 index 358ae6061..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/AcceptAllSslCertificatesContextTests.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.sidecar; - -import java.lang.reflect.Field; -import java.util.Map; - -import javax.net.ssl.HostnameVerifier; - -import org.apache.http.config.Registry; -import org.apache.http.conn.ssl.DefaultHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.conn.DefaultHttpClientConnectionOperator; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - value = { "sidecar.accept-all-ssl-certificates=false" }) -public class AcceptAllSslCertificatesContextTests { - - @Autowired - RestTemplate restTemplate; - - @Test - public void testUseRestTemplateWhenHttpClientIsNotAvailable() { - HttpComponentsClientHttpRequestFactory requestFactory = (HttpComponentsClientHttpRequestFactory) restTemplate - .getRequestFactory(); - CloseableHttpClient client = (CloseableHttpClient) requestFactory.getHttpClient(); - PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = getHttpClientConnectionManager( - client); - DefaultHttpClientConnectionOperator httpClientConnectionOperator = getHttpClientConnectionOperator( - poolingHttpClientConnectionManager); - Registry registry = getRegistry(httpClientConnectionOperator); - Map registryMap = getRegistryMap(registry); - SSLConnectionSocketFactory connectionSocketFactory = (SSLConnectionSocketFactory) registryMap - .get("https"); - HostnameVerifier hostnameVerifier = getHostnameVerifier(connectionSocketFactory); - assertThat(hostnameVerifier).isInstanceOf(DefaultHostnameVerifier.class); - } - - private HostnameVerifier getHostnameVerifier( - SSLConnectionSocketFactory connectionSocketFactory) { - return getField(connectionSocketFactory, "hostnameVerifier"); - } - - private PoolingHttpClientConnectionManager getHttpClientConnectionManager( - CloseableHttpClient httpClient) { - return getField(httpClient, "connManager"); - } - - private DefaultHttpClientConnectionOperator getHttpClientConnectionOperator( - PoolingHttpClientConnectionManager connectionManager) { - return getField(connectionManager, "connectionOperator"); - } - - private Registry getRegistry( - DefaultHttpClientConnectionOperator httpClientConnectionOperator) { - return getField(httpClientConnectionOperator, "socketFactoryRegistry"); - } - - private Map getRegistryMap(Registry registry) { - return getField(registry, "map"); - } - - private T getField(Object target, String name) { - Field field = ReflectionUtils.findField(target.getClass(), name); - ReflectionUtils.makeAccessible(field); - Object value = ReflectionUtils.getField(field, target); - return (T) value; - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/BothPropertiesEurekaTestConfigBeanTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/BothPropertiesEurekaTestConfigBeanTests.java deleted file mode 100644 index 332888a9d..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/BothPropertiesEurekaTestConfigBeanTests.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.sidecar; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", "spring.application.instance_id=1", - "eureka.instance.hostname=mhhost1", "sidecar.hostname=mhhost2", - "sidecar.port=7000", "sidecar.ip-address=127.0.0.1" }) -public class BothPropertiesEurekaTestConfigBeanTests { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBeanEurekaInstanceHostnamePropertyShouldBeUsed() { - assertThat(config.getAppname()).isEqualTo("mytest"); - assertThat(config.getHostname()).isEqualTo("mhhost1"); - assertThat(config.getInstanceId()).isEqualTo("mhhost:mytest:1"); - assertThat(config.getNonSecurePort()).isEqualTo(7000); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/EurekaTestConfigBeanTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/EurekaTestConfigBeanTests.java deleted file mode 100644 index 3d11cb7a6..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/EurekaTestConfigBeanTests.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.sidecar; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", "spring.application.instance_id=1", - "eureka.instance.hostname=mhhost", "sidecar.port=7000", - "sidecar.ip-address=127.0.0.1" }) -public class EurekaTestConfigBeanTests { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBean() { - assertThat(this.config.getAppname()).isEqualTo("mytest"); - assertThat(this.config.getHostname()).isEqualTo("mhhost"); - assertThat(this.config.getInstanceId()).isEqualTo("mhhost:mytest:1"); - assertThat(this.config.getNonSecurePort()).isEqualTo(7000); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandlerTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandlerTests.java deleted file mode 100644 index 9c4b49c52..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandlerTests.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.sidecar; - -import com.netflix.appinfo.InstanceInfo.InstanceStatus; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; - -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.MockitoAnnotations.initMocks; - -/** - * @author Spencer Gibb - */ -public class LocalApplicationHealthCheckHandlerTests { - - @Mock - private HealthIndicator healthIndicator; - - @Before - public void setup() { - initMocks(this); - } - - @Test - public void upMappingWorks() { - assertStatus(InstanceStatus.UP, Health.up()); - } - - @Test - public void downMappingWorks() { - assertStatus(InstanceStatus.DOWN, Health.down()); - } - - @Test - public void outOfServiceMappingWorks() { - assertStatus(InstanceStatus.OUT_OF_SERVICE, Health.outOfService()); - } - - @Test - public void unknownMappingWorks() { - assertStatus(InstanceStatus.UNKNOWN, Health.unknown()); - } - - private void assertStatus(InstanceStatus expected, Health.Builder builder) { - given(healthIndicator.health()).willReturn(builder.build()); - - LocalApplicationHealthCheckHandler handler = new LocalApplicationHealthCheckHandler( - healthIndicator); - InstanceStatus status = handler.getStatus(InstanceStatus.UP); - assertThat(status).isEqualTo(expected); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/ManagementContextPathStatusAndHealthCheckUrlsTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/ManagementContextPathStatusAndHealthCheckUrlsTests.java deleted file mode 100644 index b133a47f4..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/ManagementContextPathStatusAndHealthCheckUrlsTests.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.sidecar; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - value = { "spring.application.name=mytest", "spring.cloud.client.hostname=mhhost", - "spring.application.instance_id=1", "eureka.instance.hostname=mhhost1", - "sidecar.hostname=mhhost2", "sidecar.port=7000", - "sidecar.ipAddress=127.0.0.1", - "management.server.servlet.context-path=/foo" }) -public class ManagementContextPathStatusAndHealthCheckUrlsTests { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testStatusAndHealthCheckUrls() { - assertThat(config.getStatusPageUrl()) - .isEqualTo("http://mhhost2:0/foo/actuator/info"); - assertThat(config.getHealthCheckUrl()) - .isEqualTo("http://mhhost2:0/foo/actuator/health"); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/NewPropertyEurekaTestConfigBeanTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/NewPropertyEurekaTestConfigBeanTests.java deleted file mode 100644 index 1240f535c..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/NewPropertyEurekaTestConfigBeanTests.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.sidecar; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", "spring.application.instance_id=1", - "sidecar.hostname=mhhost", "sidecar.port=7000", - "sidecar.ip-address=127.0.0.1" }) -public class NewPropertyEurekaTestConfigBeanTests { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBean() { - assertThat(config.getAppname()).isEqualTo("mytest"); - assertThat(config.getHostname()).isEqualTo("mhhost"); - assertThat(config.getInstanceId()).isEqualTo("mhhost:mytest:1"); - assertThat(config.getNonSecurePort()).isEqualTo(7000); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/PreferIpAddressTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/PreferIpAddressTests.java deleted file mode 100644 index 3b84b0717..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/PreferIpAddressTests.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.sidecar; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", "spring.application.instance_id=1", - "eureka.instance.hostname=mhhost1", "sidecar.hostname=mhhost2", - "sidecar.port=7000", "sidecar.ip-address=10.0.0.1", - "eureka.instance.prefer-ip-address=true" }) -public class PreferIpAddressTests { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBeanPreferIpAddress() { - assertThat(config.getAppname()).isEqualTo("mytest"); - assertThat(config.getHostname()).isEqualTo("10.0.0.1"); - assertThat(config.getInstanceId()).isEqualTo("mhhost:mytest:1"); - assertThat(config.getNonSecurePort()).isEqualTo(7000); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SecurePortEnableds.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SecurePortEnableds.java deleted file mode 100644 index 6bce2d2ca..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SecurePortEnableds.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.sidecar; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - value = { "sidecar.port=7000", "sidecar.ip-address=127.0.0.1", - "sidecar.secure-port-enabled=true" }) -public class SecurePortEnableds { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testThatSecureEnabledOptionIsSetFromPropertyFile() { - assertThat(this.config.isSecurePortEnabled()).isEqualTo(true); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/ServerContextPathStatusAndHealthCheckUrlsTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/ServerContextPathStatusAndHealthCheckUrlsTests.java deleted file mode 100644 index 08ef061f6..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/ServerContextPathStatusAndHealthCheckUrlsTests.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.sidecar; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - value = { "spring.application.name=mytest", "spring.cloud.client.hostname=mhhost", - "spring.application.instance_id=1", "eureka.instance.hostname=mhhost1", - "sidecar.hostname=mhhost2", "sidecar.port=7000", - "sidecar.ipAddress=127.0.0.1", "server.servlet.context-path=/foo" }) -public class ServerContextPathStatusAndHealthCheckUrlsTests { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testStatusAndHealthCheckUrls() { - assertThat(config.getStatusPageUrl()) - .isEqualTo("http://mhhost2:0/foo/actuator/info"); - assertThat(config.getHealthCheckUrl()) - .isEqualTo("http://mhhost2:0/foo/actuator/health"); - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplication.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplication.java deleted file mode 100644 index c2ee06b2f..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplication.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.sidecar; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.cloud.netflix.eureka.metadata.DefaultManagementMetadataProvider; -import org.springframework.cloud.netflix.eureka.metadata.ManagementMetadata; -import org.springframework.cloud.netflix.eureka.metadata.ManagementMetadataProvider; -import org.springframework.context.annotation.Bean; -import org.springframework.web.bind.annotation.RestController; - -@SpringBootConfiguration -@EnableAutoConfiguration -@EnableSidecar -@RestController -public class SidecarApplication { - - public static void main(String[] args) { - SpringApplication.run(SidecarApplication.class, args); - } - - @Bean - public ManagementMetadataProvider managementMetadataProvider() { - // The default management metadata provider checks for random ports, we dont care - // about this in tests - return new DefaultManagementMetadataProvider() { - @Override - public ManagementMetadata get(EurekaInstanceConfigBean instance, - int serverPort, String serverContextPath, - String managementContextPath, Integer managementPort) { - String healthCheckUrl = getHealthCheckUrl(instance, serverPort, - serverContextPath, managementContextPath, managementPort, false); - String statusPageUrl = getStatusPageUrl(instance, serverPort, - serverContextPath, managementContextPath, managementPort); - - ManagementMetadata metadata = new ManagementMetadata(healthCheckUrl, - statusPageUrl, - managementPort == null ? serverPort : managementPort); - if (instance.isSecurePortEnabled()) { - metadata.setSecureHealthCheckUrl( - getHealthCheckUrl(instance, serverPort, serverContextPath, - managementContextPath, managementPort, true)); - } - return metadata; - } - }; - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplicationTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplicationTests.java deleted file mode 100644 index 6a7c222ee..000000000 --- a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/SidecarApplicationTests.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.sidecar; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.util.InetUtils; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -public class SidecarApplicationTests { - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", - "spring.application.instance_id=1", "eureka.instance.hostname=mhhost", - "sidecar.port=7000", "sidecar.ip-address=127.0.0.1" }) - public static class EurekaTestConfigBeanTest { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBean() { - assertThat(this.config.getAppname()).isEqualTo("mytest"); - assertThat(this.config.getHostname()).isEqualTo("mhhost"); - assertThat(this.config.getInstanceId()).isEqualTo("mhhost:mytest:1"); - assertThat(this.config.getNonSecurePort()).isEqualTo(7000); - } - - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", - "spring.application.instance_id=1", "sidecar.hostname=mhhost", - "sidecar.port=7000", "sidecar.ip-address=127.0.0.1" }) - public static class NewPropertyEurekaTestConfigBeanTest { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBean() { - assertThat(config.getAppname()).isEqualTo("mytest"); - assertThat(config.getHostname()).isEqualTo("mhhost"); - assertThat(config.getInstanceId()).isEqualTo("mhhost:mytest:1"); - assertThat(config.getNonSecurePort()).isEqualTo(7000); - } - - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", - "spring.application.instance_id=1", - "eureka.instance.hostname=mhhost1", "sidecar.hostname=mhhost2", - "sidecar.port=7000", "sidecar.ip-address=127.0.0.1" }) - public static class BothPropertiesEurekaTestConfigBeanTest { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBeanEurekaInstanceHostnamePropertyShouldBeUsed() { - assertThat(config.getAppname()).isEqualTo("mytest"); - assertThat(config.getHostname()).isEqualTo("mhhost1"); - assertThat(config.getInstanceId()).isEqualTo("mhhost:mytest:1"); - assertThat(config.getNonSecurePort()).isEqualTo(7000); - } - - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", - "spring.application.instance_id=1", - "eureka.instance.hostname=mhhost1", "sidecar.hostname=mhhost2", - "sidecar.port=7000", "sidecar.ip-address=10.0.0.1", - "eureka.instance.prefer-ip-address=true" }) - public static class PreferIpAddressTest { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBeanPreferIpAddress() { - assertThat(config.getAppname()).isEqualTo("mytest"); - assertThat(config.getHostname()).isEqualTo("10.0.0.1"); - assertThat(config.getInstanceId()).isEqualTo("mhhost:mytest:1"); - assertThat(config.getNonSecurePort()).isEqualTo(7000); - } - - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - value = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", - "spring.application.instance_id=1", - "eureka.instance.hostname=mhhost1", "sidecar.hostname=mhhost2", - "sidecar.port=7000", "sidecar.ipAddress=127.0.0.1", - "management.context-path=/foo" }) - public static class ManagementContextPathStatusAndHealthCheckUrls { - - @Autowired - EurekaInstanceConfigBean config; - - public void testStatusAndHealthCheckUrls() { - assertThat(config.getStatusPageUrl()).isEqualTo("https://mhhost2:0/foo/info"); - assertThat(config.getHealthCheckUrl()) - .isEqualTo("https://mhhost2:0/foo/health"); - } - - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - value = { "spring.application.name=mytest", - "spring.cloud.client.hostname=mhhost", - "spring.application.instance_id=1", - "eureka.instance.hostname=mhhost1", "sidecar.hostname=mhhost2", - "sidecar.port=7000", "sidecar.ipAddress=127.0.0.1", - "server.context-path=/foo" }) - public static class ServerContextPathStatusAndHealthCheckUrls { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testStatusAndHealthCheckUrls() { - assertThat(config.getStatusPageUrl()).isEqualTo("https://mhhost2:0/foo/info"); - assertThat(config.getHealthCheckUrl()) - .isEqualTo("https://mhhost2:0/foo/health"); - } - - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - value = { "sidecar.accept-all-ssl-certificates=false" }) - public static class AcceptAllSslCertificatesContext { - - @Autowired - RestTemplate restTemplate; - - @Test - public void testUseRestTemplateWhenHttpClientIsNotAvailable() { - assertThat(restTemplate.getRequestFactory()).isNull(); - } - - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, - value = { "sidecar.port=7000", "sidecar.ip-address=127.0.0.1", - "sidecar.secure-port-enabled=true" }) - public static class SecurePortEnabled { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testThatSecureEnabledOptionIsSetFromPropertyFile() { - assertThat(this.config.isSecurePortEnabled()).isEqualTo(true); - } - - } - - @RunWith(SpringRunner.class) - @SpringBootTest(classes = EurekaInstanceConfigBeanOverrideApplication.class, - webEnvironment = RANDOM_PORT) - public static class EurekaInstanceConfigBeanOverrideTest { - - @Autowired - EurekaInstanceConfigBean config; - - @Test - public void testEurekaConfigBeanOverride() { - assertThat(this.config.getHostname()).isEqualTo("overridden"); - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @EnableSidecar - protected static class EurekaInstanceConfigBeanOverrideApplication { - - @Bean - public EurekaInstanceConfigBean eurekaInstanceConfigBean(InetUtils inetUtils) { - EurekaInstanceConfigBean eurekaInstanceConfigBean = new EurekaInstanceConfigBean( - inetUtils); - eurekaInstanceConfigBean.setHostname("overridden"); - return eurekaInstanceConfigBean; - } - - } - -} diff --git a/spring-cloud-netflix-sidecar/src/test/resources/application.yml b/spring-cloud-netflix-sidecar/src/test/resources/application.yml deleted file mode 100644 index 2ea917289..000000000 --- a/spring-cloud-netflix-sidecar/src/test/resources/application.yml +++ /dev/null @@ -1,30 +0,0 @@ -server: - port: 5678 -spring: - application: - name: sidecarTest - -sidecar: - port: 8000 - health-uri: http://localhost:8000/src/test/resources/health.json - accept-all-ssl-certificates: true - -eureka: - instance: - app-group-name: mysidecargroup - client: - serviceUrl: - defaultZone: https://user:password@localhost:8761/eureka/ - -ribbon: - ServerListRefreshInterval: 5000 - ReadTimeout: 7777 - -endpoints: - refresh: - enabled: true - shutdown: - enabled: true - health: - sensitive: false - diff --git a/spring-cloud-netflix-sidecar/src/test/resources/bootstrap.yml b/spring-cloud-netflix-sidecar/src/test/resources/bootstrap.yml deleted file mode 100644 index bbd589280..000000000 --- a/spring-cloud-netflix-sidecar/src/test/resources/bootstrap.yml +++ /dev/null @@ -1,7 +0,0 @@ -spring: - #application: - # name: sideCarTest - cloud: - config: - username: user - password: password diff --git a/spring-cloud-netflix-sidecar/src/test/resources/health.json b/spring-cloud-netflix-sidecar/src/test/resources/health.json deleted file mode 100644 index 41f3615e9..000000000 --- a/spring-cloud-netflix-sidecar/src/test/resources/health.json +++ /dev/null @@ -1 +0,0 @@ -{"status":"UP"} \ No newline at end of file diff --git a/spring-cloud-netflix-turbine-stream/.jdk8 b/spring-cloud-netflix-turbine-stream/.jdk8 deleted file mode 100644 index e69de29bb..000000000 diff --git a/spring-cloud-netflix-turbine-stream/pom.xml b/spring-cloud-netflix-turbine-stream/pom.xml deleted file mode 100644 index 512e78c50..000000000 --- a/spring-cloud-netflix-turbine-stream/pom.xml +++ /dev/null @@ -1,140 +0,0 @@ - - - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT - .. - - spring-cloud-netflix-turbine-stream - jar - Spring Cloud Netflix Turbine Stream - Spring Cloud Netflix Turbine Stream - - 2.0.0-DP.2 - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.20 - - - ${project.version} - - - - - - - - - com.netflix.turbine - turbine-core - ${turbine.version} - - - com.netflix.rxjava - rxjava-core - - - org.slf4j - slf4j-simple - - - - - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.cloud - spring-cloud-commons - true - - - org.springframework.integration - spring-integration-core - - - org.springframework.cloud - spring-cloud-netflix-hystrix - - - org.springframework.cloud - spring-cloud-stream - - - org.springframework.boot - spring-boot-starter-web - - - - - com.netflix.turbine - turbine-core - - - io.reactivex - rxjava - - - org.springframework.boot - spring-boot-starter-webflux - - - io.reactivex - rxjava-reactive-streams - - - org.springframework.cloud - spring-cloud-stream-binder-rabbit - true - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - org.springframework.boot - spring-boot-starter-test - test - - - io.projectreactor - reactor-test - test - - - org.springframework.cloud - spring-cloud-starter-contract-stub-runner - test - - - org.springframework.cloud - spring-cloud-netflix-hystrix-contract - test - - - org.springframework.cloud - spring-cloud-stream-test-support - test - - - diff --git a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/EnableTurbineStream.java b/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/EnableTurbineStream.java deleted file mode 100644 index 188a06b9b..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/EnableTurbineStream.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.stream; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.context.annotation.Import; - -/** - * Run the RxNetty based Spring Cloud Turbine Stream server. Based on Netflix Turbine 2 - * and Spring Cloud Stream - * - * @author Spencer Gibb - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Import(TurbineStreamConfiguration.class) -public @interface EnableTurbineStream { - -} diff --git a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/HystrixStreamAggregator.java b/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/HystrixStreamAggregator.java deleted file mode 100644 index fd154c761..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/HystrixStreamAggregator.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.stream; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.Map; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import rx.subjects.PublishSubject; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.messaging.handler.annotation.Payload; -import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; - -/** - * @author Spencer Gibb - */ -@Component // needed for ServiceActivator to be picked up -public class HystrixStreamAggregator { - - private static final Log log = LogFactory.getLog(HystrixStreamAggregator.class); - - private ObjectMapper objectMapper; - - private PublishSubject> subject; - - @Autowired - public HystrixStreamAggregator(ObjectMapper objectMapper, - PublishSubject> subject) { - this.objectMapper = objectMapper; - this.subject = subject; - } - - @ServiceActivator(inputChannel = TurbineStreamClient.INPUT) - public void sendToSubject(@Payload byte[] bytePayload) { - String payload = new String(bytePayload, StandardCharsets.UTF_8); - if (log.isTraceEnabled()) { - log.trace("Received hystrix stream payload string: " + payload); - } - if (payload.startsWith("\"")) { - // Legacy payload from an Angel client - payload = payload.substring(1, payload.length() - 1); - payload = payload.replace("\\\"", "\""); - } - try { - if (payload.startsWith("[")) { - @SuppressWarnings("unchecked") - List> list = this.objectMapper.readValue(payload, - List.class); - for (Map map : list) { - sendMap(map); - } - } - else { - @SuppressWarnings("unchecked") - Map map = this.objectMapper.readValue(payload, Map.class); - sendMap(map); - } - } - catch (IOException ex) { - log.error("Error receiving hystrix stream payload: " + payload, ex); - } - } - - private void sendMap(Map map) { - Map data = getPayloadData(map); - if (log.isDebugEnabled()) { - log.debug("Received hystrix stream payload: " + data); - } - this.subject.onNext(data); - } - - public static Map getPayloadData(Map jsonMap) { - @SuppressWarnings("unchecked") - Map origin = (Map) jsonMap.get("origin"); - String instanceId = null; - if (origin.containsKey("id")) { - instanceId = origin.get("id").toString(); - } - if (!StringUtils.hasText(instanceId)) { - // TODO: instanceid template - instanceId = origin.get("serviceId") + ":" + origin.get("host") + ":" - + origin.get("port"); - } - @SuppressWarnings("unchecked") - Map data = (Map) jsonMap.get("data"); - data.put("instanceId", instanceId); - return data; - } - -} diff --git a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineApplication.java b/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineApplication.java deleted file mode 100644 index de0219304..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineApplication.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2015-2019 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 - * - * https://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.stream; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.context.annotation.Configuration; - -/** - * Turbine application class. - * - * @author Dave Syer - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@EnableAutoConfiguration -@EnableTurbineStream -public class TurbineApplication { - - public static void main(String[] args) { - new SpringApplicationBuilder(TurbineApplication.class) - .properties("spring.config.name=turbine").run(args); - } - -} diff --git a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineController.java b/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineController.java deleted file mode 100644 index e6fd609db..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineController.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2014-2019 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 - * - * https://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.stream; - -import java.time.Duration; -import java.util.Collections; -import java.util.Map; - -import com.netflix.turbine.aggregator.InstanceKey; -import com.netflix.turbine.aggregator.StreamAggregator; -import com.netflix.turbine.internal.JsonUtility; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Flux; -import rx.Observable; -import rx.RxReactiveStreams; -import rx.subjects.PublishSubject; - -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * Turbine stream controller. - * - * @author Spencer Gibb - * @author Ryan Baxter - */ -@RestController -public class TurbineController { - - private static final Log log = LogFactory.getLog(TurbineController.class); - - private final Flux flux; - - public TurbineController(PublishSubject> hystrixSubject) { - Observable> stream = StreamAggregator - .aggregateGroupedStreams(hystrixSubject.groupBy( - data -> InstanceKey.create((String) data.get("instanceId")))) - .doOnUnsubscribe(() -> log.info("Unsubscribing aggregation.")) - .doOnSubscribe(() -> log.info("Starting aggregation")).flatMap(o -> o); - Flux> ping = Flux - .interval(Duration.ofSeconds(5), Duration.ofSeconds(10)) - .map(l -> Collections.singletonMap("type", (Object) "ping")).share(); - flux = Flux.merge(RxReactiveStreams.toPublisher(stream), ping).share() - .map(JsonUtility::mapToJson); - } - - @GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE) - public Flux stream() { - return this.flux; - } - -} diff --git a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamAutoConfiguration.java b/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamAutoConfiguration.java deleted file mode 100644 index fbaa59616..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamAutoConfiguration.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.stream; - -import java.util.Map; - -import javax.annotation.PostConstruct; - -import com.fasterxml.jackson.databind.ObjectMapper; -import rx.subjects.PublishSubject; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.stream.annotation.EnableBinding; -import org.springframework.cloud.stream.config.BindingProperties; -import org.springframework.cloud.stream.config.BindingServiceProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Autoconfiguration for a Spring Cloud Turbine using Spring Cloud Stream. Enabled by - * default if spring-cloud-stream is on the classpath, and can be switched off with - * turbine.stream.enabled. - * - * @author Spencer Gibb - * @author Dave Syer - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(EnableBinding.class) -@ConditionalOnProperty(value = "turbine.stream.enabled", matchIfMissing = true) -@EnableBinding(TurbineStreamClient.class) -public class TurbineStreamAutoConfiguration { - - @Autowired - private BindingServiceProperties bindings; - - @Autowired - private TurbineStreamProperties properties; - - @PostConstruct - public void init() { - BindingProperties inputBinding = this.bindings.getBindings() - .get(TurbineStreamClient.INPUT); - if (inputBinding == null) { - this.bindings.getBindings().put(TurbineStreamClient.INPUT, - new BindingProperties()); - } - BindingProperties input = this.bindings.getBindings() - .get(TurbineStreamClient.INPUT); - if (input.getDestination() == null) { - input.setDestination(this.properties.getDestination()); - } - if (input.getContentType() == null) { - input.setContentType(this.properties.getContentType()); - } - } - - @Bean - public HystrixStreamAggregator hystrixStreamAggregator(ObjectMapper mapper, - PublishSubject> publisher) { - return new HystrixStreamAggregator(mapper, publisher); - } - -} diff --git a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamClient.java b/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamClient.java deleted file mode 100644 index c60dd2d9a..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamClient.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.stream; - -import org.springframework.cloud.stream.annotation.Input; -import org.springframework.messaging.SubscribableChannel; - -/** - * @author Dave Syer - * - */ -public interface TurbineStreamClient { - - /** - * Turbine Stream Input name. - */ - String INPUT = "turbineStreamInput"; - - @Input(INPUT) - SubscribableChannel turbineStreamInput(); - -} diff --git a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamConfiguration.java b/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamConfiguration.java deleted file mode 100644 index e36fad900..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamConfiguration.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.stream; - -import java.util.Map; - -import rx.subjects.PublishSubject; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - * @author Daniel Lavoie - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties(TurbineStreamProperties.class) -public class TurbineStreamConfiguration { - - @Bean - public HasFeatures Feature() { - return HasFeatures.namedFeature("Turbine (Stream)", - TurbineStreamProperties.class); - } - - @Bean - public PublishSubject> hystrixSubject() { - return PublishSubject.create(); - } - - @Bean - public TurbineController turbineController( - PublishSubject> hystrixSubject) { - return new TurbineController(hystrixSubject); - } - -} diff --git a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamProperties.java b/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamProperties.java deleted file mode 100644 index d05939765..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamProperties.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.stream; - -import java.util.Objects; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.netflix.hystrix.HystrixConstants; -import org.springframework.http.MediaType; - -/** - * @author Dave Syer - * @author Gregor Zurowski - */ -@ConfigurationProperties("turbine.stream") -public class TurbineStreamProperties { - - private String destination = HystrixConstants.HYSTRIX_STREAM_DESTINATION; - - private String contentType = MediaType.APPLICATION_JSON_VALUE; - - public String getDestination() { - return destination; - } - - public void setDestination(String destination) { - this.destination = destination; - } - - public String getContentType() { - return contentType; - } - - public void setContentType(String contentType) { - this.contentType = contentType; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - TurbineStreamProperties that = (TurbineStreamProperties) o; - return Objects.equals(destination, that.destination) - && Objects.equals(contentType, that.contentType); - } - - @Override - public int hashCode() { - return Objects.hash(destination, contentType); - } - - @Override - public String toString() { - return new StringBuilder("TurbineStreamProperties{").append(", ") - .append("destination='").append(destination).append("', ") - .append("contentType='").append(contentType).append("'}").toString(); - } - -} diff --git a/spring-cloud-netflix-turbine-stream/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-turbine-stream/src/main/resources/META-INF/spring.factories deleted file mode 100644 index e4ee427e2..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.turbine.stream.TurbineStreamAutoConfiguration diff --git a/spring-cloud-netflix-turbine-stream/src/main/resources/turbine.yml b/spring-cloud-netflix-turbine-stream/src/main/resources/turbine.yml deleted file mode 100644 index 0f4cef40c..000000000 --- a/spring-cloud-netflix-turbine-stream/src/main/resources/turbine.yml +++ /dev/null @@ -1,10 +0,0 @@ -info: - component: Turbine Stream -spring: - application: - name: turbine - jmx: - default_domain: cloud.turbine.stream - -server: - port: 8989 diff --git a/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/HystrixStreamAggregatorTests.java b/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/HystrixStreamAggregatorTests.java deleted file mode 100644 index ae87f7ca9..000000000 --- a/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/HystrixStreamAggregatorTests.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.stream; - -import java.util.Map; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Rule; -import org.junit.Test; -import rx.subjects.PublishSubject; - -import org.springframework.boot.test.system.OutputCaptureRule; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.core.IsNot.not; - -public class HystrixStreamAggregatorTests { - - private ObjectMapper mapper = new ObjectMapper(); - - private PublishSubject> publisher = PublishSubject.create(); - - private HystrixStreamAggregator aggregator = new HystrixStreamAggregator(this.mapper, - this.publisher); - - @Rule - public OutputCaptureRule output = new OutputCaptureRule(); - - private static String PAYLOAD = "{\"origin\":{\"host\":\"dsyer\",\"port\":-1," - + "\"serviceId\":\"application\",\"id\":\"application\"},\"data\":{\"type\":" - + "\"HystrixCommand\",\"name\":\"application.ok\",\"group\":\"MyService\"," - + "\"currentTime\":1457089387160,\"isCircuitBreakerOpen\":false," - + "\"errorPercentage\":0,\"errorCount\":0,\"requestCount\":0," - + "\"rollingCountCollapsedRequests\":0,\"rollingCountExceptionsThrown\":0," - + "\"rollingCountFailure\":0,\"rollingCountFallbackFailure\":0," - + "\"rollingCountFallbackRejection\":0,\"rollingCountFallbackSuccess\":0," - + "\"rollingCountResponsesFromCache\":0,\"rollingCountSemaphoreRejected\":0," - + "\"rollingCountShortCircuited\":0,\"rollingCountSuccess\":1," - + "\"rollingCountThreadPoolRejected\":0,\"rollingCountTimeout\":0," - + "\"currentConcurrentExecutionCount\":0,\"latencyExecute_mean\":0," - + "\"latencyExecute\":{\"0\":0,\"25\":0,\"50\":0,\"75\":0,\"90\":0,\"95\":0," - + "\"99\":0,\"99.5\":0,\"100\":0},\"latencyTotal_mean\":0,\"latencyTotal" - + "\":{\"0\":0,\"25\":0,\"50\":0,\"75\":0,\"90\":0,\"95\":0,\"99\":0,\"99.5" - + "\":0,\"100\":0},\"propertyValue_circuitBreakerRequestVolumeThreshold\":20," - + "\"propertyValue_circuitBreakerSleepWindowInMilliseconds\":5000," - + "\"propertyValue_circuitBreakerErrorThresholdPercentage\":50," - + "\"propertyValue_circuitBreakerForceOpen\":false," - + "\"propertyValue_circuitBreakerForceClosed\":false," - + "\"propertyValue_circuitBreakerEnabled\":true," - + "\"propertyValue_executionIsolationStrategy\":\"THREAD\"," - + "\"propertyValue_executionIsolationThreadTimeoutInMilliseconds\":1000," - + "\"propertyValue_executionIsolationThreadInterruptOnTimeout\":true," - + "\"propertyValue_executionIsolationThreadPoolKeyOverride\":null," - + "\"propertyValue_executionIsolationSemaphoreMaxConcurrentRequests\":10," - + "\"propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests\":10," - + "\"propertyValue_metricsRollingStatisticalWindowInMilliseconds\":10000," - + "\"propertyValue_requestCacheEnabled\":true," - + "\"propertyValue_requestLogEnabled\":true,\"reportingHosts\":1}}"; - - @Test - public void messageDecoded() throws Exception { - this.publisher.subscribe( - map -> assertThat(map.get("type")).isEqualTo("HystrixCommand")); - this.aggregator.sendToSubject(PAYLOAD.getBytes()); - this.output.expect(not(containsString("ERROR"))); - } - - @Test - public void messageWrappedInArray() throws Exception { - this.publisher.subscribe( - map -> assertThat(map.get("type")).isEqualTo("HystrixCommand")); - this.aggregator.sendToSubject(new StringBuilder().append("[").append(PAYLOAD) - .append("]").toString().getBytes()); - this.output.expect(not(containsString("ERROR"))); - } - - @Test - public void doubleEncodedMessage() throws Exception { - this.publisher.subscribe( - map -> assertThat(map.get("type")).isEqualTo("HystrixCommand")); - // If The JSON is embedded in a JSON String this is what it looks like - String payload = "\"" + PAYLOAD.replace("\"", "\\\"") + "\""; - this.aggregator.sendToSubject(payload.getBytes()); - this.output.expect(not(containsString("ERROR"))); - } - -} diff --git a/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamConfigurationTest.java b/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamConfigurationTest.java deleted file mode 100644 index f37c8ac60..000000000 --- a/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamConfigurationTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.stream; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Before; - -/** - * @author Yongsung Yoon - */ -public class TurbineStreamConfigurationTest { - - TurbineStreamConfiguration turbineStreamConfiguration; - - List> testMetricList; - - @Before - public void setUp() { - turbineStreamConfiguration = new TurbineStreamConfiguration(); - testMetricList = createBasicTestMetricList(); - } - - private List> createBasicTestMetricList() { - List> testDataList = new ArrayList<>(); - HashMap map = new HashMap<>(); - map.put("instanceId", "abc:127.0.0.1:8080"); - map.put("type", "HystrixCommand"); - testDataList.add(map); - - map = new HashMap<>(); - map.put("instanceId", "def:127.0.0.1:8080"); - map.put("type", "HystrixCommand"); - testDataList.add(map); - - map = new HashMap<>(); - map.put("instanceId", "xyz:127.0.0.1:8080"); - map.put("type", "HystrixThreadPool"); - testDataList.add(map); - - map = new HashMap<>(); - map.put("type", "ping"); - testDataList.add(map); - - map = new HashMap<>(); - map.put("dummy", "data"); - testDataList.add(map); - - return testDataList; - } - -} diff --git a/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamTests.java b/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamTests.java deleted file mode 100644 index 8b2a00250..000000000 --- a/spring-cloud-netflix-turbine-stream/src/test/java/org/springframework/cloud/netflix/turbine/stream/TurbineStreamTests.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.stream; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URI; -import java.util.Map; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.contract.stubrunner.StubTrigger; -import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner; -import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties.StubsMode; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpRequest; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.integration.support.management.MessageChannelMetrics; -import org.springframework.messaging.SubscribableChannel; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Spencer Gibb - * @author Daniel Lavoie - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, properties = { - // TODO: we don't need this if we harmonize the turbine and hystrix - // destinations - // https://github.com/spring-cloud/spring-cloud-netflix/issues/1948 - "spring.cloud.stream.bindings.turbineStreamInput.destination=hystrixStreamOutput", - "spring.jmx.enabled=true", "stubrunner.workOffline=true", - "stubrunner.ids=org.springframework.cloud:spring-cloud-netflix-hystrix-stream:${projectVersion:2.1.3.BUILD-SNAPSHOT}:stubs" }) -@AutoConfigureStubRunner(stubsMode = StubsMode.LOCAL) -public class TurbineStreamTests { - - @Autowired - StubTrigger stubTrigger; - - @Autowired - ObjectMapper mapper; - - @Autowired - @Qualifier(TurbineStreamClient.INPUT) - SubscribableChannel input; - - RestTemplate rest = new RestTemplate(); - - @Autowired - TurbineStreamConfiguration turbine; - - @LocalServerPort - int port; - - @Test - public void contextLoads() throws Exception { - rest.getInterceptors().add(new NonClosingInterceptor()); - int count = ((MessageChannelMetrics) input).getSendCount(); - ResponseEntity response = rest.execute( - new URI("http://localhost:" + port + "/"), HttpMethod.GET, null, - this::extract); - assertThat(response.getHeaders().getContentType() - .isCompatibleWith(MediaType.TEXT_EVENT_STREAM)).isTrue(); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); - Map metrics = extractMetrics(response.getBody()); - assertThat(metrics).containsEntry("type", "HystrixCommand"); - assertThat(((MessageChannelMetrics) input).getSendCount()).isEqualTo(count + 1); - } - - private boolean containsMetrics(String line) { - return line.startsWith("data:") && !line.contains("ping"); - } - - @SuppressWarnings("unchecked") - private Map extractMetrics(String body) throws Exception { - for (String value : body.split("\n")) { - if (containsMetrics(value)) { - return mapper.readValue(value.split("data:")[1], Map.class); - } - } - return null; - } - - private ResponseEntity extract(ClientHttpResponse response) - throws IOException { - // The message has to be sent after the endpoint is activated, so this is a - // convenient place to put it - stubTrigger.trigger("metrics"); - - String responseBody = ""; - boolean metricFound = false; - try (BufferedReader buffer = new BufferedReader( - new InputStreamReader(response.getBody()))) { - do { - String line = buffer.readLine(); - responseBody += line + "\n"; - if (containsMetrics(line)) { - metricFound = true; - } - } - while (!metricFound); - } - - return ResponseEntity.status(response.getStatusCode()) - .headers(response.getHeaders()).body(responseBody); - } - - @EnableAutoConfiguration - @EnableTurbineStream - @Configuration(proxyBeanMethods = false) - public static class TestConfig { - - } - - /** - * Special interceptor that prevents the response from being closed and allows us to - * assert on the contents of an event stream. - */ - private class NonClosingInterceptor implements ClientHttpRequestInterceptor { - - @Override - public ClientHttpResponse intercept(HttpRequest request, byte[] body, - ClientHttpRequestExecution execution) throws IOException { - return new NonClosingResponse(execution.execute(request, body)); - } - - private class NonClosingResponse implements ClientHttpResponse { - - private ClientHttpResponse delegate; - - NonClosingResponse(ClientHttpResponse delegate) { - this.delegate = delegate; - } - - @Override - public InputStream getBody() throws IOException { - return delegate.getBody(); - } - - @Override - public HttpHeaders getHeaders() { - return delegate.getHeaders(); - } - - @Override - public HttpStatus getStatusCode() throws IOException { - return delegate.getStatusCode(); - } - - @Override - public int getRawStatusCode() throws IOException { - return delegate.getRawStatusCode(); - } - - @Override - public String getStatusText() throws IOException { - return delegate.getStatusText(); - } - - @Override - public void close() { - } - - } - - } - -} diff --git a/spring-cloud-netflix-turbine/pom.xml b/spring-cloud-netflix-turbine/pom.xml deleted file mode 100644 index 68277b580..000000000 --- a/spring-cloud-netflix-turbine/pom.xml +++ /dev/null @@ -1,97 +0,0 @@ - - - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT - .. - - spring-cloud-netflix-turbine - jar - Spring Cloud Netflix Turbine - https://projects.spring.io/spring-cloud/ - - 1.0.0 - - - - - com.netflix.turbine - turbine-core - ${turbine.version} - - - javax.servlet - servlet-api - - - log4j - log4j - - - com.netflix.rxjava - rxjava-core - - - org.slf4j - slf4j-simple - - - org.mockito - mockito-all - - - - - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework.cloud - spring-cloud-context - true - - - org.springframework.cloud - spring-cloud-netflix-hystrix - true - - - org.springframework.cloud - spring-cloud-netflix-eureka-client - true - - - com.netflix.eureka - eureka-client - true - - - org.apache.httpcomponents - httpclient - - - com.netflix.turbine - turbine-core - - - org.springframework.boot - spring-boot-starter-test - test - - - diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/ClusterInformation.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/ClusterInformation.java deleted file mode 100644 index cb4a57f75..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/ClusterInformation.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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 java.util.Objects; - -/** - * @author Anastasiia Smirnova - * @author Ryan Baxter Contains cluster-relevant information, such as name and link. - */ -public class ClusterInformation { - - private String name; - - private String link; - - public ClusterInformation() { - } - - public ClusterInformation(String name, String link) { - this.name = name; - this.link = link; - } - - public String getName() { - return name; - } - - public String getLink() { - return link; - } - - public void setName(String name) { - this.name = name; - } - - public void setLink(String link) { - this.link = link; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ClusterInformation that = (ClusterInformation) o; - return Objects.equals(name, that.name) && Objects.equals(link, that.link); - } - - @Override - public int hashCode() { - return Objects.hash(name, link); - } - - @Override - public String toString() { - return "ClusterInformation{" + "name='" + name + '\'' + ", link='" + link + '\'' - + '}'; - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscovery.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscovery.java deleted file mode 100644 index d03e3df76..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscovery.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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 java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import com.netflix.turbine.discovery.Instance; -import com.netflix.turbine.discovery.InstanceDiscovery; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.expression.Expression; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; - -/** - * Class that encapsulates an {@link InstanceDiscovery} implementation that uses Spring - * Cloud Commons (see https://github.com/spring-cloud/spring-cloud-commons) The plugin - * requires a list of applications configured. It then queries the set of instances for * - * each application. Instance information retrieved from the {@link DiscoveryClient} must - * be translated to * something that Turbine can understand i.e the {@link Instance} - * class. - *

- * All the logic to perform this translation can be overriden here, so that you can - * provide your own implementation if needed. - * - * @author Spencer Gibb - */ -public class CommonsInstanceDiscovery implements InstanceDiscovery { - - private static final Log log = LogFactory.getLog(CommonsInstanceDiscovery.class); - - private static final String DEFAULT_CLUSTER_NAME_EXPRESSION = "serviceId"; - - protected static final String PORT_KEY = "port"; - - protected static final String SECURE_PORT_KEY = "securePort"; - - protected static final String FUSED_HOST_PORT_KEY = "fusedHostPort"; - - private final Expression clusterNameExpression; - - private DiscoveryClient discoveryClient; - - private TurbineProperties turbineProperties; - - private final boolean combineHostPort; - - public CommonsInstanceDiscovery(TurbineProperties turbineProperties, - DiscoveryClient discoveryClient) { - this(turbineProperties, DEFAULT_CLUSTER_NAME_EXPRESSION); - this.discoveryClient = discoveryClient; - } - - protected CommonsInstanceDiscovery(TurbineProperties turbineProperties, - String defaultExpression) { - this.turbineProperties = turbineProperties; - SpelExpressionParser parser = new SpelExpressionParser(); - String clusterNameExpression = turbineProperties.getClusterNameExpression(); - if (clusterNameExpression == null) { - clusterNameExpression = defaultExpression; - } - this.clusterNameExpression = parser.parseExpression(clusterNameExpression); - this.combineHostPort = turbineProperties.isCombineHostPort(); - } - - protected Expression getClusterNameExpression() { - return clusterNameExpression; - } - - public TurbineProperties getTurbineProperties() { - return turbineProperties; - } - - protected boolean isCombineHostPort() { - return combineHostPort; - } - - /** - * Method that queries DiscoveryClient for a list of configured application names. - * @return Collection of instances - */ - @Override - public Collection getInstanceList() throws Exception { - List instances = new ArrayList<>(); - List appNames = getApplications(); - if (appNames == null || appNames.size() == 0) { - log.info("No apps configured, returning an empty instance list"); - return instances; - } - log.info("Fetching instance list for apps: " + appNames); - for (String appName : appNames) { - try { - instances.addAll(getInstancesForApp(appName)); - } - catch (Exception ex) { - log.error("Failed to fetch instances for app: " + appName - + ", retrying once more", ex); - try { - instances.addAll(getInstancesForApp(appName)); - } - catch (Exception retryException) { - log.error("Failed again to fetch instances for app: " + appName - + ", giving up", ex); - } - } - } - return instances; - } - - protected List getApplications() { - return turbineProperties.getAppConfigList(); - } - - /** - * helper that fetches the Instances for each application from DiscoveryClient. - * @param serviceId Id of the service whose instances should be returned - * @return List of instances - * @throws Exception - retrieving and marshalling service instances may result in an - * Exception - */ - protected List getInstancesForApp(String serviceId) throws Exception { - List instances = new ArrayList<>(); - log.info("Fetching instances for app: " + serviceId); - List serviceInstances = discoveryClient.getInstances(serviceId); - if (serviceInstances == null || serviceInstances.isEmpty()) { - log.warn("DiscoveryClient returned null or empty for service: " + serviceId); - return instances; - } - try { - log.info("Received instance list for service: " + serviceId + ", size=" - + serviceInstances.size()); - for (ServiceInstance serviceInstance : serviceInstances) { - Instance instance = marshall(serviceInstance); - if (instance != null) { - instances.add(instance); - } - } - } - catch (Exception e) { - log.warn("Failed to retrieve instances from DiscoveryClient", e); - } - return instances; - } - - /** - * Private helper that marshals the information from each instance into something that - * Turbine can understand. Override this method for your own implementation. - * @param serviceInstance whose information should be marshaled - * @return Instance - */ - Instance marshall(ServiceInstance serviceInstance) { - String hostname = serviceInstance.getHost(); - String managementPort = serviceInstance.getMetadata().get("management.port"); - String port = managementPort == null ? String.valueOf(serviceInstance.getPort()) - : managementPort; - String cluster = getClusterName(serviceInstance); - Boolean status = Boolean.TRUE; // TODO: where to get? - if (hostname != null && cluster != null && status != null) { - Instance instance = getInstance(hostname, port, cluster, status); - - Map metadata = serviceInstance.getMetadata(); - boolean securePortEnabled = serviceInstance.isSecure(); - - addMetadata(instance, hostname, port, securePortEnabled, port, metadata); - - return instance; - } - else { - return null; - } - } - - protected void addMetadata(Instance instance, String hostname, String port, - boolean securePortEnabled, String securePort, Map metadata) { - // add metadata - if (metadata != null) { - instance.getAttributes().putAll(metadata); - } - - // add ports - instance.getAttributes().put(PORT_KEY, port); - if (securePortEnabled) { - instance.getAttributes().put(SECURE_PORT_KEY, securePort); - } - if (this.isCombineHostPort()) { - String fusedHostPort = securePortEnabled ? hostname + ":" + securePort - : instance.getHostname(); - instance.getAttributes().put(FUSED_HOST_PORT_KEY, fusedHostPort); - } - } - - protected Instance getInstance(String hostname, String port, String cluster, - Boolean status) { - String hostPart = this.isCombineHostPort() ? hostname + ":" + port : hostname; - return new Instance(hostPart, cluster, status); - } - - /** - * Helper that fetches the cluster name. Cluster is a Turbine concept and not a - * commons concept. By default we choose the amazon serviceId as the cluster. A custom - * implementation can be plugged in by overriding this method. - * @param object cluster whose name should be evaluated - * @return String name of the cluster - */ - protected String getClusterName(Object object) { - StandardEvaluationContext context = new StandardEvaluationContext(object); - Object value = this.clusterNameExpression.getValue(context); - if (value != null) { - return value.toString(); - } - return null; - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/ConfigurationBasedTurbineClustersProvider.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/ConfigurationBasedTurbineClustersProvider.java deleted file mode 100644 index ed755a4a2..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/ConfigurationBasedTurbineClustersProvider.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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 java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Provides clusters names for Turbine based on configuration value. - * - * @author Anastasiia Smirnova - */ -public class ConfigurationBasedTurbineClustersProvider - implements TurbineClustersProvider { - - private static final Log log = LogFactory - .getLog(ConfigurationBasedTurbineClustersProvider.class); - - private final TurbineAggregatorProperties properties; - - public ConfigurationBasedTurbineClustersProvider( - TurbineAggregatorProperties turbineAggregatorProperties) { - this.properties = turbineAggregatorProperties; - } - - @Override - public List getClusterNames() { - List clusterNames = properties.getClusterConfig(); - log.trace("Using clusters names: " + clusterNames); - return clusterNames; - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EnableTurbine.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EnableTurbine.java deleted file mode 100644 index c653c5c0f..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EnableTurbine.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2013-2014 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 - * - * https://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 java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.context.annotation.Import; - -/** - * @author Spencer Gibb - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Import(TurbineHttpConfiguration.class) -public @interface EnableTurbine { - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaBasedTurbineClustersProvider.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaBasedTurbineClustersProvider.java deleted file mode 100644 index f8f9bd5b8..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaBasedTurbineClustersProvider.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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 java.util.ArrayList; -import java.util.List; - -import com.netflix.discovery.EurekaClient; -import com.netflix.discovery.shared.Application; -import com.netflix.discovery.shared.Applications; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Provides clusters names for Turbine based on applications names registered in Eureka. - * - * @author Anastasiia Smirnova - */ -public class EurekaBasedTurbineClustersProvider implements TurbineClustersProvider { - - private static final Log log = LogFactory - .getLog(EurekaBasedTurbineClustersProvider.class); - - private final EurekaClient eurekaClient; - - public EurekaBasedTurbineClustersProvider(EurekaClient eurekaClient) { - this.eurekaClient = eurekaClient; - } - - @Override - public List getClusterNames() { - Applications applications = eurekaClient.getApplications(); - List registeredApplications = applications - .getRegisteredApplications(); - List appNames = new ArrayList<>(registeredApplications.size()); - for (Application application : registeredApplications) { - appNames.add(application.getName()); - } - log.trace("Using clusters names: " + appNames); - return appNames; - } - -} 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 deleted file mode 100644 index 4693017e8..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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 java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import com.netflix.appinfo.AmazonInfo; -import com.netflix.appinfo.DataCenterInfo; -import com.netflix.appinfo.InstanceInfo; -import com.netflix.appinfo.InstanceInfo.InstanceStatus; -import com.netflix.discovery.EurekaClient; -import com.netflix.discovery.shared.Application; -import com.netflix.turbine.discovery.Instance; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Class that encapsulates an {@link com.netflix.turbine.discovery.InstanceDiscovery} - * implementation that uses Eureka (see https://github.com/Netflix/eureka) The plugin - * requires a list of applications configured. It then queries the set of instances for - * each application. Instance information retrieved from Eureka must be translated to - * something that Turbine can understand i.e the - * {@link com.netflix.turbine.discovery.Instance} class. - *

- * All the logic to perform this translation can be overriden here, so that you can - * provide your own implementation if needed. - * - * @author Spencer Gibb - */ -public class EurekaInstanceDiscovery extends CommonsInstanceDiscovery { - - private static final Log log = LogFactory.getLog(EurekaInstanceDiscovery.class); - - private static final String EUREKA_DEFAULT_CLUSTER_NAME_EXPRESSION = "appName"; - - private static final String ASG_KEY = "asg"; - - private final EurekaClient eurekaClient; - - public EurekaInstanceDiscovery(TurbineProperties turbineProperties, - EurekaClient eurekaClient) { - super(turbineProperties, EUREKA_DEFAULT_CLUSTER_NAME_EXPRESSION); - this.eurekaClient = eurekaClient; - } - - /** - * Private helper that fetches the Instances for each application. - * @param serviceId of the service that the instance list should be returned for - * @return List of instances for a given service id - * @throws Exception - retrieving and marshalling service instances may result in an - * Exception - */ - @Override - protected List getInstancesForApp(String serviceId) throws Exception { - List instances = new ArrayList<>(); - log.info("Fetching instances for app: " + serviceId); - Application app = eurekaClient.getApplication(serviceId); - if (app == null) { - log.warn("Eureka returned null for app: " + serviceId); - return instances; - } - try { - List instancesForApp = app.getInstances(); - if (instancesForApp != null) { - log.info("Received instance list for app: " + serviceId + ", size=" - + instancesForApp.size()); - for (InstanceInfo iInfo : instancesForApp) { - Instance instance = marshall(iInfo); - if (instance != null) { - instances.add(instance); - } - } - } - } - catch (Exception e) { - log.warn("Failed to retrieve instances from Eureka", e); - } - return instances; - } - - /** - * Private helper that marshals the information from each instance into something that - * Turbine can understand. Override this method for your own implementation for - * parsing Eureka info. - * @param instanceInfo {@link InstanceInfo} to marshal - * @return {@link Instance} marshaled from provided {@link InstanceInfo} - */ - Instance marshall(InstanceInfo instanceInfo) { - String hostname = instanceInfo.getHostName(); - final String managementPort = instanceInfo.getMetadata().get("management.port"); - String port = managementPort == null ? String.valueOf(instanceInfo.getPort()) - : managementPort; - String cluster = getClusterName(instanceInfo); - Boolean status = parseInstanceStatus(instanceInfo.getStatus()); - if (hostname != null && cluster != null && status != null) { - Instance instance = getInstance(hostname, port, cluster, status); - - Map metadata = instanceInfo.getMetadata(); - boolean securePortEnabled = instanceInfo - .isPortEnabled(InstanceInfo.PortType.SECURE); - String securePort = String.valueOf(instanceInfo.getSecurePort()); - - addMetadata(instance, hostname, port, securePortEnabled, securePort, - metadata); - - // add amazon metadata - String asgName = instanceInfo.getASGName(); - if (asgName != null) { - instance.getAttributes().put(ASG_KEY, asgName); - } - - DataCenterInfo dcInfo = instanceInfo.getDataCenterInfo(); - if (dcInfo != null && dcInfo.getName().equals(DataCenterInfo.Name.Amazon)) { - AmazonInfo amznInfo = (AmazonInfo) dcInfo; - instance.getAttributes().putAll(amznInfo.getMetadata()); - } - - return instance; - } - else { - return null; - } - } - - /** - * Helper that returns whether the instance is Up of Down. - * @param status {@link InstanceStatus} instance to evaluate the status from - * @return {@code true} if {@link InstanceStatus} is UP - */ - protected Boolean parseInstanceStatus(InstanceStatus status) { - if (status == null) { - return null; - } - return status == InstanceStatus.UP; - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringAggregatorFactory.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringAggregatorFactory.java deleted file mode 100644 index e264183a2..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringAggregatorFactory.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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 java.util.Collection; - -import com.netflix.turbine.data.AggDataFromCluster; -import com.netflix.turbine.discovery.Instance; -import com.netflix.turbine.handler.PerformanceCriteria; -import com.netflix.turbine.handler.TurbineDataHandler; -import com.netflix.turbine.monitor.TurbineDataMonitor; -import com.netflix.turbine.monitor.cluster.AggregateClusterMonitor; -import com.netflix.turbine.monitor.cluster.ClusterMonitor; -import com.netflix.turbine.monitor.cluster.ClusterMonitorFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import static com.netflix.turbine.monitor.cluster.AggregateClusterMonitor.AggregatorClusterMonitorConsole; - -/** - * @author Spencer Gibb - */ -public class SpringAggregatorFactory - implements ClusterMonitorFactory { - - private static final Log log = LogFactory.getLog(SpringAggregatorFactory.class); - - private final TurbineClustersProvider clustersProvider; - - public SpringAggregatorFactory(TurbineClustersProvider clustersProvider) { - this.clustersProvider = clustersProvider; - } - - /** - * @return {@link com.netflix.turbine.monitor.cluster.ClusterMonitor} - * {@link com.netflix.turbine.data.AggDataFromCluster} - */ - @Override - public ClusterMonitor getClusterMonitor(String name) { - TurbineDataMonitor clusterMonitor = AggregateClusterMonitor.AggregatorClusterMonitorConsole - .findMonitor(name + "_agg"); - return (ClusterMonitor) clusterMonitor; - } - - public static TurbineDataMonitor findOrRegisterAggregateMonitor( - String clusterName) { - TurbineDataMonitor clusterMonitor = AggregatorClusterMonitorConsole - .findMonitor(clusterName + "_agg"); - if (clusterMonitor == null) { - log.info("Could not find monitors: " - + AggregatorClusterMonitorConsole.toString()); - clusterMonitor = new SpringClusterMonitor(clusterName + "_agg", clusterName); - clusterMonitor = AggregatorClusterMonitorConsole - .findOrRegisterMonitor(clusterMonitor); - } - return clusterMonitor; - } - - @Override - public void initClusterMonitors() { - for (String clusterName : clustersProvider.getClusterNames()) { - - ClusterMonitor clusterMonitor = (ClusterMonitor) findOrRegisterAggregateMonitor( - clusterName); - clusterMonitor.registerListenertoClusterMonitor(this.StaticListener); - try { - clusterMonitor.startMonitor(); - } - catch (Exception ex) { - log.warn("Could not init cluster monitor for: " + clusterName); - clusterMonitor.stopMonitor(); - clusterMonitor.getDispatcher().stopDispatcher(); - } - } - } - - /** - * shutdown all configured cluster monitors. - */ - @Override - public void shutdownClusterMonitors() { - for (String clusterName : clustersProvider.getClusterNames()) { - ClusterMonitor clusterMonitor = (ClusterMonitor) AggregateClusterMonitor - .findOrRegisterAggregateMonitor(clusterName); - clusterMonitor.stopMonitor(); - clusterMonitor.getDispatcher().stopDispatcher(); - } - } - - private TurbineDataHandler StaticListener = new TurbineDataHandler() { - - @Override - public String getName() { - return "StaticListener_For_Aggregator"; - } - - @Override - public void handleData(Collection stats) { - } - - @Override - public void handleHostLost(Instance host) { - } - - @Override - public PerformanceCriteria getCriteria() { - return SpringAggregatorFactory.this.NonCriticalCriteria; - } - - }; - - private PerformanceCriteria NonCriticalCriteria = new PerformanceCriteria() { - - @Override - public boolean isCritical() { - return false; - } - - @Override - public int getMaxQueueSize() { - return 0; - } - - @Override - public int numThreads() { - return 0; - } - - }; - -} 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 deleted file mode 100644 index a476609af..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/SpringClusterMonitor.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.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<>(), 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", - "actuator/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; - } - }; - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineAggregatorProperties.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineAggregatorProperties.java deleted file mode 100644 index 739202baa..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineAggregatorProperties.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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 java.util.Collections; -import java.util.List; -import java.util.Objects; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * @author Anastasiia Smirnova - */ -@ConfigurationProperties("turbine.aggregator") -public class TurbineAggregatorProperties { - - private static final String DEFAULT = "default"; - - /** - * The list of cluster names. - */ - private List clusterConfig = Collections.singletonList(DEFAULT); - - public List getClusterConfig() { - return clusterConfig; - } - - public void setClusterConfig(List clusterConfig) { - this.clusterConfig = clusterConfig; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - TurbineAggregatorProperties that = (TurbineAggregatorProperties) o; - return Objects.equals(clusterConfig, that.clusterConfig); - } - - @Override - public int hashCode() { - return Objects.hash(clusterConfig); - } - - @Override - public String toString() { - return "TurbineAggregatorProperties{" + "clusterConfig='" + clusterConfig + '\'' - + '}'; - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineClustersProvider.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineClustersProvider.java deleted file mode 100644 index 760c05870..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineClustersProvider.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2013-2017 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 - * - * https://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 java.util.List; - -/** - * Interface that gives possibility to customize which clusters names Turbine will use. - * - * @author Anastasiia Smirnova - */ -public interface TurbineClustersProvider { - - List getClusterNames(); - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineController.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineController.java deleted file mode 100644 index ad6928cd4..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineController.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2018-2019 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 - * - * https://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 java.util.Collection; - -import javax.servlet.http.HttpServletRequest; - -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * Defines endpoints to use with the Turbine. - * - * @author Anastasiia Smirnova - */ -@RestController -public class TurbineController { - - private final TurbineInformationService turbineInformationService; - - public TurbineController(TurbineInformationService turbineInformationService) { - this.turbineInformationService = turbineInformationService; - } - - @GetMapping(value = "/clusters", produces = MediaType.APPLICATION_JSON_VALUE) - public Collection clusters(HttpServletRequest request) { - return turbineInformationService.getClusterInformations(request); - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineHttpConfiguration.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineHttpConfiguration.java deleted file mode 100644 index e4affe6c7..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineHttpConfiguration.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.discovery.EurekaClient; -import com.netflix.turbine.discovery.InstanceDiscovery; -import com.netflix.turbine.monitor.cluster.ClusterMonitorFactory; -import com.netflix.turbine.streaming.servlet.TurbineStreamServlet; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties -public class TurbineHttpConfiguration { - - @Bean - public HasFeatures Feature() { - return HasFeatures.namedFeature("Turbine (HTTP)", TurbineHttpConfiguration.class); - } - - @Bean - @ConditionalOnMissingBean(name = "turbineStreamServlet") - public ServletRegistrationBean turbineStreamServlet() { - return new ServletRegistrationBean(new TurbineStreamServlet(), "/turbine.stream"); - } - - @Bean - @ConditionalOnMissingBean - public TurbineProperties turbineProperties() { - return new TurbineProperties(); - } - - @Bean - @ConditionalOnMissingBean - public TurbineInformationService turbineInformationService() { - return new TurbineInformationService(); - } - - @Bean - @ConditionalOnProperty(value = "turbine.endpoints.clusters.enabled", - matchIfMissing = true) - public TurbineController turbineController(TurbineInformationService service) { - return new TurbineController(service); - } - - @Bean - @ConditionalOnMissingBean - public TurbineAggregatorProperties turbineAggregatorProperties() { - return new TurbineAggregatorProperties(); - } - - @Bean - @ConditionalOnMissingBean - public TurbineLifecycle turbineLifecycle(InstanceDiscovery instanceDiscovery, - ClusterMonitorFactory factory) { - return new TurbineLifecycle(instanceDiscovery, factory); - } - - @Bean - @ConditionalOnMissingBean - public ClusterMonitorFactory clusterMonitorFactory( - TurbineClustersProvider clustersProvider) { - return new SpringAggregatorFactory(clustersProvider); - } - - @Bean - @ConditionalOnMissingBean - public TurbineClustersProvider clustersProvider( - TurbineAggregatorProperties turbineAggregatorProperties) { - return new ConfigurationBasedTurbineClustersProvider(turbineAggregatorProperties); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(EurekaClient.class) - protected static class EurekaTurbineConfiguration { - - @Bean - @ConditionalOnMissingBean - public InstanceDiscovery instanceDiscovery(TurbineProperties turbineProperties, - EurekaClient eurekaClient) { - return new EurekaInstanceDiscovery(turbineProperties, eurekaClient); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnMissingClass("com.netflix.discovery.EurekaClient") - protected static class DiscoveryClientTurbineConfiguration { - - @Bean - @ConditionalOnMissingBean - public InstanceDiscovery instanceDiscovery(TurbineProperties turbineProperties, - DiscoveryClient discoveryClient) { - return new CommonsInstanceDiscovery(turbineProperties, discoveryClient); - } - - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineInformationService.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineInformationService.java deleted file mode 100644 index ae403153c..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineInformationService.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2018-2019 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 - * - * https://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 java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.turbine.data.AggDataFromCluster; -import com.netflix.turbine.data.DataFromSingleInstance; -import com.netflix.turbine.monitor.MonitorConsole; -import com.netflix.turbine.monitor.TurbineDataMonitor; -import com.netflix.turbine.monitor.cluster.ClusterMonitor; - -import org.springframework.http.server.ServletServerHttpRequest; -import org.springframework.web.util.UriComponents; -import org.springframework.web.util.UriComponentsBuilder; - -import static com.netflix.turbine.monitor.cluster.AggregateClusterMonitor.AggregatorClusterMonitorConsole; - -/** - * Service providing information on Turbine clusters. - * - * @author Anastasiia Smirnova - */ -public class TurbineInformationService { - - public Collection getClusterInformations( - HttpServletRequest request) { - String hostName = getHostName(request); - return getClusterInformations(hostName); - } - - private Collection getClusterInformations(String hostName) { - Collection> monitors = AggregatorClusterMonitorConsole - .getAllMonitors(); - List clusterInformations = new ArrayList<>(); - for (TurbineDataMonitor monitor : monitors) { - ClusterMonitor clusterMonitor = (ClusterMonitor) monitor; - MonitorConsole instanceConsole = clusterMonitor - .getInstanceMonitors(); - for (TurbineDataMonitor single : instanceConsole - .getAllMonitors()) { - String cluster = single.getStatsInstance().getCluster(); - ClusterInformation info = new ClusterInformation(cluster, - getLink(hostName, cluster)); - clusterInformations.add(info); - } - } - return clusterInformations; - } - - private String getLink(String hostName, String cluster) { - return hostName + "/turbine.stream?cluster=" + cluster; - } - - private String getHostName(HttpServletRequest request) { - UriComponents components = UriComponentsBuilder - .fromHttpRequest(new ServletServerHttpRequest(request)).build(); - String host = components.getHost(); - int port = components.getPort(); - String scheme = components.getScheme(); - if (port > -1) { - return String.format("%s://%s:%d", scheme, host, port); - } - return String.format("%s://%s", scheme, host); - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineLifecycle.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineLifecycle.java deleted file mode 100644 index f6290064b..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineLifecycle.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.turbine.discovery.InstanceDiscovery; -import com.netflix.turbine.init.TurbineInit; -import com.netflix.turbine.monitor.cluster.ClusterMonitorFactory; -import com.netflix.turbine.plugins.PluginsFactory; - -import org.springframework.context.SmartLifecycle; -import org.springframework.core.Ordered; - -/** - * @author Spencer Gibb - */ -public class TurbineLifecycle implements SmartLifecycle, Ordered { - - private final InstanceDiscovery instanceDiscovery; - - private final ClusterMonitorFactory factory; - - private volatile boolean running; - - public TurbineLifecycle(InstanceDiscovery instanceDiscovery, - ClusterMonitorFactory factory) { - this.instanceDiscovery = instanceDiscovery; - this.factory = factory; - } - - @Override - public boolean isAutoStartup() { - return true; - } - - @Override - public void stop(Runnable callback) { - callback.run(); - } - - @Override - public void start() { - PluginsFactory.setClusterMonitorFactory(factory); - PluginsFactory.setInstanceDiscovery(instanceDiscovery); - TurbineInit.init(); - } - - @Override - public void stop() { - this.running = false; - } - - @Override - public boolean isRunning() { - return this.running; - } - - @Override - public int getPhase() { - return 0; - } - - @Override - public int getOrder() { - return -1; - } - -} diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineProperties.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineProperties.java deleted file mode 100644 index cd27d300b..000000000 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineProperties.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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 - * - * https://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 java.util.Arrays; -import java.util.List; -import java.util.Objects; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.util.StringUtils; - -/** - * @author Spencer Gibb - * @author Gregor Zurowski - */ -@ConfigurationProperties("turbine") -public class TurbineProperties { - - private String clusterNameExpression; - - private String appConfig; - - private boolean combineHostPort = true; - - public List getAppConfigList() { - if (!StringUtils.hasText(this.appConfig)) { - return null; - } - String[] parts = StringUtils.commaDelimitedListToStringArray(this.appConfig); - if (parts != null && parts.length > 0) { - parts = StringUtils.trimArrayElements(parts); - return Arrays.asList(parts); - } - return null; - } - - public String getClusterNameExpression() { - return clusterNameExpression; - } - - public void setClusterNameExpression(String clusterNameExpression) { - this.clusterNameExpression = clusterNameExpression; - } - - public String getAppConfig() { - return appConfig; - } - - public void setAppConfig(String appConfig) { - this.appConfig = appConfig; - } - - public boolean isCombineHostPort() { - return combineHostPort; - } - - public void setCombineHostPort(boolean combineHostPort) { - this.combineHostPort = combineHostPort; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - TurbineProperties that = (TurbineProperties) o; - return Objects.equals(clusterNameExpression, that.clusterNameExpression) - && Objects.equals(appConfig, that.appConfig) - && Objects.equals(combineHostPort, that.combineHostPort); - } - - @Override - public int hashCode() { - return Objects.hash(clusterNameExpression, appConfig, combineHostPort); - } - - @Override - public String toString() { - return new StringBuilder("TurbineProperties{").append("clusterNameExpression='") - .append(clusterNameExpression).append("', ").append("appConfig='") - .append(appConfig).append("', ").append("combineHostPort=") - .append(combineHostPort).append("}").toString(); - } - -} diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/AdhocTurbineTestSuite.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/AdhocTurbineTestSuite.java deleted file mode 100644 index 3248216c1..000000000 --- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/AdhocTurbineTestSuite.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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 org.junit.Ignore; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -@RunWith(Suite.class) -@Suite.SuiteClasses({ - // org.springframework.cloud.netflix.turbine.EurekaBasedTurbineClustersProviderTest.class, - // org.springframework.cloud.netflix.turbine.ConfigurationBasedTurbineClustersProviderTest.class, - // org.springframework.cloud.netflix.turbine.CommonsInstanceDiscoveryTests.class, - // org.springframework.cloud.netflix.turbine.TurbineAggregatorPropertiesTest.class, - // org.springframework.cloud.netflix.turbine.TurbineHttpTests.class, - // org.springframework.cloud.netflix.turbine.EurekaInstanceDiscoveryTests.class, -}) -@Ignore -public class AdhocTurbineTestSuite { - -} diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscoveryTests.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscoveryTests.java deleted file mode 100644 index 5893b340f..000000000 --- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscoveryTests.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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 java.util.Collections; - -import com.netflix.turbine.discovery.Instance; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * @author Spencer Gibb - */ -public class CommonsInstanceDiscoveryTests { - - private DiscoveryClient discoveryClient; - - private TurbineProperties turbineProperties; - - @Before - public void setUp() throws Exception { - this.discoveryClient = mock(DiscoveryClient.class); - this.turbineProperties = new TurbineProperties(); - } - - @Test - public void testSecureCombineHostPort() { - turbineProperties.setCombineHostPort(true); - CommonsInstanceDiscovery discovery = createDiscovery(); - String appName = "testAppName"; - int port = 8443; - String hostName = "myhost"; - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, - hostName, port, true); - Instance instance = discovery.marshall(serviceInstance); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(port)); - assertThat(instance.getAttributes().get("securePort")).as("securePort is wrong") - .isEqualTo(String.valueOf(port)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "https://" + hostName + ":" + port + "/actuator/hystrix.stream"); - } - - @Test - public void testCombineHostPort() { - turbineProperties.setCombineHostPort(true); - CommonsInstanceDiscovery discovery = createDiscovery(); - String appName = "testAppName"; - int port = 8080; - String hostName = "myhost"; - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, - hostName, port, false); - Instance instance = discovery.marshall(serviceInstance); - assertThat(instance.getHostname()).as("hostname is wrong") - .isEqualTo(hostName + ":" + port); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(port)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "http://" + hostName + ":" + port + "/actuator/hystrix.stream"); - - String clusterName = discovery.getClusterName(serviceInstance); - assertThat(clusterName).as("clusterName is wrong").isEqualTo(appName); - } - - @Test - public void testGetClusterName() { - CommonsInstanceDiscovery discovery = createDiscovery(); - String appName = "testAppName"; - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, - "myhost", 8080, false); - String clusterName = discovery.getClusterName(serviceInstance); - assertThat(clusterName).as("clusterName is wrong").isEqualTo(appName); - } - - @Test - public void testGetPort() { - CommonsInstanceDiscovery discovery = createDiscovery(); - String appName = "testAppName"; - int port = 8080; - String hostName = "myhost"; - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, - hostName, port, false); - Instance instance = discovery.marshall(serviceInstance); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(port)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "http://" + hostName + ":" + port + "/actuator/hystrix.stream"); - } - - @Test - public void testUseManagementPortFromMetadata() { - CommonsInstanceDiscovery discovery = createDiscovery(); - String appName = "testAppName"; - int port = 8080; - int managementPort = 8081; - String hostName = "myhost"; - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, - hostName, port, false); - serviceInstance.getMetadata().put("management.port", - String.valueOf(managementPort)); - Instance instance = discovery.marshall(serviceInstance); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(managementPort)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "http://" + hostName + ":" + managementPort + "/actuator/hystrix.stream"); - } - - @Test - public void testGetSecurePort() { - CommonsInstanceDiscovery discovery = createDiscovery(); - String appName = "testAppName"; - // int port = 8080; - int port = 8443; - String hostName = "myhost"; - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, - hostName, port, true); - Instance instance = discovery.marshall(serviceInstance); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(port)); - assertThat(instance.getAttributes().get("securePort")).as("securePort is wrong") - .isEqualTo(String.valueOf(port)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "https://" + hostName + ":" + port + "/actuator/hystrix.stream"); - } - - @Test - public void testGetClusterNameCustomExpression() { - turbineProperties.setClusterNameExpression("host"); - CommonsInstanceDiscovery discovery = createDiscovery(); - String appName = "testAppName"; - String hostName = "myhost"; - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, - hostName, 8080, true); - String clusterName = discovery.getClusterName(serviceInstance); - assertThat(clusterName).as("clusterName is wrong").isEqualTo(hostName); - } - - @Test - public void testGetClusterNameInstanceMetadataMapExpression() { - turbineProperties.setClusterNameExpression("metadata['cluster']"); - CommonsInstanceDiscovery discovery = createDiscovery(); - String metadataProperty = "myCluster"; - String appName = "testAppName"; - String hostName = "myhost"; - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, - hostName, 8080, true, - Collections.singletonMap("cluster", metadataProperty)); - String clusterName = discovery.getClusterName(serviceInstance); - assertThat(clusterName).as("clusterName is wrong").isEqualTo(metadataProperty); - } - - private CommonsInstanceDiscovery createDiscovery() { - return new CommonsInstanceDiscovery(turbineProperties, discoveryClient); - } - -} diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/ConfigurationBasedTurbineClustersProviderTest.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/ConfigurationBasedTurbineClustersProviderTest.java deleted file mode 100644 index d2507c8fa..000000000 --- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/ConfigurationBasedTurbineClustersProviderTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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 java.util.Arrays; -import java.util.List; - -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class ConfigurationBasedTurbineClustersProviderTest { - - @Test - public void shouldReturnDefaultClusterIfConfigurationIsEmpty() throws Exception { - TurbineAggregatorProperties properties = new TurbineAggregatorProperties(); - TurbineClustersProvider provider = new ConfigurationBasedTurbineClustersProvider( - properties); - List clusterNames = provider.getClusterNames(); - - assertThat(clusterNames).containsOnly("default"); - } - - @Test - public void shouldReturnConfiguredClusters() throws Exception { - TurbineAggregatorProperties properties = new TurbineAggregatorProperties(); - properties.setClusterConfig(Arrays.asList("cluster1", "cluster2", "cluster3")); - TurbineClustersProvider provider = new ConfigurationBasedTurbineClustersProvider( - properties); - List clusterNames = provider.getClusterNames(); - - assertThat(clusterNames).containsOnly("cluster1", "cluster2", "cluster3"); - } - -} diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaBasedTurbineClustersProviderTest.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaBasedTurbineClustersProviderTest.java deleted file mode 100644 index 75550c321..000000000 --- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaBasedTurbineClustersProviderTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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 java.util.List; - -import com.netflix.discovery.EurekaClient; -import com.netflix.discovery.shared.Application; -import com.netflix.discovery.shared.Applications; -import org.junit.Test; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class EurekaBasedTurbineClustersProviderTest { - - EurekaClient eurekaClient = mock(EurekaClient.class); - - TurbineClustersProvider provider = new EurekaBasedTurbineClustersProvider( - eurekaClient); - - @Test - public void shouldProvideAllClustersNames() throws Exception { - Applications applications = registeredApplications(asList(application("service1"), - application("service2"), application("service3"))); - when(eurekaClient.getApplications()).thenReturn(applications); - - List clusterNames = provider.getClusterNames(); - - assertThat(clusterNames).containsOnly("service1", "service2", "service3"); - } - - private Applications registeredApplications(List registered) { - Applications applications = mock(Applications.class); - when(applications.getRegisteredApplications()).thenReturn(registered); - return applications; - } - - private Application application(String name) { - Application application = mock(Application.class); - when(application.getName()).thenReturn(name); - return application; - } - -} diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTests.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTests.java deleted file mode 100644 index 9df959959..000000000 --- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTests.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.appinfo.InstanceInfo; -import com.netflix.discovery.EurekaClient; -import com.netflix.turbine.discovery.Instance; -import org.junit.Before; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * @author Spencer Gibb - */ -public class EurekaInstanceDiscoveryTests { - - 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 testSecureCombineHostPort() { - turbineProperties.setCombineHostPort(true); - 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.marshall(instanceInfo); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(port)); - assertThat(instance.getAttributes().get("securePort")).as("securePort is wrong") - .isEqualTo(String.valueOf(securePort)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "https://" + hostName + ":" + securePort + "/actuator/hystrix.stream"); - } - - @Test - public void testCombineHostPort() { - turbineProperties.setCombineHostPort(true); - 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.marshall(instanceInfo); - assertThat(instance.getHostname()).as("hostname is wrong") - .isEqualTo(hostName + ":" + port); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(port)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "http://" + hostName + ":" + port + "/actuator/hystrix.stream"); - - String clusterName = discovery.getClusterName(instanceInfo); - assertThat(clusterName).as("clusterName is wrong") - .isEqualTo(appName.toUpperCase()); - } - - @Test - public void testUseManagementPortFromMetadata() { - EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties, - eurekaClient); - String appName = "testAppName"; - int port = 8080; - int managementPort = 8081; - String hostName = "myhost"; - InstanceInfo instanceInfo = builder.setAppName(appName).setHostName(hostName) - .setPort(port).build(); - instanceInfo.getMetadata().put("management.port", "8081"); - Instance instance = discovery.marshall(instanceInfo); - assertThat(instance.getHostname()).as("hostname is wrong") - .isEqualTo(hostName + ":" + managementPort); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(managementPort)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "http://" + hostName + ":" + managementPort + "/actuator/hystrix.stream"); - - String clusterName = discovery.getClusterName(instanceInfo); - assertThat(clusterName).as("clusterName is wrong") - .isEqualTo(appName.toUpperCase()); - } - - @Test - public void testGetClusterName() { - EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties, - eurekaClient); - String appName = "testAppName"; - InstanceInfo instanceInfo = builder.setAppName(appName).build(); - String clusterName = discovery.getClusterName(instanceInfo); - assertThat(clusterName).as("clusterName is wrong") - .isEqualTo(appName.toUpperCase()); - } - - @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.marshall(instanceInfo); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(port)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "http://" + hostName + ":" + port + "/actuator/hystrix.stream"); - } - - @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.marshall(instanceInfo); - assertThat(instance.getAttributes().get("port")).as("port is wrong") - .isEqualTo(String.valueOf(port)); - assertThat(instance.getAttributes().get("securePort")).as("securePort is wrong") - .isEqualTo(String.valueOf(securePort)); - - String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure - .getUrlPath(instance); - assertThat(urlPath).as("url is wrong").isEqualTo( - "https://" + hostName + ":" + securePort + "/actuator/hystrix.stream"); - } - - @Test - public void testGetClusterNameCustomExpression() { - turbineProperties.setClusterNameExpression("aSGName"); - EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties, - eurekaClient); - String asgName = "myAsgName"; - InstanceInfo instanceInfo = builder.setAppName("testApp").setASGName(asgName) - .build(); - String clusterName = discovery.getClusterName(instanceInfo); - assertThat(clusterName).as("clusterName is wrong").isEqualTo(asgName); - } - - @Test - public void testGetClusterNameInstanceMetadataMapExpression() { - turbineProperties.setClusterNameExpression("metadata['cluster']"); - EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties, - eurekaClient); - String metadataProperty = "myCluster"; - InstanceInfo instanceInfo = builder.setAppName("testApp") - .add("cluster", metadataProperty).build(); - String clusterName = discovery.getClusterName(instanceInfo); - assertThat(clusterName).as("clusterName is wrong").isEqualTo(metadataProperty); - } - -} diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/TurbineAggregatorPropertiesTest.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/TurbineAggregatorPropertiesTest.java deleted file mode 100644 index 39e4108ed..000000000 --- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/TurbineAggregatorPropertiesTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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 org.junit.After; -import org.junit.Test; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -public class TurbineAggregatorPropertiesTest { - - private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - - @After - public void clear() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - public void shouldHaveDefaultConfiguration() throws Exception { - setupContext(); - - TurbineAggregatorProperties actual = getProperties(); - assertThat(actual.getClusterConfig()).containsOnly("default"); - } - - @Test - public void shouldLoadCustomProperties() { - TestPropertyValues - .of("turbine.aggregator.clusterConfig=cluster1, cluster2, cluster3") - .applyTo(this.context); - setupContext(); - - TurbineAggregatorProperties actual = getProperties(); - assertThat(actual.getClusterConfig()).containsOnly("cluster1", "cluster2", - "cluster3"); - } - - private void setupContext() { - this.context.register(TestConfiguration.class); - this.context.refresh(); - } - - private TurbineAggregatorProperties getProperties() { - return this.context.getBean(TurbineAggregatorProperties.class); - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(TurbineAggregatorProperties.class) - static class TestConfiguration { - - } - -} diff --git a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/TurbineHttpTests.java b/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/TurbineHttpTests.java deleted file mode 100644 index ebf0a5aad..000000000 --- a/spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/TurbineHttpTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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 java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = TurbineHttpTests.TurbineHttpSampleApplication.class, - webEnvironment = WebEnvironment.RANDOM_PORT) -public class TurbineHttpTests { - - private static final ClusterInformation foo = new ClusterInformation("foo", - "https://foo"); - - private static final ClusterInformation bar = new ClusterInformation("bar", - "https://bar"); - - @Autowired - TestRestTemplate rest; - - @Test - public void contextLoads() { - ClusterInformation[] clusters = rest.getForObject("/clusters", - ClusterInformation[].class); - System.err.println(Arrays.asList(clusters)); - assertThat(clusters.length).isEqualTo(2); - assertThat(clusters[0]).isEqualTo(foo); - assertThat(clusters[1]).isEqualTo(bar); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableTurbine - protected static class TurbineHttpSampleApplication { - - @Bean - @Primary - TurbineInformationService myInfoService() { - return new TurbineInformationService() { - @Override - public Collection getClusterInformations( - HttpServletRequest request) { - List clusterInformationList = new ArrayList<>(); - clusterInformationList.add(foo); - clusterInformationList.add(bar); - return clusterInformationList; - } - }; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/pom.xml b/spring-cloud-netflix-zuul/pom.xml deleted file mode 100644 index 904f77acb..000000000 --- a/spring-cloud-netflix-zuul/pom.xml +++ /dev/null @@ -1,128 +0,0 @@ - - - 4.0.0 - - spring-cloud-netflix - org.springframework.cloud - 2.2.2.BUILD-SNAPSHOT - .. - - - - spring-cloud-netflix-zuul - jar - Spring Cloud Netflix Zuul - Spring Cloud Netflix Zuul - - - - org.springframework.cloud - spring-cloud-netflix-hystrix - - - org.apache.httpcomponents - httpclient - - - org.springframework.boot - spring-boot-configuration-processor - true - - - com.netflix.hystrix - hystrix-core - true - - - com.netflix.ribbon - ribbon-loadbalancer - true - - - com.netflix.ribbon - ribbon-core - true - - - com.netflix.ribbon - ribbon-httpclient - true - - - org.springframework.boot - spring-boot-starter-actuator - true - - - org.springframework.boot - spring-boot-starter-web - true - - - org.springframework.boot - spring-boot-starter-security - true - - - org.springframework.cloud - spring-cloud-commons - true - - - org.springframework.cloud - spring-cloud-context - true - - - com.netflix.zuul - zuul-core - true - - - groovy-all - org.codehaus.groovy - - - mockito-all - org.mockito - - - - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - true - - - com.netflix.netflix-commons - netflix-commons-util - - - org.springframework.cloud - spring-cloud-starter-netflix-hystrix - - - org.springframework.retry - spring-retry - true - - - org.springframework.cloud - spring-cloud-test-support - test - - - org.springframework.boot - spring-boot-starter-test - test - - - com.squareup.okhttp3 - okhttp - true - - - - diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulProxy.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulProxy.java deleted file mode 100644 index 778ed471a..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulProxy.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; -import org.springframework.context.annotation.Import; - -/** - * Sets up a Zuul server endpoint and installs some reverse proxy filters in it, so it can - * forward requests to backend servers. The backends can be registered manually through - * configuration or via DiscoveryClient. - * - * @see EnableZuulServer for how to get a Zuul server without any proxying - * - * @author Spencer Gibb - * @author Dave Syer - * @author Biju Kunjummen - */ -@EnableCircuitBreaker -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Import(ZuulProxyMarkerConfiguration.class) -public @interface EnableZuulProxy { - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulServer.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulServer.java deleted file mode 100644 index 0e6a00b85..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/EnableZuulServer.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2013-2017 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 - * - * https://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.zuul; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.context.annotation.Import; - -/** - * Set up the application to act as a generic Zuul server without any built-in reverse - * proxy features. The routes into the Zuul server can be configured through - * {@link ZuulProperties} (by default there are none). - * - * @see EnableZuulProxy to see how to get reverse proxy out of the box - * - * @author Spencer Gibb - * @author Biju Kunjummen - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Import(ZuulServerMarkerConfiguration.class) -public @interface EnableZuulServer { - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/FiltersEndpoint.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/FiltersEndpoint.java deleted file mode 100644 index 5006071a6..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/FiltersEndpoint.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.zuul; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.filters.FilterRegistry; - -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; - -/** - * Endpoint for listing Zuul filters. - * - * @author Daryl Robbins - * @author Gregor Zurowski - */ -@Endpoint(id = "filters") -public class FiltersEndpoint { - - private final FilterRegistry filterRegistry; - - public FiltersEndpoint(FilterRegistry filterRegistry) { - this.filterRegistry = filterRegistry; - } - - @ReadOperation - public Map>> invoke() { - // Map of filters by type - final Map>> filterMap = new TreeMap<>(); - - for (ZuulFilter filter : this.filterRegistry.getAllFilters()) { - // Ensure that we have a list to store filters of each type - if (!filterMap.containsKey(filter.filterType())) { - filterMap.put(filter.filterType(), new ArrayList<>()); - } - - final Map filterInfo = new LinkedHashMap<>(); - filterInfo.put("class", filter.getClass().getName()); - filterInfo.put("order", filter.filterOrder()); - filterInfo.put("disabled", filter.isFilterDisabled()); - filterInfo.put("static", filter.isStaticFilter()); - - filterMap.get(filter.filterType()).add(filterInfo); - } - - return filterMap; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RibbonCommandFactoryConfiguration.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RibbonCommandFactoryConfiguration.java deleted file mode 100644 index 691344e27..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RibbonCommandFactoryConfiguration.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2015-2019 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 - * - * https://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.zuul; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.Collections; -import java.util.Set; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; - -/** - * @author Dave Syer - * - */ -public class RibbonCommandFactoryConfiguration { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnRibbonRestClient - protected static class RestClientRibbonConfiguration { - - @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); - - @Bean - @ConditionalOnMissingBean - public RibbonCommandFactory ribbonCommandFactory( - SpringClientFactory clientFactory, ZuulProperties zuulProperties) { - return new RestClientRibbonCommandFactory(clientFactory, zuulProperties, - zuulFallbackProviders); - } - - } - - @Target({ ElementType.TYPE, ElementType.METHOD }) - @Retention(RetentionPolicy.RUNTIME) - @Documented - @Conditional(OnRibbonHttpClientCondition.class) - @interface ConditionalOnRibbonHttpClient { - - } - - private static class OnRibbonHttpClientCondition extends AnyNestedCondition { - - OnRibbonHttpClientCondition() { - super(ConfigurationPhase.PARSE_CONFIGURATION); - } - - @ConditionalOnProperty(name = "ribbon.httpclient.enabled", matchIfMissing = true) - static class RibbonProperty { - - } - - } - - @Target({ ElementType.TYPE, ElementType.METHOD }) - @Retention(RetentionPolicy.RUNTIME) - @Documented - @Conditional(OnRibbonOkHttpClientCondition.class) - @interface ConditionalOnRibbonOkHttpClient { - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnRibbonOkHttpClient - @ConditionalOnClass(name = "okhttp3.OkHttpClient") - protected static class OkHttpRibbonConfiguration { - - @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); - - @Bean - @ConditionalOnMissingBean - public RibbonCommandFactory ribbonCommandFactory( - SpringClientFactory clientFactory, ZuulProperties zuulProperties) { - return new OkHttpRibbonCommandFactory(clientFactory, zuulProperties, - zuulFallbackProviders); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnRibbonHttpClient - protected static class HttpClientRibbonConfiguration { - - @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); - - @Bean - @ConditionalOnMissingBean - public RibbonCommandFactory ribbonCommandFactory( - SpringClientFactory clientFactory, ZuulProperties zuulProperties) { - return new HttpClientRibbonCommandFactory(clientFactory, zuulProperties, - zuulFallbackProviders); - } - - } - - private static class OnRibbonOkHttpClientCondition extends AnyNestedCondition { - - OnRibbonOkHttpClientCondition() { - super(ConfigurationPhase.PARSE_CONFIGURATION); - } - - @ConditionalOnProperty("ribbon.okhttp.enabled") - static class RibbonProperty { - - } - - } - - @Target({ ElementType.TYPE, ElementType.METHOD }) - @Retention(RetentionPolicy.RUNTIME) - @Documented - @Conditional(OnRibbonRestClientCondition.class) - @interface ConditionalOnRibbonRestClient { - - } - - private static class OnRibbonRestClientCondition extends AnyNestedCondition { - - OnRibbonRestClientCondition() { - super(ConfigurationPhase.PARSE_CONFIGURATION); - } - - @ConditionalOnProperty("ribbon.restclient.enabled") - static class RibbonProperty { - - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RoutesEndpoint.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RoutesEndpoint.java deleted file mode 100644 index c7bb70d81..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RoutesEndpoint.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; - -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; -import org.springframework.boot.actuate.endpoint.annotation.Selector; -import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; - -/** - * Endpoint to display the zuul proxy routes. - * - * @author Spencer Gibb - * @author Dave Syer - * @author Ryan Baxter - * @author Gregor Zurowski - */ -@Endpoint(id = RoutesEndpoint.ID) -public class RoutesEndpoint implements ApplicationEventPublisherAware { - - static final String ID = "routes"; - static final String FORMAT_DETAILS = "details"; - - private RouteLocator routes; - - private ApplicationEventPublisher publisher; - - public RoutesEndpoint(RouteLocator routes) { - this.routes = routes; - } - - @Override - public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { - this.publisher = publisher; - } - - @ReadOperation - public Map invoke() { - Map map = new LinkedHashMap<>(); - for (Route route : this.routes.getRoutes()) { - map.put(route.getFullPath(), route.getLocation()); - } - return map; - } - - Map invokeRouteDetails() { - Map map = new LinkedHashMap<>(); - for (Route route : this.routes.getRoutes()) { - map.put(route.getFullPath(), new RouteDetails(route)); - } - return map; - } - - @WriteOperation - public Object reset() { - this.publisher.publishEvent(new RoutesRefreshedEvent(this.routes)); - return invoke(); - } - - /** - * Expose Zuul {@link Route} information with details. - * @param format used to determine whether only locations or route details should be - * provided - * @return a map of routes and their details - */ - @ReadOperation - public Object invokeRouteDetails(@Selector String format) { - if (FORMAT_DETAILS.equalsIgnoreCase(format)) { - return invokeRouteDetails(); - } - else { - return invoke(); - } - } - - /** - * Container for exposing Zuul {@link Route} details as JSON. - */ - @JsonPropertyOrder({ "id", "fullPath", "location" }) - @JsonInclude(JsonInclude.Include.NON_EMPTY) - public static class RouteDetails { - - private String id; - - private String fullPath; - - private String path; - - private String location; - - private String prefix; - - private Boolean retryable; - - private Set sensitiveHeaders; - - private boolean customSensitiveHeaders; - - private boolean prefixStripped; - - public RouteDetails() { - } - - RouteDetails(final Route route) { - this.id = route.getId(); - this.fullPath = route.getFullPath(); - this.path = route.getPath(); - this.location = route.getLocation(); - this.prefix = route.getPrefix(); - this.retryable = route.getRetryable(); - this.sensitiveHeaders = route.getSensitiveHeaders(); - this.customSensitiveHeaders = route.isCustomSensitiveHeaders(); - this.prefixStripped = route.isPrefixStripped(); - } - - public String getId() { - return id; - } - - public String getFullPath() { - return fullPath; - } - - public String getPath() { - return path; - } - - public String getLocation() { - return location; - } - - public String getPrefix() { - return prefix; - } - - public Boolean getRetryable() { - return retryable; - } - - public Set getSensitiveHeaders() { - return sensitiveHeaders; - } - - public boolean isCustomSensitiveHeaders() { - return customSensitiveHeaders; - } - - public boolean isPrefixStripped() { - return prefixStripped; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RouteDetails that = (RouteDetails) o; - return Objects.equals(id, that.id) && Objects.equals(fullPath, that.fullPath) - && Objects.equals(path, that.path) - && Objects.equals(location, that.location) - && Objects.equals(prefix, that.prefix) - && Objects.equals(retryable, that.retryable) - && Objects.equals(sensitiveHeaders, that.sensitiveHeaders) - && customSensitiveHeaders == that.customSensitiveHeaders - && prefixStripped == that.prefixStripped; - } - - @Override - public int hashCode() { - return Objects.hash(id, fullPath, path, location, prefix, retryable, - sensitiveHeaders, customSensitiveHeaders, prefixStripped); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RoutesRefreshedEvent.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RoutesRefreshedEvent.java deleted file mode 100644 index 7e66d9d9f..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RoutesRefreshedEvent.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2013-2014 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 - * - * https://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.zuul; - -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.context.ApplicationEvent; - -/** - * @author Dave Syer - */ -@SuppressWarnings("serial") -public class RoutesRefreshedEvent extends ApplicationEvent { - - private RouteLocator locator; - - public RoutesRefreshedEvent(RouteLocator locator) { - super(locator); - this.locator = locator; - } - - public RouteLocator getLocator() { - return this.locator; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializer.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializer.java deleted file mode 100644 index 0c381bd98..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializer.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import java.lang.reflect.Field; -import java.util.Map; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; - -import com.netflix.zuul.FilterLoader; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.filters.FilterRegistry; -import com.netflix.zuul.monitoring.CounterFactory; -import com.netflix.zuul.monitoring.TracerFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.util.ReflectionUtils; - -/** - * Initializes various Zuul components including {@link ZuulFilter}. - * - * @author Spencer Gibb - * - */ -public class ZuulFilterInitializer { - - private static final Log log = LogFactory.getLog(ZuulFilterInitializer.class); - - private final Map filters; - - private final CounterFactory counterFactory; - - private final TracerFactory tracerFactory; - - private final FilterLoader filterLoader; - - private final FilterRegistry filterRegistry; - - public ZuulFilterInitializer(Map filters, - CounterFactory counterFactory, TracerFactory tracerFactory, - FilterLoader filterLoader, FilterRegistry filterRegistry) { - this.filters = filters; - this.counterFactory = counterFactory; - this.tracerFactory = tracerFactory; - this.filterLoader = filterLoader; - this.filterRegistry = filterRegistry; - } - - @PostConstruct - public void contextInitialized() { - log.info("Starting filter initializer"); - - TracerFactory.initialize(tracerFactory); - CounterFactory.initialize(counterFactory); - - for (Map.Entry entry : this.filters.entrySet()) { - filterRegistry.put(entry.getKey(), entry.getValue()); - } - } - - @PreDestroy - public void contextDestroyed() { - log.info("Stopping filter initializer"); - for (Map.Entry entry : this.filters.entrySet()) { - filterRegistry.remove(entry.getKey()); - } - clearLoaderCache(); - - TracerFactory.initialize(null); - CounterFactory.initialize(null); - } - - private void clearLoaderCache() { - Field field = ReflectionUtils.findField(FilterLoader.class, "hashFiltersByType"); - ReflectionUtils.makeAccessible(field); - @SuppressWarnings("rawtypes") - Map cache = (Map) ReflectionUtils.getField(field, filterLoader); - cache.clear(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfiguration.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfiguration.java deleted file mode 100644 index 0d0759111..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfiguration.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import java.util.Collections; -import java.util.List; - -import com.netflix.zuul.filters.FilterRegistry; -import org.apache.http.impl.client.CloseableHttpClient; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.trace.http.HttpTraceRepository; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; -import org.springframework.cloud.commons.httpclient.HttpClientConfiguration; -import org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer; -import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.filters.TraceProxyRequestHelper; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.discovery.ServiceRouteMapper; -import org.springframework.cloud.netflix.zuul.filters.discovery.SimpleServiceRouteMapper; -import org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter; -import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * @author Spencer Gibb - * @author Dave Syer - * @author Biju Kunjummen - */ -@Configuration(proxyBeanMethods = false) -@Import({ RibbonCommandFactoryConfiguration.RestClientRibbonConfiguration.class, - RibbonCommandFactoryConfiguration.OkHttpRibbonConfiguration.class, - RibbonCommandFactoryConfiguration.HttpClientRibbonConfiguration.class, - HttpClientConfiguration.class }) -@ConditionalOnBean(ZuulProxyMarkerConfiguration.Marker.class) -public class ZuulProxyAutoConfiguration extends ZuulServerAutoConfiguration { - - @SuppressWarnings("rawtypes") - @Autowired(required = false) - private List requestCustomizers = Collections.emptyList(); - - @Autowired(required = false) - private Registration registration; - - @Autowired - private DiscoveryClient discovery; - - @Autowired - private ServiceRouteMapper serviceRouteMapper; - - @Override - public HasFeatures zuulFeature() { - return HasFeatures.namedFeature("Zuul (Discovery)", - ZuulProxyAutoConfiguration.class); - } - - @Bean - @ConditionalOnMissingBean(DiscoveryClientRouteLocator.class) - public DiscoveryClientRouteLocator discoveryRouteLocator() { - return new DiscoveryClientRouteLocator(this.server.getServlet().getContextPath(), - this.discovery, this.zuulProperties, this.serviceRouteMapper, - this.registration); - } - - // pre filters - @Bean - @ConditionalOnMissingBean(PreDecorationFilter.class) - public PreDecorationFilter preDecorationFilter(RouteLocator routeLocator, - ProxyRequestHelper proxyRequestHelper) { - return new PreDecorationFilter(routeLocator, - this.server.getServlet().getContextPath(), this.zuulProperties, - proxyRequestHelper); - } - - // route filters - @Bean - @ConditionalOnMissingBean(RibbonRoutingFilter.class) - public RibbonRoutingFilter ribbonRoutingFilter(ProxyRequestHelper helper, - RibbonCommandFactory ribbonCommandFactory) { - RibbonRoutingFilter filter = new RibbonRoutingFilter(helper, ribbonCommandFactory, - this.requestCustomizers); - return filter; - } - - @Bean - @ConditionalOnMissingBean({ SimpleHostRoutingFilter.class, - CloseableHttpClient.class }) - public SimpleHostRoutingFilter simpleHostRoutingFilter(ProxyRequestHelper helper, - ZuulProperties zuulProperties, - ApacheHttpClientConnectionManagerFactory connectionManagerFactory, - ApacheHttpClientFactory httpClientFactory) { - return new SimpleHostRoutingFilter(helper, zuulProperties, - connectionManagerFactory, httpClientFactory); - } - - @Bean - @ConditionalOnMissingBean({ SimpleHostRoutingFilter.class }) - public SimpleHostRoutingFilter simpleHostRoutingFilter2(ProxyRequestHelper helper, - ZuulProperties zuulProperties, CloseableHttpClient httpClient) { - return new SimpleHostRoutingFilter(helper, zuulProperties, httpClient); - } - - @Bean - @ConditionalOnMissingBean(ServiceRouteMapper.class) - public ServiceRouteMapper serviceRouteMapper() { - return new SimpleServiceRouteMapper(); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnMissingClass("org.springframework.boot.actuate.health.Health") - protected static class NoActuatorConfiguration { - - @Bean - public ProxyRequestHelper proxyRequestHelper(ZuulProperties zuulProperties) { - ProxyRequestHelper helper = new ProxyRequestHelper(zuulProperties); - return helper; - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(Health.class) - protected static class EndpointConfiguration { - - @Autowired(required = false) - private HttpTraceRepository traces; - - @Bean - @ConditionalOnAvailableEndpoint - public RoutesEndpoint routesEndpoint(RouteLocator routeLocator) { - return new RoutesEndpoint(routeLocator); - } - - @ConditionalOnAvailableEndpoint - @Bean - public FiltersEndpoint filtersEndpoint() { - FilterRegistry filterRegistry = FilterRegistry.instance(); - return new FiltersEndpoint(filterRegistry); - } - - @Bean - public ProxyRequestHelper proxyRequestHelper(ZuulProperties zuulProperties) { - TraceProxyRequestHelper helper = new TraceProxyRequestHelper(zuulProperties); - if (this.traces != null) { - helper.setTraces(this.traces); - } - return helper; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyMarkerConfiguration.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyMarkerConfiguration.java deleted file mode 100644 index aedf5e154..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyMarkerConfiguration.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.zuul; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Responsible for adding in a marker bean to trigger activation of - * {@link ZuulProxyAutoConfiguration}. - * - * @author Biju Kunjummen - */ - -@Configuration(proxyBeanMethods = false) -public class ZuulProxyMarkerConfiguration { - - @Bean - public Marker zuulProxyMarkerBean() { - return new Marker(); - } - - class Marker { - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulRouteApplicationContextInitializer.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulRouteApplicationContextInitializer.java deleted file mode 100644 index 77cbb63f7..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulRouteApplicationContextInitializer.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.zuul; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import org.springframework.cloud.netflix.ribbon.RibbonApplicationContextInitializer; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; - -/** - * Responsible for taking in the list of registered serviceid's (Ribbon client names) and - * creating the Spring {@link org.springframework.context.ApplicationContext} on start-up. - * - * @author Biju Kunjummen - */ - -public class ZuulRouteApplicationContextInitializer - extends RibbonApplicationContextInitializer { - - public ZuulRouteApplicationContextInitializer(SpringClientFactory springClientFactory, - ZuulProperties zuulProperties) { - super(springClientFactory, getServiceIdsFromZuulProps(zuulProperties)); - } - - private static List getServiceIdsFromZuulProps( - ZuulProperties zuulProperties) { - Map zuulRoutes = zuulProperties.getRoutes(); - Collection registeredRoutes = zuulRoutes.values(); - List serviceIds = new ArrayList<>(); - if (registeredRoutes != null) { - for (ZuulProperties.ZuulRoute route : registeredRoutes) { - String serviceId = route.getServiceId(); - if (serviceId != null) { - serviceIds.add(serviceId); - } - } - } - return serviceIds; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServerAutoConfiguration.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServerAutoConfiguration.java deleted file mode 100644 index 79373a608..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServerAutoConfiguration.java +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import com.netflix.zuul.FilterLoader; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.filters.FilterRegistry; -import com.netflix.zuul.filters.ZuulServletFilter; -import com.netflix.zuul.http.ZuulServlet; -import com.netflix.zuul.monitoring.CounterFactory; -import com.netflix.zuul.monitoring.TracerFactory; -import io.micrometer.core.instrument.MeterRegistry; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.boot.web.servlet.error.ErrorController; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.discovery.event.HeartbeatEvent; -import org.springframework.cloud.client.discovery.event.HeartbeatMonitor; -import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent; -import org.springframework.cloud.client.discovery.event.ParentHeartbeatEvent; -import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.zuul.filters.CompositeRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter; -import org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter; -import org.springframework.cloud.netflix.zuul.filters.pre.DebugFilter; -import org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilter; -import org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter; -import org.springframework.cloud.netflix.zuul.filters.pre.ServletDetectionFilter; -import org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter; -import org.springframework.cloud.netflix.zuul.metrics.DefaultCounterFactory; -import org.springframework.cloud.netflix.zuul.metrics.EmptyCounterFactory; -import org.springframework.cloud.netflix.zuul.metrics.EmptyTracerFactory; -import org.springframework.cloud.netflix.zuul.web.ZuulController; -import org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.core.Ordered; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.servlet.config.annotation.CorsRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -import static java.util.Collections.emptyList; - -/** - * @author Spencer Gibb - * @author Dave Syer - * @author Biju Kunjummen - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties({ ZuulProperties.class }) -@ConditionalOnClass({ ZuulServlet.class, ZuulServletFilter.class }) -@ConditionalOnBean(ZuulServerMarkerConfiguration.Marker.class) -// Make sure to get the ServerProperties from the same place as a normal web app would -// FIXME @Import(ServerPropertiesAutoConfiguration.class) -public class ZuulServerAutoConfiguration { - - @Autowired - protected ZuulProperties zuulProperties; - - @Autowired - protected ServerProperties server; - - @Autowired(required = false) - private ErrorController errorController; - - private Map corsConfigurations; - - @Autowired(required = false) - private List configurers = emptyList(); - - @Bean - public HasFeatures zuulFeature() { - return HasFeatures.namedFeature("Zuul (Simple)", - ZuulServerAutoConfiguration.class); - } - - @Bean - @Primary - public CompositeRouteLocator primaryRouteLocator( - Collection routeLocators) { - return new CompositeRouteLocator(routeLocators); - } - - @Bean - @ConditionalOnMissingBean(SimpleRouteLocator.class) - public SimpleRouteLocator simpleRouteLocator() { - return new SimpleRouteLocator(this.server.getServlet().getContextPath(), - this.zuulProperties); - } - - @Bean - public ZuulController zuulController() { - return new ZuulController(); - } - - @Bean - public ZuulHandlerMapping zuulHandlerMapping(RouteLocator routes, - ZuulController zuulController) { - ZuulHandlerMapping mapping = new ZuulHandlerMapping(routes, zuulController); - mapping.setErrorController(this.errorController); - mapping.setCorsConfigurations(getCorsConfigurations()); - return mapping; - } - - protected final Map getCorsConfigurations() { - if (this.corsConfigurations == null) { - ZuulCorsRegistry registry = new ZuulCorsRegistry(); - this.configurers.forEach(configurer -> configurer.addCorsMappings(registry)); - this.corsConfigurations = registry.getCorsConfigurations(); - } - return this.corsConfigurations; - } - - @Bean - public ApplicationListener zuulRefreshRoutesListener() { - return new ZuulRefreshListener(); - } - - @Bean - @ConditionalOnMissingBean(name = "zuulServlet") - @ConditionalOnProperty(name = "zuul.use-filter", havingValue = "false", - matchIfMissing = true) - public ServletRegistrationBean zuulServlet() { - ServletRegistrationBean servlet = new ServletRegistrationBean<>( - new ZuulServlet(), this.zuulProperties.getServletPattern()); - // The whole point of exposing this servlet is to provide a route that doesn't - // buffer requests. - servlet.addInitParameter("buffer-requests", "false"); - return servlet; - } - - @Bean - @ConditionalOnMissingBean(name = "zuulServletFilter") - @ConditionalOnProperty(name = "zuul.use-filter", havingValue = "true", - matchIfMissing = false) - public FilterRegistrationBean zuulServletFilter() { - final FilterRegistrationBean filterRegistration = new FilterRegistrationBean<>(); - filterRegistration.setUrlPatterns( - Collections.singleton(this.zuulProperties.getServletPattern())); - filterRegistration.setFilter(new ZuulServletFilter()); - filterRegistration.setOrder(Ordered.LOWEST_PRECEDENCE); - // The whole point of exposing this servlet is to provide a route that doesn't - // buffer requests. - filterRegistration.addInitParameter("buffer-requests", "false"); - return filterRegistration; - } - - // pre filters - - @Bean - public ServletDetectionFilter servletDetectionFilter() { - return new ServletDetectionFilter(); - } - - @Bean - @ConditionalOnMissingBean - public FormBodyWrapperFilter formBodyWrapperFilter() { - return new FormBodyWrapperFilter(); - } - - @Bean - @ConditionalOnMissingBean - public DebugFilter debugFilter() { - return new DebugFilter(); - } - - @Bean - @ConditionalOnMissingBean - public Servlet30WrapperFilter servlet30WrapperFilter() { - return new Servlet30WrapperFilter(); - } - - // post filters - - @Bean - public SendResponseFilter sendResponseFilter(ZuulProperties properties) { - return new SendResponseFilter(zuulProperties); - } - - @Bean - public SendErrorFilter sendErrorFilter() { - return new SendErrorFilter(); - } - - @Bean - public SendForwardFilter sendForwardFilter() { - return new SendForwardFilter(); - } - - @Bean - @ConditionalOnProperty("zuul.ribbon.eager-load.enabled") - public ZuulRouteApplicationContextInitializer zuulRoutesApplicationContextInitiazer( - SpringClientFactory springClientFactory) { - return new ZuulRouteApplicationContextInitializer(springClientFactory, - zuulProperties); - } - - @Configuration(proxyBeanMethods = false) - protected static class ZuulFilterConfiguration { - - @Autowired - private Map filters; - - @Bean - public ZuulFilterInitializer zuulFilterInitializer(CounterFactory counterFactory, - TracerFactory tracerFactory) { - FilterLoader filterLoader = FilterLoader.getInstance(); - FilterRegistry filterRegistry = FilterRegistry.instance(); - return new ZuulFilterInitializer(this.filters, counterFactory, tracerFactory, - filterLoader, filterRegistry); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(MeterRegistry.class) - protected static class ZuulCounterFactoryConfiguration { - - @Bean - @ConditionalOnBean(MeterRegistry.class) - @ConditionalOnMissingBean(CounterFactory.class) - public CounterFactory counterFactory(MeterRegistry meterRegistry) { - return new DefaultCounterFactory(meterRegistry); - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class ZuulMetricsConfiguration { - - @Bean - @ConditionalOnMissingClass("io.micrometer.core.instrument.MeterRegistry") - @ConditionalOnMissingBean(CounterFactory.class) - public CounterFactory counterFactory() { - return new EmptyCounterFactory(); - } - - @ConditionalOnMissingBean(TracerFactory.class) - @Bean - public TracerFactory tracerFactory() { - return new EmptyTracerFactory(); - } - - } - - private static class ZuulRefreshListener - implements ApplicationListener { - - @Autowired - private ZuulHandlerMapping zuulHandlerMapping; - - private HeartbeatMonitor heartbeatMonitor = new HeartbeatMonitor(); - - @Override - public void onApplicationEvent(ApplicationEvent event) { - if (event instanceof ContextRefreshedEvent - || event instanceof RefreshScopeRefreshedEvent - || event instanceof RoutesRefreshedEvent - || event instanceof InstanceRegisteredEvent) { - reset(); - } - else if (event instanceof ParentHeartbeatEvent) { - ParentHeartbeatEvent e = (ParentHeartbeatEvent) event; - resetIfNeeded(e.getValue()); - } - else if (event instanceof HeartbeatEvent) { - HeartbeatEvent e = (HeartbeatEvent) event; - resetIfNeeded(e.getValue()); - } - } - - private void resetIfNeeded(Object value) { - if (this.heartbeatMonitor.update(value)) { - reset(); - } - } - - private void reset() { - this.zuulHandlerMapping.setDirty(true); - } - - } - - private static class ZuulCorsRegistry extends CorsRegistry { - - @Override - protected Map getCorsConfigurations() { - return super.getCorsConfigurations(); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServerMarkerConfiguration.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServerMarkerConfiguration.java deleted file mode 100644 index c622fee9c..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServerMarkerConfiguration.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.zuul; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Responsible for adding in a marker bean to trigger activation of - * {@link ZuulServerAutoConfiguration}. - * - * @author Biju Kunjummen - */ - -@Configuration(proxyBeanMethods = false) -public class ZuulServerMarkerConfiguration { - - @Bean - public Marker zuulServerMarkerBean() { - return new Marker(); - } - - class Marker { - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServletFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServletFilter.java deleted file mode 100644 index 3e79fed3a..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/ZuulServletFilter.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2018-2019 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 - * - * https://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.zuul; - -import java.io.IOException; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import com.netflix.zuul.context.RequestContext; - -/** - * @author Craig Andrews - */ -public class ZuulServletFilter extends com.netflix.zuul.filters.ZuulServletFilter { - - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, - FilterChain filterChain) throws IOException, ServletException { - - // Workaround https://github.com/Netflix/zuul/pull/430 - // This class can be removed, and com.netflix.zuul.filters.ZuulServletFilter used - // in its place, - // when using a Zuul release with that change in it. - - // Marks this request as having passed through the "Zuul engine", as opposed to - // servlets - // explicitly bound in web.xml, for which requests will not have the same data - // attached - RequestContext context = RequestContext.getCurrentContext(); - context.setZuulEngineRan(); - - super.doFilter(servletRequest, servletResponse, filterChain); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/CompositeRouteLocator.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/CompositeRouteLocator.java deleted file mode 100644 index 29e858cc9..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/CompositeRouteLocator.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.util.Assert; - -/** - * RouteLocator that composes multiple RouteLocators. - * - * @author Johannes Edmeier - * - */ -public class CompositeRouteLocator implements RefreshableRouteLocator { - - private final Collection routeLocators; - - private ArrayList rl; - - public CompositeRouteLocator(Collection routeLocators) { - Assert.notNull(routeLocators, "'routeLocators' must not be null"); - rl = new ArrayList<>(routeLocators); - AnnotationAwareOrderComparator.sort(rl); - this.routeLocators = rl; - } - - @Override - public Collection getIgnoredPaths() { - List ignoredPaths = new ArrayList<>(); - for (RouteLocator locator : routeLocators) { - ignoredPaths.addAll(locator.getIgnoredPaths()); - } - return ignoredPaths; - } - - @Override - public List getRoutes() { - List route = new ArrayList<>(); - for (RouteLocator locator : routeLocators) { - route.addAll(locator.getRoutes()); - } - return route; - } - - @Override - public Route getMatchingRoute(String path) { - for (RouteLocator locator : routeLocators) { - Route route = locator.getMatchingRoute(path); - if (route != null) { - return route; - } - } - return null; - } - - @Override - public void refresh() { - for (RouteLocator locator : routeLocators) { - if (locator instanceof RefreshableRouteLocator) { - ((RefreshableRouteLocator) locator).refresh(); - } - } - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelper.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelper.java deleted file mode 100755 index ad67f55b1..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelper.java +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.regex.Pattern; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.util.HTTPRequestUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.netflix.zuul.util.RequestUtils; -import org.springframework.http.HttpHeaders; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.util.UriTemplate; -import org.springframework.web.util.UriUtils; -import org.springframework.web.util.WebUtils; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_URI_KEY; - -/** - * @author Dave Syer - * @author Marcos Barbero - * @author Spencer Gibb - */ -public class ProxyRequestHelper { - - private static final Log log = LogFactory.getLog(ProxyRequestHelper.class); - - /** - * Zuul context key for a collection of ignored headers for the current request. - * Pre-filters can set this up as a set of lowercase strings. - */ - public static final String IGNORED_HEADERS = "ignoredHeaders"; - - /** - * Form feed pattern. - */ - public static final Pattern FORM_FEED_PATTERN = Pattern.compile("\f"); - - /** - * Colon pattern. - */ - public static final Pattern COLON_PATTERN = Pattern.compile(":"); - - private Set ignoredHeaders = new LinkedHashSet<>(); - - private Set sensitiveHeaders = new LinkedHashSet<>(); - - private Set whitelistHosts = new LinkedHashSet<>(); - - private boolean traceRequestBody = true; - - private boolean addHostHeader = false; - - private boolean urlDecoded = true; - - @Deprecated - // TODO Remove in 2.1.x - public ProxyRequestHelper() { - } - - public ProxyRequestHelper(ZuulProperties zuulProperties) { - this.ignoredHeaders.addAll(zuulProperties.getIgnoredHeaders()); - this.traceRequestBody = zuulProperties.isTraceRequestBody(); - this.addHostHeader = zuulProperties.isAddHostHeader(); - this.urlDecoded = zuulProperties.isDecodeUrl(); - } - - public void setWhitelistHosts(Set whitelistHosts) { - this.whitelistHosts.addAll(whitelistHosts); - } - - public void setSensitiveHeaders(Set sensitiveHeaders) { - this.sensitiveHeaders.addAll(sensitiveHeaders); - } - - @Deprecated - // TODO Remove in 2.1.x - public void setIgnoredHeaders(Set ignoredHeaders) { - this.ignoredHeaders.addAll(ignoredHeaders); - } - - @Deprecated - // TODO Remove in 2.1.x - public void setTraceRequestBody(boolean traceRequestBody) { - this.traceRequestBody = traceRequestBody; - } - - public String buildZuulRequestURI(HttpServletRequest request) { - RequestContext context = RequestContext.getCurrentContext(); - String uri = request.getRequestURI(); - String contextURI = (String) context.get(REQUEST_URI_KEY); - if (contextURI != null) { - try { - uri = contextURI; - if (this.urlDecoded) { - uri = UriUtils.encodePath(contextURI, characterEncoding(request)); - } - } - catch (Exception e) { - log.debug( - "unable to encode uri path from context, falling back to uri from request", - e); - } - } - return uri; - } - - private String characterEncoding(HttpServletRequest request) { - return request.getCharacterEncoding() != null ? request.getCharacterEncoding() - : WebUtils.DEFAULT_CHARACTER_ENCODING; - } - - public MultiValueMap buildZuulRequestQueryParams( - HttpServletRequest request) { - Map> map = HTTPRequestUtils.getInstance().getQueryParams(); - MultiValueMap params = new LinkedMultiValueMap<>(); - if (map == null) { - return params; - } - for (String key : map.keySet()) { - for (String value : map.get(key)) { - params.add(key, value); - } - } - return params; - } - - public MultiValueMap buildZuulRequestHeaders( - HttpServletRequest request) { - RequestContext context = RequestContext.getCurrentContext(); - MultiValueMap headers = new HttpHeaders(); - Enumeration headerNames = request.getHeaderNames(); - if (headerNames != null) { - while (headerNames.hasMoreElements()) { - String name = headerNames.nextElement(); - if (isIncludedHeader(name)) { - Enumeration values = request.getHeaders(name); - while (values.hasMoreElements()) { - String value = values.nextElement(); - headers.add(name, value); - } - } - } - } - Map zuulRequestHeaders = context.getZuulRequestHeaders(); - for (String header : zuulRequestHeaders.keySet()) { - if (isIncludedHeader(header)) { - headers.set(header, zuulRequestHeaders.get(header)); - } - } - if (!headers.containsKey(HttpHeaders.ACCEPT_ENCODING)) { - headers.set(HttpHeaders.ACCEPT_ENCODING, "gzip"); - } - return headers; - } - - public void setResponse(int status, InputStream entity, - MultiValueMap headers) throws IOException { - RequestContext context = RequestContext.getCurrentContext(); - context.setResponseStatusCode(status); - if (entity != null) { - context.setResponseDataStream(entity); - } - - boolean isOriginResponseGzipped = false; - for (Entry> header : headers.entrySet()) { - String name = header.getKey(); - for (String value : header.getValue()) { - context.addOriginResponseHeader(name, value); - - if (name.equalsIgnoreCase(HttpHeaders.CONTENT_ENCODING) - && HTTPRequestUtils.getInstance().isGzipped(value)) { - isOriginResponseGzipped = true; - } - if (name.equalsIgnoreCase(HttpHeaders.CONTENT_LENGTH)) { - context.setOriginContentLength(value); - } - if (isIncludedHeader(name)) { - context.addZuulResponseHeader(name, value); - } - } - } - context.setResponseGZipped(isOriginResponseGzipped); - } - - public void addIgnoredHeaders(String... names) { - RequestContext ctx = RequestContext.getCurrentContext(); - if (!ctx.containsKey(IGNORED_HEADERS)) { - ctx.set(IGNORED_HEADERS, new HashSet()); - } - @SuppressWarnings("unchecked") - Set set = (Set) ctx.get(IGNORED_HEADERS); - for (String name : this.ignoredHeaders) { - set.add(name.toLowerCase()); - } - for (String name : names) { - set.add(name.toLowerCase()); - } - } - - public boolean isIncludedHeader(String headerName) { - String name = headerName.toLowerCase(); - RequestContext ctx = RequestContext.getCurrentContext(); - if (ctx.containsKey(IGNORED_HEADERS)) { - Object object = ctx.get(IGNORED_HEADERS); - if (object instanceof Collection && ((Collection) object).contains(name)) { - return false; - } - } - switch (name) { - case "host": - if (addHostHeader) { - return true; - } - case "connection": - case "content-length": - case "server": - case "transfer-encoding": - case "x-application-context": - return false; - default: - return true; - } - } - - public Map debug(String verb, String uri, - MultiValueMap headers, MultiValueMap params, - InputStream requestEntity) throws IOException { - Map info = new LinkedHashMap<>(); - return info; - } - - protected boolean shouldDebugBody(RequestContext ctx) { - HttpServletRequest request = ctx.getRequest(); - if (!this.traceRequestBody || ctx.isChunkedRequestBody() - || RequestUtils.isZuulServletRequest()) { - return false; - } - if (request == null || request.getContentType() == null) { - return true; - } - return !request.getContentType().toLowerCase().contains("multipart"); - } - - public void appendDebug(Map info, int status, - MultiValueMap headers) { - } - - /** - * Get url encoded query string. Pay special attention to single parameters with no - * values and parameter names with colon (:) from use of UriTemplate. - * @param params Un-encoded request parameters - * @return url-encoded query String built from provided parameters - */ - public String getQueryString(MultiValueMap params) { - if (params.isEmpty()) { - return ""; - } - StringBuilder query = new StringBuilder(); - Map singles = new HashMap<>(); - for (String param : params.keySet()) { - int i = 0; - for (String value : params.get(param)) { - query.append("&"); - query.append(param); - if (!"".equals(value)) { // don't add =, if original is ?wsdl, output is - // not ?wsdl= - String key = param; - // if form feed is already part of param name double - // since form feed is used as the colon replacement below - if (key.contains("\f")) { - key = (FORM_FEED_PATTERN.matcher(key).replaceAll("\f\f")); - } - // colon is special to UriTemplate - if (key.contains(":")) { - key = COLON_PATTERN.matcher(key).replaceAll("\f"); - } - key = key + i; - singles.put(key, value); - query.append("={"); - query.append(key); - query.append("}"); - } - i++; - } - } - - UriTemplate template = new UriTemplate("?" + query.toString().substring(1)); - return template.expand(singles).toString(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/RefreshableRouteLocator.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/RefreshableRouteLocator.java deleted file mode 100644 index 6f368958e..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/RefreshableRouteLocator.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 - * - * https://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.zuul.filters; - -/** - * Interface for a route locator that can be refreshed if routes change. - * - * @author Dave Syer - */ -public interface RefreshableRouteLocator extends RouteLocator { - - void refresh(); - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/Route.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/Route.java deleted file mode 100644 index e26c7c054..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/Route.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters; - -import java.util.LinkedHashSet; -import java.util.Objects; -import java.util.Set; - -import org.springframework.util.StringUtils; - -/** - * Represents Zuul route. - * - * @author Dave Syer - * @author Biju Kunjummen - * @author Gregor Zurowski - */ -public class Route { - - public Route(String id, String path, String location, String prefix, - Boolean retryable, Set ignoredHeaders) { - this.id = id; - this.prefix = StringUtils.hasText(prefix) ? prefix : ""; - this.path = path; - this.fullPath = prefix + path; - this.location = location; - this.retryable = retryable; - this.sensitiveHeaders = new LinkedHashSet<>(); - if (ignoredHeaders != null) { - this.customSensitiveHeaders = true; - for (String header : ignoredHeaders) { - this.sensitiveHeaders.add(header.toLowerCase()); - } - } - } - - public Route(String id, String path, String location, String prefix, - Boolean retryable, Set ignoredHeaders, boolean prefixStripped) { - this(id, path, location, prefix, retryable, ignoredHeaders); - this.prefixStripped = prefixStripped; - } - - private String id; - - private String fullPath; - - private String path; - - private String location; - - private String prefix; - - private Boolean retryable; - - private Set sensitiveHeaders = new LinkedHashSet<>(); - - private boolean customSensitiveHeaders; - - private boolean prefixStripped = true; - - public boolean isCustomSensitiveHeaders() { - return this.customSensitiveHeaders; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getFullPath() { - return fullPath; - } - - public void setFullPath(String fullPath) { - this.fullPath = fullPath; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getPrefix() { - return prefix; - } - - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - public Boolean getRetryable() { - return retryable; - } - - public void setRetryable(Boolean retryable) { - this.retryable = retryable; - } - - public Set getSensitiveHeaders() { - return sensitiveHeaders; - } - - public void setSensitiveHeaders(Set sensitiveHeaders) { - this.sensitiveHeaders = sensitiveHeaders; - } - - public void setCustomSensitiveHeaders(boolean customSensitiveHeaders) { - this.customSensitiveHeaders = customSensitiveHeaders; - } - - public boolean isPrefixStripped() { - return prefixStripped; - } - - public void setPrefixStripped(boolean prefixStripped) { - this.prefixStripped = prefixStripped; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Route that = (Route) o; - return customSensitiveHeaders == that.customSensitiveHeaders - && prefixStripped == that.prefixStripped && Objects.equals(id, that.id) - && Objects.equals(fullPath, that.fullPath) - && Objects.equals(path, that.path) - && Objects.equals(location, that.location) - && Objects.equals(prefix, that.prefix) - && Objects.equals(retryable, that.retryable) - && Objects.equals(sensitiveHeaders, that.sensitiveHeaders); - } - - @Override - public int hashCode() { - return Objects.hash(id, fullPath, path, location, prefix, retryable, - sensitiveHeaders, customSensitiveHeaders, prefixStripped); - } - - @Override - public String toString() { - return new StringBuilder("Route{").append("id='").append(id).append("', ") - .append("fullPath='").append(fullPath).append("', ").append("path='") - .append(path).append("', ").append("location='").append(location) - .append("', ").append("prefix='").append(prefix).append("', ") - .append("retryable=").append(retryable).append(", ") - .append("sensitiveHeaders=").append(sensitiveHeaders).append(", ") - .append("customSensitiveHeaders=").append(customSensitiveHeaders) - .append(", ").append("prefixStripped=").append(prefixStripped).append("}") - .toString(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/RouteLocator.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/RouteLocator.java deleted file mode 100644 index cd5be3dab..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/RouteLocator.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters; - -import java.util.Collection; -import java.util.List; - -/** - * @author Dave Syer - */ -public interface RouteLocator { - - /** - * Ignored route paths (or patterns), if any. - * @return {@link Collection} of ignored paths - */ - Collection getIgnoredPaths(); - - /** - * A map of route path (pattern) to location (e.g. service id or URL). - * @return {@link List} of routes - */ - List getRoutes(); - - /** - * Maps a path to an actual route with full metadata. - * @param path used to match the {@link Route} - * @return matching {@link Route} based on the provided path - */ - Route getMatchingRoute(String path); - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocator.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocator.java deleted file mode 100644 index a7c3290c2..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocator.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.atomic.AtomicReference; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; -import org.springframework.cloud.netflix.zuul.util.RequestUtils; -import org.springframework.core.Ordered; -import org.springframework.util.AntPathMatcher; -import org.springframework.util.PathMatcher; -import org.springframework.util.StringUtils; - -/** - * Simple {@link RouteLocator} based on configuration data held in {@link ZuulProperties}. - * - * @author Dave Syer - */ -public class SimpleRouteLocator implements RouteLocator, Ordered { - - private static final Log log = LogFactory.getLog(SimpleRouteLocator.class); - - private static final int DEFAULT_ORDER = 0; - - private ZuulProperties properties; - - private PathMatcher pathMatcher = new AntPathMatcher(); - - private String dispatcherServletPath = "/"; - - private String zuulServletPath; - - private AtomicReference> routes = new AtomicReference<>(); - - private int order = DEFAULT_ORDER; - - public SimpleRouteLocator(String servletPath, ZuulProperties properties) { - this.properties = properties; - if (StringUtils.hasText(servletPath)) { - this.dispatcherServletPath = servletPath; - } - - this.zuulServletPath = properties.getServletPath(); - } - - @Override - public List getRoutes() { - List values = new ArrayList<>(); - for (Entry entry : getRoutesMap().entrySet()) { - ZuulRoute route = entry.getValue(); - String path = route.getPath(); - try { - values.add(getRoute(route, path)); - } - catch (Exception e) { - if (log.isWarnEnabled()) { - log.warn("Invalid route, routeId: " + route.getId() - + ", routeServiceId: " + route.getServiceId() + ", msg: " - + e.getMessage()); - } - if (log.isDebugEnabled()) { - log.debug("", e); - } - } - } - return values; - } - - @Override - public Collection getIgnoredPaths() { - return this.properties.getIgnoredPatterns(); - } - - @Override - public Route getMatchingRoute(final String path) { - - return getSimpleMatchingRoute(path); - - } - - protected Map getRoutesMap() { - if (this.routes.get() == null) { - this.routes.set(locateRoutes()); - } - return this.routes.get(); - } - - protected Route getSimpleMatchingRoute(final String path) { - if (log.isDebugEnabled()) { - log.debug("Finding route for path: " + path); - } - - // This is called for the initialization done in getRoutesMap() - getRoutesMap(); - - if (log.isDebugEnabled()) { - log.debug("servletPath=" + this.dispatcherServletPath); - log.debug("zuulServletPath=" + this.zuulServletPath); - log.debug("RequestUtils.isDispatcherServletRequest()=" - + RequestUtils.isDispatcherServletRequest()); - log.debug("RequestUtils.isZuulServletRequest()=" - + RequestUtils.isZuulServletRequest()); - } - - String adjustedPath = adjustPath(path); - - ZuulRoute route = getZuulRoute(adjustedPath); - - return getRoute(route, adjustedPath); - } - - protected ZuulRoute getZuulRoute(String adjustedPath) { - if (!matchesIgnoredPatterns(adjustedPath)) { - for (Entry entry : getRoutesMap().entrySet()) { - String pattern = entry.getKey(); - log.debug("Matching pattern:" + pattern); - if (this.pathMatcher.match(pattern, adjustedPath)) { - return entry.getValue(); - } - } - } - return null; - } - - protected Route getRoute(ZuulRoute route, String path) { - if (route == null) { - return null; - } - if (log.isDebugEnabled()) { - log.debug("route matched=" + route); - } - String targetPath = path; - String prefix = this.properties.getPrefix(); - if (prefix.endsWith("/")) { - prefix = prefix.substring(0, prefix.length() - 1); - } - if (path.startsWith(prefix + "/") && this.properties.isStripPrefix()) { - targetPath = path.substring(prefix.length()); - } - if (route.isStripPrefix()) { - int index = route.getPath().indexOf("*") - 1; - if (index > 0) { - String routePrefix = route.getPath().substring(0, index); - targetPath = targetPath.replaceFirst(routePrefix, ""); - prefix = prefix + routePrefix; - } - } - Boolean retryable = this.properties.getRetryable(); - if (route.getRetryable() != null) { - retryable = route.getRetryable(); - } - return new Route(route.getId(), targetPath, route.getLocation(), prefix, - retryable, - route.isCustomSensitiveHeaders() ? route.getSensitiveHeaders() : null, - route.isStripPrefix()); - } - - /** - * Calculate all the routes and set up a cache for the values. Subclasses can call - * this method if they need to implement {@link RefreshableRouteLocator}. - */ - protected void doRefresh() { - this.routes.set(locateRoutes()); - } - - /** - * Compute a map of path pattern to route. The default is just a static map from the - * {@link ZuulProperties}, but subclasses can add dynamic calculations. - * @return map of Zuul routes - */ - protected Map locateRoutes() { - LinkedHashMap routesMap = new LinkedHashMap<>(); - for (ZuulRoute route : this.properties.getRoutes().values()) { - routesMap.put(route.getPath(), route); - } - return routesMap; - } - - protected boolean matchesIgnoredPatterns(String path) { - for (String pattern : this.properties.getIgnoredPatterns()) { - log.debug("Matching ignored pattern:" + pattern); - if (this.pathMatcher.match(pattern, path)) { - log.debug("Path " + path + " matches ignored pattern " + pattern); - return true; - } - } - return false; - } - - private String adjustPath(final String path) { - String adjustedPath = path; - - if (RequestUtils.isDispatcherServletRequest() - && StringUtils.hasText(this.dispatcherServletPath)) { - if (!this.dispatcherServletPath.equals("/") - && path.startsWith(this.dispatcherServletPath)) { - adjustedPath = path.substring(this.dispatcherServletPath.length()); - log.debug("Stripped dispatcherServletPath"); - } - } - else if (RequestUtils.isZuulServletRequest()) { - if (StringUtils.hasText(this.zuulServletPath) - && !this.zuulServletPath.equals("/")) { - adjustedPath = path.substring(this.zuulServletPath.length()); - log.debug("Stripped zuulServletPath"); - } - } - else { - // do nothing - } - - log.debug("adjustedPath=" + adjustedPath); - return adjustedPath; - } - - @Override - public int getOrder() { - return order; - } - - public void setOrder(int order) { - this.order = order; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/TraceProxyRequestHelper.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/TraceProxyRequestHelper.java deleted file mode 100644 index 428394775..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/TraceProxyRequestHelper.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URI; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Enumeration; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.context.RequestContext; - -import org.springframework.boot.actuate.trace.http.HttpExchangeTracer; -import org.springframework.boot.actuate.trace.http.HttpTrace; -import org.springframework.boot.actuate.trace.http.HttpTraceRepository; -import org.springframework.boot.actuate.trace.http.Include; -import org.springframework.boot.actuate.trace.http.TraceableRequest; -import org.springframework.util.MultiValueMap; -import org.springframework.util.StringUtils; - -/** - * @author Spencer Gibb - */ -public class TraceProxyRequestHelper extends ProxyRequestHelper { - - private HttpTraceRepository traces; - - @Deprecated - // TODO Remove in 2.1.x - public TraceProxyRequestHelper() { - } - - public TraceProxyRequestHelper(ZuulProperties zuulProperties) { - super(zuulProperties); - } - - private final HttpExchangeTracer tracer = new HttpExchangeTracer( - Include.defaultIncludes()); - - public void setTraces(HttpTraceRepository traces) { - this.traces = traces; - } - - @Override - public Map debug(String verb, String uri, - MultiValueMap headers, MultiValueMap params, - InputStream requestEntity) throws IOException { - Map info = new LinkedHashMap<>(); - if (this.traces != null) { - RequestContext context = RequestContext.getCurrentContext(); - info.put("method", verb); - info.put("path", uri); - info.put("query", getQueryString(params)); - info.put("remote", true); - info.put("proxy", context.get("proxy")); - Map trace = new LinkedHashMap<>(); - Map input = new LinkedHashMap<>(); - trace.put("request", input); - info.put("headers", trace); - debugHeaders(headers, input); - HttpServletRequest request = context.getRequest(); - if (shouldDebugBody(context)) { - // Prevent input stream from being read if it needs to go downstream - if (requestEntity != null) { - debugRequestEntity(info, request.getInputStream()); - } - } - HttpTrace httpTrace = tracer - .receivedRequest(new ServletTraceableRequest(request)); - this.traces.add(httpTrace); - return info; - } - return info; - } - - void debugHeaders(MultiValueMap headers, Map map) { - for (Entry> entry : headers.entrySet()) { - Collection collection = entry.getValue(); - Object value = collection; - if (collection.size() < 2) { - value = collection.isEmpty() ? "" : collection.iterator().next(); - } - map.put(entry.getKey(), value); - } - } - - public void appendDebug(Map info, int status, - MultiValueMap headers) { - if (this.traces != null) { - @SuppressWarnings("unchecked") - Map trace = (Map) info.get("headers"); - Map output = new LinkedHashMap<>(); - trace.put("response", output); - debugHeaders(headers, output); - output.put("status", "" + status); - } - } - - private void debugRequestEntity(Map info, InputStream inputStream) - throws IOException { - if (RequestContext.getCurrentContext().isChunkedRequestBody()) { - info.put("body", ""); - return; - } - char[] buffer = new char[4096]; - int count = new InputStreamReader(inputStream, Charset.forName("UTF-8")) - .read(buffer, 0, buffer.length); - if (count > 0) { - String entity = new String(buffer).substring(0, count); - info.put("body", entity.length() < 4096 ? entity : entity + ""); - } - } - - private class ServletTraceableRequest implements TraceableRequest { - - private HttpServletRequest request; - - ServletTraceableRequest(HttpServletRequest request) { - this.request = request; - } - - @Override - public String getMethod() { - return request.getMethod(); - } - - @Override - public URI getUri() { - StringBuffer urlBuffer = request.getRequestURL(); - if (StringUtils.hasText(request.getQueryString())) { - urlBuffer.append("?"); - urlBuffer.append(request.getQueryString()); - } - return URI.create(urlBuffer.toString()); - } - - @Override - public Map> getHeaders() { - return extractHeaders(); - } - - @Override - public String getRemoteAddress() { - return request.getRemoteAddr(); - } - - private Map> extractHeaders() { - Map> headers = new LinkedHashMap<>(); - Enumeration names = request.getHeaderNames(); - while (names.hasMoreElements()) { - String name = names.nextElement(); - headers.put(name, toList(request.getHeaders(name))); - } - return headers; - } - - private List toList(Enumeration enumeration) { - List list = new ArrayList<>(); - while (enumeration.hasMoreElements()) { - list.add(enumeration.nextElement()); - } - return list; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java deleted file mode 100755 index 5d1926c97..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java +++ /dev/null @@ -1,967 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters; - -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import javax.annotation.PostConstruct; - -import com.netflix.hystrix.HystrixCommandProperties.ExecutionIsolationStrategy; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.core.style.ToStringCreator; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; - -import static com.netflix.hystrix.HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE; - -/** - * @author Spencer Gibb - * @author Dave Syer - * @author Mathias Düsterhöft - * @author Bilal Alp - * @author Gregor Zurowski - */ -@ConfigurationProperties("zuul") -public class ZuulProperties { - - /** - * Headers that are generally expected to be added by Spring Security, and hence often - * duplicated if the proxy and the backend are secured with Spring. By default they - * are added to the ignored headers if Spring Security is present and - * ignoreSecurityHeaders = true. - */ - public static final List SECURITY_HEADERS = Arrays.asList("Pragma", - "Cache-Control", "X-Frame-Options", "X-Content-Type-Options", - "X-XSS-Protection", "Expires"); - - /** - * A common prefix for all routes. - */ - private String prefix = ""; - - /** - * Flag saying whether to strip the prefix from the path before forwarding. - */ - private boolean stripPrefix = true; - - /** - * Flag for whether retry is supported by default (assuming the routes themselves - * support it). - */ - private Boolean retryable = false; - - /** - * Map of route names to properties. - */ - private Map routes = new LinkedHashMap<>(); - - /** - * Flag to determine whether the proxy adds X-Forwarded-* headers. - */ - private boolean addProxyHeaders = true; - - /** - * Flag to determine whether the proxy forwards the Host header. - */ - private boolean addHostHeader = false; - - /** - * Set of service names not to consider for proxying automatically. By default all - * services in the discovery client will be proxied. - */ - private Set ignoredServices = new LinkedHashSet<>(); - - private Set ignoredPatterns = new LinkedHashSet<>(); - - /** - * Names of HTTP headers to ignore completely (i.e. leave them out of downstream - * requests and drop them from downstream responses). - */ - private Set ignoredHeaders = new LinkedHashSet<>(); - - /** - * Flag to say that SECURITY_HEADERS are added to ignored headers if spring security - * is on the classpath. By setting ignoreSecurityHeaders to false we can switch off - * this default behaviour. This should be used together with disabling the default - * spring security headers see - * https://docs.spring.io/spring-security/site/docs/current/reference/html/headers.html#default-security-headers - */ - private boolean ignoreSecurityHeaders = true; - - /** - * Flag to force the original query string encoding when building the backend URI in - * SimpleHostRoutingFilter. When activated, query string will be built using - * HttpServletRequest getQueryString() method instead of UriTemplate. Note that this - * flag is not used in RibbonRoutingFilter with services found via DiscoveryClient - * (like Eureka). - */ - private boolean forceOriginalQueryStringEncoding = false; - - /** - * Path to install Zuul as a servlet (not part of Spring MVC). The servlet is more - * memory efficient for requests with large bodies, e.g. file uploads. - */ - private String servletPath = "/zuul"; - - private boolean ignoreLocalService = true; - - /** - * Host properties controlling default connection pool properties. - */ - private Host host = new Host(); - - /** - * Flag to say that request bodies can be traced. - */ - private boolean traceRequestBody = false; - - /** - * Flag to say that path elements past the first semicolon can be dropped. - */ - private boolean removeSemicolonContent = true; - - /** - * Flag to indicate whether to decode the matched URL or use it as is. - */ - private boolean decodeUrl = true; - - /** - * List of sensitive headers that are not passed to downstream requests. Defaults to a - * "safe" set of headers that commonly contain user credentials. It's OK to remove - * those from the list if the downstream service is part of the same system as the - * proxy, so they are sharing authentication data. If using a physical URL outside - * your own domain, then generally it would be a bad idea to leak user credentials. - */ - private Set sensitiveHeaders = new LinkedHashSet<>( - Arrays.asList("Cookie", "Set-Cookie", "Authorization")); - - /** - * Flag to say whether the hostname for ssl connections should be verified or not. - * Default is true. This should only be used in test setups! - */ - private boolean sslHostnameValidationEnabled = true; - - private ExecutionIsolationStrategy ribbonIsolationStrategy = SEMAPHORE; - - private HystrixSemaphore semaphore = new HystrixSemaphore(); - - private HystrixThreadPool threadPool = new HystrixThreadPool(); - - /** - * Setting for SendResponseFilter to conditionally set Content-Length header. - */ - private boolean setContentLength = false; - - /** - * Setting for SendResponseFilter to conditionally include X-Zuul-Debug-Header header. - */ - private boolean includeDebugHeader = false; - - /** - * Setting for SendResponseFilter for the initial stream buffer size. - */ - private int initialStreamBufferSize = 8192; - - public Set getIgnoredHeaders() { - Set ignoredHeaders = new LinkedHashSet<>(this.ignoredHeaders); - if (ClassUtils.isPresent( - "org.springframework.security.config.annotation.web.WebSecurityConfigurer", - null) && Collections.disjoint(ignoredHeaders, SECURITY_HEADERS) - && ignoreSecurityHeaders) { - // Allow Spring Security in the gateway to control these headers - ignoredHeaders.addAll(SECURITY_HEADERS); - } - return ignoredHeaders; - } - - public void setIgnoredHeaders(Set ignoredHeaders) { - this.ignoredHeaders.addAll(ignoredHeaders); - } - - @PostConstruct - public void init() { - for (Entry entry : this.routes.entrySet()) { - ZuulRoute value = entry.getValue(); - if (!StringUtils.hasText(value.getLocation())) { - value.serviceId = entry.getKey(); - } - if (!StringUtils.hasText(value.getId())) { - value.id = entry.getKey(); - } - if (!StringUtils.hasText(value.getPath())) { - value.path = "/" + entry.getKey() + "/**"; - } - } - } - - public String getServletPattern() { - String path = this.servletPath; - if (!path.startsWith("/")) { - path = "/" + path; - } - if (!path.contains("*")) { - path = path.endsWith("/") ? (path + "*") : (path + "/*"); - } - return path; - } - - public String getPrefix() { - return prefix; - } - - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - public boolean isStripPrefix() { - return stripPrefix; - } - - public void setStripPrefix(boolean stripPrefix) { - this.stripPrefix = stripPrefix; - } - - public Boolean getRetryable() { - return retryable; - } - - public void setRetryable(Boolean retryable) { - this.retryable = retryable; - } - - public Map getRoutes() { - return routes; - } - - public void setRoutes(Map routes) { - this.routes = routes; - } - - public boolean isAddProxyHeaders() { - return addProxyHeaders; - } - - public void setAddProxyHeaders(boolean addProxyHeaders) { - this.addProxyHeaders = addProxyHeaders; - } - - public boolean isAddHostHeader() { - return addHostHeader; - } - - public void setAddHostHeader(boolean addHostHeader) { - this.addHostHeader = addHostHeader; - } - - public Set getIgnoredServices() { - return ignoredServices; - } - - public void setIgnoredServices(Set ignoredServices) { - this.ignoredServices = ignoredServices; - } - - public Set getIgnoredPatterns() { - return ignoredPatterns; - } - - public void setIgnoredPatterns(Set ignoredPatterns) { - this.ignoredPatterns = ignoredPatterns; - } - - public boolean isIgnoreSecurityHeaders() { - return ignoreSecurityHeaders; - } - - public void setIgnoreSecurityHeaders(boolean ignoreSecurityHeaders) { - this.ignoreSecurityHeaders = ignoreSecurityHeaders; - } - - public boolean isForceOriginalQueryStringEncoding() { - return forceOriginalQueryStringEncoding; - } - - public void setForceOriginalQueryStringEncoding( - boolean forceOriginalQueryStringEncoding) { - this.forceOriginalQueryStringEncoding = forceOriginalQueryStringEncoding; - } - - public String getServletPath() { - return servletPath; - } - - public void setServletPath(String servletPath) { - this.servletPath = servletPath; - } - - public boolean isIgnoreLocalService() { - return ignoreLocalService; - } - - public void setIgnoreLocalService(boolean ignoreLocalService) { - this.ignoreLocalService = ignoreLocalService; - } - - public Host getHost() { - return host; - } - - public void setHost(Host host) { - this.host = host; - } - - public boolean isTraceRequestBody() { - return traceRequestBody; - } - - public void setTraceRequestBody(boolean traceRequestBody) { - this.traceRequestBody = traceRequestBody; - } - - public boolean isRemoveSemicolonContent() { - return removeSemicolonContent; - } - - public void setRemoveSemicolonContent(boolean removeSemicolonContent) { - this.removeSemicolonContent = removeSemicolonContent; - } - - public boolean isDecodeUrl() { - return decodeUrl; - } - - public void setDecodeUrl(boolean decodeUrl) { - this.decodeUrl = decodeUrl; - } - - public Set getSensitiveHeaders() { - return sensitiveHeaders; - } - - public void setSensitiveHeaders(Set sensitiveHeaders) { - this.sensitiveHeaders = sensitiveHeaders; - } - - public boolean isSslHostnameValidationEnabled() { - return sslHostnameValidationEnabled; - } - - public void setSslHostnameValidationEnabled(boolean sslHostnameValidationEnabled) { - this.sslHostnameValidationEnabled = sslHostnameValidationEnabled; - } - - public ExecutionIsolationStrategy getRibbonIsolationStrategy() { - return ribbonIsolationStrategy; - } - - public void setRibbonIsolationStrategy( - ExecutionIsolationStrategy ribbonIsolationStrategy) { - this.ribbonIsolationStrategy = ribbonIsolationStrategy; - } - - public HystrixSemaphore getSemaphore() { - return semaphore; - } - - public void setSemaphore(HystrixSemaphore semaphore) { - this.semaphore = semaphore; - } - - public HystrixThreadPool getThreadPool() { - return threadPool; - } - - public void setThreadPool(HystrixThreadPool threadPool) { - this.threadPool = threadPool; - } - - public boolean isSetContentLength() { - return setContentLength; - } - - public void setSetContentLength(boolean setContentLength) { - this.setContentLength = setContentLength; - } - - public boolean isIncludeDebugHeader() { - return includeDebugHeader; - } - - public void setIncludeDebugHeader(boolean includeDebugHeader) { - this.includeDebugHeader = includeDebugHeader; - } - - public int getInitialStreamBufferSize() { - return initialStreamBufferSize; - } - - public void setInitialStreamBufferSize(int initialStreamBufferSize) { - this.initialStreamBufferSize = initialStreamBufferSize; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ZuulProperties that = (ZuulProperties) o; - return addHostHeader == that.addHostHeader - && addProxyHeaders == that.addProxyHeaders - && forceOriginalQueryStringEncoding == that.forceOriginalQueryStringEncoding - && Objects.equals(host, that.host) - && Objects.equals(ignoredHeaders, that.ignoredHeaders) - && Objects.equals(ignoredPatterns, that.ignoredPatterns) - && Objects.equals(ignoredServices, that.ignoredServices) - && ignoreLocalService == that.ignoreLocalService - && ignoreSecurityHeaders == that.ignoreSecurityHeaders - && Objects.equals(prefix, that.prefix) - && removeSemicolonContent == that.removeSemicolonContent - && Objects.equals(retryable, that.retryable) - && Objects.equals(ribbonIsolationStrategy, that.ribbonIsolationStrategy) - && Objects.equals(routes, that.routes) - && Objects.equals(semaphore, that.semaphore) - && Objects.equals(sensitiveHeaders, that.sensitiveHeaders) - && Objects.equals(servletPath, that.servletPath) - && sslHostnameValidationEnabled == that.sslHostnameValidationEnabled - && stripPrefix == that.stripPrefix - && setContentLength == that.setContentLength - && includeDebugHeader == that.includeDebugHeader - && initialStreamBufferSize == that.initialStreamBufferSize - && Objects.equals(threadPool, that.threadPool) - && traceRequestBody == that.traceRequestBody; - } - - @Override - public int hashCode() { - return Objects.hash(addHostHeader, addProxyHeaders, - forceOriginalQueryStringEncoding, host, ignoredHeaders, ignoredPatterns, - ignoredServices, ignoreLocalService, ignoreSecurityHeaders, prefix, - removeSemicolonContent, retryable, ribbonIsolationStrategy, routes, - semaphore, sensitiveHeaders, servletPath, sslHostnameValidationEnabled, - stripPrefix, threadPool, traceRequestBody, setContentLength, - includeDebugHeader, initialStreamBufferSize); - } - - @Override - public String toString() { - return new StringBuilder("ZuulProperties{").append("prefix='").append(prefix) - .append("', ").append("stripPrefix=").append(stripPrefix).append(", ") - .append("retryable=").append(retryable).append(", ").append("routes=") - .append(routes).append(", ").append("addProxyHeaders=") - .append(addProxyHeaders).append(", ").append("addHostHeader=") - .append(addHostHeader).append(", ").append("ignoredServices=") - .append(ignoredServices).append(", ").append("ignoredPatterns=") - .append(ignoredPatterns).append(", ").append("ignoredHeaders=") - .append(ignoredHeaders).append(", ").append("ignoreSecurityHeaders=") - .append(ignoreSecurityHeaders).append(", ") - .append("forceOriginalQueryStringEncoding=") - .append(forceOriginalQueryStringEncoding).append(", ") - .append("servletPath='").append(servletPath).append("', ") - .append("ignoreLocalService=").append(ignoreLocalService).append(", ") - .append("host=").append(host).append(", ").append("traceRequestBody=") - .append(traceRequestBody).append(", ").append("removeSemicolonContent=") - .append(removeSemicolonContent).append(", ").append("sensitiveHeaders=") - .append(sensitiveHeaders).append(", ") - .append("sslHostnameValidationEnabled=") - .append(sslHostnameValidationEnabled).append(", ") - .append("ribbonIsolationStrategy=").append(ribbonIsolationStrategy) - .append(", ").append("semaphore=").append(semaphore).append(", ") - .append("threadPool=").append(threadPool).append(", ") - .append("setContentLength=").append(setContentLength).append(", ") - .append("includeDebugHeader=").append(includeDebugHeader).append(", ") - .append("initialStreamBufferSize=").append(initialStreamBufferSize) - .append(", ").append("}").toString(); - } - - /** - * Represents a Zuul route. - */ - public static class ZuulRoute { - - /** - * The ID of the route (the same as its map key by default). - */ - private String id; - - /** - * The path (pattern) for the route, e.g. /foo/**. - */ - private String path; - - /** - * The service ID (if any) to map to this route. You can specify a physical URL or - * a service, but not both. - */ - private String serviceId; - - /** - * A full physical URL to map to the route. An alternative is to use a service ID - * and service discovery to find the physical address. - */ - private String url; - - /** - * Flag to determine whether the prefix for this route (the path, minus pattern - * patcher) should be stripped before forwarding. - */ - private boolean stripPrefix = true; - - /** - * Flag to indicate that this route should be retryable (if supported). Generally - * retry requires a service ID and ribbon. - */ - private Boolean retryable; - - /** - * List of sensitive headers that are not passed to downstream requests. Defaults - * to a "safe" set of headers that commonly contain user credentials. It's OK to - * remove those from the list if the downstream service is part of the same system - * as the proxy, so they are sharing authentication data. If using a physical URL - * outside your own domain, then generally it would be a bad idea to leak user - * credentials. - */ - private Set sensitiveHeaders = new LinkedHashSet<>(); - - private boolean customSensitiveHeaders = false; - - public ZuulRoute() { - } - - public ZuulRoute(String id, String path, String serviceId, String url, - boolean stripPrefix, Boolean retryable, Set sensitiveHeaders) { - this.id = id; - this.path = path; - this.serviceId = serviceId; - this.url = url; - this.stripPrefix = stripPrefix; - this.retryable = retryable; - this.sensitiveHeaders = sensitiveHeaders; - this.customSensitiveHeaders = sensitiveHeaders != null; - } - - public ZuulRoute(String text) { - String location = null; - String path = text; - if (text.contains("=")) { - String[] values = StringUtils - .trimArrayElements(StringUtils.split(text, "=")); - location = values[1]; - path = values[0]; - } - this.id = extractId(path); - if (!path.startsWith("/")) { - path = "/" + path; - } - setLocation(location); - this.path = path; - } - - public ZuulRoute(String path, String location) { - this.id = extractId(path); - this.path = path; - setLocation(location); - } - - public String getLocation() { - if (StringUtils.hasText(this.url)) { - return this.url; - } - return this.serviceId; - } - - public void setLocation(String location) { - if (location != null - && (location.startsWith("http:") || location.startsWith("https:"))) { - this.url = location; - } - else { - this.serviceId = location; - } - } - - private String extractId(String path) { - path = path.startsWith("/") ? path.substring(1) : path; - path = path.replace("/*", "").replace("*", ""); - return path; - } - - public Route getRoute(String prefix) { - return new Route(this.id, this.path, getLocation(), prefix, this.retryable, - isCustomSensitiveHeaders() ? this.sensitiveHeaders : null, - this.stripPrefix); - } - - public boolean isCustomSensitiveHeaders() { - return this.customSensitiveHeaders; - } - - public void setCustomSensitiveHeaders(boolean customSensitiveHeaders) { - this.customSensitiveHeaders = customSensitiveHeaders; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public String getServiceId() { - return serviceId; - } - - public void setServiceId(String serviceId) { - this.serviceId = serviceId; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public boolean isStripPrefix() { - return stripPrefix; - } - - public void setStripPrefix(boolean stripPrefix) { - this.stripPrefix = stripPrefix; - } - - public Boolean getRetryable() { - return retryable; - } - - public void setRetryable(Boolean retryable) { - this.retryable = retryable; - } - - public Set getSensitiveHeaders() { - return sensitiveHeaders; - } - - public void setSensitiveHeaders(Set headers) { - this.customSensitiveHeaders = true; - this.sensitiveHeaders = new LinkedHashSet<>(headers); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ZuulRoute that = (ZuulRoute) o; - return customSensitiveHeaders == that.customSensitiveHeaders - && Objects.equals(id, that.id) && Objects.equals(path, that.path) - && Objects.equals(retryable, that.retryable) - && Objects.equals(sensitiveHeaders, that.sensitiveHeaders) - && Objects.equals(serviceId, that.serviceId) - && stripPrefix == that.stripPrefix && Objects.equals(url, that.url); - } - - @Override - public int hashCode() { - return Objects.hash(customSensitiveHeaders, id, path, retryable, - sensitiveHeaders, serviceId, stripPrefix, url); - } - - @Override - public String toString() { - return new StringBuilder("ZuulRoute{").append("id='").append(id).append("', ") - .append("path='").append(path).append("', ").append("serviceId='") - .append(serviceId).append("', ").append("url='").append(url) - .append("', ").append("stripPrefix=").append(stripPrefix).append(", ") - .append("retryable=").append(retryable).append(", ") - .append("sensitiveHeaders=").append(sensitiveHeaders).append(", ") - .append("customSensitiveHeaders=").append(customSensitiveHeaders) - .append(", ").append("}").toString(); - } - - } - - /** - * Represents a host. - */ - public static class Host { - - /** - * The maximum number of total connections the proxy can hold open to backends. - */ - private int maxTotalConnections = 200; - - /** - * The maximum number of connections that can be used by a single route. - */ - private int maxPerRouteConnections = 20; - - /** - * The socket timeout in millis. Defaults to 10000. - */ - private int socketTimeoutMillis = 10000; - - /** - * The connection timeout in millis. Defaults to 2000. - */ - private int connectTimeoutMillis = 2000; - - /** - * The timeout in milliseconds used when requesting a connection from the - * connection manager. Defaults to -1, undefined use the system default. - */ - private int connectionRequestTimeoutMillis = -1; - - /** - * The lifetime for the connection pool. - */ - private long timeToLive = -1; - - /** - * The time unit for timeToLive. - */ - private TimeUnit timeUnit = TimeUnit.MILLISECONDS; - - public Host() { - } - - public Host(int maxTotalConnections, int maxPerRouteConnections, - int socketTimeoutMillis, int connectTimeoutMillis, long timeToLive, - TimeUnit timeUnit) { - this.maxTotalConnections = maxTotalConnections; - this.maxPerRouteConnections = maxPerRouteConnections; - this.socketTimeoutMillis = socketTimeoutMillis; - this.connectTimeoutMillis = connectTimeoutMillis; - this.timeToLive = timeToLive; - this.timeUnit = timeUnit; - } - - public int getMaxTotalConnections() { - return maxTotalConnections; - } - - public void setMaxTotalConnections(int maxTotalConnections) { - this.maxTotalConnections = maxTotalConnections; - } - - public int getMaxPerRouteConnections() { - return maxPerRouteConnections; - } - - public void setMaxPerRouteConnections(int maxPerRouteConnections) { - this.maxPerRouteConnections = maxPerRouteConnections; - } - - public int getSocketTimeoutMillis() { - return socketTimeoutMillis; - } - - public void setSocketTimeoutMillis(int socketTimeoutMillis) { - this.socketTimeoutMillis = socketTimeoutMillis; - } - - public int getConnectTimeoutMillis() { - return connectTimeoutMillis; - } - - public void setConnectTimeoutMillis(int connectTimeoutMillis) { - this.connectTimeoutMillis = connectTimeoutMillis; - } - - public int getConnectionRequestTimeoutMillis() { - return connectionRequestTimeoutMillis; - } - - public void setConnectionRequestTimeoutMillis( - int connectionRequestTimeoutMillis) { - this.connectionRequestTimeoutMillis = connectionRequestTimeoutMillis; - } - - public long getTimeToLive() { - return timeToLive; - } - - public void setTimeToLive(long timeToLive) { - this.timeToLive = timeToLive; - } - - public TimeUnit getTimeUnit() { - return timeUnit; - } - - public void setTimeUnit(TimeUnit timeUnit) { - this.timeUnit = timeUnit; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Host host = (Host) o; - return maxTotalConnections == host.maxTotalConnections - && maxPerRouteConnections == host.maxPerRouteConnections - && socketTimeoutMillis == host.socketTimeoutMillis - && connectTimeoutMillis == host.connectTimeoutMillis - && connectionRequestTimeoutMillis == host.connectionRequestTimeoutMillis - && timeToLive == host.timeToLive && timeUnit == host.timeUnit; - } - - @Override - public int hashCode() { - return Objects.hash(maxTotalConnections, maxPerRouteConnections, - socketTimeoutMillis, connectTimeoutMillis, - connectionRequestTimeoutMillis, timeToLive, timeUnit); - } - - @Override - public String toString() { - return new ToStringCreator(this) - .append("maxTotalConnections", maxTotalConnections) - .append("maxPerRouteConnections", maxPerRouteConnections) - .append("socketTimeoutMillis", socketTimeoutMillis) - .append("connectTimeoutMillis", connectTimeoutMillis) - .append("connectionRequestTimeoutMillis", - connectionRequestTimeoutMillis) - .append("timeToLive", timeToLive).append("timeUnit", timeUnit) - .toString(); - } - - } - - /** - * Represents Hystrix Sempahores. - */ - public static class HystrixSemaphore { - - /** - * The maximum number of total semaphores for Hystrix. - */ - private int maxSemaphores = 100; - - public HystrixSemaphore() { - } - - public HystrixSemaphore(int maxSemaphores) { - this.maxSemaphores = maxSemaphores; - } - - public int getMaxSemaphores() { - return maxSemaphores; - } - - public void setMaxSemaphores(int maxSemaphores) { - this.maxSemaphores = maxSemaphores; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - HystrixSemaphore that = (HystrixSemaphore) o; - return maxSemaphores == that.maxSemaphores; - } - - @Override - public int hashCode() { - return Objects.hash(maxSemaphores); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("HystrixSemaphore{"); - sb.append("maxSemaphores=").append(maxSemaphores); - sb.append('}'); - return sb.toString(); - } - - } - - /** - * Represents Hystrix ThreadPool. - */ - public static class HystrixThreadPool { - - /** - * Flag to determine whether RibbonCommands should use separate thread pools for - * hystrix. By setting to true, RibbonCommands will be executed in a hystrix's - * thread pool that it is associated with. Each RibbonCommand will be associated - * with a thread pool according to its commandKey (serviceId). As default, all - * commands will be executed in a single thread pool whose threadPoolKey is - * "RibbonCommand". This property is only applicable when using THREAD as - * ribbonIsolationStrategy - */ - private boolean useSeparateThreadPools = false; - - /** - * A prefix for HystrixThreadPoolKey of hystrix's thread pool that is allocated to - * each service Id. This property is only applicable when using THREAD as - * ribbonIsolationStrategy and useSeparateThreadPools = true - */ - private String threadPoolKeyPrefix = ""; - - public boolean isUseSeparateThreadPools() { - return useSeparateThreadPools; - } - - public void setUseSeparateThreadPools(boolean useSeparateThreadPools) { - this.useSeparateThreadPools = useSeparateThreadPools; - } - - public String getThreadPoolKeyPrefix() { - return threadPoolKeyPrefix; - } - - public void setThreadPoolKeyPrefix(String threadPoolKeyPrefix) { - this.threadPoolKeyPrefix = threadPoolKeyPrefix; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/DiscoveryClientRouteLocator.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/DiscoveryClientRouteLocator.java deleted file mode 100644 index 89e9ff041..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/DiscoveryClientRouteLocator.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.discovery; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; -import org.springframework.util.PatternMatchUtils; -import org.springframework.util.StringUtils; - -/** - * A {@link RouteLocator} that combines static, configured routes with those from a - * {@link DiscoveryClient}. The discovery client takes precedence. - * - * @author Spencer Gibb - * @author Dave Syer - */ -public class DiscoveryClientRouteLocator extends SimpleRouteLocator - implements RefreshableRouteLocator { - - private static final Log log = LogFactory.getLog(DiscoveryClientRouteLocator.class); - - /** - * Default route. - */ - public static final String DEFAULT_ROUTE = "/**"; - - private DiscoveryClient discovery; - - private ZuulProperties properties; - - private ServiceRouteMapper serviceRouteMapper; - - @Deprecated - public DiscoveryClientRouteLocator(String servletPath, DiscoveryClient discovery, - ZuulProperties properties) { - this(servletPath, discovery, properties, (ServiceInstance) null); - } - - public DiscoveryClientRouteLocator(String servletPath, DiscoveryClient discovery, - ZuulProperties properties, ServiceInstance localServiceInstance) { - super(servletPath, properties); - - if (properties.isIgnoreLocalService() && localServiceInstance != null) { - String localServiceId = localServiceInstance.getServiceId(); - if (!properties.getIgnoredServices().contains(localServiceId)) { - properties.getIgnoredServices().add(localServiceId); - } - } - this.serviceRouteMapper = new SimpleServiceRouteMapper(); - this.discovery = discovery; - this.properties = properties; - } - - @Deprecated - public DiscoveryClientRouteLocator(String servletPath, DiscoveryClient discovery, - ZuulProperties properties, ServiceRouteMapper serviceRouteMapper) { - this(servletPath, discovery, properties, (ServiceInstance) null); - this.serviceRouteMapper = serviceRouteMapper; - } - - public DiscoveryClientRouteLocator(String servletPath, DiscoveryClient discovery, - ZuulProperties properties, ServiceRouteMapper serviceRouteMapper, - ServiceInstance localServiceInstance) { - this(servletPath, discovery, properties, localServiceInstance); - this.serviceRouteMapper = serviceRouteMapper; - } - - public void addRoute(String path, String location) { - this.properties.getRoutes().put(path, new ZuulRoute(path, location)); - refresh(); - } - - public void addRoute(ZuulRoute route) { - this.properties.getRoutes().put(route.getPath(), route); - refresh(); - } - - @Override - protected LinkedHashMap locateRoutes() { - LinkedHashMap routesMap = new LinkedHashMap<>(); - routesMap.putAll(super.locateRoutes()); - if (this.discovery != null) { - Map staticServices = new LinkedHashMap<>(); - for (ZuulRoute route : routesMap.values()) { - String serviceId = route.getServiceId(); - if (serviceId == null) { - serviceId = route.getId(); - } - if (serviceId != null) { - staticServices.put(serviceId, route); - } - } - // Add routes for discovery services by default - List services = this.discovery.getServices(); - String[] ignored = this.properties.getIgnoredServices() - .toArray(new String[0]); - for (String serviceId : services) { - // Ignore specifically ignored services and those that were manually - // configured - String key = "/" + mapRouteToService(serviceId) + "/**"; - if (staticServices.containsKey(serviceId) - && staticServices.get(serviceId).getUrl() == null) { - // Explicitly configured with no URL, cannot be ignored - // all static routes are already in routesMap - // Update location using serviceId if location is null - ZuulRoute staticRoute = staticServices.get(serviceId); - if (!StringUtils.hasText(staticRoute.getLocation())) { - staticRoute.setLocation(serviceId); - } - } - if (!PatternMatchUtils.simpleMatch(ignored, serviceId) - && !routesMap.containsKey(key)) { - // Not ignored - routesMap.put(key, new ZuulRoute(key, serviceId)); - } - } - } - if (routesMap.get(DEFAULT_ROUTE) != null) { - ZuulRoute defaultRoute = routesMap.get(DEFAULT_ROUTE); - // Move the defaultServiceId to the end - routesMap.remove(DEFAULT_ROUTE); - routesMap.put(DEFAULT_ROUTE, defaultRoute); - } - LinkedHashMap values = new LinkedHashMap<>(); - for (Entry entry : routesMap.entrySet()) { - String path = entry.getKey(); - // Prepend with slash if not already present. - if (!path.startsWith("/")) { - path = "/" + path; - } - if (StringUtils.hasText(this.properties.getPrefix())) { - path = this.properties.getPrefix() + path; - if (!path.startsWith("/")) { - path = "/" + path; - } - } - values.put(path, entry.getValue()); - } - return values; - } - - @Override - public void refresh() { - doRefresh(); - } - - protected String mapRouteToService(String serviceId) { - return this.serviceRouteMapper.apply(serviceId); - } - - protected void addConfiguredRoutes(Map routes) { - Map routeEntries = this.properties.getRoutes(); - for (ZuulRoute entry : routeEntries.values()) { - String route = entry.getPath(); - if (routes.containsKey(route)) { - log.warn("Overwriting route " + route + ": already defined by " - + routes.get(route)); - } - routes.put(route, entry); - } - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapper.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapper.java deleted file mode 100644 index 4ee261c56..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapper.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2015-2019 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 - * - * https://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.zuul.filters.discovery; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.springframework.util.StringUtils; - -/** - * @author Stéphane Leroy - * - * This service route mapper use Java 7 RegEx named group feature to rewrite a discovered - * service Id into a route. - * - * Ex : If we want to map service Id [rest-service-v1] to - * /v1/rest-service/** route service pattern : - * "(?.*)-(?v.*$)" route pattern : - * "${version}/${name}" - * - * This implementation uses Matcher.replaceFirst so only one match will be - * replaced. - */ -public class PatternServiceRouteMapper implements ServiceRouteMapper { - - private static final Pattern MULTIPLE_SLASH_PATTERN = Pattern.compile("/{2,}"); - - /** - * A RegExp Pattern that extract needed information from a service ID. Ex : - * "(?.*)-(?v.*$)" - */ - private Pattern servicePattern; - - /** - * A RegExp that refer to named groups define in servicePattern. Ex : - * "${version}/${name}" - */ - private String routePattern; - - public PatternServiceRouteMapper(String servicePattern, String routePattern) { - this.servicePattern = Pattern.compile(servicePattern); - this.routePattern = routePattern; - } - - /** - * Use servicePattern to extract groups and routePattern to construct the route. - * - * If there is no matches, the serviceId is returned. - * @param serviceId service discovered name - * @return route path - */ - @Override - public String apply(String serviceId) { - Matcher matcher = this.servicePattern.matcher(serviceId); - String route = matcher.replaceFirst(this.routePattern); - route = cleanRoute(route); - return (StringUtils.hasText(route) ? route : serviceId); - } - - /** - * Route with regex and replace can be a bit messy when used with conditional named - * group. We clean here first and trailing '/' and remove multiple consecutive '/'. - * @param route a {@link String} representation of the route to be cleaned - * @return cleaned up route {@link String} - */ - private String cleanRoute(final String route) { - String routeToClean = MULTIPLE_SLASH_PATTERN.matcher(route).replaceAll("/"); - if (routeToClean.startsWith("/")) { - routeToClean = routeToClean.substring(1); - } - if (routeToClean.endsWith("/")) { - routeToClean = routeToClean.substring(0, routeToClean.length() - 1); - } - return routeToClean; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/ServiceRouteMapper.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/ServiceRouteMapper.java deleted file mode 100644 index 32997d0c0..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/ServiceRouteMapper.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2015-2019 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 - * - * https://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.zuul.filters.discovery; - -/** - * Provide a way to apply convention between routes and discovered services name. - * - * @author Stéphane LEROY - * - */ -public interface ServiceRouteMapper { - - /** - * Take a service Id (its discovered name) and return a route path. - * @param serviceId service discovered name - * @return route path - */ - String apply(String serviceId); - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/SimpleServiceRouteMapper.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/SimpleServiceRouteMapper.java deleted file mode 100644 index a34efa39d..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/discovery/SimpleServiceRouteMapper.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2015-2019 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 - * - * https://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.zuul.filters.discovery; - -/** - * @author Stéphane Leroy - * - * A simple passthru service route mapper. - */ -public class SimpleServiceRouteMapper implements ServiceRouteMapper { - - @Override - public String apply(String serviceId) { - return serviceId; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilter.java deleted file mode 100644 index 91b897f5b..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilter.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.zuul.filters.post; - -import java.net.URI; - -import com.netflix.util.Pair; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.http.HttpStatus; -import org.springframework.http.server.ServletServerHttpRequest; -import org.springframework.util.StringUtils; -import org.springframework.web.util.UriComponents; -import org.springframework.web.util.UriComponentsBuilder; -import org.springframework.web.util.UrlPathHelper; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER; - -/** - * {@link ZuulFilter} Responsible for rewriting the Location header to be the Zuul URL. - * - * @author Biju Kunjummen - */ -public class LocationRewriteFilter extends ZuulFilter { - - private final UrlPathHelper urlPathHelper = new UrlPathHelper(); - - @Autowired - private ZuulProperties zuulProperties; - - @Autowired - private RouteLocator routeLocator; - - private static final String LOCATION_HEADER = "Location"; - - public LocationRewriteFilter() { - } - - public LocationRewriteFilter(ZuulProperties zuulProperties, - RouteLocator routeLocator) { - this.routeLocator = routeLocator; - this.zuulProperties = zuulProperties; - } - - @Override - public String filterType() { - return POST_TYPE; - } - - @Override - public int filterOrder() { - return SEND_RESPONSE_FILTER_ORDER - 100; - } - - @Override - public boolean shouldFilter() { - RequestContext ctx = RequestContext.getCurrentContext(); - int statusCode = ctx.getResponseStatusCode(); - return HttpStatus.valueOf(statusCode).is3xxRedirection(); - } - - @Override - public Object run() { - RequestContext ctx = RequestContext.getCurrentContext(); - Route route = routeLocator.getMatchingRoute( - urlPathHelper.getPathWithinApplication(ctx.getRequest())); - - if (route != null) { - Pair lh = locationHeader(ctx); - if (lh != null) { - String location = lh.second(); - URI originalRequestUri = UriComponentsBuilder - .fromHttpRequest(new ServletServerHttpRequest(ctx.getRequest())) - .build().toUri(); - - UriComponentsBuilder redirectedUriBuilder = UriComponentsBuilder - .fromUriString(location); - - UriComponents redirectedUriComps = redirectedUriBuilder.build(); - - String newPath = getRestoredPath(this.zuulProperties, route, - redirectedUriComps); - - String modifiedLocation = redirectedUriBuilder - .scheme(originalRequestUri.getScheme()) - .host(originalRequestUri.getHost()) - .port(originalRequestUri.getPort()).replacePath(newPath).build() - .toUriString(); - - lh.setSecond(modifiedLocation); - } - } - return null; - } - - private String getRestoredPath(ZuulProperties zuulProperties, Route route, - UriComponents redirectedUriComps) { - StringBuilder path = new StringBuilder(); - String redirectedPathWithoutGlobal = downstreamHasGlobalPrefix(zuulProperties) - ? redirectedUriComps.getPath() - .substring(("/" + zuulProperties.getPrefix()).length()) - : redirectedUriComps.getPath(); - - if (downstreamHasGlobalPrefix(zuulProperties)) { - path.append("/").append(zuulProperties.getPrefix()); - } - else { - path.append(zuulHasGlobalPrefix(zuulProperties) - ? "/" + zuulProperties.getPrefix() : ""); - } - - path.append(downstreamHasRoutePrefix(route) ? "" : "/" + route.getPrefix()) - .append(redirectedPathWithoutGlobal); - - return path.toString(); - } - - private boolean downstreamHasGlobalPrefix(ZuulProperties zuulProperties) { - return (!zuulProperties.isStripPrefix() - && StringUtils.hasText(zuulProperties.getPrefix())); - } - - private boolean zuulHasGlobalPrefix(ZuulProperties zuulProperties) { - return StringUtils.hasText(zuulProperties.getPrefix()); - } - - private boolean downstreamHasRoutePrefix(Route route) { - return (!route.isPrefixStripped() && StringUtils.hasText(route.getPrefix())); - } - - private Pair locationHeader(RequestContext ctx) { - if (ctx.getZuulResponseHeaders() != null) { - for (Pair pair : ctx.getZuulResponseHeaders()) { - if (pair.first().equals(LOCATION_HEADER)) { - return pair; - } - } - } - return null; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilter.java deleted file mode 100644 index 1fa58b521..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilter.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.post; - -import java.net.SocketTimeoutException; - -import javax.servlet.RequestDispatcher; -import javax.servlet.http.HttpServletRequest; - -import com.netflix.client.ClientException; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.exception.ZuulException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.cloud.netflix.zuul.util.ZuulRuntimeException; -import org.springframework.http.HttpStatus; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ERROR_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_ERROR_FILTER_ORDER; - -/** - * Error {@link ZuulFilter} that forwards to /error (by default) if - * {@link RequestContext#getThrowable()} is not null. - * - * @author Spencer Gibb - */ -// TODO: move to error package in Edgware -public class SendErrorFilter extends ZuulFilter { - - private static final Log log = LogFactory.getLog(SendErrorFilter.class); - - protected static final String SEND_ERROR_FILTER_RAN = "sendErrorFilter.ran"; - - @Value("${error.path:/error}") - private String errorPath; - - @Override - public String filterType() { - return ERROR_TYPE; - } - - @Override - public int filterOrder() { - return SEND_ERROR_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - RequestContext ctx = RequestContext.getCurrentContext(); - // only forward to errorPath if it hasn't been forwarded to already - return ctx.getThrowable() != null - && !ctx.getBoolean(SEND_ERROR_FILTER_RAN, false); - } - - @Override - public Object run() { - try { - RequestContext ctx = RequestContext.getCurrentContext(); - ExceptionHolder exception = findZuulException(ctx.getThrowable()); - HttpServletRequest request = ctx.getRequest(); - - request.setAttribute("javax.servlet.error.status_code", - exception.getStatusCode()); - - log.warn("Error during filtering", exception.getThrowable()); - request.setAttribute("javax.servlet.error.exception", - exception.getThrowable()); - - if (StringUtils.hasText(exception.getErrorCause())) { - request.setAttribute("javax.servlet.error.message", - exception.getErrorCause()); - } - - RequestDispatcher dispatcher = request.getRequestDispatcher(this.errorPath); - if (dispatcher != null) { - ctx.set(SEND_ERROR_FILTER_RAN, true); - if (!ctx.getResponse().isCommitted()) { - ctx.setResponseStatusCode(exception.getStatusCode()); - dispatcher.forward(request, ctx.getResponse()); - } - } - } - catch (Exception ex) { - ReflectionUtils.rethrowRuntimeException(ex); - } - return null; - } - - protected ExceptionHolder findZuulException(Throwable throwable) { - if (throwable.getCause() instanceof ZuulRuntimeException) { - Throwable cause = null; - if (throwable.getCause().getCause() != null) { - cause = throwable.getCause().getCause().getCause(); - } - if (cause instanceof ClientException && cause.getCause() != null - && cause.getCause().getCause() instanceof SocketTimeoutException) { - - ZuulException zuulException = new ZuulException("", 504, - ZuulException.class.getName() + ": Hystrix Readed time out"); - return new ZuulExceptionHolder(zuulException); - } - // this was a failure initiated by one of the local filters - if (throwable.getCause().getCause() instanceof ZuulException) { - return new ZuulExceptionHolder( - (ZuulException) throwable.getCause().getCause()); - } - } - - if (throwable.getCause() instanceof ZuulException) { - // wrapped zuul exception - return new ZuulExceptionHolder((ZuulException) throwable.getCause()); - } - - if (throwable instanceof ZuulException) { - // exception thrown by zuul lifecycle - return new ZuulExceptionHolder((ZuulException) throwable); - } - - // fallback - return new DefaultExceptionHolder(throwable); - } - - public void setErrorPath(String errorPath) { - this.errorPath = errorPath; - } - - protected interface ExceptionHolder { - - Throwable getThrowable(); - - default int getStatusCode() { - return HttpStatus.INTERNAL_SERVER_ERROR.value(); - } - - default String getErrorCause() { - return null; - } - - } - - protected static class DefaultExceptionHolder implements ExceptionHolder { - - private final Throwable throwable; - - public DefaultExceptionHolder(Throwable throwable) { - this.throwable = throwable; - } - - @Override - public Throwable getThrowable() { - return this.throwable; - } - - } - - protected static class ZuulExceptionHolder implements ExceptionHolder { - - private final ZuulException exception; - - public ZuulExceptionHolder(ZuulException exception) { - this.exception = exception; - } - - @Override - public Throwable getThrowable() { - return this.exception; - } - - @Override - public int getStatusCode() { - return this.exception.nStatusCode; - } - - @Override - public String getErrorCause() { - return this.exception.errorCause; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilter.java deleted file mode 100644 index 4151d89ab..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilter.java +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.post; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.SequenceInputStream; -import java.util.List; -import java.util.Objects; -import java.util.zip.GZIPInputStream; - -import javax.servlet.http.HttpServletResponse; - -import com.netflix.util.Pair; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.constants.ZuulHeaders; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.util.HTTPRequestUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.util.ReflectionUtils; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTING_DEBUG_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_ZUUL_DEBUG_HEADER; - -/** - * Post {@link ZuulFilter} that writes responses from proxied requests to the current - * response. - * - * @author Spencer Gibb - * @author Dave Syer - * @author Ryan Baxter - */ -public class SendResponseFilter extends ZuulFilter { - - private static final Log log = LogFactory.getLog(SendResponseFilter.class); - - private boolean useServlet31 = true; - - private ZuulProperties zuulProperties; - - private ThreadLocal buffers; - - @Deprecated - public SendResponseFilter() { - this(new ZuulProperties()); - } - - public SendResponseFilter(ZuulProperties zuulProperties) { - this.zuulProperties = zuulProperties; - // To support Servlet API 3.1 we need to check if setContentLengthLong exists - // minimum support in Spring 5 is 3.0 so we need to keep tihs - try { - HttpServletResponse.class.getMethod("setContentLengthLong", long.class); - } - catch (NoSuchMethodException e) { - useServlet31 = false; - } - buffers = ThreadLocal - .withInitial(() -> new byte[zuulProperties.getInitialStreamBufferSize()]); - } - - /* for testing */ boolean isUseServlet31() { - return useServlet31; - } - - @Override - public String filterType() { - return POST_TYPE; - } - - @Override - public int filterOrder() { - return SEND_RESPONSE_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - RequestContext context = RequestContext.getCurrentContext(); - return context.getThrowable() == null - && (!context.getZuulResponseHeaders().isEmpty() - || context.getResponseDataStream() != null - || context.getResponseBody() != null); - } - - @Override - public Object run() { - try { - addResponseHeaders(); - writeResponse(); - } - catch (Exception ex) { - ReflectionUtils.rethrowRuntimeException(ex); - } - return null; - } - - private void writeResponse() throws Exception { - RequestContext context = RequestContext.getCurrentContext(); - // there is no body to send - if (context.getResponseBody() == null - && context.getResponseDataStream() == null) { - return; - } - HttpServletResponse servletResponse = context.getResponse(); - if (servletResponse.getCharacterEncoding() == null) { // only set if not set - servletResponse.setCharacterEncoding("UTF-8"); - } - - String servletResponseContentEncoding = getResponseContentEncoding(context); - OutputStream outStream = servletResponse.getOutputStream(); - InputStream is = null; - try { - if (context.getResponseBody() != null) { - String body = context.getResponseBody(); - is = new ByteArrayInputStream( - body.getBytes(servletResponse.getCharacterEncoding())); - } - else { - is = context.getResponseDataStream(); - if (is != null && context.getResponseGZipped()) { - // if origin response is gzipped, and client has not requested gzip, - // decompress stream before sending to client - // else, stream gzip directly to client - if (isGzipRequested(context)) { - servletResponseContentEncoding = "gzip"; - } - else { - servletResponseContentEncoding = null; - is = handleGzipStream(is); - } - } - } - if (servletResponseContentEncoding != null) { - servletResponse.setHeader(ZuulHeaders.CONTENT_ENCODING, - servletResponseContentEncoding); - } - - if (is != null) { - writeResponse(is, outStream); - } - } - finally { - /** - * We must ensure that the InputStream provided by our upstream pooling - * mechanism is ALWAYS closed even in the case of wrapped streams, which are - * supplied by pooled sources such as Apache's - * PoolingHttpClientConnectionManager. In that particular case, the underlying - * HTTP connection will be returned back to the connection pool iif either - * close() is explicitly called, a read error occurs, or the end of the - * underlying stream is reached. If, however a write error occurs, we will end - * up leaking a connection from the pool without an explicit close() - * - * @author Johannes Edmeier - */ - if (is != null) { - try { - is.close(); - } - catch (Exception ex) { - log.warn("Error while closing upstream input stream", ex); - } - } - - // cleanup ThreadLocal when we are all done - if (buffers != null) { - buffers.remove(); - } - - try { - Object zuulResponse = context.get("zuulResponse"); - if (zuulResponse instanceof Closeable) { - ((Closeable) zuulResponse).close(); - } - outStream.flush(); - // The container will close the stream for us - } - catch (IOException ex) { - log.warn("Error while sending response to client: " + ex.getMessage()); - } - } - } - - protected InputStream handleGzipStream(InputStream in) throws Exception { - // Record bytes read during GZip initialization to allow to rewind the stream if - // needed - // - RecordingInputStream stream = new RecordingInputStream(in); - try { - return new GZIPInputStream(stream); - } - catch (java.util.zip.ZipException | java.io.EOFException ex) { - - if (stream.getBytesRead() == 0) { - // stream was empty, return the original "empty" stream - return in; - } - else { - // reset the stream and assume an unencoded response - log.warn( - "gzip response expected but failed to read gzip headers, assuming unencoded response for request " - + RequestContext.getCurrentContext().getRequest() - .getRequestURL().toString()); - - stream.reset(); - return stream; - } - } - finally { - stream.stopRecording(); - } - } - - protected boolean isGzipRequested(RequestContext context) { - final String requestEncoding = context.getRequest() - .getHeader(ZuulHeaders.ACCEPT_ENCODING); - - return requestEncoding != null - && HTTPRequestUtils.getInstance().isGzipped(requestEncoding); - } - - private String getResponseContentEncoding(RequestContext context) { - List> zuulResponseHeaders = context.getZuulResponseHeaders(); - if (zuulResponseHeaders != null) { - for (Pair it : zuulResponseHeaders) { - if (ZuulHeaders.CONTENT_ENCODING.equalsIgnoreCase(it.first())) { - return it.second(); - } - } - } - return null; - } - - private void writeResponse(InputStream zin, OutputStream out) throws Exception { - byte[] bytes = buffers.get(); - int bytesRead = -1; - while ((bytesRead = zin.read(bytes)) != -1) { - out.write(bytes, 0, bytesRead); - } - } - - private void addResponseHeaders() { - RequestContext context = RequestContext.getCurrentContext(); - HttpServletResponse servletResponse = context.getResponse(); - if (this.zuulProperties.isIncludeDebugHeader()) { - @SuppressWarnings("unchecked") - List rd = (List) context.get(ROUTING_DEBUG_KEY); - if (rd != null) { - StringBuilder debugHeader = new StringBuilder(); - for (String it : rd) { - debugHeader.append("[[[").append(it).append("]]]"); - } - servletResponse.addHeader(X_ZUUL_DEBUG_HEADER, debugHeader.toString()); - } - } - List> zuulResponseHeaders = context.getZuulResponseHeaders(); - if (zuulResponseHeaders != null) { - for (Pair it : zuulResponseHeaders) { - if (!ZuulHeaders.CONTENT_ENCODING.equalsIgnoreCase(it.first())) { - servletResponse.addHeader(it.first(), it.second()); - } - } - } - if (includeContentLengthHeader(context)) { - Long contentLength = context.getOriginContentLength(); - if (useServlet31) { - servletResponse.setContentLengthLong(contentLength); - } - else { - // Try and set some kind of content length if we can safely convert the - // Long to an int - if (isLongSafe(contentLength)) { - servletResponse.setContentLength(contentLength.intValue()); - } - } - } - } - - private boolean isLongSafe(long value) { - return value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE; - } - - protected boolean includeContentLengthHeader(RequestContext context) { - // Not configured to forward the header - if (!this.zuulProperties.isSetContentLength()) { - return false; - } - - // Only if Content-Length is provided - if (context.getOriginContentLength() == null) { - return false; - } - - // If response is compressed, include header only if we are not about to - // decompress it - if (context.getResponseGZipped()) { - return context.isGzipRequested(); - } - - // Forward it in all other cases - return true; - } - - /** - * InputStream recording bytes read to allow for a reset() until recording is stopped. - */ - private static class RecordingInputStream extends InputStream { - - private InputStream delegate; - - private ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - RecordingInputStream(InputStream delegate) { - super(); - this.delegate = Objects.requireNonNull(delegate); - } - - @Override - public int read() throws IOException { - int read = delegate.read(); - - if (buffer != null && read != -1) { - buffer.write(read); - } - - return read; - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - int read = delegate.read(b, off, len); - - if (buffer != null && read != -1) { - buffer.write(b, off, read); - } - - return read; - } - - public void reset() { - if (buffer == null) { - throw new IllegalStateException("Stream is not recording"); - } - - this.delegate = new SequenceInputStream( - new ByteArrayInputStream(buffer.toByteArray()), delegate); - this.buffer = new ByteArrayOutputStream(); - } - - public int getBytesRead() { - return (buffer == null) ? -1 : buffer.size(); - } - - public void stopRecording() { - this.buffer = null; - } - - @Override - public void close() throws IOException { - this.delegate.close(); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/DebugFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/DebugFilter.java deleted file mode 100644 index 6484b0961..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/DebugFilter.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.pre; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.config.DynamicBooleanProperty; -import com.netflix.config.DynamicPropertyFactory; -import com.netflix.config.DynamicStringProperty; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.constants.ZuulConstants; -import com.netflix.zuul.context.RequestContext; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.DEBUG_FILTER_ORDER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; - -/** - * Pre {@link ZuulFilter} that sets {@link RequestContext} debug attributes to true if the - * "debug" request parameter is set. - * - * @author Spencer Gibb - */ -public class DebugFilter extends ZuulFilter { - - private static final DynamicBooleanProperty ROUTING_DEBUG = DynamicPropertyFactory - .getInstance().getBooleanProperty(ZuulConstants.ZUUL_DEBUG_REQUEST, false); - - private static final DynamicStringProperty DEBUG_PARAMETER = DynamicPropertyFactory - .getInstance().getStringProperty(ZuulConstants.ZUUL_DEBUG_PARAMETER, "debug"); - - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public int filterOrder() { - return DEBUG_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - HttpServletRequest request = RequestContext.getCurrentContext().getRequest(); - if ("true".equals(request.getParameter(DEBUG_PARAMETER.get()))) { - return true; - } - return ROUTING_DEBUG.get(); - } - - @Override - public Object run() { - RequestContext ctx = RequestContext.getCurrentContext(); - ctx.setDebugRouting(true); - ctx.setDebugRequest(true); - return null; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java deleted file mode 100644 index 984a82a4a..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.pre; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.lang.reflect.Field; - -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletRequestWrapper; -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.http.HttpServletRequestWrapper; -import com.netflix.zuul.http.ServletInputStreamWrapper; - -import org.springframework.cloud.netflix.zuul.util.RequestContentDataExtractor; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpOutputMessage; -import org.springframework.http.InvalidMediaTypeException; -import org.springframework.http.MediaType; -import org.springframework.http.converter.FormHttpMessageConverter; -import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; -import org.springframework.util.Assert; -import org.springframework.util.MultiValueMap; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.servlet.DispatcherServlet; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORM_BODY_WRAPPER_FILTER_ORDER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; - -/** - * Pre {@link ZuulFilter} that parses form data and reencodes it for downstream services. - * - * @author Dave Syer - */ -public class FormBodyWrapperFilter extends ZuulFilter { - - private FormHttpMessageConverter formHttpMessageConverter; - - private Field requestField; - - private Field servletRequestField; - - public FormBodyWrapperFilter() { - this(new AllEncompassingFormHttpMessageConverter()); - } - - public FormBodyWrapperFilter(FormHttpMessageConverter formHttpMessageConverter) { - this.formHttpMessageConverter = formHttpMessageConverter; - this.requestField = ReflectionUtils.findField(HttpServletRequestWrapper.class, - "req", HttpServletRequest.class); - this.servletRequestField = ReflectionUtils.findField(ServletRequestWrapper.class, - "request", ServletRequest.class); - Assert.notNull(this.requestField, - "HttpServletRequestWrapper.req field not found"); - Assert.notNull(this.servletRequestField, - "ServletRequestWrapper.request field not found"); - this.requestField.setAccessible(true); - this.servletRequestField.setAccessible(true); - } - - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public int filterOrder() { - return FORM_BODY_WRAPPER_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - RequestContext ctx = RequestContext.getCurrentContext(); - HttpServletRequest request = ctx.getRequest(); - String contentType = request.getContentType(); - // Don't use this filter on GET method - if (contentType == null) { - return false; - } - // Only use this filter for form data and only for multipart data in a - // DispatcherServlet handler - try { - MediaType mediaType = MediaType.valueOf(contentType); - return MediaType.APPLICATION_FORM_URLENCODED.includes(mediaType) - || (isDispatcherServletRequest(request) - && MediaType.MULTIPART_FORM_DATA.includes(mediaType)); - } - catch (InvalidMediaTypeException ex) { - return false; - } - } - - private boolean isDispatcherServletRequest(HttpServletRequest request) { - return request.getAttribute( - DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null; - } - - @Override - public Object run() { - RequestContext ctx = RequestContext.getCurrentContext(); - HttpServletRequest request = ctx.getRequest(); - FormBodyRequestWrapper wrapper = null; - if (request instanceof HttpServletRequestWrapper) { - HttpServletRequest wrapped = (HttpServletRequest) ReflectionUtils - .getField(this.requestField, request); - wrapper = new FormBodyRequestWrapper(wrapped); - ReflectionUtils.setField(this.requestField, request, wrapper); - if (request instanceof ServletRequestWrapper) { - ReflectionUtils.setField(this.servletRequestField, request, wrapper); - } - } - else { - wrapper = new FormBodyRequestWrapper(request); - ctx.setRequest(wrapper); - } - if (wrapper != null) { - ctx.getZuulRequestHeaders().put("content-type", wrapper.getContentType()); - } - return null; - } - - private class FormBodyRequestWrapper extends Servlet30RequestWrapper { - - private HttpServletRequest request; - - private volatile byte[] contentData; - - private MediaType contentType; - - private int contentLength; - - FormBodyRequestWrapper(HttpServletRequest request) { - super(request); - this.request = request; - } - - @Override - public String getContentType() { - if (this.contentData == null) { - buildContentData(); - } - return this.contentType.toString(); - } - - @Override - public int getContentLength() { - if (super.getContentLength() <= 0) { - return super.getContentLength(); - } - if (this.contentData == null) { - buildContentData(); - } - return this.contentLength; - } - - public long getContentLengthLong() { - return getContentLength(); - } - - @Override - public ServletInputStream getInputStream() throws IOException { - if (this.contentData == null) { - buildContentData(); - } - return new ServletInputStreamWrapper(this.contentData); - } - - private synchronized void buildContentData() { - if (this.contentData != null) { - return; - } - try { - MultiValueMap builder = RequestContentDataExtractor - .extract(this.request); - FormHttpOutputMessage data = new FormHttpOutputMessage(); - - this.contentType = MediaType.valueOf(this.request.getContentType()); - data.getHeaders().setContentType(this.contentType); - FormBodyWrapperFilter.this.formHttpMessageConverter.write(builder, - this.contentType, data); - // copy new content type including multipart boundary - this.contentType = data.getHeaders().getContentType(); - byte[] input = data.getInput(); - this.contentLength = input.length; - this.contentData = input; - } - catch (Exception e) { - throw new IllegalStateException("Cannot convert form data", e); - } - } - - private class FormHttpOutputMessage implements HttpOutputMessage { - - private HttpHeaders headers = new HttpHeaders(); - - private ByteArrayOutputStream output = new ByteArrayOutputStream(); - - @Override - public HttpHeaders getHeaders() { - return this.headers; - } - - @Override - public OutputStream getBody() throws IOException { - return this.output; - } - - public byte[] getInput() throws IOException { - this.output.flush(); - return this.output.toByteArray(); - } - - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java deleted file mode 100755 index 0fa378080..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilter.java +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.pre; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.regex.Pattern; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; -import org.springframework.cloud.netflix.zuul.util.RequestUtils; -import org.springframework.http.HttpHeaders; -import org.springframework.util.StringUtils; -import org.springframework.web.util.UrlPathHelper; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_LOCATION_PREFIX; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_TO_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.HTTPS_PORT; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.HTTPS_SCHEME; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.HTTP_PORT; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.HTTP_SCHEME; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PROXY_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_URI_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.RETRYABLE_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_HEADER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_HEADER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_FORWARDED_FOR_HEADER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_FORWARDED_HOST_HEADER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_FORWARDED_PORT_HEADER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_FORWARDED_PREFIX_HEADER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_FORWARDED_PROTO_HEADER; - -/** - * Pre {@link ZuulFilter} that determines where and how to route based on the supplied - * {@link RouteLocator}. Also sets various proxy related headers for downstream requests. - * - * @author Spencer Gibb - * @author Dave Syer - * @author Philip Webb - * @author Stefan Fussenegger - * @author Adrian Ivan - * @author Jacques-Etienne Beaudet - * @author Durigon Durigon - */ -public class PreDecorationFilter extends ZuulFilter { - - private static final Log log = LogFactory.getLog(PreDecorationFilter.class); - - /** - * @deprecated use {@link FilterConstants#PRE_DECORATION_FILTER_ORDER} - */ - @Deprecated - public static final int FILTER_ORDER = PRE_DECORATION_FILTER_ORDER; - - /** - * A double slash pattern. - */ - public static final Pattern DOUBLE_SLASH = Pattern.compile("//"); - - private RouteLocator routeLocator; - - private String dispatcherServletPath; - - private ZuulProperties properties; - - private UrlPathHelper urlPathHelper = new UrlPathHelper(); - - private ProxyRequestHelper proxyRequestHelper; - - public PreDecorationFilter(RouteLocator routeLocator, String dispatcherServletPath, - ZuulProperties properties, ProxyRequestHelper proxyRequestHelper) { - this.routeLocator = routeLocator; - this.properties = properties; - this.urlPathHelper - .setRemoveSemicolonContent(properties.isRemoveSemicolonContent()); - this.urlPathHelper.setUrlDecode(properties.isDecodeUrl()); - this.dispatcherServletPath = dispatcherServletPath; - this.proxyRequestHelper = proxyRequestHelper; - } - - @Override - public int filterOrder() { - return PRE_DECORATION_FILTER_ORDER; - } - - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public boolean shouldFilter() { - RequestContext ctx = RequestContext.getCurrentContext(); - return !ctx.containsKey(FORWARD_TO_KEY) // a filter has already forwarded - && !ctx.containsKey(SERVICE_ID_KEY); // a filter has already determined - // serviceId - } - - @Override - public Object run() { - RequestContext ctx = RequestContext.getCurrentContext(); - final String requestURI = this.urlPathHelper - .getPathWithinApplication(ctx.getRequest()); - Route route = this.routeLocator.getMatchingRoute(requestURI); - if (route != null) { - String location = route.getLocation(); - if (location != null) { - ctx.put(REQUEST_URI_KEY, route.getPath()); - ctx.put(PROXY_KEY, route.getId()); - if (!route.isCustomSensitiveHeaders()) { - this.proxyRequestHelper.addIgnoredHeaders( - this.properties.getSensitiveHeaders().toArray(new String[0])); - } - else { - this.proxyRequestHelper.addIgnoredHeaders( - route.getSensitiveHeaders().toArray(new String[0])); - } - - if (route.getRetryable() != null) { - ctx.put(RETRYABLE_KEY, route.getRetryable()); - } - - if (location.startsWith(HTTP_SCHEME + ":") - || location.startsWith(HTTPS_SCHEME + ":")) { - ctx.setRouteHost(getUrl(location)); - ctx.addOriginResponseHeader(SERVICE_HEADER, location); - } - else if (location.startsWith(FORWARD_LOCATION_PREFIX)) { - ctx.set(FORWARD_TO_KEY, - StringUtils.cleanPath( - location.substring(FORWARD_LOCATION_PREFIX.length()) - + route.getPath())); - ctx.setRouteHost(null); - return null; - } - else { - // set serviceId for use in filters.route.RibbonRequest - ctx.set(SERVICE_ID_KEY, location); - ctx.setRouteHost(null); - ctx.addOriginResponseHeader(SERVICE_ID_HEADER, location); - } - if (this.properties.isAddProxyHeaders()) { - addProxyHeaders(ctx, route); - String xforwardedfor = ctx.getRequest() - .getHeader(X_FORWARDED_FOR_HEADER); - String remoteAddr = ctx.getRequest().getRemoteAddr(); - if (xforwardedfor == null) { - xforwardedfor = remoteAddr; - } - else if (!xforwardedfor.contains(remoteAddr)) { // Prevent duplicates - xforwardedfor += ", " + remoteAddr; - } - ctx.addZuulRequestHeader(X_FORWARDED_FOR_HEADER, xforwardedfor); - } - if (this.properties.isAddHostHeader()) { - ctx.addZuulRequestHeader(HttpHeaders.HOST, - toHostHeader(ctx.getRequest())); - } - } - } - else { - log.warn("No route found for uri: " + requestURI); - String forwardURI = getForwardUri(requestURI); - - ctx.set(FORWARD_TO_KEY, forwardURI); - } - return null; - } - - /* for testing */ String getForwardUri(String requestURI) { - // default fallback servlet is DispatcherServlet - String fallbackPrefix = this.dispatcherServletPath; - - String fallBackUri = requestURI; - if (RequestUtils.isZuulServletRequest()) { - // remove the Zuul servletPath from the requestUri - log.debug("zuulServletPath=" + this.properties.getServletPath()); - fallBackUri = fallBackUri.replaceFirst(this.properties.getServletPath(), ""); - log.debug("Replaced Zuul servlet path:" + fallBackUri); - } - else if (this.dispatcherServletPath != null) { - // remove the DispatcherServlet servletPath from the requestUri - log.debug("dispatcherServletPath=" + this.dispatcherServletPath); - fallBackUri = fallBackUri.replaceFirst(this.dispatcherServletPath, ""); - log.debug("Replaced DispatcherServlet servlet path:" + fallBackUri); - } - if (!fallBackUri.startsWith("/")) { - fallBackUri = "/" + fallBackUri; - } - - String forwardURI = (fallbackPrefix == null) ? fallBackUri - : fallbackPrefix + fallBackUri; - forwardURI = DOUBLE_SLASH.matcher(forwardURI).replaceAll("/"); - return forwardURI; - } - - private void addProxyHeaders(RequestContext ctx, Route route) { - HttpServletRequest request = ctx.getRequest(); - String host = toHostHeader(request); - String port = String.valueOf(request.getServerPort()); - String proto = request.getScheme(); - if (hasHeader(request, X_FORWARDED_HOST_HEADER)) { - host = request.getHeader(X_FORWARDED_HOST_HEADER) + "," + host; - } - if (!hasHeader(request, X_FORWARDED_PORT_HEADER)) { - if (hasHeader(request, X_FORWARDED_PROTO_HEADER)) { - StringBuilder builder = new StringBuilder(); - for (String previous : StringUtils.commaDelimitedListToStringArray( - request.getHeader(X_FORWARDED_PROTO_HEADER))) { - if (builder.length() > 0) { - builder.append(","); - } - builder.append( - HTTPS_SCHEME.equals(previous) ? HTTPS_PORT : HTTP_PORT); - } - builder.append(",").append(port); - port = builder.toString(); - } - } - else { - port = request.getHeader(X_FORWARDED_PORT_HEADER) + "," + port; - } - if (hasHeader(request, X_FORWARDED_PROTO_HEADER)) { - proto = request.getHeader(X_FORWARDED_PROTO_HEADER) + "," + proto; - } - ctx.addZuulRequestHeader(X_FORWARDED_HOST_HEADER, host); - ctx.addZuulRequestHeader(X_FORWARDED_PORT_HEADER, port); - ctx.addZuulRequestHeader(X_FORWARDED_PROTO_HEADER, proto); - addProxyPrefix(ctx, route); - } - - private boolean hasHeader(HttpServletRequest request, String name) { - return StringUtils.hasLength(request.getHeader(name)); - } - - private void addProxyPrefix(RequestContext ctx, Route route) { - String forwardedPrefix = ctx.getRequest().getHeader(X_FORWARDED_PREFIX_HEADER); - String contextPath = ctx.getRequest().getContextPath(); - String prefix = StringUtils.hasLength(forwardedPrefix) ? forwardedPrefix - : (StringUtils.hasLength(contextPath) ? contextPath : null); - if (StringUtils.hasText(route.getPrefix())) { - StringBuilder newPrefixBuilder = new StringBuilder(); - if (prefix != null) { - if (prefix.endsWith("/") && route.getPrefix().startsWith("/")) { - newPrefixBuilder.append(prefix, 0, prefix.length() - 1); - } - else { - newPrefixBuilder.append(prefix); - } - } - newPrefixBuilder.append(route.getPrefix()); - prefix = newPrefixBuilder.toString(); - } - if (prefix != null) { - ctx.addZuulRequestHeader(X_FORWARDED_PREFIX_HEADER, prefix); - } - } - - private String toHostHeader(HttpServletRequest request) { - int port = request.getServerPort(); - if ((port == HTTP_PORT && HTTP_SCHEME.equals(request.getScheme())) - || (port == HTTPS_PORT && HTTPS_SCHEME.equals(request.getScheme()))) { - return request.getServerName(); - } - else { - return request.getServerName() + ":" + port; - } - } - - private URL getUrl(String target) { - try { - return new URL(target); - } - catch (MalformedURLException ex) { - throw new IllegalStateException("Target URL is malformed", ex); - } - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30RequestWrapper.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30RequestWrapper.java deleted file mode 100644 index 11d084369..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30RequestWrapper.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.pre; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.http.HttpServletRequestWrapper; - -/** - * A Servlet 3.0 compliant wrapper. - */ -class Servlet30RequestWrapper extends HttpServletRequestWrapper { - - private HttpServletRequest request; - - Servlet30RequestWrapper(HttpServletRequest request) { - super(request); - this.request = request; - } - - /** - * There is a bug in zuul 1.2.2 where HttpServletRequestWrapper.getRequest returns a - * wrapped request rather than the raw one. - * @return the original HttpServletRequest - */ - @Override - public HttpServletRequest getRequest() { - return this.request; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30WrapperFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30WrapperFilter.java deleted file mode 100644 index d9145ae09..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/Servlet30WrapperFilter.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.pre; - -import java.lang.reflect.Field; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.http.HttpServletRequestWrapper; - -import org.springframework.cloud.netflix.zuul.util.RequestUtils; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_30_WRAPPER_FILTER_ORDER; - -/** - * Pre {@link ZuulFilter} that wraps requests in a Servlet 3.0 compliant wrapper. Zuul's - * default wrapper is only Servlet 2.5 compliant. - * - * @author Spencer Gibb - */ -public class Servlet30WrapperFilter extends ZuulFilter { - - private Field requestField = null; - - public Servlet30WrapperFilter() { - this.requestField = ReflectionUtils.findField(HttpServletRequestWrapper.class, - "req", HttpServletRequest.class); - Assert.notNull(this.requestField, - "HttpServletRequestWrapper.req field not found"); - this.requestField.setAccessible(true); - } - - protected Field getRequestField() { - return this.requestField; - } - - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public int filterOrder() { - return SERVLET_30_WRAPPER_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - return true; // TODO: only if in servlet 3.0 env - } - - @Override - public Object run() { - RequestContext ctx = RequestContext.getCurrentContext(); - HttpServletRequest request = ctx.getRequest(); - if (request instanceof HttpServletRequestWrapper) { - request = (HttpServletRequest) ReflectionUtils.getField(this.requestField, - request); - ctx.setRequest(new Servlet30RequestWrapper(request)); - } - else if (RequestUtils.isDispatcherServletRequest()) { - // If it's going through the dispatcher we need to buffer the body - ctx.setRequest(new Servlet30RequestWrapper(request)); - } - return null; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/ServletDetectionFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/ServletDetectionFilter.java deleted file mode 100644 index e8d5f15d8..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/ServletDetectionFilter.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2013-2017 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 - * - * https://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.zuul.filters.pre; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.http.HttpServletRequestWrapper; -import com.netflix.zuul.http.ZuulServlet; - -import org.springframework.web.servlet.DispatcherServlet; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.IS_DISPATCHER_SERVLET_REQUEST_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_DETECTION_FILTER_ORDER; - -/** - * Detects whether a request is ran through the {@link DispatcherServlet} or - * {@link ZuulServlet}. The purpose was to detect this up-front at the very beginning of - * Zuul filter processing and rely on this information in all filters. RequestContext is - * used such that the information is accessible to classes which do not have a request - * reference. - * - * @author Adrian Ivan - */ -public class ServletDetectionFilter extends ZuulFilter { - - public ServletDetectionFilter() { - } - - @Override - public String filterType() { - return PRE_TYPE; - } - - /** - * Must run before other filters that rely on the difference between DispatcherServlet - * and ZuulServlet. - */ - @Override - public int filterOrder() { - return SERVLET_DETECTION_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public Object run() { - RequestContext ctx = RequestContext.getCurrentContext(); - HttpServletRequest request = ctx.getRequest(); - if (!(request instanceof HttpServletRequestWrapper) - && isDispatcherServletRequest(request)) { - ctx.set(IS_DISPATCHER_SERVLET_REQUEST_KEY, true); - } - else { - ctx.set(IS_DISPATCHER_SERVLET_REQUEST_KEY, false); - } - - return null; - } - - private boolean isDispatcherServletRequest(HttpServletRequest request) { - return request.getAttribute( - DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/FallbackProvider.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/FallbackProvider.java deleted file mode 100644 index 781410cd8..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/FallbackProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route; - -import org.springframework.http.client.ClientHttpResponse; - -/** - * Provides fallback when a failure occurs on a route. - * - * @author Ryan Baxter - * @author Dominik Mostek - */ -public interface FallbackProvider { - - /** - * The route this fallback will be used for. - * @return The route the fallback will be used for. - */ - String getRoute(); - - /** - * Provides a fallback response based on the cause of the failed execution. - * @param route The route the fallback is for - * @param cause cause of the main method failure, may be null - * @return the fallback response - */ - ClientHttpResponse fallbackResponse(String route, Throwable cause); - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommand.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommand.java deleted file mode 100644 index d93137651..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommand.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route; - -import java.io.InputStream; -import java.net.URI; -import java.util.List; - -import com.netflix.client.config.IClientConfig; -import com.netflix.client.http.HttpRequest; -import com.netflix.client.http.HttpResponse; -import com.netflix.niws.client.http.RestClient; - -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommand; -import org.springframework.http.HttpMethod; -import org.springframework.util.MultiValueMap; - -import static org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer.Runner.customize; - -/** - * Hystrix wrapper around Eureka Ribbon command. - * - * see original - * - * @author Spencer Gibb - * @author Stephane Lagraulet - * @author Ryan Baxter - */ -@SuppressWarnings("deprecation") -public class RestClientRibbonCommand - extends AbstractRibbonCommand { - - public RestClientRibbonCommand(String commandKey, RestClient client, - RibbonCommandContext context, ZuulProperties zuulProperties) { - super(commandKey, client, context, zuulProperties); - } - - public RestClientRibbonCommand(String commandKey, RestClient client, - RibbonCommandContext context, ZuulProperties zuulProperties, - FallbackProvider zuulFallbackProvider) { - super(commandKey, client, context, zuulProperties, zuulFallbackProvider); - } - - public RestClientRibbonCommand(String commandKey, RestClient client, - RibbonCommandContext context, ZuulProperties zuulProperties, - FallbackProvider zuulFallbackProvider, IClientConfig config) { - super(commandKey, client, context, zuulProperties, zuulFallbackProvider, config); - } - - @Deprecated - public RestClientRibbonCommand(String commandKey, RestClient restClient, - HttpRequest.Verb verb, String uri, Boolean retryable, - MultiValueMap headers, MultiValueMap params, - InputStream requestEntity) { - this(commandKey, restClient, new RibbonCommandContext(commandKey, verb.verb(), - uri, retryable, headers, params, requestEntity), new ZuulProperties()); - } - - @Override - protected HttpRequest createRequest() throws Exception { - final InputStream requestEntity; - // ApacheHttpClient4Handler does not support body in delete requests - if (getContext().getMethod().equalsIgnoreCase(HttpMethod.DELETE.toString())) { - requestEntity = null; - } - else { - requestEntity = this.context.getRequestEntity(); - } - - HttpRequest.Builder builder = HttpRequest.newBuilder() - .verb(getVerb(this.context.getMethod())).uri(this.context.uri()) - .entity(requestEntity); - - if (this.context.getRetryable() != null) { - builder.setRetriable(this.context.getRetryable()); - } - - for (String name : this.context.getHeaders().keySet()) { - List values = this.context.getHeaders().get(name); - for (String value : values) { - builder.header(name, value); - } - } - for (String name : this.context.getParams().keySet()) { - List values = this.context.getParams().get(name); - for (String value : values) { - builder.queryParams(name, value); - } - } - - customizeRequest(builder); - - return builder.build(); - } - - protected void customizeRequest(HttpRequest.Builder requestBuilder) { - customize(this.context.getRequestCustomizers(), requestBuilder); - } - - @Deprecated - public URI getUri() { - return this.context.uri(); - } - - @SuppressWarnings("unused") - @Deprecated - public HttpRequest.Verb getVerb() { - return getVerb(this.context.getVerb()); - } - - protected static HttpRequest.Verb getVerb(String method) { - if (method == null) { - return HttpRequest.Verb.GET; - } - try { - return HttpRequest.Verb.valueOf(method.toUpperCase()); - } - catch (IllegalArgumentException e) { - return HttpRequest.Verb.GET; - } - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommandFactory.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommandFactory.java deleted file mode 100644 index 5f341e4e6..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommandFactory.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route; - -import java.util.Collections; -import java.util.Set; - -import com.netflix.client.http.HttpRequest; -import com.netflix.niws.client.http.RestClient; - -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommandFactory; - -/** - * @author Spencer Gibb - * @author Ryan Baxter - */ -public class RestClientRibbonCommandFactory extends AbstractRibbonCommandFactory { - - private SpringClientFactory clientFactory; - - private ZuulProperties zuulProperties; - - public RestClientRibbonCommandFactory(SpringClientFactory clientFactory) { - this(clientFactory, new ZuulProperties(), - Collections.emptySet()); - } - - public RestClientRibbonCommandFactory(SpringClientFactory clientFactory, - ZuulProperties zuulProperties, Set zuulFallbackProviders) { - super(zuulFallbackProviders); - this.clientFactory = clientFactory; - this.zuulProperties = zuulProperties; - } - - @Override - @SuppressWarnings("deprecation") - public RestClientRibbonCommand create(RibbonCommandContext context) { - String serviceId = context.getServiceId(); - FallbackProvider fallbackProvider = getFallbackProvider(serviceId); - RestClient restClient = this.clientFactory.getClient(serviceId, RestClient.class); - return new RestClientRibbonCommand(context.getServiceId(), restClient, context, - this.zuulProperties, fallbackProvider, - clientFactory.getClientConfig(serviceId)); - } - - public SpringClientFactory getClientFactory() { - return clientFactory; - } - - public void setZuulProperties(ZuulProperties zuulProperties) { - this.zuulProperties = zuulProperties; - } - - protected static HttpRequest.Verb getVerb(String method) { - return RestClientRibbonCommand.getVerb(method); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommand.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommand.java deleted file mode 100644 index 89919f4e3..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommand.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route; - -import com.netflix.hystrix.HystrixExecutable; - -import org.springframework.http.client.ClientHttpResponse; - -/** - * @author Spencer Gibb - */ -public interface RibbonCommand extends HystrixExecutable { - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommandFactory.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommandFactory.java deleted file mode 100644 index 126b4921f..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonCommandFactory.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route; - -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; - -/** - * @param a {@link RibbonCommand subtype} - * @author Spencer Gibb - * - */ -public interface RibbonCommandFactory { - - T create(RibbonCommandContext context); - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java deleted file mode 100644 index 8c440c775..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route; - -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.client.ClientException; -import com.netflix.hystrix.exception.HystrixRuntimeException; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.exception.ZuulException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer; -import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; -import org.springframework.cloud.netflix.zuul.util.ZuulRuntimeException; -import org.springframework.http.HttpStatus; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.util.MultiValueMap; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.LOAD_BALANCER_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_ENTITY_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.RETRYABLE_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.RIBBON_ROUTING_FILTER_ORDER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTE_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_KEY; - -/** - * Route {@link ZuulFilter} that uses Ribbon, Hystrix and pluggable http clients to send - * requests. ServiceIds are found in the {@link RequestContext} attribute - * {@link org.springframework.cloud.netflix.zuul.filters.support.FilterConstants#SERVICE_ID_KEY}. - * - * @author Spencer Gibb - * @author Dave Syer - * @author Ryan Baxter - */ -public class RibbonRoutingFilter extends ZuulFilter { - - private static final Log log = LogFactory.getLog(RibbonRoutingFilter.class); - - protected ProxyRequestHelper helper; - - protected RibbonCommandFactory ribbonCommandFactory; - - protected List requestCustomizers; - - private boolean useServlet31 = true; - - public RibbonRoutingFilter(ProxyRequestHelper helper, - RibbonCommandFactory ribbonCommandFactory, - List requestCustomizers) { - this.helper = helper; - this.ribbonCommandFactory = ribbonCommandFactory; - this.requestCustomizers = requestCustomizers; - // To support Servlet API 3.1 we need to check if getContentLengthLong exists - // Spring 5 minimum support is 3.0, so this stays - try { - HttpServletRequest.class.getMethod("getContentLengthLong"); - } - catch (NoSuchMethodException e) { - useServlet31 = false; - } - } - - @Deprecated - // TODO Remove in 2.1.x - public RibbonRoutingFilter(RibbonCommandFactory ribbonCommandFactory) { - this(new ProxyRequestHelper(), ribbonCommandFactory, null); - } - - /* for testing */ boolean isUseServlet31() { - return useServlet31; - } - - @Override - public String filterType() { - return ROUTE_TYPE; - } - - @Override - public int filterOrder() { - return RIBBON_ROUTING_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - RequestContext ctx = RequestContext.getCurrentContext(); - return (ctx.getRouteHost() == null && ctx.get(SERVICE_ID_KEY) != null - && ctx.sendZuulResponse()); - } - - @Override - public Object run() { - RequestContext context = RequestContext.getCurrentContext(); - this.helper.addIgnoredHeaders(); - try { - RibbonCommandContext commandContext = buildCommandContext(context); - ClientHttpResponse response = forward(commandContext); - setResponse(response); - return response; - } - catch (ZuulException ex) { - throw new ZuulRuntimeException(ex); - } - catch (Exception ex) { - throw new ZuulRuntimeException(ex); - } - } - - protected RibbonCommandContext buildCommandContext(RequestContext context) { - HttpServletRequest request = context.getRequest(); - - MultiValueMap headers = this.helper - .buildZuulRequestHeaders(request); - MultiValueMap params = this.helper - .buildZuulRequestQueryParams(request); - String verb = getVerb(request); - InputStream requestEntity = getRequestBody(request); - if (request.getContentLength() < 0 && !verb.equalsIgnoreCase("GET")) { - context.setChunkedRequestBody(); - } - - String serviceId = (String) context.get(SERVICE_ID_KEY); - Boolean retryable = (Boolean) context.get(RETRYABLE_KEY); - Object loadBalancerKey = context.get(LOAD_BALANCER_KEY); - - String uri = this.helper.buildZuulRequestURI(request); - - // remove double slashes - uri = uri.replace("//", "/"); - - long contentLength = useServlet31 ? request.getContentLengthLong() - : request.getContentLength(); - - return new RibbonCommandContext(serviceId, verb, uri, retryable, headers, params, - requestEntity, this.requestCustomizers, contentLength, loadBalancerKey); - } - - protected ClientHttpResponse forward(RibbonCommandContext context) throws Exception { - Map info = this.helper.debug(context.getMethod(), - context.getUri(), context.getHeaders(), context.getParams(), - context.getRequestEntity()); - - RibbonCommand command = this.ribbonCommandFactory.create(context); - try { - ClientHttpResponse response = command.execute(); - this.helper.appendDebug(info, response.getRawStatusCode(), - response.getHeaders()); - return response; - } - catch (HystrixRuntimeException ex) { - return handleException(info, ex); - } - - } - - protected ClientHttpResponse handleException(Map info, - HystrixRuntimeException ex) throws ZuulException { - int statusCode = HttpStatus.INTERNAL_SERVER_ERROR.value(); - Throwable cause = ex; - String message = ex.getFailureType().toString(); - - ClientException clientException = findClientException(ex); - if (clientException == null) { - clientException = findClientException(ex.getFallbackException()); - } - - if (clientException != null) { - if (clientException - .getErrorType() == ClientException.ErrorType.SERVER_THROTTLED) { - statusCode = HttpStatus.SERVICE_UNAVAILABLE.value(); - } - cause = clientException; - message = clientException.getErrorType().toString(); - } - info.put("status", String.valueOf(statusCode)); - throw new ZuulException(cause, "Forwarding error", statusCode, message); - } - - protected ClientException findClientException(Throwable t) { - if (t == null) { - return null; - } - if (t instanceof ClientException) { - return (ClientException) t; - } - return findClientException(t.getCause()); - } - - protected InputStream getRequestBody(HttpServletRequest request) { - InputStream requestEntity = null; - try { - requestEntity = (InputStream) RequestContext.getCurrentContext() - .get(REQUEST_ENTITY_KEY); - if (requestEntity == null) { - requestEntity = request.getInputStream(); - } - } - catch (IOException ex) { - log.error("Error during getRequestBody", ex); - } - return requestEntity; - } - - protected String getVerb(HttpServletRequest request) { - String method = request.getMethod(); - if (method == null) { - return "GET"; - } - return method; - } - - protected void setResponse(ClientHttpResponse resp) - throws ClientException, IOException { - RequestContext.getCurrentContext().set("zuulResponse", resp); - this.helper.setResponse(resp.getRawStatusCode(), resp.getBody(), - resp.getHeaders()); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SendForwardFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SendForwardFilter.java deleted file mode 100644 index 6b4b6e70a..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SendForwardFilter.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route; - -import javax.servlet.RequestDispatcher; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; - -import org.springframework.util.ReflectionUtils; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_TO_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTE_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_FORWARD_FILTER_ORDER; - -/** - * Route {@link ZuulFilter} that forwards requests using the {@link RequestDispatcher}. - * Forwarding location is located in the {@link RequestContext} attribute - * {@link org.springframework.cloud.netflix.zuul.filters.support.FilterConstants#FORWARD_TO_KEY}. - * Useful for forwarding to endpoints in the current application. - * - * @author Dave Syer - */ -public class SendForwardFilter extends ZuulFilter { - - protected static final String SEND_FORWARD_FILTER_RAN = "sendForwardFilter.ran"; - - @Override - public String filterType() { - return ROUTE_TYPE; - } - - @Override - public int filterOrder() { - return SEND_FORWARD_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - RequestContext ctx = RequestContext.getCurrentContext(); - return ctx.containsKey(FORWARD_TO_KEY) - && !ctx.getBoolean(SEND_FORWARD_FILTER_RAN, false); - } - - @Override - public Object run() { - try { - RequestContext ctx = RequestContext.getCurrentContext(); - String path = (String) ctx.get(FORWARD_TO_KEY); - RequestDispatcher dispatcher = ctx.getRequest().getRequestDispatcher(path); - if (dispatcher != null) { - ctx.set(SEND_FORWARD_FILTER_RAN, true); - if (!ctx.getResponse().isCommitted()) { - dispatcher.forward(ctx.getRequest(), ctx.getResponse()); - ctx.getResponse().flushBuffer(); - } - } - } - catch (Exception ex) { - ReflectionUtils.rethrowRuntimeException(ex); - } - return null; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java deleted file mode 100644 index f6809d791..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java +++ /dev/null @@ -1,490 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Timer; -import java.util.TimerTask; -import java.util.regex.Pattern; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.servlet.http.HttpServletRequest; - -import com.netflix.client.ClientException; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.exception.ZuulException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.Header; -import org.apache.http.HttpHost; -import org.apache.http.HttpRequest; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPatch; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpPut; -import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.InputStreamEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.message.BasicHeader; -import org.apache.http.message.BasicHttpEntityEnclosingRequest; -import org.apache.http.message.BasicHttpRequest; - -import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.Host; -import org.springframework.cloud.netflix.zuul.util.ZuulRuntimeException; -import org.springframework.context.ApplicationListener; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.util.StringUtils; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_ENTITY_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTE_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SIMPLE_HOST_ROUTING_FILTER_ORDER; - -/** - * Route {@link ZuulFilter} that sends requests to predetermined URLs via apache - * {@link HttpClient}. URLs are found in {@link RequestContext#getRouteHost()}. - * - * @author Spencer Gibb - * @author Dave Syer - * @author Bilal Alp - * @author Gang Li - * @author Denys Ivano - */ -public class SimpleHostRoutingFilter extends ZuulFilter - implements ApplicationListener { - - private static final Log log = LogFactory.getLog(SimpleHostRoutingFilter.class); - - private static final Pattern MULTIPLE_SLASH_PATTERN = Pattern.compile("/{2,}"); - - private final Timer connectionManagerTimer = new Timer( - "SimpleHostRoutingFilter.connectionManagerTimer", true); - - private boolean sslHostnameValidationEnabled; - - private boolean forceOriginalQueryStringEncoding; - - private ProxyRequestHelper helper; - - private Host hostProperties; - - private ApacheHttpClientConnectionManagerFactory connectionManagerFactory; - - private ApacheHttpClientFactory httpClientFactory; - - private HttpClientConnectionManager connectionManager; - - private CloseableHttpClient httpClient; - - private boolean customHttpClient = false; - - private boolean useServlet31 = true; - - @Override - @SuppressWarnings("Deprecation") - public void onApplicationEvent(EnvironmentChangeEvent event) { - onPropertyChange(event); - } - - @Deprecated - public void onPropertyChange(EnvironmentChangeEvent event) { - if (!customHttpClient) { - boolean createNewClient = false; - - for (String key : event.getKeys()) { - if (key.startsWith("zuul.host.")) { - createNewClient = true; - break; - } - } - - if (createNewClient) { - try { - this.httpClient.close(); - } - catch (IOException ex) { - log.error("error closing client", ex); - } - // Re-create connection manager (may be shut down on HTTP client close) - try { - this.connectionManager.shutdown(); - } - catch (RuntimeException ex) { - log.error("error shutting down connection manager", ex); - } - this.connectionManager = newConnectionManager(); - this.httpClient = newClient(); - } - } - } - - public SimpleHostRoutingFilter(ProxyRequestHelper helper, ZuulProperties properties, - ApacheHttpClientConnectionManagerFactory connectionManagerFactory, - ApacheHttpClientFactory httpClientFactory) { - this.helper = helper; - this.hostProperties = properties.getHost(); - this.sslHostnameValidationEnabled = properties.isSslHostnameValidationEnabled(); - this.forceOriginalQueryStringEncoding = properties - .isForceOriginalQueryStringEncoding(); - this.connectionManagerFactory = connectionManagerFactory; - this.httpClientFactory = httpClientFactory; - checkServletVersion(); - } - - public SimpleHostRoutingFilter(ProxyRequestHelper helper, ZuulProperties properties, - CloseableHttpClient httpClient) { - this.helper = helper; - this.hostProperties = properties.getHost(); - this.sslHostnameValidationEnabled = properties.isSslHostnameValidationEnabled(); - this.forceOriginalQueryStringEncoding = properties - .isForceOriginalQueryStringEncoding(); - this.httpClient = httpClient; - this.customHttpClient = true; - checkServletVersion(); - } - - @PostConstruct - private void initialize() { - if (!customHttpClient) { - this.connectionManager = newConnectionManager(); - this.httpClient = newClient(); - this.connectionManagerTimer.schedule(new TimerTask() { - @Override - public void run() { - if (SimpleHostRoutingFilter.this.connectionManager == null) { - return; - } - SimpleHostRoutingFilter.this.connectionManager - .closeExpiredConnections(); - } - }, 30000, 5000); - } - } - - @PreDestroy - public void stop() { - this.connectionManagerTimer.cancel(); - } - - @Override - public String filterType() { - return ROUTE_TYPE; - } - - @Override - public int filterOrder() { - return SIMPLE_HOST_ROUTING_FILTER_ORDER; - } - - @Override - public boolean shouldFilter() { - return RequestContext.getCurrentContext().getRouteHost() != null - && RequestContext.getCurrentContext().sendZuulResponse(); - } - - @Override - public Object run() { - RequestContext context = RequestContext.getCurrentContext(); - HttpServletRequest request = context.getRequest(); - MultiValueMap headers = this.helper - .buildZuulRequestHeaders(request); - MultiValueMap params = this.helper - .buildZuulRequestQueryParams(request); - String verb = getVerb(request); - InputStream requestEntity = getRequestBody(request); - if (getContentLength(request) < 0) { - context.setChunkedRequestBody(); - } - - String uri = this.helper.buildZuulRequestURI(request); - this.helper.addIgnoredHeaders(); - - try { - CloseableHttpResponse response = forward(this.httpClient, verb, uri, request, - headers, params, requestEntity); - setResponse(response); - } - catch (Exception ex) { - throw new ZuulRuntimeException(handleException(ex)); - } - return null; - } - - protected ZuulException handleException(Exception ex) { - int statusCode = HttpStatus.INTERNAL_SERVER_ERROR.value(); - Throwable cause = ex; - String message = ex.getMessage(); - - ClientException clientException = findClientException(ex); - - if (clientException != null) { - if (clientException - .getErrorType() == ClientException.ErrorType.SERVER_THROTTLED) { - statusCode = HttpStatus.SERVICE_UNAVAILABLE.value(); - } - cause = clientException; - message = clientException.getErrorType().toString(); - } - return new ZuulException(cause, "Forwarding error", statusCode, message); - } - - protected ClientException findClientException(Throwable t) { - if (t == null) { - return null; - } - if (t instanceof ClientException) { - return (ClientException) t; - } - return findClientException(t.getCause()); - } - - protected void checkServletVersion() { - // To support Servlet API 3.1 we need to check if getContentLengthLong exists - // Spring 5 minimum support is 3.0, so this stays - try { - HttpServletRequest.class.getMethod("getContentLengthLong"); - useServlet31 = true; - } - catch (NoSuchMethodException e) { - useServlet31 = false; - } - } - - protected void setUseServlet31(boolean useServlet31) { - this.useServlet31 = useServlet31; - } - - protected HttpClientConnectionManager getConnectionManager() { - return connectionManager; - } - - protected HttpClientConnectionManager newConnectionManager() { - return connectionManagerFactory.newConnectionManager( - !this.sslHostnameValidationEnabled, - this.hostProperties.getMaxTotalConnections(), - this.hostProperties.getMaxPerRouteConnections(), - this.hostProperties.getTimeToLive(), this.hostProperties.getTimeUnit(), - null); - } - - protected CloseableHttpClient newClient() { - final RequestConfig requestConfig = RequestConfig.custom() - .setConnectionRequestTimeout( - this.hostProperties.getConnectionRequestTimeoutMillis()) - .setSocketTimeout(this.hostProperties.getSocketTimeoutMillis()) - .setConnectTimeout(this.hostProperties.getConnectTimeoutMillis()) - .setCookieSpec(CookieSpecs.IGNORE_COOKIES).build(); - return httpClientFactory.createBuilder().setDefaultRequestConfig(requestConfig) - .setConnectionManager(this.connectionManager).disableRedirectHandling() - .build(); - } - - private CloseableHttpResponse forward(CloseableHttpClient httpclient, String verb, - String uri, HttpServletRequest request, MultiValueMap headers, - MultiValueMap params, InputStream requestEntity) - throws Exception { - Map info = this.helper.debug(verb, uri, headers, params, - requestEntity); - URL host = RequestContext.getCurrentContext().getRouteHost(); - HttpHost httpHost = getHttpHost(host); - uri = StringUtils.cleanPath( - MULTIPLE_SLASH_PATTERN.matcher(host.getPath() + uri).replaceAll("/")); - long contentLength = getContentLength(request); - - ContentType contentType = null; - - if (request.getContentType() != null) { - contentType = ContentType.parse(request.getContentType()); - } - - InputStreamEntity entity = new InputStreamEntity(requestEntity, contentLength, - contentType); - - HttpRequest httpRequest = buildHttpRequest(verb, uri, entity, headers, params, - request); - try { - log.debug(httpHost.getHostName() + " " + httpHost.getPort() + " " - + httpHost.getSchemeName()); - CloseableHttpResponse zuulResponse = forwardRequest(httpclient, httpHost, - httpRequest); - this.helper.appendDebug(info, zuulResponse.getStatusLine().getStatusCode(), - revertHeaders(zuulResponse.getAllHeaders())); - return zuulResponse; - } - finally { - // When HttpClient instance is no longer needed, - // shut down the connection manager to ensure - // immediate deallocation of all system resources - // httpclient.getConnectionManager().shutdown(); - } - } - - protected HttpRequest buildHttpRequest(String verb, String uri, - InputStreamEntity entity, MultiValueMap headers, - MultiValueMap params, HttpServletRequest request) { - HttpRequest httpRequest; - String uriWithQueryString = uri + (this.forceOriginalQueryStringEncoding - ? getEncodedQueryString(request) : this.helper.getQueryString(params)); - - switch (verb.toUpperCase()) { - case "POST": - HttpPost httpPost = new HttpPost(uriWithQueryString); - httpRequest = httpPost; - httpPost.setEntity(entity); - break; - case "PUT": - HttpPut httpPut = new HttpPut(uriWithQueryString); - httpRequest = httpPut; - httpPut.setEntity(entity); - break; - case "PATCH": - HttpPatch httpPatch = new HttpPatch(uriWithQueryString); - httpRequest = httpPatch; - httpPatch.setEntity(entity); - break; - case "DELETE": - BasicHttpEntityEnclosingRequest entityRequest = new BasicHttpEntityEnclosingRequest( - verb, uriWithQueryString); - httpRequest = entityRequest; - entityRequest.setEntity(entity); - break; - default: - httpRequest = new BasicHttpRequest(verb, uriWithQueryString); - log.debug(uriWithQueryString); - } - - httpRequest.setHeaders(convertHeaders(headers)); - return httpRequest; - } - - private String getEncodedQueryString(HttpServletRequest request) { - String query = request.getQueryString(); - return (query != null) ? "?" + query : ""; - } - - private MultiValueMap revertHeaders(Header[] headers) { - MultiValueMap map = new LinkedMultiValueMap<>(); - for (Header header : headers) { - String name = header.getName(); - if (!map.containsKey(name)) { - map.put(name, new ArrayList()); - } - map.get(name).add(header.getValue()); - } - return map; - } - - private Header[] convertHeaders(MultiValueMap headers) { - List

list = new ArrayList<>(); - for (String name : headers.keySet()) { - for (String value : headers.get(name)) { - list.add(new BasicHeader(name, value)); - } - } - return list.toArray(new BasicHeader[0]); - } - - private CloseableHttpResponse forwardRequest(CloseableHttpClient httpclient, - HttpHost httpHost, HttpRequest httpRequest) throws IOException { - return httpclient.execute(httpHost, httpRequest); - } - - private HttpHost getHttpHost(URL host) { - HttpHost httpHost = new HttpHost(host.getHost(), host.getPort(), - host.getProtocol()); - return httpHost; - } - - protected InputStream getRequestBody(HttpServletRequest request) { - InputStream requestEntity = null; - try { - requestEntity = (InputStream) RequestContext.getCurrentContext() - .get(REQUEST_ENTITY_KEY); - if (requestEntity == null) { - requestEntity = request.getInputStream(); - } - } - catch (IOException ex) { - log.error("error during getRequestBody", ex); - } - return requestEntity; - } - - private String getVerb(HttpServletRequest request) { - String sMethod = request.getMethod(); - return sMethod.toUpperCase(); - } - - private void setResponse(HttpResponse response) throws IOException { - RequestContext.getCurrentContext().set("zuulResponse", response); - this.helper.setResponse(response.getStatusLine().getStatusCode(), - response.getEntity() == null ? null : response.getEntity().getContent(), - revertHeaders(response.getAllHeaders())); - } - - /** - * Add header names to exclude from proxied response in the current request. - * @param names names of headers to exclude - */ - protected void addIgnoredHeaders(String... names) { - this.helper.addIgnoredHeaders(names); - } - - /** - * Determines whether the filter enables the validation for ssl hostnames. - * @return true if enabled - */ - boolean isSslHostnameValidationEnabled() { - return this.sslHostnameValidationEnabled; - } - - // Get the header value as a long in order to more correctly proxy very large requests - protected long getContentLength(HttpServletRequest request) { - if (useServlet31) { - return request.getContentLengthLong(); - } - String contentLengthHeader = request.getHeader(HttpHeaders.CONTENT_LENGTH); - if (contentLengthHeader != null) { - try { - return Long.parseLong(contentLengthHeader); - } - catch (NumberFormatException ignored) { - } - } - return request.getContentLength(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommand.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommand.java deleted file mode 100644 index efd45e5eb..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommand.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route.apache; - -import com.netflix.client.config.IClientConfig; - -import org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpRequest; -import org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpResponse; -import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommand; - -/** - * @author Spencer Gibb - * @author Ryan Baxter - */ -public class HttpClientRibbonCommand extends - AbstractRibbonCommand { - - public HttpClientRibbonCommand(final String commandKey, - final RibbonLoadBalancingHttpClient client, - final RibbonCommandContext context, final ZuulProperties zuulProperties) { - super(commandKey, client, context, zuulProperties); - } - - public HttpClientRibbonCommand(final String commandKey, - final RibbonLoadBalancingHttpClient client, - final RibbonCommandContext context, final ZuulProperties zuulProperties, - final FallbackProvider zuulFallbackProvider) { - super(commandKey, client, context, zuulProperties, zuulFallbackProvider); - } - - public HttpClientRibbonCommand(final String commandKey, - final RibbonLoadBalancingHttpClient client, - final RibbonCommandContext context, final ZuulProperties zuulProperties, - final FallbackProvider zuulFallbackProvider, final IClientConfig config) { - super(commandKey, client, context, zuulProperties, zuulFallbackProvider, config); - } - - @Override - protected RibbonApacheHttpRequest createRequest() throws Exception { - return new RibbonApacheHttpRequest(this.context); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactory.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactory.java deleted file mode 100644 index 01881f47d..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactory.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route.apache; - -import java.util.Collections; -import java.util.Set; - -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommandFactory; - -/** - * @author Christian Lohmann - * @author Ryan Baxter - */ -public class HttpClientRibbonCommandFactory extends AbstractRibbonCommandFactory { - - private final SpringClientFactory clientFactory; - - private final ZuulProperties zuulProperties; - - public HttpClientRibbonCommandFactory(SpringClientFactory clientFactory, - ZuulProperties zuulProperties) { - this(clientFactory, zuulProperties, Collections.emptySet()); - } - - public HttpClientRibbonCommandFactory(SpringClientFactory clientFactory, - ZuulProperties zuulProperties, Set fallbackProviders) { - super(fallbackProviders); - this.clientFactory = clientFactory; - this.zuulProperties = zuulProperties; - } - - @Override - public HttpClientRibbonCommand create(final RibbonCommandContext context) { - FallbackProvider zuulFallbackProvider = getFallbackProvider( - context.getServiceId()); - final String serviceId = context.getServiceId(); - final RibbonLoadBalancingHttpClient client = this.clientFactory - .getClient(serviceId, RibbonLoadBalancingHttpClient.class); - client.setLoadBalancer(this.clientFactory.getLoadBalancer(serviceId)); - - return new HttpClientRibbonCommand(serviceId, client, context, zuulProperties, - zuulFallbackProvider, clientFactory.getClientConfig(serviceId)); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommand.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommand.java deleted file mode 100644 index ff85abe8e..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommand.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route.okhttp; - -import com.netflix.client.config.IClientConfig; - -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpRibbonRequest; -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpRibbonResponse; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommand; - -/** - * @author Spencer Gibb - * @author Ryan Baxter - */ -public class OkHttpRibbonCommand extends - AbstractRibbonCommand { - - public OkHttpRibbonCommand(final String commandKey, - final OkHttpLoadBalancingClient client, final RibbonCommandContext context, - final ZuulProperties zuulProperties) { - super(commandKey, client, context, zuulProperties); - } - - public OkHttpRibbonCommand(final String commandKey, - final OkHttpLoadBalancingClient client, final RibbonCommandContext context, - final ZuulProperties zuulProperties, - final FallbackProvider zuulFallbackProvider) { - super(commandKey, client, context, zuulProperties, zuulFallbackProvider); - } - - public OkHttpRibbonCommand(final String commandKey, - final OkHttpLoadBalancingClient client, final RibbonCommandContext context, - final ZuulProperties zuulProperties, - final FallbackProvider zuulFallbackProvider, final IClientConfig config) { - super(commandKey, client, context, zuulProperties, zuulFallbackProvider, config); - } - - @Override - protected OkHttpRibbonRequest createRequest() throws Exception { - return new OkHttpRibbonRequest(this.context); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactory.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactory.java deleted file mode 100644 index c2e3d5018..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactory.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route.okhttp; - -import java.util.Collections; -import java.util.Set; - -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommandFactory; - -/** - * @author Spencer Gibb - * @author Ryan Baxter - */ -public class OkHttpRibbonCommandFactory extends AbstractRibbonCommandFactory { - - private SpringClientFactory clientFactory; - - private ZuulProperties zuulProperties; - - public OkHttpRibbonCommandFactory(SpringClientFactory clientFactory, - ZuulProperties zuulProperties) { - this(clientFactory, zuulProperties, Collections.emptySet()); - } - - public OkHttpRibbonCommandFactory(SpringClientFactory clientFactory, - ZuulProperties zuulProperties, Set zuulFallbackProviders) { - super(zuulFallbackProviders); - this.clientFactory = clientFactory; - this.zuulProperties = zuulProperties; - } - - @Override - public OkHttpRibbonCommand create(final RibbonCommandContext context) { - final String serviceId = context.getServiceId(); - FallbackProvider fallbackProvider = getFallbackProvider(serviceId); - final OkHttpLoadBalancingClient client = this.clientFactory.getClient(serviceId, - OkHttpLoadBalancingClient.class); - client.setLoadBalancer(this.clientFactory.getLoadBalancer(serviceId)); - - return new OkHttpRibbonCommand(serviceId, client, context, zuulProperties, - fallbackProvider, clientFactory.getClientConfig(serviceId)); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommand.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommand.java deleted file mode 100644 index 3ad23aff9..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommand.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route.support; - -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.ClientRequest; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.client.config.IClientConfigKey; -import com.netflix.client.http.HttpResponse; -import com.netflix.config.DynamicIntProperty; -import com.netflix.config.DynamicPropertyFactory; -import com.netflix.hystrix.HystrixCommand; -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.HystrixCommandProperties.ExecutionIsolationStrategy; -import com.netflix.hystrix.HystrixThreadPoolKey; -import com.netflix.zuul.constants.ZuulConstants; -import com.netflix.zuul.context.RequestContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonHttpResponse; -import org.springframework.cloud.netflix.ribbon.support.AbstractLoadBalancingClient; -import org.springframework.cloud.netflix.ribbon.support.ContextAwareRequest; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand; -import org.springframework.http.client.ClientHttpResponse; - -/** - * @param {@link ClientRequest} subtype - * @param {@link AbstractLoadBalancingClient} subtype - * @param {@link ClientRequest} subtype - * @param {@link HttpResponse} subtype - * @author Spencer Gibb - */ -public abstract class AbstractRibbonCommand, RQ extends ClientRequest, RS extends HttpResponse> - extends HystrixCommand implements RibbonCommand { - - private static final Log LOGGER = LogFactory.getLog(AbstractRibbonCommand.class); - - protected final LBC client; - - protected RibbonCommandContext context; - - protected FallbackProvider zuulFallbackProvider; - - protected IClientConfig config; - - public AbstractRibbonCommand(LBC client, RibbonCommandContext context, - ZuulProperties zuulProperties) { - this("default", client, context, zuulProperties); - } - - public AbstractRibbonCommand(String commandKey, LBC client, - RibbonCommandContext context, ZuulProperties zuulProperties) { - this(commandKey, client, context, zuulProperties, null); - } - - public AbstractRibbonCommand(String commandKey, LBC client, - RibbonCommandContext context, ZuulProperties zuulProperties, - FallbackProvider fallbackProvider) { - this(commandKey, client, context, zuulProperties, fallbackProvider, null); - } - - public AbstractRibbonCommand(String commandKey, LBC client, - RibbonCommandContext context, ZuulProperties zuulProperties, - FallbackProvider fallbackProvider, IClientConfig config) { - this(getSetter(commandKey, zuulProperties, config), client, context, - fallbackProvider, config); - } - - protected AbstractRibbonCommand(Setter setter, LBC client, - RibbonCommandContext context, FallbackProvider fallbackProvider, - IClientConfig config) { - super(setter); - this.client = client; - this.context = context; - this.zuulFallbackProvider = fallbackProvider; - this.config = config; - } - - protected static HystrixCommandProperties.Setter createSetter(IClientConfig config, - String commandKey, ZuulProperties zuulProperties) { - int hystrixTimeout = getHystrixTimeout(config, commandKey); - return HystrixCommandProperties.Setter() - .withExecutionIsolationStrategy( - zuulProperties.getRibbonIsolationStrategy()) - .withExecutionTimeoutInMilliseconds(hystrixTimeout); - } - - protected static int getHystrixTimeout(IClientConfig config, String commandKey) { - int ribbonTimeout = getRibbonTimeout(config, commandKey); - DynamicPropertyFactory dynamicPropertyFactory = DynamicPropertyFactory - .getInstance(); - int defaultHystrixTimeout = dynamicPropertyFactory.getIntProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 0).get(); - int commandHystrixTimeout = dynamicPropertyFactory - .getIntProperty("hystrix.command." + commandKey - + ".execution.isolation.thread.timeoutInMilliseconds", 0) - .get(); - int hystrixTimeout; - if (commandHystrixTimeout > 0) { - hystrixTimeout = commandHystrixTimeout; - } - else if (defaultHystrixTimeout > 0) { - hystrixTimeout = defaultHystrixTimeout; - } - else { - hystrixTimeout = ribbonTimeout; - } - if (hystrixTimeout < ribbonTimeout) { - LOGGER.warn("The Hystrix timeout of " + hystrixTimeout + "ms for the command " - + commandKey - + " is set lower than the combination of the Ribbon read and connect timeout, " - + ribbonTimeout + "ms."); - } - return hystrixTimeout; - } - - protected static int getRibbonTimeout(IClientConfig config, String commandKey) { - int ribbonTimeout; - if (config == null) { - ribbonTimeout = RibbonClientConfiguration.DEFAULT_READ_TIMEOUT - + RibbonClientConfiguration.DEFAULT_CONNECT_TIMEOUT; - } - else { - int ribbonReadTimeout = getTimeout(config, commandKey, "ReadTimeout", - IClientConfigKey.Keys.ReadTimeout, - RibbonClientConfiguration.DEFAULT_READ_TIMEOUT); - int ribbonConnectTimeout = getTimeout(config, commandKey, "ConnectTimeout", - IClientConfigKey.Keys.ConnectTimeout, - RibbonClientConfiguration.DEFAULT_CONNECT_TIMEOUT); - int maxAutoRetries = getTimeout(config, commandKey, "MaxAutoRetries", - IClientConfigKey.Keys.MaxAutoRetries, - DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES); - int maxAutoRetriesNextServer = getTimeout(config, commandKey, - "MaxAutoRetriesNextServer", - IClientConfigKey.Keys.MaxAutoRetriesNextServer, - DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES_NEXT_SERVER); - ribbonTimeout = (ribbonReadTimeout + ribbonConnectTimeout) - * (maxAutoRetries + 1) * (maxAutoRetriesNextServer + 1); - } - return ribbonTimeout; - } - - private static int getTimeout(IClientConfig config, String commandKey, - String property, IClientConfigKey configKey, int defaultValue) { - DynamicPropertyFactory dynamicPropertyFactory = DynamicPropertyFactory - .getInstance(); - return dynamicPropertyFactory - .getIntProperty(commandKey + "." + config.getNameSpace() + "." + property, - config.get(configKey, defaultValue)) - .get(); - } - - @Deprecated - // TODO remove in 2.0.x - protected static Setter getSetter(final String commandKey, - ZuulProperties zuulProperties) { - return getSetter(commandKey, zuulProperties, null); - } - - protected static Setter getSetter(final String commandKey, - ZuulProperties zuulProperties, IClientConfig config) { - - // @formatter:off - Setter commandSetter = Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("RibbonCommand")) - .andCommandKey(HystrixCommandKey.Factory.asKey(commandKey)); - final HystrixCommandProperties.Setter setter = createSetter(config, commandKey, zuulProperties); - if (zuulProperties.getRibbonIsolationStrategy() == ExecutionIsolationStrategy.SEMAPHORE) { - final String name = ZuulConstants.ZUUL_EUREKA + commandKey + ".semaphore.maxSemaphores"; - // we want to default to semaphore-isolation since this wraps - // 2 others commands that are already thread isolated - final DynamicIntProperty value = DynamicPropertyFactory.getInstance() - .getIntProperty(name, zuulProperties.getSemaphore().getMaxSemaphores()); - setter.withExecutionIsolationSemaphoreMaxConcurrentRequests(value.get()); - } - else if (zuulProperties.getThreadPool().isUseSeparateThreadPools()) { - final String threadPoolKey = zuulProperties.getThreadPool().getThreadPoolKeyPrefix() + commandKey; - commandSetter.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(threadPoolKey)); - } - return commandSetter.andCommandPropertiesDefaults(setter); - // @formatter:on - } - - @Override - protected ClientHttpResponse run() throws Exception { - final RequestContext context = RequestContext.getCurrentContext(); - - RQ request = createRequest(); - RS response; - - boolean retryableClient = this.client instanceof AbstractLoadBalancingClient - && ((AbstractLoadBalancingClient) this.client) - .isClientRetryable((ContextAwareRequest) request); - - if (retryableClient) { - response = this.client.execute(request, config); - } - else { - response = this.client.executeWithLoadBalancer(request, config); - } - context.set("ribbonResponse", response); - - // Explicitly close the HttpResponse if the Hystrix command timed out to - // release the underlying HTTP connection held by the response. - // - if (this.isResponseTimedOut()) { - if (response != null) { - response.close(); - } - } - - return new RibbonHttpResponse(response); - } - - @Override - protected ClientHttpResponse getFallback() { - if (zuulFallbackProvider != null) { - return getFallbackResponse(); - } - return super.getFallback(); - } - - protected ClientHttpResponse getFallbackResponse() { - Throwable cause = getFailedExecutionException(); - cause = cause == null ? getExecutionException() : cause; - return zuulFallbackProvider.fallbackResponse(context.getServiceId(), cause); - } - - public LBC getClient() { - return client; - } - - public RibbonCommandContext getContext() { - return context; - } - - protected abstract RQ createRequest() throws Exception; - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommandFactory.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommandFactory.java deleted file mode 100644 index 3a9cfa56d..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommandFactory.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route.support; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; - -/** - * @author Ryan Baxter - */ -public abstract class AbstractRibbonCommandFactory implements RibbonCommandFactory { - - private Map fallbackProviderCache; - - private FallbackProvider defaultFallbackProvider = null; - - public AbstractRibbonCommandFactory(Set fallbackProviders) { - this.fallbackProviderCache = new HashMap<>(); - for (FallbackProvider provider : fallbackProviders) { - String route = provider.getRoute(); - if ("*".equals(route) || route == null) { - defaultFallbackProvider = provider; - } - else { - fallbackProviderCache.put(route, provider); - } - } - } - - protected FallbackProvider getFallbackProvider(String route) { - FallbackProvider provider = fallbackProviderCache.get(route); - if (provider == null) { - provider = defaultFallbackProvider; - } - return provider; - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/support/FilterConstants.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/support/FilterConstants.java deleted file mode 100644 index 9d318c359..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/support/FilterConstants.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.support; - -import com.netflix.zuul.ZuulFilter; - -import org.springframework.cloud.netflix.zuul.filters.pre.DebugFilter; -import org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter; -import org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter; - -/** - * @author Spencer Gibb - */ -public final class FilterConstants { - - // KEY constants ----------------------------------- - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in - * {@link org.springframework.cloud.netflix.zuul.filters.pre.ServletDetectionFilter}. - */ - public static final String IS_DISPATCHER_SERVLET_REQUEST_KEY = "isDispatcherServletRequest"; - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in - * {@link org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter}. - */ - public static final String FORWARD_TO_KEY = "forward.to"; - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in TODO: determine - * use. - */ - public static final String PROXY_KEY = "proxy"; - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in - * {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter}. - */ - public static final String REQUEST_ENTITY_KEY = "requestEntity"; - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in to override the - * path of the request. - */ - public static final String REQUEST_URI_KEY = "requestURI"; - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in - * {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter}. - */ - public static final String RETRYABLE_KEY = "retryable"; - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in - * {@link org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter}. - */ - public static final String ROUTING_DEBUG_KEY = "routingDebug"; - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in - * {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter}. - */ - public static final String SERVICE_ID_KEY = "serviceId"; - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in - * {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter}. - */ - public static final String LOAD_BALANCER_KEY = "loadBalancerKey"; - - // ORDER constants ----------------------------------- - - /** - * Filter Order for {@link DebugFilter#filterOrder()}. - */ - public static final int DEBUG_FILTER_ORDER = 1; - - /** - * Filter Order for - * {@link org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilter#filterOrder()}. - */ - public static final int FORM_BODY_WRAPPER_FILTER_ORDER = -1; - - /** - * Filter Order for - * {@link org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter}. - */ - public static final int PRE_DECORATION_FILTER_ORDER = 5; - - /** - * Filter Order for - * {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter#filterOrder()}. - */ - public static final int RIBBON_ROUTING_FILTER_ORDER = 10; - - /** - * Filter Order for - * {@link org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter#filterOrder()}. - */ - public static final int SEND_ERROR_FILTER_ORDER = 0; - - /** - * Filter Order for {@link SendForwardFilter#filterOrder()}. - */ - public static final int SEND_FORWARD_FILTER_ORDER = 500; - - /** - * Filter Order for - * {@link org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter#filterOrder()}. - */ - public static final int SEND_RESPONSE_FILTER_ORDER = 1000; - - /** - * Filter Order for - * {@link org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter#filterOrder()}. - */ - public static final int SIMPLE_HOST_ROUTING_FILTER_ORDER = 100; - - /** - * filter order for {@link Servlet30WrapperFilter#filterOrder()}. - */ - public static final int SERVLET_30_WRAPPER_FILTER_ORDER = -2; - - /** - * filter order for - * {@link org.springframework.cloud.netflix.zuul.filters.pre.ServletDetectionFilter#filterOrder()}. - */ - public static final int SERVLET_DETECTION_FILTER_ORDER = -3; - - // Zuul Filter TYPE constants ----------------------------------- - - /** - * {@link ZuulFilter#filterType()} error type. - */ - public static final String ERROR_TYPE = "error"; - - /** - * {@link ZuulFilter#filterType()} post type. - */ - public static final String POST_TYPE = "post"; - - /** - * {@link ZuulFilter#filterType()} pre type. - */ - public static final String PRE_TYPE = "pre"; - - /** - * {@link ZuulFilter#filterType()} route type. - */ - public static final String ROUTE_TYPE = "route"; - - // OTHER constants ----------------------------------- - - /** - * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in - * {@link org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter}. - */ - public static final String FORWARD_LOCATION_PREFIX = "forward:"; - - /** - * Dfault http port. - */ - public static final int HTTP_PORT = 80; - - /** - * Default https port. - */ - public static final int HTTPS_PORT = 443; - - /** - * Http url scheme. - */ - public static final String HTTP_SCHEME = "http"; - - /** - * Https url scheme. - */ - public static final String HTTPS_SCHEME = "https"; - - // HEADER constants ----------------------------------- - - /** - * X-* Header for the matching url. Used when routes use a url rather than serviceId. - */ - public static final String SERVICE_HEADER = "X-Zuul-Service"; - - /** - * X-* Header for the matching serviceId. - */ - public static final String SERVICE_ID_HEADER = "X-Zuul-ServiceId"; - - /** - * X-Forwarded-For Header. - */ - public static final String X_FORWARDED_FOR_HEADER = "X-Forwarded-For"; - - /** - * X-Forwarded-Host Header. - */ - public static final String X_FORWARDED_HOST_HEADER = "X-Forwarded-Host"; - - /** - * X-Forwarded-Prefix Header. - */ - public static final String X_FORWARDED_PREFIX_HEADER = "X-Forwarded-Prefix"; - - /** - * X-Forwarded-Port Header. - */ - public static final String X_FORWARDED_PORT_HEADER = "X-Forwarded-Port"; - - /** - * X-Forwarded-Proto Header. - */ - public static final String X_FORWARDED_PROTO_HEADER = "X-Forwarded-Proto"; - - /** - * X-Zuul-Debug Header. - */ - public static final String X_ZUUL_DEBUG_HEADER = "X-Zuul-Debug-Header"; - - private FilterConstants() { - throw new AssertionError("Must not instantiate constant utility class"); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/DefaultCounterFactory.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/DefaultCounterFactory.java deleted file mode 100644 index 5e263084d..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/DefaultCounterFactory.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.metrics; - -import com.netflix.zuul.monitoring.CounterFactory; -import io.micrometer.core.instrument.MeterRegistry; - -/** - * A counter based monitoring factory that uses {@link MeterRegistry} to increment - * counters. - * - * @author Anastasiia Smirnova - */ -public class DefaultCounterFactory extends CounterFactory { - - private final MeterRegistry meterRegistry; - - public DefaultCounterFactory(MeterRegistry meterRegistry) { - this.meterRegistry = meterRegistry; - } - - @Override - public void increment(String name) { - this.meterRegistry.counter(name).increment(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/EmptyCounterFactory.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/EmptyCounterFactory.java deleted file mode 100644 index 6d9aa7854..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/EmptyCounterFactory.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 - * - * https://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.zuul.metrics; - -import com.netflix.zuul.monitoring.CounterFactory; - -/** - * A counter based monitoring factory that does nothing. - * - * @author Anastasiia Smirnova - */ -public class EmptyCounterFactory extends CounterFactory { - - @Override - public void increment(String name) { - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/EmptyTracerFactory.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/EmptyTracerFactory.java deleted file mode 100644 index b9138818c..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/metrics/EmptyTracerFactory.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.metrics; - -import com.netflix.zuul.monitoring.Tracer; -import com.netflix.zuul.monitoring.TracerFactory; - -/** - * A time based monitoring factory that does nothing. - * - * @author Anastasiia Smirnova - */ -public class EmptyTracerFactory extends TracerFactory { - - private final EmptyTracer emptyTracer = new EmptyTracer(); - - @Override - public Tracer startMicroTracer(String name) { - return emptyTracer; - } - - private static final class EmptyTracer implements Tracer { - - @Override - public void setName(String name) { - } - - @Override - public void stopAndLog() { - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractor.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractor.java deleted file mode 100644 index 510aad4a6..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractor.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.util; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; - -import javax.servlet.http.HttpServletRequest; - -import org.springframework.core.io.InputStreamResource; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.multipart.MultipartHttpServletRequest; -import org.springframework.web.util.UriComponentsBuilder; - -import static java.util.Arrays.stream; -import static java.util.Collections.emptyMap; -import static org.springframework.util.StringUtils.isEmpty; -import static org.springframework.util.StringUtils.tokenizeToStringArray; -import static org.springframework.util.StringUtils.uriDecode; - -/** - * Utility class providing methods for extracting {@link HttpServletRequest} content as a - * {@link MultiValueMap}. - * - * @author Eloi Poch - * @author Spencer Gibb - * @author Dmitrii Priporov - * @author Ryan Baxter - */ -public final class RequestContentDataExtractor { - - private RequestContentDataExtractor() { - throw new AssertionError("Must not instantiate utility class."); - } - - public static MultiValueMap extract(HttpServletRequest request) - throws IOException { - return (request instanceof MultipartHttpServletRequest) - ? extractFromMultipartRequest((MultipartHttpServletRequest) request) - : extractFromRequest(request); - } - - private static MultiValueMap extractFromRequest( - HttpServletRequest request) throws IOException { - MultiValueMap builder = new LinkedMultiValueMap<>(); - Set queryParams = findQueryParams(request); - - for (Entry entry : request.getParameterMap().entrySet()) { - String key = entry.getKey(); - - if (!queryParams.contains(key) && entry.getValue() != null) { - for (String value : entry.getValue()) { - builder.add(key, value); - } - } - } - - return builder; - } - - private static MultiValueMap extractFromMultipartRequest( - MultipartHttpServletRequest request) throws IOException { - MultiValueMap builder = new LinkedMultiValueMap<>(); - Map> queryParamsGroupedByName = findQueryParamsGroupedByName( - request); - Set queryParams = findQueryParams(request); - - for (Entry entry : request.getParameterMap().entrySet()) { - String key = entry.getKey(); - List listOfAllParams = stream(request.getParameterMap().get(key)) - .collect(Collectors.toList()); - List listOfOnlyQueryParams = queryParamsGroupedByName.get(key); - - if (listOfOnlyQueryParams != null) { - listOfOnlyQueryParams = listOfOnlyQueryParams.stream() - .filter(Objects::nonNull) - .map(param -> uriDecode(param, Charset.defaultCharset())) - .collect(Collectors.toList()); - if (!listOfOnlyQueryParams.containsAll(listOfAllParams)) { - listOfAllParams.removeAll(listOfOnlyQueryParams); - for (String value : listOfAllParams) { - builder.add(key, - new HttpEntity<>(value, newHttpHeaders(request, key))); - } - } - } - - if (!queryParams.contains(key)) { - for (String value : entry.getValue()) { - builder.add(key, - new HttpEntity<>(value, newHttpHeaders(request, key))); - } - } - } - - for (Entry> parts : request.getMultiFileMap() - .entrySet()) { - for (MultipartFile file : parts.getValue()) { - HttpHeaders headers = new HttpHeaders(); - headers.setContentDispositionFormData(file.getName(), - file.getOriginalFilename()); - if (file.getContentType() != null) { - headers.setContentType(MediaType.valueOf(file.getContentType())); - } - - HttpEntity entity = new HttpEntity<>( - new InputStreamResource(file.getInputStream()), headers); - builder.add(parts.getKey(), entity); - } - } - - return builder; - } - - private static HttpHeaders newHttpHeaders(MultipartHttpServletRequest request, - String key) { - HttpHeaders headers = new HttpHeaders(); - String type = request.getMultipartContentType(key); - - if (type != null) { - headers.setContentType(MediaType.valueOf(type)); - } - return headers; - } - - private static Set findQueryParams(HttpServletRequest request) { - Set result = new HashSet<>(); - String query = request.getQueryString(); - - if (query != null) { - for (String value : tokenizeToStringArray(query, "&")) { - if (value.contains("=")) { - value = value.substring(0, value.indexOf("=")); - } - result.add(value); - } - } - - return result; - } - - static Map> findQueryParamsGroupedByName( - HttpServletRequest request) { - String query = request.getQueryString(); - if (isEmpty(query)) { - return emptyMap(); - } - return UriComponentsBuilder.fromUriString("?" + query).build().getQueryParams(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestUtils.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestUtils.java deleted file mode 100644 index bdcbb881d..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/RequestUtils.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.util; - -import com.netflix.zuul.context.RequestContext; - -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.IS_DISPATCHER_SERVLET_REQUEST_KEY; - -/** - * Utility class providing methods to verify if the current request is a dispatcher - * servlet or a Zuul servlet request. - * - * @author Adrian Ivan - * @author Spencer Gibb - */ -public final class RequestUtils { - - private RequestUtils() { - throw new AssertionError("Must not instantiate utility class."); - } - - /** - * @deprecated use - * {@link org.springframework.cloud.netflix.zuul.filters.support.FilterConstants#IS_DISPATCHER_SERVLET_REQUEST_KEY} - */ - @Deprecated - public static final String IS_DISPATCHERSERVLETREQUEST = IS_DISPATCHER_SERVLET_REQUEST_KEY; - - public static boolean isDispatcherServletRequest() { - return RequestContext.getCurrentContext() - .getBoolean(IS_DISPATCHER_SERVLET_REQUEST_KEY); - } - - public static boolean isZuulServletRequest() { - // extra check for dispatcher since ZuulServlet can run from ZuulController - return !isDispatcherServletRequest() - && RequestContext.getCurrentContext().getZuulEngineRan(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/ZuulRuntimeException.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/ZuulRuntimeException.java deleted file mode 100644 index c4d5593c9..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/util/ZuulRuntimeException.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.util; - -import com.netflix.zuul.exception.ZuulException; - -/** - * @author Spencer Gibb - */ -public class ZuulRuntimeException extends RuntimeException { - - public ZuulRuntimeException(ZuulException cause) { - super(cause); - } - - @Deprecated - public ZuulRuntimeException(Exception ex) { - super(ex); - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/web/ZuulController.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/web/ZuulController.java deleted file mode 100644 index 84ed5919b..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/web/ZuulController.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.web; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.http.ZuulServlet; - -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.ServletWrappingController; - -/** - * @author Spencer Gibb - */ -public class ZuulController extends ServletWrappingController { - - public ZuulController() { - setServletClass(ZuulServlet.class); - setServletName("zuul"); - setSupportedMethods((String[]) null); // Allow all - } - - @Override - public ModelAndView handleRequest(HttpServletRequest request, - HttpServletResponse response) throws Exception { - try { - // We don't care about the other features of the base class, just want to - // handle the request - return super.handleRequestInternal(request, response); - } - finally { - // @see com.netflix.zuul.context.ContextLifecycleFilter.doFilter - RequestContext.getCurrentContext().unset(); - } - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/web/ZuulHandlerMapping.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/web/ZuulHandlerMapping.java deleted file mode 100644 index 2ff1d0c19..000000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/web/ZuulHandlerMapping.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.web; - -import java.util.Collection; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.context.RequestContext; - -import org.springframework.boot.web.servlet.error.ErrorController; -import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.util.AntPathMatcher; -import org.springframework.util.PathMatcher; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.servlet.HandlerExecutionChain; -import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping; - -/** - * MVC HandlerMapping that maps incoming request paths to remote services. - * - * @author Spencer Gibb - * @author Dave Syer - * @author João Salavessa - * @author Biju Kunjummen - */ -public class ZuulHandlerMapping extends AbstractUrlHandlerMapping { - - private final RouteLocator routeLocator; - - private final ZuulController zuul; - - private ErrorController errorController; - - private PathMatcher pathMatcher = new AntPathMatcher(); - - private volatile boolean dirty = true; - - public ZuulHandlerMapping(RouteLocator routeLocator, ZuulController zuul) { - this.routeLocator = routeLocator; - this.zuul = zuul; - setOrder(-200); - } - - @Override - protected HandlerExecutionChain getCorsHandlerExecutionChain( - HttpServletRequest request, HandlerExecutionChain chain, - CorsConfiguration config) { - if (config == null) { - // Allow CORS requests to go to the backend - return chain; - } - return super.getCorsHandlerExecutionChain(request, chain, config); - } - - public void setErrorController(ErrorController errorController) { - this.errorController = errorController; - } - - public void setDirty(boolean dirty) { - this.dirty = dirty; - if (this.routeLocator instanceof RefreshableRouteLocator) { - ((RefreshableRouteLocator) this.routeLocator).refresh(); - } - } - - @Override - protected Object lookupHandler(String urlPath, HttpServletRequest request) - throws Exception { - if (this.errorController != null - && urlPath.equals(this.errorController.getErrorPath())) { - return null; - } - if (isIgnoredPath(urlPath, this.routeLocator.getIgnoredPaths())) { - return null; - } - RequestContext ctx = RequestContext.getCurrentContext(); - if (ctx.containsKey("forward.to")) { - return null; - } - if (this.dirty) { - synchronized (this) { - if (this.dirty) { - registerHandlers(); - this.dirty = false; - } - } - } - return super.lookupHandler(urlPath, request); - } - - private boolean isIgnoredPath(String urlPath, Collection ignored) { - if (ignored != null) { - for (String ignoredPath : ignored) { - if (this.pathMatcher.match(ignoredPath, urlPath)) { - return true; - } - } - } - return false; - } - - private void registerHandlers() { - Collection routes = this.routeLocator.getRoutes(); - if (routes.isEmpty()) { - this.logger.warn("No routes found from RouteLocator"); - } - else { - for (Route route : routes) { - registerHandler(route.getFullPath(), this.zuul); - } - } - } - -} diff --git a/spring-cloud-netflix-zuul/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-netflix-zuul/src/main/resources/META-INF/additional-spring-configuration-metadata.json deleted file mode 100644 index 61ec66969..000000000 --- a/spring-cloud-netflix-zuul/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "properties": [ - { - "defaultValue": false, - "name": "ribbon.restclient.enabled", - "description": "Enables the use of the deprecated Ribbon RestClient.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": false, - "name": "ribbon.okhttp.enabled", - "description": "Enables the use of the OK HTTP Client with Ribbon.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": false, - "name": "zuul.ribbon.eager-load.enabled", - "description": "Enables eager loading of Ribbon clients on startup.", - "type": "java.lang.Boolean" - } - ] -} \ No newline at end of file diff --git a/spring-cloud-netflix-zuul/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-zuul/src/main/resources/META-INF/spring.factories deleted file mode 100644 index ac5fe6070..000000000 --- a/spring-cloud-netflix-zuul/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,3 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.zuul.ZuulServerAutoConfiguration,\ -org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfiguration diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ContextPathZuulProxyApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ContextPathZuulProxyApplicationTests.java deleted file mode 100644 index 2412260c6..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ContextPathZuulProxyApplicationTests.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest( - classes = ContextPathZuulProxyApplicationTests.ContextPathZuulProxyApplication.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "server.servlet.contextPath: /app", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class ContextPathZuulProxyApplicationTests { - - @LocalServerPort - private int port; - - @Autowired - private TestRestTemplate testRestTemplate; - - @Autowired - private DiscoveryClientRouteLocator routes; - - @Autowired - private RoutesEndpoint endpoint; - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void getOnSelfViaSimpleHostRoutingFilter() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app/local"); - this.endpoint.reset(); - ResponseEntity result = testRestTemplate.exchange( - "http://localhost:" + this.port + "/app/self/1", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Gotten 1!"); - } - - @Test - public void stripPrefixFalseAppendsPath() { - this.routes.addRoute(new ZuulRoute("strip", "/strip/**", "strip", - "http://localhost:" + this.port + "/app/local", false, false, null)); - this.endpoint.reset(); - ResponseEntity result = testRestTemplate.exchange( - "http://localhost:" + this.port + "/app/strip", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - // Prefix not stripped to it goes to /local/strip - assertThat(result.getBody()).isEqualTo("Gotten strip!"); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @Import(NoSecurityConfiguration.class) - static class ContextPathZuulProxyApplication { - - @RequestMapping(value = "/local/{id}", method = RequestMethod.GET) - public String get(@PathVariable String id) { - return "Gotten " + id + "!"; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FiltersEndpointTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FiltersEndpointTests.java deleted file mode 100644 index dcdfd4e6d..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FiltersEndpointTests.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import java.util.List; -import java.util.Map; - -import com.netflix.zuul.ZuulFilter; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Bean; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hibernate.validator.internal.util.Contracts.assertTrue; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * Tests for Filters endpoint - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - properties = "management.endpoints.web.exposure.include=*") -@DirtiesContext -public class FiltersEndpointTests { - - @Autowired - private FiltersEndpoint endpoint; - - @Test - public void getFilters() { - final Map>> filters = endpoint.invoke(); - - boolean foundFilter = false; - - if (filters.containsKey("sample")) { - for (Map filterInfo : filters.get("sample")) { - if (TestFilter.class.getName().equals(filterInfo.get("class"))) { - foundFilter = true; - - // Verify filter's attributes - assertThat(filterInfo.get("order")).isEqualTo(0); - - break; // the search is over - } - } - } - - assertTrue(foundFilter, - "Could not find expected sample filter from filters endpoint"); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableZuulProxy - static class FiltersEndpointApplication { - - @Bean - public ZuulFilter sampleFilter() { - return new TestFilter(); - } - - } - - static class TestFilter extends ZuulFilter { - - @Override - public String filterType() { - return "sample"; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public Object run() { - return null; - } - - @Override - public int filterOrder() { - return 0; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulProxyApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulProxyApplicationTests.java deleted file mode 100644 index a438143a6..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulProxyApplicationTests.java +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import java.io.IOException; - -import javax.inject.Inject; -import javax.servlet.http.Part; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.actuate.trace.http.HttpTraceRepository; -import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -import static java.nio.charset.Charset.defaultCharset; -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; -import static org.springframework.util.StreamUtils.copyToString; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = FormZuulProxyApplication.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "zuul.routes.simplefzpat:/simplefzpat/**" }) -@DirtiesContext -public class FormZuulProxyApplicationTests { - - @Inject - private TestRestTemplate restTemplate; - - @Before - public void setTestRequestContext() { - RequestContext.testSetCurrentContext(new RequestContext()); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void postWithForm() { - MultiValueMap form = new LinkedMultiValueMap<>(); - form.set("foo", "bar"); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); - - ResponseEntity result = sendPost("/simplefzpat/form", form, headers); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {foo=[bar]}"); - } - - @Test - public void postWithMultipartForm() { - MultiValueMap form = new LinkedMultiValueMap<>(); - form.set("foo", "bar"); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.MULTIPART_FORM_DATA); - - ResponseEntity result = sendPost("/simplefzpat/form", form, headers); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {foo=[bar]}"); - } - - @Test - public void postWithMultipartFile() { - MultiValueMap form = new LinkedMultiValueMap<>(); - - HttpHeaders part = new HttpHeaders(); - part.setContentType(MediaType.TEXT_PLAIN); - part.setContentDispositionFormData("file", "foo.txt"); - - form.set("foo", new HttpEntity<>("bar".getBytes(), part)); - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.MULTIPART_FORM_DATA); - - ResponseEntity result = sendPost("/simplefzpat/file", form, headers); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! bar"); - } - - @Test - public void postWithMultipartFileAndForm() { - MultiValueMap form = new LinkedMultiValueMap<>(); - - HttpHeaders part = new HttpHeaders(); - part.setContentType(MediaType.TEXT_PLAIN); - part.setContentDispositionFormData("file", "foo.txt"); - form.set("foo", new HttpEntity<>("bar".getBytes(), part)); - - form.set("field", "data"); - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.MULTIPART_FORM_DATA); - - ResponseEntity result = sendPost("/simplefzpat/fileandform", form, headers); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! bar!field!data"); - } - - @Test - public void postWithMultipartApplicationJson() { - MultiValueMap form = new LinkedMultiValueMap<>(); - - HttpHeaders partHeaders = new HttpHeaders(); - partHeaders.setContentType(MediaType.APPLICATION_JSON); - form.set("field", new HttpEntity<>("{foo=[bar]}", partHeaders)); - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.MULTIPART_FORM_DATA); - - ResponseEntity result = sendPost("/simplefzpat/json", form, headers); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {foo=[bar]} as application/json"); - } - - @Test - public void postWithUTF8Form() { - MultiValueMap form = new LinkedMultiValueMap<>(); - - form.set("foo", "bar"); - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.valueOf( - MediaType.APPLICATION_FORM_URLENCODED_VALUE + "; charset=UTF-8")); - - ResponseEntity result = sendPost("/simplefzpat/form", form, headers); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {foo=[bar]}"); - } - - @Test - public void postWithUrlParams() throws Exception { - MultiValueMap form = new LinkedMultiValueMap<>(); - - form.set("foo", "bar"); - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.valueOf( - MediaType.APPLICATION_FORM_URLENCODED_VALUE + "; charset=UTF-8")); - - ResponseEntity result = sendPost("/simplefzpat/form?uriParam=uriValue", form, - headers); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()) - .isEqualTo("Posted! {uriParam=[uriValue], foo=[bar]}"); - } - - @Test - public void getWithUrlParams() throws Exception { - ResponseEntity result = sendGet("/simplefzpat/form?uriParam=uriValue"); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {uriParam=[uriValue]}"); - } - - private ResponseEntity sendPost(String url, MultiValueMap form, - HttpHeaders headers) { - return restTemplate.postForEntity(url, new HttpEntity<>(form, headers), - String.class); - } - - private ResponseEntity sendGet(String url) { - return restTemplate.getForEntity(url, String.class); - } - -} - -// Don't use @SpringBootApplication because we don't want to component scan -@Configuration(proxyBeanMethods = false) -@EnableAutoConfiguration -@RestController -@EnableZuulProxy -@RibbonClients({ @RibbonClient(name = "simplefzpat", - configuration = FormRibbonClientConfiguration.class) }) -@Import(NoSecurityConfiguration.class) -class FormZuulProxyApplication { - - @RequestMapping(value = "/form", method = RequestMethod.POST) - public String accept(@RequestParam MultiValueMap form) - throws IOException { - return "Posted! " + form; - } - - @RequestMapping(value = "/form", method = RequestMethod.GET) - public String get(@RequestParam MultiValueMap form) - throws IOException { - return "Posted! " + form; - } - - // TODO: Why does this not work if you add @RequestParam as above? - @RequestMapping(value = "/file", method = RequestMethod.POST) - public String file(@RequestParam(required = false) MultipartFile file) - throws IOException { - - return "Posted! " + copyToString(file.getInputStream(), defaultCharset()); - } - - @RequestMapping(value = "/fileandform", method = RequestMethod.POST) - public String fileAndForm(@RequestParam MultipartFile file, - @RequestParam String field) throws IOException { - - return "Posted! " + copyToString(file.getInputStream(), defaultCharset()) - + "!field!" + field; - } - - @RequestMapping(value = "/json", method = RequestMethod.POST) - public String fileAndJson(@RequestPart Part field) throws IOException { - - return "Posted! " + copyToString(field.getInputStream(), defaultCharset()) - + " as " + field.getContentType(); - } - - @Bean - public ZuulFilter sampleFilter() { - return new ZuulFilter() { - - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public Object run() { - return null; - } - - @Override - public int filterOrder() { - return 0; - } - - }; - } - - @Bean - public HttpTraceRepository traceRepository() { - return new InMemoryHttpTraceRepository(); - } - - public static void main(String[] args) { - } - -} - -// Load balancer with fixed server list for "simplefzpat" pointing to localhost -@Configuration(proxyBeanMethods = false) -class FormRibbonClientConfiguration { - - @LocalServerPort - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulServletProxyApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulServletProxyApplicationTests.java deleted file mode 100644 index c91dc8bab..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/FormZuulServletProxyApplicationTests.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import java.io.IOException; -import java.io.InputStream; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.trace.http.HttpTraceRepository; -import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = FormZuulServletProxyApplication.class, - webEnvironment = RANDOM_PORT, - properties = { "zuul.routes[simplefzspat].path:/simplefzspat/**", - "zuul.routes[simplefzspat].serviceId:simplefzspat" }) -@DirtiesContext -public class FormZuulServletProxyApplicationTests { - - @Autowired - private TestRestTemplate testRestTemplate; - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void unsetTestRequestContext() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void postWithForm() { - MultiValueMap form = new LinkedMultiValueMap<>(); - form.set("foo", "bar"); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); - ResponseEntity result = testRestTemplate.exchange( - "/zuul/simplefzspat/form", HttpMethod.POST, - new HttpEntity<>(form, headers), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {foo=[bar]}"); - } - - @Test - public void postWithMultipartForm() { - MultiValueMap form = new LinkedMultiValueMap<>(); - form.set("foo", "bar"); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.MULTIPART_FORM_DATA); - ResponseEntity result = testRestTemplate.exchange( - "/zuul/simplefzspat/form", HttpMethod.POST, - new HttpEntity<>(form, headers), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {foo=[bar]}"); - } - - @Test - public void postWithMultipartFile() { - MultiValueMap form = new LinkedMultiValueMap<>(); - HttpHeaders part = new HttpHeaders(); - part.setContentType(MediaType.TEXT_PLAIN); - part.setContentDispositionFormData("file", "foo.txt"); - form.set("foo", new HttpEntity<>("bar".getBytes(), part)); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.MULTIPART_FORM_DATA); - headers.set("Transfer-Encoding", "chunked"); - headers.setContentLength(-1); - ResponseEntity result = testRestTemplate.exchange( - "/zuul/simplefzspat/file", HttpMethod.POST, - new HttpEntity<>(form, headers), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! bar"); - } - - @Test - public void postWithUTF8Form() { - MultiValueMap form = new LinkedMultiValueMap<>(); - form.set("foo", "bar"); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.valueOf( - MediaType.APPLICATION_FORM_URLENCODED_VALUE + "; charset=UTF-8")); - ResponseEntity result = testRestTemplate.exchange( - "/zuul/simplefzspat/form", HttpMethod.POST, - new HttpEntity<>(form, headers), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {foo=[bar]}"); - } - -} - -// Don't use @SpringBootApplication because we don't want to component scan -@Configuration(proxyBeanMethods = false) -@EnableAutoConfiguration -@RestController -@EnableZuulProxy -@RibbonClients(@RibbonClient(name = "simplefzspat", - configuration = ServletFormRibbonClientConfiguration.class)) -@Import(NoSecurityConfiguration.class) -class FormZuulServletProxyApplication { - - private static final Log log = LogFactory - .getLog(FormZuulServletProxyApplication.class); - - @RequestMapping(value = "/form", method = RequestMethod.POST) - public String accept(@RequestParam MultiValueMap form) - throws IOException { - return "Posted! " + form; - } - - // TODO: Why does this not work if you add @RequestParam as above? - @RequestMapping(value = "/file", method = RequestMethod.POST) - public String file(@RequestParam(required = false) MultipartFile file) - throws IOException { - byte[] bytes = new byte[0]; - if (file != null) { - if (file.getSize() > 1024) { - bytes = new byte[1024]; - InputStream inputStream = file.getInputStream(); - inputStream.read(bytes); - byte[] buffer = new byte[1024 * 1024 * 10]; - while (inputStream.read(buffer) >= 0) { - log.info("Read more bytes"); - } - } - else { - bytes = file.getBytes(); - } - } - return "Posted! " + new String(bytes); - } - - @Bean - public ZuulFilter sampleFilter() { - return new ZuulFilter() { - - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public Object run() { - return null; - } - - @Override - public int filterOrder() { - return 0; - } - - }; - } - - @Bean - public HttpTraceRepository traceRepository() { - return new InMemoryHttpTraceRepository(); - } - -} - -// Load balancer with fixed server list for "simplefzspat" pointing to localhost -@Configuration(proxyBeanMethods = false) -class ServletFormRibbonClientConfiguration { - - @LocalServerPort - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java deleted file mode 100644 index 6018b46b2..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = RetryableZuulProxyApplication.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "zuul.routes[simplerzpat].path: /simplerzpat/**", - "zuul.routes[simplerzpat].retryable: true", - "zuul.routes[simplerzpat].serviceId: simplerzpat", - "ribbon.OkToRetryOnAllOperations: true", - "simplerzpat.ribbon.retryableStatusCodes: 404", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class RetryableZuulProxyApplicationTests { - - @Autowired - private TestRestTemplate testRestTemplate; - - @Autowired - @SuppressWarnings("unused") - private DiscoveryClientRouteLocator routes; - - @Autowired - @SuppressWarnings("unused") - private RoutesEndpoint endpoint; - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void postWithForm() { - MultiValueMap form = new LinkedMultiValueMap(); - form.set("foo", "bar"); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); - ResponseEntity result = testRestTemplate.exchange("/simplerzpat/poster", - HttpMethod.POST, new HttpEntity<>(form, headers), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted! {foo=[bar]}"); - } - -} - -// Don't use @SpringBootApplication because we don't want to component scan -@Configuration(proxyBeanMethods = false) -@EnableAutoConfiguration -@RestController -@EnableZuulProxy -@RibbonClient(name = "simplerzpat", - configuration = RetryableRibbonClientConfiguration.class) -@Import(NoSecurityConfiguration.class) -class RetryableZuulProxyApplication { - - @RequestMapping(value = "/poster", method = RequestMethod.POST) - public String delete(@RequestBody MultiValueMap form) { - return "Posted! " + form; - } - - @Bean - public ZuulFilter sampleFilter() { - return new ZuulFilter() { - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public Object run() { - return null; - } - - @Override - public int filterOrder() { - return 0; - } - }; - } - -} - -// Load balancer with fixed server list for "simplerzpat" pointing to localhost -@Configuration(proxyBeanMethods = false) -class RetryableRibbonClientConfiguration { - - @LocalServerPort - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port), - new Server("failed-localhost", this.port)); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointDetailsTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointDetailsTests.java deleted file mode 100644 index acfcdab16..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointDetailsTests.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.context.ApplicationEventPublisher; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -/** - * @author Ryan Baxter - * @author Gregor Zurowski - */ -@SpringBootTest -@RunWith(MockitoJUnitRunner.class) -public class RoutesEndpointDetailsTests { - - private RouteLocator locator; - - private RoutesEndpoint endpoint; - - @Mock - private ApplicationEventPublisher publisher; - - @Before - public void setUp() { - this.locator = new RouteLocator() { - @Override - public Collection getIgnoredPaths() { - return null; - } - - @Override - public List getRoutes() { - List routes = new ArrayList<>(); - routes.add(new Route("foo", "foopath", "foolocation", null, true, - Collections.EMPTY_SET)); - routes.add(new Route("bar", "barpath", "barlocation", "bar-prefix", true, - Collections.EMPTY_SET)); - return routes; - } - - @Override - public Route getMatchingRoute(String path) { - return null; - } - }; - endpoint = spy(new RoutesEndpoint(locator)); - } - - @Test - public void reset() throws Exception { - this.endpoint.setApplicationEventPublisher(publisher); - Map result = new HashMap<>(); - for (Route r : locator.getRoutes()) { - result.put(r.getFullPath(), r.getLocation()); - } - assertThat(endpoint.reset()).isEqualTo(result); - verify(endpoint, times(1)).invoke(); - verify(publisher, times(1)).publishEvent(isA(RoutesRefreshedEvent.class)); - } - - @Test - public void routeDetails() throws Exception { - Map results = new HashMap<>(); - for (Route route : locator.getRoutes()) { - results.put(route.getFullPath(), new RoutesEndpoint.RouteDetails(route)); - } - assertThat(this.endpoint.invokeRouteDetails(RoutesEndpoint.FORMAT_DETAILS)) - .isEqualTo(results); - verify(endpoint, times(1)).invokeRouteDetails(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointIntegrationTests.java deleted file mode 100644 index 4a397cc1d..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointIntegrationTests.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import java.util.Map; - -import org.assertj.core.api.Assertions; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - * @author Gregor Zurowski - */ -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - value = { "zuul.routes.sslservice.url=https://localhost:8443", - "management.security.enabled=false", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class RoutesEndpointIntegrationTests { - - private static final String BASE_PATH = new WebEndpointProperties().getBasePath(); - - @Autowired - private TestRestTemplate restTemplate; - - @Autowired - private SimpleZuulProxyApplication.RoutesRefreshListener refreshListener; - - @Test - @SuppressWarnings("unchecked") - public void getRoutesTest() { - ResponseEntity entity = restTemplate.getForEntity(BASE_PATH + "/routes", - Map.class); - Assertions.assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - Map routes = entity.getBody(); - assertThat(routes.get("/sslservice/**")).isEqualTo("https://localhost:8443"); - } - - @Test - @SuppressWarnings("unchecked") - public void postRoutesTest() { - ResponseEntity entity = restTemplate.postForEntity(BASE_PATH + "/routes", - null, Map.class); - Assertions.assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - Map routes = entity.getBody(); - assertThat(routes.get("/sslservice/**")).isEqualTo("https://localhost:8443"); - assertThat(refreshListener.wasCalled()).isTrue(); - } - - @Test - public void getRouteDetailsTest() { - ResponseEntity> responseEntity = restTemplate - .exchange(BASE_PATH + "/routes/details", HttpMethod.GET, null, - new ParameterizedTypeReference>() { - }); - - assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); - - RoutesEndpoint.RouteDetails details = responseEntity.getBody() - .get("/sslservice/**"); - assertThat(details.getPath()).isEqualTo("/**"); - assertThat(details.getFullPath()).isEqualTo("/sslservice/**"); - assertThat(details.getLocation()).isEqualTo("https://localhost:8443"); - assertThat(details.getPrefix()).isEqualTo("/sslservice"); - assertThat(details.isPrefixStripped()).isTrue(); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @Import(NoSecurityConfiguration.class) - static class SimpleZuulProxyApplication { - - @Component - static class RoutesRefreshListener - implements ApplicationListener { - - private boolean called = false; - - @Override - public void onApplicationEvent(RoutesRefreshedEvent routesRefreshedEvent) { - called = true; - } - - public boolean wasCalled() { - return called; - } - - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointTests.java deleted file mode 100644 index 4b89fb839..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/RoutesEndpointTests.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - * @author Gregor Zurowski - */ -public class RoutesEndpointTests { - - private RouteLocator locator; - - @Before - public void setUp() { - this.locator = new RouteLocator() { - @Override - public Collection getIgnoredPaths() { - return null; - } - - @Override - public List getRoutes() { - List routes = new ArrayList<>(); - routes.add(new Route("foo", "foopath", "foolocation", null, true, - Collections.EMPTY_SET)); - routes.add(new Route("bar", "barpath", "barlocation", "/bar-prefix", true, - Collections.EMPTY_SET)); - return routes; - } - - @Override - public Route getMatchingRoute(String path) { - return null; - } - }; - } - - @Test - public void testInvoke() { - RoutesEndpoint endpoint = new RoutesEndpoint(locator); - Map result = new HashMap(); - for (Route r : locator.getRoutes()) { - result.put(r.getFullPath(), r.getLocation()); - } - assertThat(endpoint.invoke()).isEqualTo(result); - } - - @Test - public void testInvokeRouteDetails() { - RoutesEndpoint endpoint = new RoutesEndpoint(locator); - Map results = new HashMap<>(); - for (Route route : locator.getRoutes()) { - results.put(route.getFullPath(), new RoutesEndpoint.RouteDetails(route)); - } - assertThat(endpoint.invokeRouteDetails()).isEqualTo(results); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ServletPathZuulProxyApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ServletPathZuulProxyApplicationTests.java deleted file mode 100644 index 77ad24e33..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ServletPathZuulProxyApplicationTests.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import java.net.URI; - -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.RequestEntity; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest( - classes = ServletPathZuulProxyApplicationTests.ServletPathZuulProxyApplication.class, - webEnvironment = RANDOM_PORT, - properties = { "server.servlet.context-path: /app" }) -@DirtiesContext -public class ServletPathZuulProxyApplicationTests { - - @LocalServerPort - private int port; - - @Autowired - private TestRestTemplate testRestTemplate; - - @Autowired - private DiscoveryClientRouteLocator routes; - - @Autowired - private RoutesEndpoint endpoint; - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - @Ignore // FIXME: 2.1.0 - public void getOnSelfViaSimpleHostRoutingFilter() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app/local"); - this.endpoint.reset(); - ResponseEntity result = testRestTemplate.exchange("/app/self/1", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Gotten 1!"); - } - - @Test - @Ignore // FIXME: 2.1.0 - public void optionsOnRawEndpoint() throws Exception { - ResponseEntity result = testRestTemplate.exchange( - RequestEntity.options(new URI("/app/local/1")) - .header("Origin", "http://localhost:9000") - .header("Access-Control-Request-Method", "GET").build(), - String.class); - HttpHeaders httpHeaders = result.getHeaders(); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(httpHeaders.getFirst("Access-Control-Allow-Origin")).isEqualTo("*"); - } - - @Test - @Ignore // FIXME: 2.1.0 - public void optionsOnSelf() throws Exception { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app/local"); - this.endpoint.reset(); - ResponseEntity result = testRestTemplate.exchange( - RequestEntity.options(new URI("/app/self/1")) - .header("Origin", "http://localhost:9000") - .header("Access-Control-Request-Method", "GET").build(), - String.class); - HttpHeaders httpHeaders = result.getHeaders(); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(httpHeaders.getFirst("Access-Control-Allow-Origin")).isEqualTo("*"); - } - - @Test - @Ignore // FIXME: 2.1.0 - public void contentOnRawEndpoint() throws Exception { - ResponseEntity result = testRestTemplate.exchange( - RequestEntity.get(new URI("/app/local/1")).build(), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Gotten 1!"); - } - - @Test - @Ignore // FIXME: 2.1.0 - public void stripPrefixFalseAppendsPath() { - this.routes.addRoute(new ZuulRoute("strip", "/strip/**", "strip", - "http://localhost:" + this.port + "/app/local", false, false, null)); - this.endpoint.reset(); - ResponseEntity result = testRestTemplate.exchange("/app/strip", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - // Prefix not stripped to it goes to /local/strip - assertThat(result.getBody()).isEqualTo("Gotten strip!"); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @Import(NoSecurityConfiguration.class) - static class ServletPathZuulProxyApplication { - - @RequestMapping(value = "/local/{id}", method = RequestMethod.GET) - @CrossOrigin(origins = "*") - public String get(@PathVariable String id) { - return "Gotten " + id + "!"; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulProxyApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulProxyApplicationTests.java deleted file mode 100644 index 8acbeec6b..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulProxyApplicationTests.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import java.net.URI; -import java.net.URISyntaxException; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest( - classes = SimpleZuulProxyApplicationTests.SimpleZuulProxyApplication.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "zuul.forceOriginalQueryStringEncoding: true", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class SimpleZuulProxyApplicationTests { - - @LocalServerPort - private int port; - - @Autowired - private TestRestTemplate testRestTemplate; - - @Autowired - private DiscoveryClientRouteLocator routes; - - @Autowired - private RoutesEndpoint endpoint; - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - - this.routes.addRoute("/foo/**", "http://localhost:" + this.port + "/bar"); - this.endpoint.reset(); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void getOnSelfViaSimpleHostRoutingFilter() { - ResponseEntity result = executeSimpleRequest(HttpMethod.GET); - - assertResponseCodeAndBody(result, "get bar"); - } - - @Test - public void postOnSelfViaSimpleHostRoutingFilter() { - ResponseEntity result = executeSimpleRequest(HttpMethod.POST); - - assertResponseCodeAndBody(result, "post bar"); - } - - @Test - public void putOnSelfViaSimpleHostRoutingFilter() { - ResponseEntity result = executeSimpleRequest(HttpMethod.PUT); - - assertResponseCodeAndBody(result, "put bar"); - } - - @Test - public void patchOnSelfViaSimpleHostRoutingFilter() { - ResponseEntity result = executeSimpleRequest(HttpMethod.PATCH); - - assertResponseCodeAndBody(result, "patch bar"); - } - - @Test - public void deleteOnSelfViaSimpleHostRoutingFilter() { - ResponseEntity result = executeSimpleRequest(HttpMethod.DELETE); - - assertResponseCodeAndBody(result, "delete bar"); - } - - @Test - public void getOnSelfWithComplexQueryParam() throws URISyntaxException { - String encodedQueryString = "foo=%7B%22project%22%3A%22stream%22%2C%22logger" - + "%22%3A%22javascript%22%2C%22platform%22%3A%22javascript%22%2C%22" - + "request%22%3A%7B%22url%22%3A%22https%3A%2F%2Ffoo%2Fadmin"; - ResponseEntity result = testRestTemplate.exchange( - new URI("/foo?" + encodedQueryString), HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo(encodedQueryString); - } - - private void assertResponseCodeAndBody(ResponseEntity result, - String expectedBody) { - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo(expectedBody); - } - - private ResponseEntity executeSimpleRequest(HttpMethod httpMethod) { - ResponseEntity result = testRestTemplate.exchange("/foo?id=bar", - httpMethod, new HttpEntity<>((Void) null), String.class); - return result; - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @Import(NoSecurityConfiguration.class) - static class SimpleZuulProxyApplication { - - @RequestMapping(value = "/bar", method = RequestMethod.GET) - public String get(@RequestParam String id) { - return "get " + id; - } - - @RequestMapping(value = "/bar", method = RequestMethod.GET, params = { "foo" }) - public String complexGet(@RequestParam String foo, HttpServletRequest request) { - return request.getQueryString(); - } - - @RequestMapping(value = "/bar", method = RequestMethod.POST) - public String post(@RequestParam String id) { - return "post " + id; - } - - @RequestMapping(value = "/bar", method = RequestMethod.PUT) - public String put(@RequestParam String id) { - return "put " + id; - } - - @RequestMapping(value = "/bar", method = RequestMethod.DELETE) - public String delete(@RequestParam String id) { - return "delete " + id; - } - - @RequestMapping(value = "/bar", method = RequestMethod.PATCH) - public String patch(@RequestParam String id) { - return "patch " + id; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulServerApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulServerApplicationTests.java deleted file mode 100644 index 6e67f25b1..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/SimpleZuulServerApplicationTests.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - properties = "zuul.routes[testclient]:/testing123/**") -@DirtiesContext -public class SimpleZuulServerApplicationTests { - - @LocalServerPort - private int port; - - @Autowired - private TestRestTemplate testRestTemplate; - - @Autowired - private RouteLocator routes; - - private String getRoute(String path) { - return this.routes.getMatchingRoute(path).getLocation(); - } - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void bindRoute() { - assertThat(getRoute("/testing123/**")).isNotNull(); - } - - @Test - public void getOnSelf() { - ResponseEntity result = testRestTemplate.exchange("/", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Hello world"); - } - - @Test - public void getOnSelfViaFilter() { - ResponseEntity result = testRestTemplate.exchange("/testing123/1", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @SpringBootConfiguration - @EnableAutoConfiguration - @RestController - @EnableZuulServer - @Import(NoSecurityConfiguration.class) - static class SimpleZuulServerApplication { - - @RequestMapping("/local") - public String local() { - return "Hello local"; - } - - @RequestMapping("/") - public String home() { - return "Hello world"; - } - - @Bean - public ZuulFilter sampleFilter() { - return new ZuulFilter() { - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public Object run() { - return null; - } - - @Override - public int filterOrder() { - return 0; - } - }; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializerTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializerTests.java deleted file mode 100644 index b8d945212..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulFilterInitializerTests.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.Map; - -import com.netflix.zuul.FilterLoader; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.filters.FilterRegistry; -import com.netflix.zuul.monitoring.CounterFactory; -import com.netflix.zuul.monitoring.TracerFactory; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.util.ReflectionUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -public class ZuulFilterInitializerTests { - - private Map filters; - - private CounterFactory counterFactory; - - private TracerFactory tracerFactory; - - private FilterLoader filterLoader; - - private FilterRegistry filterRegistry; - - private ZuulFilterInitializer initializer; - - @Before - public void init() { - filters = getFilters(); - counterFactory = mock(CounterFactory.class); - tracerFactory = mock(TracerFactory.class); - filterLoader = new FilterLoader(); - filterRegistry = getFilterRegistry(); - initializer = new ZuulFilterInitializer(filters, counterFactory, tracerFactory, - filterLoader, filterRegistry); - - initializer.contextInitialized(); - } - - @Test - public void shouldSetupOnContextInitializedEvent() { - - assertThat(TracerFactory.instance()).isEqualTo(tracerFactory); - assertThat(CounterFactory.instance()).isEqualTo(counterFactory); - assertThat(filterRegistry.getAllFilters()).containsAll(filters.values()); - - initializer.contextDestroyed(); - } - - @Test - public void shouldCleanupOnContextDestroyed() { - - initializer.contextDestroyed(); - - assertThat(ReflectionTestUtils.getField(TracerFactory.class, "INSTANCE")) - .isNull(); - assertThat(ReflectionTestUtils.getField(CounterFactory.class, "INSTANCE")) - .isNull(); - assertThat(filterRegistry.getAllFilters()).isEmpty(); - assertThat(getHashFiltersByType().isEmpty()).isTrue(); - } - - private Map getHashFiltersByType() { - Field field = ReflectionUtils.findField(FilterLoader.class, "hashFiltersByType"); - ReflectionUtils.makeAccessible(field); - return (Map) ReflectionUtils.getField(field, FilterLoader.getInstance()); - } - - private Map getFilters() { - Map filters = new HashMap<>(); - filters.put("key1", mock(ZuulFilter.class)); - filters.put("key2", mock(ZuulFilter.class)); - return filters; - } - - private FilterRegistry getFilterRegistry() { - try { - Constructor constructor = FilterRegistry.class - .getDeclaredConstructor(new Class[0]); - constructor.setAccessible(true); - return constructor.newInstance(new Object[0]); - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyApplicationTests.java deleted file mode 100644 index 33ecf2deb..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyApplicationTests.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.servlet.config.annotation.CorsRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = ZuulProxyApplicationTests.ZuulProxyApplication.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - properties = { "zuul.routes.simplezpat:/simplezpat/**", - "logging.level.org.apache.http: DEBUG" }) -@DirtiesContext -public class ZuulProxyApplicationTests { - - @LocalServerPort - private int port; - - @Autowired - private TestRestTemplate testRestTemplate; - - @Before - public void setTestRequestcontext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void getHasCorrectTransferEncoding() { - ResponseEntity result = testRestTemplate.getForEntity(url(), - String.class); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("missing"); - } - - @Test - public void postHasCorrectTransferEncoding() { - ResponseEntity result = testRestTemplate.postForEntity(url(), - new HttpEntity<>("hello"), String.class); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("missing"); - } - - @Test - public void preflightRequestSucceedsForGetRequest() { - MultiValueMap headers = new LinkedMultiValueMap<>(); - headers.put("Origin", singletonList("https://hello.com")); - headers.put("Access-Control-Request-Method", singletonList("GET")); - ResponseEntity result = testRestTemplate.exchange(url(), HttpMethod.OPTIONS, - new HttpEntity<>(headers), Void.class); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void preflightRequestIsForbiddenForUnsupportedMethod() { - MultiValueMap headers = new LinkedMultiValueMap<>(); - headers.put("Origin", singletonList("https://hello.com")); - headers.put("Access-Control-Request-Method", singletonList("PUT")); - ResponseEntity result = testRestTemplate.exchange(url(), HttpMethod.OPTIONS, - new HttpEntity<>(headers), Void.class); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); - } - - @Test - public void preflightRequestIsForbiddenForUnsupportedorigin() { - MultiValueMap headers = new LinkedMultiValueMap<>(); - headers.put("Origin", singletonList("http://unknown-origin.com")); - headers.put("Access-Control-Request-Method", singletonList("GET")); - ResponseEntity result = testRestTemplate.exchange(url(), HttpMethod.OPTIONS, - new HttpEntity<>(headers), Void.class); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); - } - - private String url() { - return "http://localhost:" + this.port + "/simplezpat/transferencoding"; - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @RibbonClient(name = "simplezpat", - configuration = TestRibbonClientConfiguration.class) - @Import(NoSecurityConfiguration.class) - static class ZuulProxyApplication { - - @RequestMapping(value = "/transferencoding", method = RequestMethod.GET) - public String get(@RequestHeader(name = "Transfer-Encoding", - required = false) String transferEncoding) { - if (transferEncoding == null) { - return "missing"; - } - return transferEncoding; - } - - @RequestMapping(value = "/transferencoding", method = RequestMethod.POST) - public String post( - @RequestHeader(name = "Transfer-Encoding", - required = false) String transferEncoding, - @RequestBody String hello) { - if (transferEncoding == null) { - return "missing"; - } - return transferEncoding; - } - - @Bean - public WebMvcConfigurer corsConfigurer() { - return new WebMvcConfigurer() { - public void addCorsMappings(CorsRegistry registry) { - registry.addMapping("/simplezpat/**") - .allowedOrigins("https://hello.com") - .allowedMethods("GET", "POST") - .allowedHeaders("Authorization"); - } - }; - } - - } - - // Load balancer with fixed server list for "simplezpat" pointing to localhost - @Configuration(proxyBeanMethods = false) - static class TestRibbonClientConfiguration { - - @LocalServerPort - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfigurationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfigurationTests.java deleted file mode 100644 index d3a9b4c3f..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfigurationTests.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.zuul; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.filters.CompositeRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * To test the auto-configuration of Zuul Proxy - * - * @author Biju Kunjummen - * - */ - -@RunWith(SpringRunner.class) -@SpringBootTest -@DirtiesContext -public class ZuulProxyAutoConfigurationTests { - - @Autowired - private RouteLocator routeLocator; - - @Autowired(required = false) - private RibbonRoutingFilter ribbonRoutingFilter; - - @Test - public void testAutoConfiguredBeans() { - assertThat(routeLocator).isInstanceOf(CompositeRouteLocator.class); - assertThat(this.ribbonRoutingFilter).isNotNull(); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @EnableZuulProxy - static class TestConfig { - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfigurationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfigurationTests.java deleted file mode 100644 index 43a97e23d..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfigurationTests.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul; - -import org.junit.Test; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandFactory; -import org.springframework.context.annotation.Bean; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * @author Spencer Gibb - * @author Biju Kunjummen - */ -public class ZuulProxyConfigurationTests { - - @Test - public void testDefaultsToApacheHttpClient() { - testClient(HttpClientRibbonCommandFactory.class, null); - testClient(HttpClientRibbonCommandFactory.class, - "ribbon.httpclient.enabled=true"); - } - - @Test - public void testEnableRestClient() { - testClient(RestClientRibbonCommandFactory.class, - "ribbon.restclient.enabled=true"); - } - - @Test - public void testEnableOkHttpClient() { - testClient(OkHttpRibbonCommandFactory.class, "ribbon.okhttp.enabled=true"); - } - - void testClient(Class clientType, String property) { - if (property == null) { - property = "aaa=bbb"; - } - new WebApplicationContextRunner().withUserConfiguration(TestConfig.class) - .withPropertyValues(property) - .run(c -> assertThat(c).hasSingleBean(clientType)); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableZuulProxy - static class TestConfig { - - @Bean - SpringClientFactory springClientFactory() { - return mock(SpringClientFactory.class); - } - - @Bean - DiscoveryClient discoveryClient() { - return mock(DiscoveryClient.class); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulServerAutoConfigurationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulServerAutoConfigurationTests.java deleted file mode 100644 index a61bbf53c..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/ZuulServerAutoConfigurationTests.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.zuul; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.filters.CompositeRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * To test the auto-configuration of Zuul Proxy - * - * @author Biju Kunjummen - * - */ - -@RunWith(SpringRunner.class) -@SpringBootTest -public class ZuulServerAutoConfigurationTests { - - @Autowired - private RouteLocator routeLocator; - - @Autowired(required = false) - private RibbonRoutingFilter ribbonRoutingFilter; - - @Test - public void testAutoConfiguredBeans() { - assertThat(routeLocator).isInstanceOf(CompositeRouteLocator.class); - assertThat(ribbonRoutingFilter).isNull(); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @EnableZuulServer - static class TestConfig { - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CompositeRouteLocatorTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CompositeRouteLocatorTests.java deleted file mode 100644 index dcbf6db4c..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CompositeRouteLocatorTests.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.zuul.filters; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.junit.Test; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -/** - * @author Johannes Edmeier - */ -public class CompositeRouteLocatorTests { - - private CompositeRouteLocator locator; - - public CompositeRouteLocatorTests() { - List locators = new ArrayList<>(); - locators.add( - new TestRouteLocator(asList("ign1"), asList(createRoute("1", "/pathA")))); - locators.add(new TestRouteLocator(asList("ign1", "ign2"), - asList(createRoute("2", "/pathA"), createRoute("2", "/pathB")))); - this.locator = new CompositeRouteLocator(locators); - } - - @Test - public void test_getIgnoredPaths() { - assertThat(locator.getIgnoredPaths()).contains("ign1", "ign2"); - - } - - @Test - public void test_getRoutes() { - assertThat(locator.getRoutes()).contains(createRoute("1", "/pathA"), - createRoute("2", "/pathB")); - } - - @Test - public void test_getMatchingRoute() { - assertThat(locator.getMatchingRoute("/pathA")).isNotNull(); - assertThat(locator.getMatchingRoute("/pathA").getId()).isEqualTo("1"); - assertThat(locator.getMatchingRoute("/pathB").getId()) - .as("Locator 1 should take precedence").isEqualTo("2"); - assertThat(locator.getMatchingRoute("/pathNot")).isNull(); - } - - @Test - public void test_refresh() { - RefreshableRouteLocator mock = mock(RefreshableRouteLocator.class); - new CompositeRouteLocator(asList(mock)).refresh(); - verify(mock).refresh(); - } - - private Route createRoute(String id, String path) { - return new Route(id, path, null, null, false, Collections.emptySet()); - } - - private static class TestRouteLocator implements RouteLocator { - - private Collection ignoredPaths; - - private List routes; - - TestRouteLocator(Collection ignoredPaths, List routes) { - this.ignoredPaths = ignoredPaths; - this.routes = routes; - } - - @Override - public Collection getIgnoredPaths() { - return this.ignoredPaths; - } - - @Override - public List getRoutes() { - return this.routes; - } - - @Override - public Route getMatchingRoute(String path) { - for (Route route : routes) { - if (path.startsWith(route.getPath())) { - return route; - } - } - return null; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CustomHostRoutingFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CustomHostRoutingFilterTests.java deleted file mode 100644 index 87597f920..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/CustomHostRoutingFilterTests.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters; - -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import com.netflix.zuul.context.RequestContext; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.impl.client.BasicCookieStore; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.HttpClients; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; -import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientFactory; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.RoutesEndpoint; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.RestTemplate; - -import static junit.framework.TestCase.assertFalse; -import static junit.framework.TestCase.assertTrue; -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest( - classes = CustomHostRoutingFilterTests.SampleCustomZuulProxyApplication.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - properties = { "server.servlet.context-path: /app", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class CustomHostRoutingFilterTests { - - @LocalServerPort - private int port; - - @Autowired - private DiscoveryClientRouteLocator routes; - - @Autowired - private RoutesEndpoint endpoint; - - @Before - public void setTestRequestcontext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void getOnSelfViaCustomHostRoutingFilter() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/app/self/get/1", String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Get 1"); - } - - @Test - public void postOnSelfViaCustomHostRoutingFilter() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); - this.endpoint.reset(); - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add("id", "2"); - ResponseEntity result = new TestRestTemplate().postForEntity( - "http://localhost:" + this.port + "/app/self/post", params, String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Post 2"); - } - - @Test - public void putOnSelfViaCustomHostRoutingFilter() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/app/self/put/3", HttpMethod.PUT, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Put 3"); - } - - @Test - public void patchOnSelfViaCustomHostRoutingFilter() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); - this.endpoint.reset(); - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add("patch", "5"); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/app/self/patch/4", HttpMethod.PATCH, - new HttpEntity<>(params), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Patch 45"); - } - - @Test - public void getOnSelfIgnoredHeaders() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().getForEntity( - "http://localhost:" + this.port + "/app/self/get/1", String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertTrue(result.getHeaders().containsKey("X-NotIgnored")); - assertFalse(result.getHeaders().containsKey("X-Ignored")); - } - - @Test - public void getOnSelfWithSessionCookie() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/app"); - this.endpoint.reset(); - - RestTemplate restTemplate = new RestTemplate(); - - ResponseEntity result1 = restTemplate.getForEntity( - "http://localhost:" + this.port + "/app/self/cookie/1", String.class); - - ResponseEntity result2 = restTemplate.getForEntity( - "http://localhost:" + this.port + "/app/self/cookie/2", String.class); - - assertThat(result1.getBody()).isEqualTo("SetCookie 1"); - assertThat(result2.getBody()).isEqualTo("GetCookie 1"); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @Import(NoSecurityConfiguration.class) - static class SampleCustomZuulProxyApplication { - - @RequestMapping(value = "/get/{id}", method = RequestMethod.GET) - public String get(@PathVariable String id, HttpServletResponse response) { - response.setHeader("X-Ignored", "foo"); - response.setHeader("X-NotIgnored", "bar"); - return "Get " + id; - } - - @RequestMapping(value = "/cookie/{id}", method = RequestMethod.GET) - public String getWithCookie(@PathVariable String id, HttpSession session) { - Object testCookie = session.getAttribute("testCookie"); - if (testCookie != null) { - return "GetCookie " + testCookie; - } - session.setAttribute("testCookie", id); - return "SetCookie " + id; - } - - @RequestMapping(value = "/post", method = RequestMethod.POST) - public String post(@RequestParam("id") String id) { - return "Post " + id; - } - - @RequestMapping(value = "/put/{id}", method = RequestMethod.PUT) - public String put(@PathVariable String id) { - return "Put " + id; - } - - @RequestMapping(value = "/patch/{id}", method = RequestMethod.PATCH) - public String patch(@PathVariable String id, - @RequestParam("patch") String patch) { - return "Patch " + id + patch; - } - - public static void main(String[] args) { - SpringApplication.run(SampleCustomZuulProxyApplication.class, args); - } - - @Configuration(proxyBeanMethods = false) - @EnableZuulProxy - protected static class CustomZuulProxyConfig { - - @Bean - public ApacheHttpClientFactory customHttpClientFactory( - HttpClientBuilder builder) { - return new CustomApacheHttpClientFactory(builder); - } - - @Bean - public CloseableHttpClient closeableClient() { - return HttpClients.custom().setDefaultCookieStore(new BasicCookieStore()) - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.DEFAULT).build()) - .build(); - } - - @Bean - public SimpleHostRoutingFilter simpleHostRoutingFilter( - ProxyRequestHelper helper, ZuulProperties zuulProperties, - CloseableHttpClient httpClient) { - return new CustomHostRoutingFilter(helper, zuulProperties, httpClient); - } - - private class CustomHostRoutingFilter extends SimpleHostRoutingFilter { - - CustomHostRoutingFilter(ProxyRequestHelper helper, - ZuulProperties zuulProperties, CloseableHttpClient httpClient) { - super(helper, zuulProperties, httpClient); - } - - @Override - public Object run() { - super.addIgnoredHeaders("X-Ignored"); - return super.run(); - } - - } - - private class CustomApacheHttpClientFactory - extends DefaultApacheHttpClientFactory { - - CustomApacheHttpClientFactory(HttpClientBuilder builder) { - super(builder); - } - - } - - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelperTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelperTests.java deleted file mode 100644 index 9615a95ff..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelperTests.java +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters; - -import java.io.IOException; -import java.util.List; - -import com.netflix.util.Pair; -import com.netflix.zuul.context.RequestContext; -import org.assertj.core.api.Assertions; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; - -import org.springframework.boot.actuate.trace.http.HttpTrace; -import org.springframework.boot.actuate.trace.http.HttpTraceRepository; -import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_URI_KEY; - -/** - * @author Spencer Gibb - */ -public class ProxyRequestHelperTests { - - @Mock - private HttpTraceRepository traceRepository; - - @Before - public void init() { - initMocks(this); - } - - @Before - public void setTestRequestcontext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void debug() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - request.setContent("{}".getBytes()); - request.addHeader("singleName", "singleValue"); - request.addHeader("multiName", "multiValue1"); - request.addHeader("multiName", "multiValue2"); - RequestContext.getCurrentContext().setRequest(request); - - TraceProxyRequestHelper helper = new TraceProxyRequestHelper( - new ZuulProperties()); - this.traceRepository = new InMemoryHttpTraceRepository(); - helper.setTraces(this.traceRepository); - - MultiValueMap headers = helper.buildZuulRequestHeaders(request); - - helper.debug("POST", "https://example.com", headers, new LinkedMultiValueMap<>(), - request.getInputStream()); - HttpTrace actual = this.traceRepository.findAll().get(0); - Assertions.assertThat(actual.getRequest().getHeaders()).containsKeys("singleName", - "multiName"); - } - - @Test - public void shouldDebugBodyDisabled() throws Exception { - RequestContext context = RequestContext.getCurrentContext(); - - ZuulProperties zuulProperties = new ZuulProperties(); - zuulProperties.setTraceRequestBody(false); - ProxyRequestHelper helper = new ProxyRequestHelper(zuulProperties); - - assertThat(helper.shouldDebugBody(context)).as("shouldDebugBody wrong").isFalse(); - } - - @Test - public void shouldDebugBodyChunked() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - RequestContext context = RequestContext.getCurrentContext(); - context.setChunkedRequestBody(); - context.setRequest(request); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - assertThat(helper.shouldDebugBody(context)).as("shouldDebugBody wrong").isFalse(); - } - - @Test - public void shouldDebugBodyServlet() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - RequestContext context = RequestContext.getCurrentContext(); - context.setZuulEngineRan(); - context.setRequest(request); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - assertThat(helper.shouldDebugBody(context)).as("shouldDebugBody wrong").isFalse(); - } - - @Test - public void shouldDebugBodyNullContentType() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - request.setContentType(null); - RequestContext context = RequestContext.getCurrentContext(); - context.setRequest(request); - - ZuulProperties zuulProperties = new ZuulProperties(); - zuulProperties.setTraceRequestBody(true); - ProxyRequestHelper helper = new ProxyRequestHelper(zuulProperties); - - assertThat(helper.shouldDebugBody(context)).as("shouldDebugBody wrong").isTrue(); - } - - @Test - public void shouldDebugBodyNullRequest() throws Exception { - RequestContext context = RequestContext.getCurrentContext(); - - ZuulProperties zuulProperties = new ZuulProperties(); - zuulProperties.setTraceRequestBody(true); - ProxyRequestHelper helper = new ProxyRequestHelper(zuulProperties); - - assertThat(helper.shouldDebugBody(context)).as("shouldDebugBody wrong").isTrue(); - } - - @Test - public void shouldDebugBodyNotMultitypeContentType() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - request.setContentType(MediaType.APPLICATION_JSON_VALUE); - RequestContext context = RequestContext.getCurrentContext(); - context.setRequest(request); - - ZuulProperties zuulProperties = new ZuulProperties(); - zuulProperties.setTraceRequestBody(true); - ProxyRequestHelper helper = new ProxyRequestHelper(zuulProperties); - - assertThat(helper.shouldDebugBody(context)).as("shouldDebugBody wrong").isTrue(); - } - - @Test - public void shouldDebugBodyMultitypeContentType() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - request.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE); - RequestContext context = RequestContext.getCurrentContext(); - context.setRequest(request); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - assertThat(helper.shouldDebugBody(context)).as("shouldDebugBody wrong").isFalse(); - } - - @Test - public void buildZuulRequestHeadersWork() { - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/"); - request.addHeader("singleName", "singleValue"); - request.addHeader("multiName", "multiValue1"); - request.addHeader("multiName", "multiValue2"); - - TraceProxyRequestHelper helper = new TraceProxyRequestHelper( - new ZuulProperties()); - helper.setTraces(this.traceRepository); - - MultiValueMap headers = helper.buildZuulRequestHeaders(request); - List singleName = headers.get("singleName"); - assertThat(singleName).isNotNull(); - assertThat(singleName.size()).isEqualTo(1); - - List multiName = headers.get("multiName"); - assertThat(multiName).isNotNull(); - assertThat(multiName.size()).isEqualTo(2); - - List missingName = headers.get("missingName"); - assertThat(missingName).isNull(); - - } - - @Test - public void buildZuulRequestHeadersRequestsGzipAndOnlyGzip() { - MockHttpServletRequest request = new MockHttpServletRequest("", "/"); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - MultiValueMap headers = helper.buildZuulRequestHeaders(request); - - List acceptEncodings = headers.get("accept-encoding"); - assertThat(acceptEncodings).hasSize(1); - assertThat(acceptEncodings).containsExactly("gzip"); - } - - @Test - public void buildZuulRequestHeadersRequestsContentEncoding() { - MockHttpServletRequest request = new MockHttpServletRequest("", "/"); - request.addHeader("content-encoding", "identity"); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - MultiValueMap headers = helper.buildZuulRequestHeaders(request); - - List contentEncodings = headers.get("content-encoding"); - assertThat(contentEncodings).hasSize(1); - assertThat(contentEncodings).containsExactly("identity"); - } - - @Test - public void buildZuulRequestHeadersRequestsAcceptEncoding() { - MockHttpServletRequest request = new MockHttpServletRequest("", "/"); - request.addHeader("accept-encoding", "identity"); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - MultiValueMap headers = helper.buildZuulRequestHeaders(request); - - List acceptEncodings = headers.get("accept-encoding"); - assertThat(acceptEncodings).hasSize(1); - assertThat(acceptEncodings).containsExactly("identity"); - } - - @Test - public void addHostHeader() { - MockHttpServletRequest request = new MockHttpServletRequest("", "/"); - request.addHeader("host", "foo.com"); - - ZuulProperties zuulProperties = new ZuulProperties(); - zuulProperties.setAddHostHeader(true); - ProxyRequestHelper helper = new ProxyRequestHelper(zuulProperties); - - MultiValueMap headers = helper.buildZuulRequestHeaders(request); - - List acceptEncodings = headers.get("host"); - assertThat(acceptEncodings).hasSize(1); - assertThat(acceptEncodings).containsExactly("foo.com"); - - zuulProperties.setAddHostHeader(false); - helper = new ProxyRequestHelper(zuulProperties); - headers = helper.buildZuulRequestHeaders(request); - - acceptEncodings = headers.get("host"); - assertThat(acceptEncodings).isNull(); - } - - @Test - public void setResponseLowercase() throws IOException { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - RequestContext context = RequestContext.getCurrentContext(); - context.setRequest(request); - context.setResponse(response); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - MultiValueMap headers = new HttpHeaders(); - headers.add(HttpHeaders.CONTENT_ENCODING.toLowerCase(), "gzip"); - - helper.setResponse(200, request.getInputStream(), headers); - assertThat(context.getResponseGZipped()).isTrue(); - } - - @Test - public void setResponseShouldSetOriginResponseHeaders() throws IOException { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - RequestContext context = RequestContext.getCurrentContext(); - context.setRequest(request); - context.setResponse(response); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - MultiValueMap headers = new HttpHeaders(); - headers.add(HttpHeaders.CONTENT_TYPE, "text/plain"); - headers.add("some-header", "some-value"); - - helper.setResponse(200, request.getInputStream(), headers); - assertThat(context.getOriginResponseHeaders()).contains( - new Pair<>(HttpHeaders.CONTENT_TYPE, "text/plain"), - new Pair<>("some-header", "some-value")); - } - - @Test - public void setResponseUppercase() throws IOException { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - RequestContext context = RequestContext.getCurrentContext(); - context.setRequest(request); - context.setResponse(response); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - MultiValueMap headers = new HttpHeaders(); - headers.add(HttpHeaders.CONTENT_ENCODING, "gzip"); - - helper.setResponse(200, request.getInputStream(), headers); - assertThat(context.getResponseGZipped()).isTrue(); - } - - @Test - public void getQueryString() { - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add("a", "1234"); - params.add("b", "5678"); - - String queryString = new ProxyRequestHelper(new ZuulProperties()) - .getQueryString(params); - - assertThat(queryString).isEqualTo("?a=1234&b=5678"); - } - - @Test - public void getQueryStringWithEmptyParam() { - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add("wsdl", ""); - - String queryString = new ProxyRequestHelper(new ZuulProperties()) - .getQueryString(params); - - assertThat(queryString).isEqualTo("?wsdl"); - } - - @Test - public void getQueryStringEncoded() { - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add("foo", "weird#chars"); - - String queryString = new ProxyRequestHelper(new ZuulProperties()) - .getQueryString(params); - - assertThat(queryString).isEqualTo("?foo=weird%23chars"); - } - - @Test - public void getQueryParamNameWithColon() { - MultiValueMap params = new LinkedMultiValueMap<>(); - params.add("foo:bar", "baz"); - params.add("foobar", "bam"); - params.add("foo\fbar", "bat"); // form feed is the colon replacement char - - String queryString = new ProxyRequestHelper(new ZuulProperties()) - .getQueryString(params); - - assertThat(queryString).isEqualTo("?foo:bar=baz&foobar=bam&foo%0Cbar=bat"); - } - - @Test - public void buildZuulRequestURIWithUTF8() throws Exception { - String encodedURI = "/resource/esp%C3%A9cial-char"; - String decodedURI = "/resource/espécial-char"; - - MockHttpServletRequest request = new MockHttpServletRequest("GET", encodedURI); - request.setCharacterEncoding("UTF-8"); - final RequestContext context = RequestContext.getCurrentContext(); - context.setRequest(request); - context.set(REQUEST_URI_KEY, decodedURI); - - final String requestURI = new ProxyRequestHelper(new ZuulProperties()) - .buildZuulRequestURI(request); - assertThat(requestURI).isEqualTo(encodedURI); - } - - @Test - public void buildZuulRequestURIWithDefaultEncoding() { - String encodedURI = "/resource/esp%E9cial-char"; - String decodedURI = "/resource/espécial-char"; - - MockHttpServletRequest request = new MockHttpServletRequest("GET", encodedURI); - final RequestContext context = RequestContext.getCurrentContext(); - context.setRequest(request); - context.set(REQUEST_URI_KEY, decodedURI); - - final String requestURI = new ProxyRequestHelper(new ZuulProperties()) - .buildZuulRequestURI(request); - assertThat(requestURI).isEqualTo(encodedURI); - } - - @Test - public void getUTF8Url() { - String requestURI = "/oléדרעק"; - String encodedRequestURI = "/ol%C3%A9%D7%93%D7%A8%D7%A2%D7%A7"; - MockHttpServletRequest request = new MockHttpServletRequest("GET", requestURI); - request.setCharacterEncoding("UTF-8"); - - RequestContext context = RequestContext.getCurrentContext(); - context.set(REQUEST_URI_KEY, requestURI); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - String uri = helper.buildZuulRequestURI(request); - - assertThat(uri).isEqualTo(encodedRequestURI); - } - - @Test - public void getDefaultEncodingUrl() { - String requestURI = "/oléדרעק"; - String encodedRequestURI = "/ol%E9%3F%3F%3F%3F"; - MockHttpServletRequest request = new MockHttpServletRequest("GET", requestURI); - - RequestContext context = RequestContext.getCurrentContext(); - context.set(REQUEST_URI_KEY, requestURI); - - ProxyRequestHelper helper = new ProxyRequestHelper(new ZuulProperties()); - - String uri = helper.buildZuulRequestURI(request); - - assertThat(uri).isEqualTo(encodedRequestURI); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocatorTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocatorTests.java deleted file mode 100644 index 496d040d7..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/SimpleRouteLocatorTests.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters; - -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -import org.springframework.boot.test.system.OutputCaptureRule; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.containsString; - -/** - * @author Tom Cawley - */ -public class SimpleRouteLocatorTests { - - @Rule - public OutputCaptureRule output = new OutputCaptureRule(); - - private ZuulProperties properties; - - public SimpleRouteLocatorTests() { - } - - @Before - public void init() { - properties = new ZuulProperties(); - } - - @Test - public void test_getRoutesDefaultRouteAcceptor() { - RouteLocator locator = new SimpleRouteLocator("/", this.properties); - this.properties.getRoutes().clear(); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo")); - - assertThat(locator.getRoutes()).contains(createRoute("foo", "/**", "/foo")); - } - - @Test - public void test_getRoutesFilterRouteAcceptor() { - RouteLocator locator = new FilteringRouteLocator("/", this.properties); - this.properties.getRoutes().clear(); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo")); - this.properties.getRoutes().put("bar", new ZuulRoute("/bar/**", "bar")); - - final List routes = locator.getRoutes(); - assertThat(routes).contains(createRoute("bar", "/**", "/bar")); - assertThat(routes).hasSize(1); - } - - @Test - public void testStripPrefix() { - properties.setPrefix("/test"); - properties.setStripPrefix(true); - RouteLocator locator = new FilteringRouteLocator("/", properties); - properties.getRoutes().put("testservicea", - new ZuulRoute("/testservicea/**", "testservicea")); - assertThat(locator.getRoutes().get(0).getFullPath()) - .isEqualTo("/test/testservicea/**"); - } - - @Test - public void testPrefix() { - properties.setPrefix("/test/"); - RouteLocator locator = new FilteringRouteLocator("/", properties); - properties.getRoutes().put("testservicea", - new ZuulRoute("/testservicea/**", "testservicea")); - assertThat(locator.getRoutes().get(0).getFullPath()) - .isEqualTo("/test/testservicea/**"); - } - - @Test - public void test_getMatchingRouteFilterRouteAcceptor() { - RouteLocator locator = new FilteringRouteLocator("/", this.properties); - this.properties.getRoutes().clear(); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo")); - this.properties.getRoutes().put("bar", new ZuulRoute("/bar/**", "bar")); - - assertThat(locator.getMatchingRoute("/foo/1")).isNull(); - assertThat(locator.getMatchingRoute("/bar/1")) - .isEqualTo(createRoute("bar", "/1", "/bar")); - } - - @Test - public void testBadRegex() { - this.properties.getRoutes().clear(); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo{}/**", "foo")); - RouteLocator locator = new FilteringRouteLocator("/", this.properties); - locator.getRoutes(); - - this.output.expect(containsString("Invalid route, ")); - - } - - private Route createRoute(String id, String path, String prefix) { - return new Route(id, path, id, prefix, false, null); - } - - private static class FilteringRouteLocator extends SimpleRouteLocator { - - FilteringRouteLocator(String servletPath, ZuulProperties properties) { - super(servletPath, properties); - } - - @Override - public List getRoutes() { - return super.getRoutes().stream().filter(this::acceptRoute) - .collect(Collectors.toList()); - } - - private boolean acceptRoute(Route route) { - return route != null && !(route.getId().equals("foo")); - } - - private boolean acceptRoute(ZuulRoute route) { - return route != null && !(route.getId().equals("foo")); - } - - protected Route getRoute(ZuulRoute route, String path) { - if (acceptRoute(route)) { - return super.getRoute(route, path); - } - return null; - } - - // For testing, expose as public so we can call getRoutesMap() directly. - @Override - public Map getRoutesMap() { - return super.getRoutesMap(); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/ZuulPropertiesTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/ZuulPropertiesTests.java deleted file mode 100644 index 4143130c7..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/ZuulPropertiesTests.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters; - -import java.util.Arrays; -import java.util.Collections; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * @author Mathias Düsterhöft - */ -public class ZuulPropertiesTests { - - private ZuulProperties zuul; - - @Before - public void setup() { - this.zuul = new ZuulProperties(); - } - - @After - public void teardown() { - this.zuul = null; - } - - @Test - public void defaultIgnoredHeaders() { - assertThat(this.zuul.isIgnoreSecurityHeaders()).isTrue(); - assertThat(this.zuul.getIgnoredHeaders()) - .containsAll(ZuulProperties.SECURITY_HEADERS); - } - - @Test - public void securityHeadersNotIgnored() { - zuul.setIgnoreSecurityHeaders(false); - - assertThat(this.zuul.getIgnoredHeaders().isEmpty()).isTrue(); - } - - @Test - public void addIgnoredHeaders() { - this.zuul.setIgnoredHeaders(Collections.singleton("x-foo")); - assertThat(this.zuul.getIgnoredHeaders().contains("x-foo")).isTrue(); - } - - @Test - public void defaultSensitiveHeaders() { - ZuulRoute route = new ZuulRoute("foo"); - this.zuul.getRoutes().put("foo", route); - assertThat(this.zuul.getRoutes().get("foo").getSensitiveHeaders().isEmpty()) - .isTrue(); - assertThat(this.zuul.getSensitiveHeaders() - .containsAll(Arrays.asList("Cookie", "Set-Cookie", "Authorization"))) - .isTrue(); - assertThat(route.isCustomSensitiveHeaders()).isFalse(); - } - - @Test - public void addSensitiveHeaders() { - this.zuul.setSensitiveHeaders(Collections.singleton("x-bar")); - ZuulRoute route = new ZuulRoute("foo"); - route.setSensitiveHeaders(Collections.singleton("x-foo")); - this.zuul.getRoutes().put("foo", route); - ZuulRoute foo = this.zuul.getRoutes().get("foo"); - assertThat(foo.getSensitiveHeaders().contains("x-foo")).isTrue(); - assertThat(foo.getSensitiveHeaders().contains("Cookie")).isFalse(); - assertThat(foo.isCustomSensitiveHeaders()).isTrue(); - assertThat(this.zuul.getSensitiveHeaders().contains("x-bar")).isTrue(); - assertThat(this.zuul.getSensitiveHeaders().contains("Cookie")).isFalse(); - } - - @Test - public void createWithSensitiveHeaders() { - this.zuul.setSensitiveHeaders(Collections.singleton("x-bar")); - ZuulRoute route = new ZuulRoute("foo", "/path", "foo", "/path", false, false, - Collections.singleton("x-foo")); - this.zuul.getRoutes().put("foo", route); - ZuulRoute foo = this.zuul.getRoutes().get("foo"); - assertThat(foo.getSensitiveHeaders().contains("x-foo")).isTrue(); - assertThat(foo.getSensitiveHeaders().contains("Cookie")).isFalse(); - assertThat(foo.isCustomSensitiveHeaders()).isTrue(); - assertThat(this.zuul.getSensitiveHeaders().contains("x-bar")).isTrue(); - assertThat(this.zuul.getSensitiveHeaders().contains("Cookie")).isFalse(); - } - - @Test - public void defaultHystrixThreadPool() { - assertThat(this.zuul.getThreadPool().isUseSeparateThreadPools()).isFalse(); - assertThat(this.zuul.getThreadPool().getThreadPoolKeyPrefix()).isEqualTo(""); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/DiscoveryClientRouteLocatorTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/DiscoveryClientRouteLocatorTests.java deleted file mode 100644 index b91065f20..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/DiscoveryClientRouteLocatorTests.java +++ /dev/null @@ -1,751 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.discovery; - -import java.net.URI; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; - -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; -import org.springframework.cloud.netflix.zuul.util.RequestUtils; -import org.springframework.core.env.ConfigurableEnvironment; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.MockitoAnnotations.initMocks; - -/** - * @author Spencer Gibb - * @author Dave Syer - */ -public class DiscoveryClientRouteLocatorTests { - - public static final String IGNOREDSERVICE = "ignoredservice"; - - public static final String IGNOREDPATTERN = "/foo/**"; - - public static final String ASERVICE = "aservice"; - - public static final String MYSERVICE = "myservice"; - - @Mock - private ConfigurableEnvironment env; - - @Mock - private DiscoveryClient discovery; - - private ZuulProperties properties = new ZuulProperties(); - - private RegexMapper regexMapper = new RegexMapper(); - - @Before - public void init() { - initMocks(this); - setTestRequestcontext(); // re-initialize Zuul context for each test - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void testGetMatchingPath() throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getId()).isEqualTo("foo"); - } - - @Test - public void testGetMatchingPathWithPrefix() throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - this.properties.setPrefix("/proxy"); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/1"); - } - - @Test - public void testGetMatchingPathWithServletPath() throws Exception { - setTestRequestcontext(); - RequestContext.getCurrentContext().set(RequestUtils.IS_DISPATCHERSERVLETREQUEST, - true); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/app", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/app/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/1"); - } - - @Test - public void testGetMatchingPathWithZuulServletPath() throws Exception { - RequestContext.getCurrentContext().setZuulEngineRan(); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/app", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/zuul/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/1"); - - } - - @Test - public void testGetMatchingPathWithNoPrefixStripping() throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.properties.setStripPrefix(false); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/proxy/foo/1"); - } - - @Test - public void testGetMatchingPathWithLocalPrefixStripping() throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo")); - this.properties.setStripPrefix(false); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/proxy/1"); - } - - @Test - public void testGetMatchingPathWithGlobalPrefixStripping() throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/foo/1"); - } - - @Test - public void testGetMatchingPathWithGlobalPrefixStrippingAndServletPath() - throws Exception { - RequestContext.getCurrentContext().set(RequestUtils.IS_DISPATCHERSERVLETREQUEST, - true); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/app", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/app/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/foo/1"); - } - - @Test - public void testGetMatchingPathWithGlobalPrefixStrippingAndZuulServletPath() - throws Exception { - RequestContext.getCurrentContext().setZuulEngineRan(); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put("foo", - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/zuul/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/foo/1"); - } - - @Test - public void testGetMatchingPathWithRoutePrefixStripping() throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - ZuulRoute zuulRoute = new ZuulRoute("/foo/**"); - zuulRoute.setStripPrefix(true); - this.properties.getRoutes().put("foo", zuulRoute); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/1"); - } - - @Test - public void testGetMatchingPathWithoutMatchingIgnoredPattern() throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN)); - this.properties.getRoutes().put("bar", new ZuulRoute("/bar/**")); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/bar/1"); - assertThat(route.getLocation()).isEqualTo("bar"); - assertThat(route.getId()).isEqualTo("bar"); - } - - @Test - public void testGetMatchingPathWithMatchingIgnoredPattern() throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/foo/1"); - assertThat(route).as("routes did not ignore " + IGNOREDPATTERN).isNull(); - } - - @Test - public void testGetMatchingPathWithMatchingIgnoredPatternWithPrefix() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - this.properties.setPrefix("/proxy"); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/1"); - } - - @Test - public void testGetMatchingPathWithMatchingIgnoredPatternWithServletPath() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/app", - this.discovery, this.properties); - this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/app/foo/1"); - assertThat(route).as("routes did not ignore " + IGNOREDPATTERN).isNull(); - } - - @Test - public void testGetMatchingPathWithoutMatchingIgnoredPatternWithNoPrefixStripping() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.properties.setStripPrefix(false); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/proxy/foo/1"); - } - - @Test - public void testGetMatchingPathWithMatchingIgnoredPatternWithNoPrefixStripping() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties - .setIgnoredPatterns(Collections.singleton("/proxy" + IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.properties.setStripPrefix(false); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route).as("routes did not ignore " + "/proxy" + IGNOREDPATTERN) - .isNull(); - } - - @Test - public void testGetMatchingPathWithoutMatchingIgnoredPatternWithLocalPrefixStripping() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo")); - this.properties.setStripPrefix(false); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/proxy/1"); - } - - @Test - public void testGetMatchingPathWithMatchingIgnoredPatternWithLocalPrefixStripping() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties - .setIgnoredPatterns(Collections.singleton("/proxy" + IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**", "foo")); - this.properties.setStripPrefix(false); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route).as("routes did not ignore " + "/proxy" + IGNOREDPATTERN) - .isNull(); - } - - @Test - public void testGetMatchingPathWithoutMatchingIgnoredPatternWithGlobalPrefixStripping() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route.getLocation()).isEqualTo("foo"); - assertThat(route.getPath()).isEqualTo("/foo/1"); - } - - @Test - public void testGetMatchingPathWithMatchingIgnoredPatternWithGlobalPrefixStripping() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties - .setIgnoredPatterns(Collections.singleton("/proxy" + IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.properties.setPrefix("/proxy"); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/proxy/foo/1"); - assertThat(route).as("routes did not ignore " + "/proxy" + IGNOREDPATTERN) - .isNull(); - } - - @Test - public void testGetMatchingPathWithMatchingIgnoredPatternWithRoutePrefixStripping() - throws Exception { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - ZuulRoute zuulRoute = new ZuulRoute("/foo/**"); - zuulRoute.setStripPrefix(true); - this.properties.setIgnoredPatterns(Collections.singleton(IGNOREDPATTERN)); - this.properties.getRoutes().put("foo", zuulRoute); - this.properties.init(); - routeLocator.getRoutes(); // force refresh - Route route = routeLocator.getMatchingRoute("/foo/1"); - assertThat(route).as("routes did not ignore " + IGNOREDPATTERN).isNull(); - } - - @Test - public void testGetRoutes() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/" + ASERVICE + "/**")); - this.properties.init(); - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertMapping(routesMap, ASERVICE); - } - - @Test - public void testGetRoutesWithMapping() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put(ASERVICE, - new ZuulRoute("/" + ASERVICE + "/**", ASERVICE)); - this.properties.setPrefix("/foo"); - - List routesMap = routeLocator.getRoutes(); - assertMapping(routesMap, ASERVICE, "foo/" + ASERVICE); - } - - @Test - public void testGetPhysicalRoutes() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put(ASERVICE, - new ZuulRoute("/" + ASERVICE + "/**", "http://" + ASERVICE)); - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertMapping(routesMap, "http://" + ASERVICE, ASERVICE); - } - - @Test - public void testGetDefaultRoute() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put(ASERVICE, new ZuulRoute("/**", ASERVICE)); - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertDefaultMapping(routesMap, ASERVICE); - } - - @Test - public void testGetDefaultPhysicalRoute() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.getRoutes().put(ASERVICE, - new ZuulRoute("/**", "http://" + ASERVICE)); - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertDefaultMapping(routesMap, "http://" + ASERVICE); - } - - @Test - public void testIgnoreRoutes() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredServices(Collections.singleton(IGNOREDSERVICE)); - given(this.discovery.getServices()) - .willReturn(Collections.singletonList(IGNOREDSERVICE)); - List routesMap = routeLocator.getRoutes(); - assertThat(getRoute(routesMap, getMapping(IGNOREDSERVICE))) - .as("routes did not ignore " + IGNOREDSERVICE).isNull(); - } - - @Test - public void testIgnoreRoutesWithPattern() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredServices(Collections.singleton("ignore*")); - given(this.discovery.getServices()) - .willReturn(Collections.singletonList(IGNOREDSERVICE)); - List routesMap = routeLocator.getRoutes(); - assertThat(getRoute(routesMap, getMapping(IGNOREDSERVICE))) - .as("routes did not ignore " + IGNOREDSERVICE).isNull(); - } - - @Test - public void testIgnoreAllRoutes() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredServices(Collections.singleton("*")); - given(this.discovery.getServices()) - .willReturn(Collections.singletonList(IGNOREDSERVICE)); - List routesMap = routeLocator.getRoutes(); - assertThat(getRoute(routesMap, getMapping(IGNOREDSERVICE))) - .as("routes did not ignore " + IGNOREDSERVICE).isNull(); - } - - @Test - public void testIgnoredRouteIncludedIfConfiguredAndDiscovered() { - this.properties.getRoutes().put("foo", new ZuulRoute("/foo/**")); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredServices(Collections.singleton("*")); - given(this.discovery.getServices()).willReturn(Collections.singletonList("foo")); - List routesMap = routeLocator.getRoutes(); - assertThat(getRoute(routesMap, "/foo/**")).as("routes ignored foo").isNotNull(); - } - - @Test - public void testIgnoredRoutePropertiesRemain() { - ZuulRoute route = new ZuulRoute("/foo/**"); - route.setStripPrefix(true); - route.setRetryable(Boolean.TRUE); - this.properties.getRoutes().put("foo", route); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredServices(Collections.singleton("*")); - given(this.discovery.getServices()).willReturn(Collections.singletonList("foo")); - LinkedHashMap routes = routeLocator.locateRoutes(); - ZuulRoute actual = routes.get("/foo/**"); - assertThat(actual).as("routes ignored foo").isNotNull(); - assertThat(actual.isStripPrefix()).as("stripPrefix is wrong").isTrue(); - assertThat(actual.getRetryable()).as("retryable is wrong") - .isEqualTo(Boolean.TRUE); - } - - @Test - public void testIgnoredRouteNonServiceIdPathRemains() { - // This is how you setup a route defined like zuul.proxy.route.foo=/** - ZuulRoute route = new ZuulRoute("/**", "foo"); - route.setId("foo"); - - this.properties.getRoutes().put("foo", route); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredServices(Collections.singleton("*")); - given(this.discovery.getServices()).willReturn(Collections.singletonList("foo")); - LinkedHashMap routes = routeLocator.locateRoutes(); - ZuulRoute actual = routes.get("/**"); - assertThat(actual).as("routes ignored foo").isNotNull(); - assertThat(actual.getId()).as("id is wrong").isEqualTo("foo"); - assertThat(actual.getServiceId()).as("location is wrong").isEqualTo("foo"); - assertThat(actual.getPath()).as("path is wrong").isEqualTo("/**"); - } - - @Test - public void testIgnoredRouteIncludedIfConfiguredAndNotDiscovered() { - this.properties.getRoutes().put("foo", - new ZuulRoute("/foo/**", "http://www.foo.com/")); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - this.properties.setIgnoredServices(Collections.singleton("*")); - given(this.discovery.getServices()).willReturn(Collections.singletonList("bar")); - List routesMap = routeLocator.getRoutes(); - assertThat(getRoute(routesMap, getMapping("foo"))).as("routes ignored foo") - .isNotNull(); - } - - @Test - public void testAutoRoutes() { - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - given(this.discovery.getServices()) - .willReturn(Collections.singletonList(MYSERVICE)); - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertMapping(routesMap, MYSERVICE); - } - - @Test - public void testAutoRoutesCanBeOverridden() { - ZuulRoute route = new ZuulRoute("/" + MYSERVICE + "/**", - "https://example.com/" + MYSERVICE); - this.properties.getRoutes().put(MYSERVICE, route); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - given(this.discovery.getServices()) - .willReturn(Collections.singletonList(MYSERVICE)); - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertMapping(routesMap, "https://example.com/" + MYSERVICE, MYSERVICE); - } - - @Test - public void testIgnoredLocalServiceByDefault() { - given(this.discovery.getServices()) - .willReturn(Collections.singletonList(MYSERVICE)); - Registration registration = new Registration() { - @Override - public String getServiceId() { - return MYSERVICE; - } - - @Override - public String getHost() { - return "localhost"; - } - - @Override - public int getPort() { - return 80; - } - - @Override - public boolean isSecure() { - return false; - } - - @Override - public URI getUri() { - return null; - } - - @Override - public Map getMetadata() { - return null; - } - }; - - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties, registration); - - LinkedHashMap routes = routeLocator.locateRoutes(); - ZuulRoute actual = routes.get("/**"); - assertThat(actual).as("routes didn't ignore " + MYSERVICE).isNull(); - - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isTrue(); - } - - @Test - public void testIgnoredLocalServiceFalse() { - this.properties.setIgnoreLocalService(false); - - given(this.discovery.getServices()) - .willReturn(Collections.singletonList(MYSERVICE)); - - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties); - - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertMapping(routesMap, MYSERVICE); - } - - @Test - public void testLocalServiceExceptionIgnored() { - given(this.discovery.getServices()).willReturn(Collections.emptyList()); - - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties, (Registration) null); - - // if no exception is thrown in constructor, this is a success - routeLocator.locateRoutes(); - } - - @Test - public void testRegExServiceRouteMapperNoServiceIdMatches() { - given(this.discovery.getServices()) - .willReturn(Collections.singletonList(MYSERVICE)); - - PatternServiceRouteMapper regExServiceRouteMapper = new PatternServiceRouteMapper( - this.regexMapper.getServicePattern(), this.regexMapper.getRoutePattern()); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties, regExServiceRouteMapper); - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertMapping(routesMap, MYSERVICE); - } - - @Test - public void testRegExServiceRouteMapperServiceIdMatches() { - given(this.discovery.getServices()) - .willReturn(Collections.singletonList("rest-service-v1")); - - PatternServiceRouteMapper regExServiceRouteMapper = new PatternServiceRouteMapper( - this.regexMapper.getServicePattern(), this.regexMapper.getRoutePattern()); - DiscoveryClientRouteLocator routeLocator = new DiscoveryClientRouteLocator("/", - this.discovery, this.properties, regExServiceRouteMapper); - List routesMap = routeLocator.getRoutes(); - assertThat(routesMap).as("routesMap was null").isNotNull(); - assertThat(routesMap.isEmpty()).as("routesMap was empty").isFalse(); - assertMapping(routesMap, "rest-service-v1", "v1/rest-service"); - } - - protected void assertMapping(List routesMap, String serviceId) { - assertMapping(routesMap, serviceId, serviceId); - } - - protected void assertMapping(List routesMap, String expectedRoute, - String key) { - String mapping = getMapping(key); - Route route = getRoute(routesMap, mapping); - assertThat(route).as("Could not find route for " + key).isNotNull(); - String location = route.getLocation(); - assertThat(location).as("routesMap had wrong value for " + mapping) - .isEqualTo(expectedRoute); - } - - private String getMapping(String serviceId) { - return "/" + serviceId + "/**"; - } - - protected void assertDefaultMapping(List routesMap, String expectedRoute) { - String mapping = "/**"; - String route = getRoute(routesMap, mapping).getLocation(); - assertThat(route).as("routesMap had wrong value for " + mapping) - .isEqualTo(expectedRoute); - } - - private Route getRoute(List routes, String path) { - for (Route route : routes) { - String pattern = route.getFullPath(); - if (path.equals(pattern)) { - return route; - } - } - return null; - } - - private void setTestRequestcontext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - public static class RegexMapper { - - private boolean enabled = false; - - private String servicePattern = "(?.*)-(?v.*$)"; - - private String routePattern = "${version}/${name}"; - - public RegexMapper() { - } - - public RegexMapper(boolean enabled, String servicePattern, String routePattern) { - this.enabled = enabled; - this.servicePattern = servicePattern; - this.routePattern = routePattern; - } - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public String getServicePattern() { - return servicePattern; - } - - public void setServicePattern(String servicePattern) { - this.servicePattern = servicePattern; - } - - public String getRoutePattern() { - return routePattern; - } - - public void setRoutePattern(String routePattern) { - this.routePattern = routePattern; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapperIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapperIntegrationTests.java deleted file mode 100644 index 455953246..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapperIntegrationTests.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.discovery; - -import java.util.ArrayList; -import java.util.List; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.RoutesEndpoint; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Stéphane Leroy - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - properties = { "spring.application.name=regex-test-application", - "spring.jmx.enabled=false", "eureka.client.enabled=false", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class PatternServiceRouteMapperIntegrationTests { - - protected static final String SERVICE_ID = "domain-service-v1"; - - @LocalServerPort - private int port; - - @Autowired - private DiscoveryClientRouteLocator routes; - - @Autowired - private RoutesEndpoint endpoint; - - @Before - public void setTestRequestcontext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void getRegexMappedService() { - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/v1/domain/service/get/1", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Get 1"); - } - - @Test - public void getStaticRoute() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/get/1", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Get 1"); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @RibbonClient(value = SERVICE_ID, - configuration = SimpleRibbonClientConfiguration.class) - @Import(NoSecurityConfiguration.class) - protected static class SampleCustomZuulProxyApplication { - - @Bean - public DiscoveryClient discoveryClient() { - DiscoveryClient discoveryClient = mock(DiscoveryClient.class); - List services = new ArrayList<>(); - services.add(SERVICE_ID); - when(discoveryClient.getServices()).thenReturn(services); - return discoveryClient; - } - - @RequestMapping(value = "/get/{id}", method = RequestMethod.GET) - public String get(@PathVariable String id) { - return "Get " + id; - } - - @Bean - public PatternServiceRouteMapper serviceRouteMapper() { - return new PatternServiceRouteMapper( - "(?^.+)-(?.+)-(?v.+$)", - "${version}/${domain}/${name}"); - } - - } - - protected static class SimpleRibbonClientConfiguration { - - @LocalServerPort - private int port = 0; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapperTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapperTests.java deleted file mode 100644 index 6c6100d2f..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/discovery/PatternServiceRouteMapperTests.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2015-2019 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 - * - * https://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.zuul.filters.discovery; - -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Stéphane Leroy - */ -public class PatternServiceRouteMapperTests { - - /** - * Service pattern that follow convention {domain}-{name}-{version}. The name is - * optional - */ - public static final String SERVICE_PATTERN = "(?^\\w+)(-(?\\w+)-|-)(?v\\d+$)"; - - public static final String ROUTE_PATTERN = "${version}/${domain}/${name}"; - - @Before - public void setTestRequestcontext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void test_return_mapped_route_if_serviceid_matches() { - PatternServiceRouteMapper toTest = new PatternServiceRouteMapper(SERVICE_PATTERN, - ROUTE_PATTERN); - - assertThat(toTest.apply("rest-service-v1")).as("service version convention") - .isEqualTo("v1/rest/service"); - } - - @Test - public void test_return_serviceid_if_no_matches() { - PatternServiceRouteMapper toTest = new PatternServiceRouteMapper(SERVICE_PATTERN, - ROUTE_PATTERN); - - // No version here - assertThat(toTest.apply("rest-service")).as("No matches for this service id") - .isEqualTo("rest-service"); - } - - @Test - public void test_route_should_be_cleaned_before_returned() { - // Messy patterns - PatternServiceRouteMapper toTest = new PatternServiceRouteMapper( - SERVICE_PATTERN + "(?.)?", - "/${version}/${nevermatch}/${domain}/${name}/"); - assertThat(toTest.apply("domain-service-v1")).as("No matches for this service id") - .isEqualTo("v1/domain/service"); - assertThat(toTest.apply("domain-v1")).as("No matches for this service id") - .isEqualTo("v1/domain"); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilterIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilterIntegrationTests.java deleted file mode 100644 index 755343e34..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilterIntegrationTests.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.post; - -import java.util.List; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.context.RequestContext; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestMapping; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Biju Kunjummen - */ - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = { "zuul.routes.aservice.path:/service/**", - "zuul.routes.aservice.strip-prefix:true", "eureka.client.enabled:false" }) -@DirtiesContext -public class LocationRewriteFilterIntegrationTests { - - @LocalServerPort - private int port; - - @Before - public void before() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @Test - public void testWithRedirectPrefixStripped() { - String url = "http://localhost:" + port + "/service/redirectingUri"; - ResponseEntity response = new TestRestTemplate().getForEntity(url, - String.class); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.FOUND); - List locationHeaders = response.getHeaders().get("Location"); - - assertThat(locationHeaders).hasSize(1); - String locationHeader = locationHeaders.get(0); - assertThat(locationHeader).withFailMessage("Location should have prefix") - .isEqualTo( - String.format("http://localhost:%d/service/redirectedUri", port)); - - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableZuulProxy - @Controller - @RibbonClient(name = "aservice", configuration = RibbonConfig.class) - @Import(NoSecurityConfiguration.class) - protected static class Config { - - @RequestMapping("/redirectingUri") - public String redirect1() { - return "redirect:/redirectedUri"; - } - - @Bean - public LocationRewriteFilter locationRewriteFilter() { - return new LocationRewriteFilter(); - } - - } - - public static class RibbonConfig { - - @LocalServerPort - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilterTests.java deleted file mode 100644 index f80eb1334..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/LocationRewriteFilterTests.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.zuul.filters.post; - -import java.util.Collections; - -import com.netflix.util.Pair; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * @author Biju Kunjummen - */ - -public class LocationRewriteFilterTests { - - private final String ZUUL_HOST = "myzuul.com"; - - private final String ZUUL_SCHEME = "https"; - - private final int ZUUL_PORT = 8443; - - private final String ZUUL_BASE_URL = String.format("%s://%s:%d", ZUUL_SCHEME, - ZUUL_HOST, ZUUL_PORT); - - private final String SERVER_HOST = "someserver.com"; - - private final String SERVER_SCHEME = "http"; - - private final int SERVER_PORT = 8564; - - private final String SERVER_BASE_URL = String.format("%s://%s:%d", SERVER_SCHEME, - SERVER_HOST, SERVER_PORT); - - @Before - public void before() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void reset() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void shouldRewriteLocationHeadersWithRoutePrefix() { - RequestContext context = RequestContext.getCurrentContext(); - ZuulProperties zuulProperties = new ZuulProperties(); - LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties, - new Route("service1", "/redirectingUri", "service1", "prefix", false, - Collections.EMPTY_SET, true), - "/prefix/redirectingUri", "/redirectedUri;someparam?param1=abc"); - filter.run(); - assertThat(getLocationHeader(context).second()).isEqualTo(String - .format("%s/prefix/redirectedUri;someparam?param1=abc", ZUUL_BASE_URL)); - } - - @Test - public void shouldBeUntouchedIfNoRoutesFound() { - RequestContext context = RequestContext.getCurrentContext(); - ZuulProperties zuulProperties = new ZuulProperties(); - LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties, null, - "/prefix/redirectingUri", "/redirectedUri;someparam?param1=abc"); - filter.run(); - assertThat(getLocationHeader(context).second()).isEqualTo( - String.format("%s/redirectedUri;someparam?param1=abc", SERVER_BASE_URL)); - } - - @Test - public void shouldRewriteLocationHeadersIfPrefixIsNotStripped() { - RequestContext context = RequestContext.getCurrentContext(); - ZuulProperties zuulProperties = new ZuulProperties(); - LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties, - new Route("service1", "/something/redirectingUri", "service1", "prefix", - false, Collections.EMPTY_SET, false), - "/prefix/redirectingUri", - "/something/redirectedUri;someparam?param1=abc"); - filter.run(); - assertThat(getLocationHeader(context).second()).isEqualTo(String.format( - "%s/something/redirectedUri;someparam?param1=abc", ZUUL_BASE_URL)); - } - - @Test - public void shouldRewriteLocationHeadersIfPrefixIsEmpty() { - RequestContext context = RequestContext.getCurrentContext(); - ZuulProperties zuulProperties = new ZuulProperties(); - LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties, - new Route("service1", "/something/redirectingUri", "service1", "", false, - Collections.EMPTY_SET, true), - "/redirectingUri", "/something/redirectedUri;someparam?param1=abc"); - filter.run(); - assertThat(getLocationHeader(context).second()).isEqualTo(String.format( - "%s/something/redirectedUri;someparam?param1=abc", ZUUL_BASE_URL)); - } - - @Test - public void shouldAddBackGlobalPrefixIfPresent() { - RequestContext context = RequestContext.getCurrentContext(); - ZuulProperties zuulProperties = new ZuulProperties(); - zuulProperties.setPrefix("global"); - zuulProperties.setStripPrefix(true); - LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties, - new Route("service1", "/something/redirectingUri", "service1", "prefix", - false, Collections.EMPTY_SET, true), - "/global/prefix/redirectingUri", - "/something/redirectedUri;someparam?param1=abc"); - filter.run(); - assertThat(getLocationHeader(context).second()).isEqualTo(String.format( - "%s/global/prefix/something/redirectedUri;someparam?param1=abc", - ZUUL_BASE_URL)); - } - - @Test - public void shouldNotAddBackGlobalPrefixIfNotStripped() { - RequestContext context = RequestContext.getCurrentContext(); - ZuulProperties zuulProperties = new ZuulProperties(); - zuulProperties.setPrefix("global"); - zuulProperties.setStripPrefix(false); - LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties, - new Route("service1", "/something/redirectingUri", "service1", "prefix", - false, Collections.EMPTY_SET, true), - "/global/prefix/redirectingUri", - "/global/something/redirectedUri;someparam?param1=abc"); - filter.run(); - assertThat(getLocationHeader(context).second()).isEqualTo(String.format( - "%s/global/prefix/something/redirectedUri;someparam?param1=abc", - ZUUL_BASE_URL)); - } - - private LocationRewriteFilter setFilterUpWith(RequestContext context, - ZuulProperties zuulProperties, Route route, String toZuulRequestUri, - String redirectedUri) { - MockHttpServletRequest httpServletRequest = new MockHttpServletRequest(); - httpServletRequest.setRequestURI(toZuulRequestUri); - httpServletRequest.setServerName(ZUUL_HOST); - httpServletRequest.setScheme(ZUUL_SCHEME); - httpServletRequest.setServerPort(ZUUL_PORT); - context.setRequest(httpServletRequest); - - MockHttpServletResponse httpServletResponse = new MockHttpServletResponse(); - context.getZuulResponseHeaders().add(new Pair<>("Location", - String.format("%s%s", SERVER_BASE_URL, redirectedUri))); - context.setResponse(httpServletResponse); - - RouteLocator routeLocator = mock(RouteLocator.class); - when(routeLocator.getMatchingRoute(toZuulRequestUri)).thenReturn(route); - LocationRewriteFilter filter = new LocationRewriteFilter(zuulProperties, - routeLocator); - - return filter; - } - - private Pair getLocationHeader(RequestContext ctx) { - if (ctx.getZuulResponseHeaders() != null) { - for (Pair pair : ctx.getZuulResponseHeaders()) { - if (pair.first().equals("Location")) { - return pair; - } - } - } - return null; - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterIntegrationTests.java deleted file mode 100644 index 20a1b64eb..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterIntegrationTests.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.post; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.MockClock; -import io.micrometer.core.instrument.simple.SimpleConfig; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTE_TYPE; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest(properties = "zuul.routes.filtertest:/filtertest/**", - webEnvironment = RANDOM_PORT) -@DirtiesContext -public class SendErrorFilterIntegrationTests { - - @Autowired - private MeterRegistry meterRegistry; - - @LocalServerPort - private int port; - - @Before - public void setTestRequestcontext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void testPreFails() { - String url = "http://localhost:" + port + "/filtertest/get?failpre=true"; - ResponseEntity response = new TestRestTemplate().getForEntity(url, - String.class); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - - assertMetrics("pre"); - } - - private void assertMetrics(String filterType) { - Double count = meterRegistry.counter("ZUUL::EXCEPTION:" + filterType + "::500") - .count(); - assertThat(count.longValue()).isEqualTo(1L); - count = meterRegistry.counter("ZUUL::EXCEPTION:null:500").count(); - assertThat(count.longValue()).isEqualTo(0L); - } - - @Test - public void testRouteFails() { - String url = "http://localhost:" + port + "/filtertest/get?failroute=true"; - ResponseEntity response = new TestRestTemplate().getForEntity(url, - String.class); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - - assertMetrics("route"); - } - - @Test - public void testPostFails() { - String url = "http://localhost:" + port + "/filtertest/get?failpost=true"; - ResponseEntity response = new TestRestTemplate().getForEntity(url, - String.class); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - - // FIXME: 2.1.0 assertMetrics("post"); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableZuulProxy - @RestController - @RibbonClient(name = "filtertest", configuration = RibbonConfig.class) - @Import(NoSecurityConfiguration.class) - protected static class Config { - - @RequestMapping("/get") - public String get() { - return "Hello"; - } - - @Bean - public ZuulFilter testPreFilter() { - return new FailureFilter() { - @Override - public String filterType() { - return PRE_TYPE; - } - }; - } - - @Bean - public ZuulFilter testRouteFilter() { - return new FailureFilter() { - @Override - public String filterType() { - return ROUTE_TYPE; - } - }; - } - - @Bean - public ZuulFilter testPostFilter() { - return new FailureFilter() { - @Override - public String filterType() { - return POST_TYPE; - } - }; - } - - @Bean - public MeterRegistry meterRegistry() { - return new SimpleMeterRegistry(SimpleConfig.DEFAULT, new MockClock()); - } - - } - - @Configuration(proxyBeanMethods = false) - private static class RibbonConfig { - - @LocalServerPort - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - - private abstract static class FailureFilter extends ZuulFilter { - - @Override - public int filterOrder() { - return Integer.MIN_VALUE; - } - - @Override - public boolean shouldFilter() { - HttpServletRequest request = RequestContext.getCurrentContext().getRequest(); - return request.getParameter("fail" + filterType()) != null; - } - - @Override - public Object run() { - HttpServletRequest request = RequestContext.getCurrentContext().getRequest(); - if (request.getParameter("fail" + filterType()) != null) { - throw new RuntimeException("failing on purpose in " + filterType()); - } - return null; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterTests.java deleted file mode 100644 index c3f18a477..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilterTests.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.post; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.exception.ZuulException; -import com.netflix.zuul.monitoring.MonitoringHelper; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.http.HttpStatus; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * @author Spencer Gibb - */ -public class SendErrorFilterTests { - - @Before - public void setTestRequestcontext() { - MonitoringHelper.initMocks(); - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void reset() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void runsNormally() { - SendErrorFilter filter = createSendErrorFilter(new MockHttpServletRequest()); - assertThat(filter.shouldFilter()).as("shouldFilter returned false").isTrue(); - filter.run(); - } - - private SendErrorFilter createSendErrorFilter(HttpServletRequest request) { - RequestContext context = new RequestContext(); - context.setRequest(request); - context.setResponse(new MockHttpServletResponse()); - context.setThrowable(new ZuulException(new RuntimeException(), - HttpStatus.NOT_FOUND.value(), null)); - RequestContext.testSetCurrentContext(context); - SendErrorFilter filter = new SendErrorFilter(); - filter.setErrorPath("/error"); - return filter; - } - - @Test - public void noRequestDispatcher() { - SendErrorFilter filter = createSendErrorFilter(mock(HttpServletRequest.class)); - assertThat(filter.shouldFilter()).as("shouldFilter returned false").isTrue(); - filter.run(); - } - - @Test - public void doesNotRunTwice() { - SendErrorFilter filter = createSendErrorFilter(new MockHttpServletRequest()); - assertThat(filter.shouldFilter()).as("shouldFilter returned false").isTrue(); - filter.run(); - assertThat(filter.shouldFilter()).as("shouldFilter returned true").isFalse(); - } - - @Test - public void setResponseCode() { - SendErrorFilter filter = createSendErrorFilter(new MockHttpServletRequest()); - filter.run(); - - RequestContext ctx = RequestContext.getCurrentContext(); - int resCode = ctx.getResponse().getStatus(); - int ctxCode = ctx.getResponseStatusCode(); - - assertThat(resCode).as("invalid response code: " + resCode) - .isEqualTo(HttpStatus.NOT_FOUND.value()); - assertThat(ctxCode).as("invalid response code in RequestContext: " + ctxCode) - .isEqualTo(resCode); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilterTests.java deleted file mode 100644 index 1c29ae8ba..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilterTests.java +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.post; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.lang.reflect.UndeclaredThrowableException; -import java.util.zip.GZIPInputStream; -import java.util.zip.GZIPOutputStream; - -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.netflix.zuul.constants.ZuulHeaders; -import com.netflix.zuul.context.Debug; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.http.HttpStatus; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.web.util.WebUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_ZUUL_DEBUG_HEADER; - -/** - * @author Spencer Gibb - */ -public class SendResponseFilterTests { - - @Before - public void setTestRequestcontext() { - RequestContext context = new RequestContext(); - context.setRequest(new MockHttpServletRequest()); - context.setResponse(new MockHttpServletResponse()); - context.setResponseGZipped(false); - - RequestContext.testSetCurrentContext(context); - } - - @After - public void reset() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void runsNormally() throws Exception { - String characterEncoding = null; - String content = "hello"; - runFilter(characterEncoding, content, false); - } - - @Test - public void useServlet31Works() { - assertThat(new SendResponseFilter().isUseServlet31()).isTrue(); - } - - @Test - public void characterEncodingNotOverridden() throws Exception { - String characterEncoding = "UTF-16"; - String content = "\u00a5"; - runFilter(characterEncoding, content, true); - } - - @Test - public void runWithDebugHeader() throws Exception { - ZuulProperties properties = new ZuulProperties(); - properties.setIncludeDebugHeader(true); - - SendResponseFilter filter = createFilter(properties, "hello", null, - new MockHttpServletResponse(), false); - Debug.addRoutingDebug("test"); - filter.run(); - - String debugHeader = RequestContext.getCurrentContext().getResponse() - .getHeader(X_ZUUL_DEBUG_HEADER); - assertThat(debugHeader).as("wrong debug header").isEqualTo("[[[test]]]"); - } - - /* - * GZip NOT requested and NOT a GZip response -> Content-Length forwarded asis - */ - @Test - public void runWithOriginContentLength() throws Exception { - ZuulProperties properties = new ZuulProperties(); - properties.setSetContentLength(true); - - SendResponseFilter filter = createFilter(properties, "hello", null, - new MockHttpServletResponse(), false); - RequestContext.getCurrentContext().setOriginContentLength(6L); // for test - RequestContext.getCurrentContext().setResponseGZipped(false); - filter.run(); - - String contentLength = RequestContext.getCurrentContext().getResponse() - .getHeader("Content-Length"); - assertThat(contentLength).as("wrong origin content length").isEqualTo("6"); - } - - /* - * Unknown encoding requested and NOT a GZip response -> Content-Length forwarded asis - */ - @Test - public void runWithOriginContentLength_content_encoding_header() throws Exception { - ZuulProperties properties = new ZuulProperties(); - properties.setSetContentLength(true); - - SendResponseFilter filter = createFilter(properties, "hello", null, - new MockHttpServletResponse(), false); - RequestContext.getCurrentContext().addZuulResponseHeader("Content-Encoding", - "unknown"); - RequestContext.getCurrentContext().setOriginContentLength(6L); // for test - RequestContext.getCurrentContext().setResponseGZipped(false); - filter.run(); - - MockHttpServletResponse response = (MockHttpServletResponse) RequestContext - .getCurrentContext().getResponse(); - assertThat(response.getHeader("Content-Length")).as("wrong origin content length") - .isEqualTo("6"); - assertThat(response.getHeader("Content-Encoding")).isEqualTo("unknown"); - } - - /* - * GZip requested and GZip response -> Content-Length forwarded asis, response - * compressed - */ - @Test - public void runWithOriginContentLength_gzipRequested_gzipResponse() throws Exception { - ZuulProperties properties = new ZuulProperties(); - properties.setSetContentLength(true); - - SendResponseFilter filter = new SendResponseFilter(properties); - - byte[] gzipData = gzipData("hello"); - - RequestContext.getCurrentContext().setOriginContentLength((long) gzipData.length); // for - // test - RequestContext.getCurrentContext().setResponseGZipped(true); - RequestContext.getCurrentContext() - .setResponseDataStream(new ByteArrayInputStream(gzipData)); - ((MockHttpServletRequest) RequestContext.getCurrentContext().getRequest()) - .addHeader(ZuulHeaders.ACCEPT_ENCODING, "gzip"); - - filter.run(); - - MockHttpServletResponse response = (MockHttpServletResponse) RequestContext - .getCurrentContext().getResponse(); - assertThat(response.getHeader("Content-Length")) - .isEqualTo(Integer.toString(gzipData.length)); - assertThat(response.getHeader("Content-Encoding")).isEqualTo("gzip"); - assertThat(response.getContentAsByteArray()).isEqualTo(gzipData); - - BufferedReader reader = new BufferedReader( - new InputStreamReader(new GZIPInputStream( - new ByteArrayInputStream(response.getContentAsByteArray())))); - assertThat(reader.readLine()).isEqualTo("hello"); - } - - /* - * GZip NOT requested and GZip response -> Content-Length discarded and response - * uncompressed - */ - @Test - public void runWithOriginContentLength_gzipNotRequested_gzipResponse() - throws Exception { - ZuulProperties properties = new ZuulProperties(); - properties.setSetContentLength(true); - - SendResponseFilter filter = new SendResponseFilter(properties); - - byte[] gzipData = gzipData("hello"); - - RequestContext.getCurrentContext().setOriginContentLength((long) gzipData.length); // for - // test - RequestContext.getCurrentContext().setResponseGZipped(true); - RequestContext.getCurrentContext() - .setResponseDataStream(new ByteArrayInputStream(gzipData)); - - filter.run(); - - MockHttpServletResponse response = (MockHttpServletResponse) RequestContext - .getCurrentContext().getResponse(); - assertThat(response.getHeader("Content-Length")).isNull(); - assertThat(response.getHeader("Content-Encoding")).isNull(); - assertThat(response.getContentAsString()).as("wrong content").isEqualTo("hello"); - } - - /* - * GZip NOT requested and GZip response -> Content-Length discarded and response - * uncompressed - */ - @Test - public void runWithOriginContentLength_gzipNotRequested_gzipResponse_content_encoding_header() - throws Exception { - ZuulProperties properties = new ZuulProperties(); - properties.setSetContentLength(true); - - SendResponseFilter filter = new SendResponseFilter(properties); - - byte[] gzipData = gzipData("hello"); - - RequestContext.getCurrentContext().addZuulResponseHeader("Content-Encoding", - "gzip"); - RequestContext.getCurrentContext().setOriginContentLength((long) gzipData.length); // for - // test - RequestContext.getCurrentContext().setResponseGZipped(true); - RequestContext.getCurrentContext() - .setResponseDataStream(new ByteArrayInputStream(gzipData)); - - filter.run(); - - MockHttpServletResponse response = (MockHttpServletResponse) RequestContext - .getCurrentContext().getResponse(); - assertThat(response.getHeader("Content-Length")).isNull(); - assertThat(response.getHeader("Content-Encoding")).isNull(); - assertThat(response.getContentAsString()).as("wrong content").isEqualTo("hello"); - } - - /* - * Origin sends a non gzip response with Content-Encoding: gzip Request does not - * support GZIP -> filter fails to uncompress and send stream "asis". Content-Length - * is NOT preserved. - */ - @Test - public void invalidGzipResponseFromOrigin() throws Exception { - ZuulProperties properties = new ZuulProperties(); - properties.setSetContentLength(true); - - SendResponseFilter filter = new SendResponseFilter(properties); - - byte[] gzipData = "hello".getBytes(); - - RequestContext.getCurrentContext().setOriginContentLength((long) gzipData.length); // for - // test - RequestContext.getCurrentContext().setResponseGZipped(true); // say it is GZipped - // although not - // the case - RequestContext.getCurrentContext() - .setResponseDataStream(new ByteArrayInputStream(gzipData)); - - filter.run(); - - MockHttpServletResponse response = (MockHttpServletResponse) RequestContext - .getCurrentContext().getResponse(); - assertThat(response.getHeader("Content-Length")).isNull(); - assertThat(response.getHeader("Content-Encoding")).isNull(); - assertThat(response.getContentAsString()).as("wrong content").isEqualTo("hello"); // response - // sent - // "asis" - } - - /* - * Empty response from origin with Content-Encoding: gzip Request does not support - * GZIP -> filter should not fail in decoding the *empty* response stream - */ - @Test - public void emptyGzipResponseFromOrigin() throws Exception { - ZuulProperties properties = new ZuulProperties(); - properties.setSetContentLength(true); - - SendResponseFilter filter = new SendResponseFilter(properties); - - byte[] gzipData = new byte[] {}; - - RequestContext.getCurrentContext().setResponseGZipped(true); - RequestContext.getCurrentContext() - .setResponseDataStream(new ByteArrayInputStream(gzipData)); - - filter.run(); - - MockHttpServletResponse response = (MockHttpServletResponse) RequestContext - .getCurrentContext().getResponse(); - assertThat(response.getHeader("Content-Length")).isNull(); - assertThat(response.getHeader("Content-Encoding")).isNull(); - assertThat(response.getContentAsByteArray()).isEqualTo(gzipData); - } - - @Test - public void closeResponseOutputStreamError() throws Exception { - HttpServletResponse response = mock(HttpServletResponse.class); - InputStream mockStream = spy( - new ByteArrayInputStream("Hello\n".getBytes("UTF-8"))); - - RequestContext context = new RequestContext(); - context.setRequest(new MockHttpServletRequest()); - context.setResponse(response); - context.setResponseDataStream(mockStream); - context.setResponseGZipped(false); - Closeable zuulResponse = mock(Closeable.class); - context.set("zuulResponse", zuulResponse); - RequestContext.testSetCurrentContext(context); - - SendResponseFilter filter = new SendResponseFilter(); - - ServletOutputStream zuuloutputstream = mock(ServletOutputStream.class); - doThrow(new IOException("Response to client closed")).when(zuuloutputstream) - .write(isA(byte[].class), anyInt(), anyInt()); - - when(response.getOutputStream()).thenReturn(zuuloutputstream); - - try { - filter.run(); - } - catch (UndeclaredThrowableException ex) { - assertThat(ex.getUndeclaredThrowable().getMessage()) - .isEqualTo("Response to client closed"); - } - - verify(zuulResponse).close(); - verify(mockStream).close(); - } - - @Test - public void testCloseResponseDataStream() throws Exception { - HttpServletResponse response = mock(HttpServletResponse.class); - InputStream mockStream = spy( - new ByteArrayInputStream("Hello\n".getBytes("UTF-8"))); - - RequestContext context = new RequestContext(); - context.setRequest(new MockHttpServletRequest()); - context.setResponse(response); - context.setResponseDataStream(mockStream); - context.setResponseGZipped(false); - Closeable zuulResponse = mock(Closeable.class); - context.set("zuulResponse", zuulResponse); - RequestContext.testSetCurrentContext(context); - - when(response.getOutputStream()).thenReturn(mock(ServletOutputStream.class)); - - SendResponseFilter filter = new SendResponseFilter(); - - filter.run(); - - verify(mockStream).close(); - } - - private void runFilter(String characterEncoding, String content, - boolean streamContent) throws Exception { - MockHttpServletResponse response = new MockHttpServletResponse(); - SendResponseFilter filter = createFilter(content, characterEncoding, response, - streamContent); - assertThat(filter.shouldFilter()).as("shouldFilter returned false").isTrue(); - filter.run(); - String encoding = RequestContext.getCurrentContext().getResponse() - .getCharacterEncoding(); - String expectedEncoding = characterEncoding != null ? characterEncoding - : WebUtils.DEFAULT_CHARACTER_ENCODING; - assertThat(encoding).as("wrong character encoding").isEqualTo(expectedEncoding); - assertThat(response.getContentAsString()).as("wrong content").isEqualTo(content); - } - - private SendResponseFilter createFilter(String content, String characterEncoding, - MockHttpServletResponse response, boolean streamContent) throws Exception { - return createFilter(new ZuulProperties(), content, characterEncoding, response, - streamContent); - } - - private SendResponseFilter createFilter(ZuulProperties properties, String content, - String characterEncoding, MockHttpServletResponse response, - boolean streamContent) throws Exception { - HttpServletRequest request = new MockHttpServletRequest(); - RequestContext context = new RequestContext(); - context.setRequest(request); - context.setResponse(response); - - if (characterEncoding != null) { - response.setCharacterEncoding(characterEncoding); - } - - if (streamContent) { - context.setResponseDataStream( - new ByteArrayInputStream(content.getBytes(characterEncoding))); - } - else { - context.setResponseBody(content); - } - - context.setResponseGZipped(false); - context.set("error.status_code", HttpStatus.NOT_FOUND.value()); - RequestContext.testSetCurrentContext(context); - SendResponseFilter filter = new SendResponseFilter(properties); - return filter; - } - - private byte[] gzipData(String content) throws IOException { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - PrintWriter gzip = new PrintWriter(new GZIPOutputStream(bos)); - gzip.print(content); - gzip.flush(); - gzip.close(); - - return bos.toByteArray(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilterTests.java deleted file mode 100644 index 054fe8eb0..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilterTests.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 2016-2019 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 - * - * https://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.zuul.filters.pre; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.servlet.ServletException; -import javax.servlet.http.Part; - -import com.netflix.zuul.context.RequestContext; -import org.apache.commons.io.IOUtils; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.mock.web.MockMultipartHttpServletRequest; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Michael Hartle - */ -public class FormBodyWrapperFilterTests { - - private FormBodyWrapperFilter filter; - - private MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest(); - - @Before - public void init() { - this.filter = new FormBodyWrapperFilter(); - RequestContext ctx = RequestContext.getCurrentContext(); - ctx.clear(); - ctx.setRequest(this.request); - } - - @Test - public void multiplePartNamesWithMultipleParts() - throws IOException, ServletException { - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - - final Map> firstPartHeaders = new HashMap<>(); - final byte[] firstPartBody = "{ \"u\" : 1 }".getBytes(); - final Part firstPart = new MockPart("a", "application/json", null, - firstPartHeaders, firstPartBody); - this.request.addPart(firstPart); - - final Map> secondPartHeaders = new HashMap<>(); - final byte[] secondPartBody = "%PDF...1".getBytes(); - final Part secondPart = new MockPart("b", "application/pdf", "document.pdf", - secondPartHeaders, secondPartBody); - this.request.addPart(secondPart); - - final Map> thirdPartHeaders = new HashMap<>(); - final byte[] thirdPartBody = "%PDF...2".getBytes(); - final Part thirdPart = new MockPart("c", "application/pdf", "attachment1.pdf", - thirdPartHeaders, thirdPartBody); - this.request.addPart(thirdPart); - - final Map> fourthPartHeaders = new HashMap<>(); - final byte[] fourthPartBody = "%PDF...3".getBytes(); - final Part fourthPart = new MockPart("c", "application/pdf", "attachment2.pdf", - fourthPartHeaders, fourthPartBody); - this.request.addPart(fourthPart); - - final Map> fifthPartHeaders = new HashMap<>(); - final byte[] fifthPartBody = "%PDF...4".getBytes(); - final Part fifthPart = new MockPart("c", "application/pdf", "attachment3.pdf", - fifthPartHeaders, fifthPartBody); - this.request.addPart(fifthPart); - - this.filter.run(); - - final RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getRequest().getRequestURI()).isEqualTo("/api/foo/1"); - assertThat(ctx.getRequest().getRemoteAddr()).isEqualTo("5.6.7.8"); - assertThat(ctx.getRequest().getParts().size()).isEqualTo(5); - - final Part[] parts = ctx.getRequest().getParts().toArray(new Part[0]); - assertThat(parts[0].getName()).isEqualTo("a"); - assertThat(parts[0].getSubmittedFileName()).isEqualTo(null); - assertThat(parts[0].getContentType()).isEqualTo("application/json"); - assertThat(IOUtils.toByteArray(parts[0].getInputStream())) - .isEqualTo(firstPartBody); - - assertThat(parts[1].getName()).isEqualTo("b"); - assertThat(parts[1].getSubmittedFileName()).isEqualTo("document.pdf"); - assertThat(parts[1].getContentType()).isEqualTo("application/pdf"); - assertThat(IOUtils.toByteArray(parts[1].getInputStream())) - .isEqualTo(secondPartBody); - - assertThat(parts[2].getName()).isEqualTo("c"); - assertThat(parts[2].getSubmittedFileName()).isEqualTo("attachment1.pdf"); - assertThat(parts[2].getContentType()).isEqualTo("application/pdf"); - assertThat(IOUtils.toByteArray(parts[2].getInputStream())) - .isEqualTo(thirdPartBody); - - assertThat(parts[3].getName()).isEqualTo("c"); - assertThat(parts[3].getSubmittedFileName()).isEqualTo("attachment2.pdf"); - assertThat(parts[3].getContentType()).isEqualTo("application/pdf"); - assertThat(IOUtils.toByteArray(parts[3].getInputStream())) - .isEqualTo(fourthPartBody); - - assertThat(parts[4].getName()).isEqualTo("c"); - assertThat(parts[4].getSubmittedFileName()).isEqualTo("attachment3.pdf"); - assertThat(parts[4].getContentType()).isEqualTo("application/pdf"); - assertThat(IOUtils.toByteArray(parts[4].getInputStream())) - .isEqualTo(fifthPartBody); - } - - private class MockPart implements Part { - - private final String name; - - private final String contentType; - - private final String submittedFileName; - - private final Map> headers; - - private final byte[] body; - - MockPart(final String name, final String contentType, - final String submittedFileName, final Map> headers, - final byte[] body) { - this.name = name; - this.contentType = contentType; - this.submittedFileName = submittedFileName; - this.headers = headers; - this.body = body; - } - - @Override - public InputStream getInputStream() throws IOException { - return new ByteArrayInputStream(this.body); - } - - @Override - public String getContentType() { - return this.contentType; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public String getSubmittedFileName() { - return this.submittedFileName; - } - - @Override - public long getSize() { - return this.body != null ? this.body.length : 0; - } - - @Override - public void write(String fileName) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public void delete() throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public String getHeader(String name) { - if (this.headers == null) { - return null; - } - - final List values = this.headers.get(name); - - if (values == null || values.size() == 0) { - return null; - } - - return values.get(0); - } - - @Override - public Collection getHeaders(String name) { - if (this.headers == null) { - return null; - } - - return this.headers.get(name); - } - - @Override - public Collection getHeaderNames() { - if (this.headers == null) { - return null; - } - - return this.headers.keySet(); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilterTests.java deleted file mode 100755 index 5e325b6ca..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/pre/PreDecorationFilterTests.java +++ /dev/null @@ -1,711 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.pre; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import com.netflix.util.Pair; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; - -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.cloud.test.ModifiedClassPathRunner; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.util.MultiValueMap; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_TO_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_URI_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_KEY; - -/** - * @author Dave Syer - */ -@RunWith(ModifiedClassPathRunner.class) -// This is needed for sensitiveHeadersOverrideEmpty, if Spring Security is on the -// classpath -// then sensitive headers will always be present. -@ClassPathExclusions({ "spring-security-*.jar" }) -public class PreDecorationFilterTests { - - private PreDecorationFilter filter; - - @Mock - private DiscoveryClient discovery; - - private ZuulProperties properties = new ZuulProperties(); - - private DiscoveryClientRouteLocator routeLocator; - - private MockHttpServletRequest request = new MockHttpServletRequest(); - - private ProxyRequestHelper proxyRequestHelper = new ProxyRequestHelper(); - - @Before - public void init() { - initMocks(this); - this.properties = new ZuulProperties(); - this.proxyRequestHelper = new ProxyRequestHelper(properties); - this.routeLocator = new DiscoveryClientRouteLocator("/", this.discovery, - this.properties); - this.filter = new PreDecorationFilter(this.routeLocator, "/", this.properties, - this.proxyRequestHelper); - RequestContext ctx = RequestContext.getCurrentContext(); - ctx.clear(); - ctx.setRequest(this.request); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void basicProperties() throws Exception { - assertThat(this.filter.filterOrder()).isEqualTo(5); - assertThat(this.filter.shouldFilter()).isEqualTo(true); - assertThat(this.filter.filterType()).isEqualTo(PRE_TYPE); - } - - @Test - public void skippedIfServiceIdSet() throws Exception { - RequestContext.getCurrentContext().set(SERVICE_ID_KEY, "myservice"); - assertThat(this.filter.shouldFilter()).isEqualTo(false); - } - - @Test - public void skippedIfForwardToSet() throws Exception { - RequestContext.getCurrentContext().set(FORWARD_TO_KEY, "myconteext"); - assertThat(this.filter.shouldFilter()).isEqualTo(false); - } - - @Test - public void xForwardedHostHasPort() throws Exception { - this.properties.setPrefix("/api"); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.setServerPort(8080); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost:8080"); - } - - @Test - public void xForwardedHostAndProtoAppend() throws Exception { - this.properties.setPrefix("/api"); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.setServerPort(8080); - this.request.addHeader("X-Forwarded-Host", "example.com"); - this.request.addHeader("X-Forwarded-Proto", "https"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("example.com,localhost:8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")) - .isEqualTo("443,8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("https,http"); - } - - @Test - public void xForwardedHostOnlyAppends() throws Exception { - this.properties.setPrefix("/api"); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.setServerPort(8080); - this.request.addHeader("X-Forwarded-Host", "example.com"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("example.com,localhost:8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")).isEqualTo("8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - } - - @Test - public void xForwardedProtoOnlyAppends() throws Exception { - this.properties.setPrefix("/api"); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.setServerPort(8080); - this.request.addHeader("X-Forwarded-Proto", "https"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost:8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")) - .isEqualTo("443,8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("https,http"); - } - - @Test - public void xForwardedProtoHttpOnlyAppends() throws Exception { - this.properties.setPrefix("/api"); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.setServerPort(8080); - this.request.addHeader("X-Forwarded-Proto", "http"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost:8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")) - .isEqualTo("80,8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http,http"); - } - - @Test - public void xForwardedPortOnlyAppends() throws Exception { - this.properties.setPrefix("/api"); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.setServerPort(8080); - this.request.addHeader("X-Forwarded-Port", "456"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost:8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")) - .isEqualTo("456,8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - } - - @Test - public void xForwardedPortAndProtoAppends() throws Exception { - this.properties.setPrefix("/api"); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.setServerPort(8080); - this.request.addHeader("X-Forwarded-Proto", "https"); - this.request.addHeader("X-Forwarded-Port", "456"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost:8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")) - .isEqualTo("456,8080"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("https,http"); - } - - @Test - public void hostHeaderSet() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setAddHostHeader(true); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.setServerPort(8080); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost:8080"); - assertThat(ctx.getZuulRequestHeaders().get("host")).isEqualTo("localhost:8080"); - } - - @Test - public void prefixRouteAddsHeader() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.addHeader("X-Forwarded-For", "1.2.3.4"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(REQUEST_URI_KEY)).isEqualTo("/foo/1"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")).isEqualTo("80"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-prefix")) - .isEqualTo("/api"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-for")) - .isEqualTo("1.2.3.4, 5.6.7.8"); - assertThat(getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")) - .isEqualTo("foo"); - } - - @Test - public void prefixRouteWithPrefixHeaderConcatsHeader() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.request.setRequestURI("/api/foo/1"); - this.request.setRemoteAddr("5.6.7.8"); - this.request.addHeader("X-Forwarded-For", "1.2.3.4"); - this.request.addHeader("X-Forwarded-Prefix", "/prefix"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(REQUEST_URI_KEY)).isEqualTo("/foo/1"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")).isEqualTo("80"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-prefix")) - .isEqualTo("/prefix/api"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-for")) - .isEqualTo("1.2.3.4, 5.6.7.8"); - assertThat(getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")) - .isEqualTo("foo"); - } - - @Test - public void routeWithContextPath() { - this.properties.setStripPrefix(false); - this.request.setRequestURI("/api/foo/1"); - this.request.setContextPath("/context-path"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/api/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(REQUEST_URI_KEY)).isEqualTo("/api/foo/1"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")).isEqualTo("80"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-prefix")) - .isEqualTo("/context-path"); - assertThat(getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")) - .isEqualTo("foo"); - } - - @Test - public void prefixRouteWithContextPath() { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.request.setRequestURI("/api/foo/1"); - this.request.setContextPath("/context-path"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(REQUEST_URI_KEY)).isEqualTo("/foo/1"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")).isEqualTo("80"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-prefix")) - .isEqualTo("/context-path/api"); - assertThat(getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")) - .isEqualTo("foo"); - } - - @Test - public void dontDecodeUrl() { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setDecodeUrl(false); - this.request.setRequestURI("/api/foo/encoded%2Fpath"); - this.request.setContextPath("/context-path"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter = new PreDecorationFilter(this.routeLocator, "/", this.properties, - this.proxyRequestHelper); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(REQUEST_URI_KEY)).isEqualTo("/foo/encoded%2Fpath"); - } - - @Test - public void routeIgnoreContextPathIfPrefixHeader() { - this.properties.setStripPrefix(false); - this.request.setRequestURI("/api/foo/1"); - this.request.setContextPath("/context-path"); - this.request.addHeader("X-Forwarded-Prefix", "/prefix"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/api/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(REQUEST_URI_KEY)).isEqualTo("/api/foo/1"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")).isEqualTo("80"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-prefix")) - .isEqualTo("/prefix"); - assertThat(getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")) - .isEqualTo("foo"); - } - - @Test - public void prefixRouteIgnoreContextPathIfPrefixHeader() { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.request.setRequestURI("/api/foo/1"); - this.request.setContextPath("/context-path"); - this.request.addHeader("X-Forwarded-Prefix", "/prefix"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(REQUEST_URI_KEY)).isEqualTo("/foo/1"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-port")).isEqualTo("80"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-prefix")) - .isEqualTo("/prefix/api"); - assertThat(getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")) - .isEqualTo("foo"); - } - - @Test - public void forwardRouteAddsLocation() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.request.setRequestURI("/api/foo/1"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(FORWARD_TO_KEY)).isEqualTo("/foo/1"); - } - - @Test - public void forwardWithoutStripPrefixAppendsPath() throws Exception { - this.request.setRequestURI("/foo/1"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", null, "forward:/bar", false, null, null)); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(FORWARD_TO_KEY)).isEqualTo("/bar/foo/1"); - } - - @Test - public void prefixRouteWithRouteStrippingAddsHeader() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.request.setRequestURI("/api/foo/1"); - this.routeLocator.addRoute("/foo/**", "foo"); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(REQUEST_URI_KEY)).isEqualTo("/1"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-host")) - .isEqualTo("localhost"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-proto")) - .isEqualTo("http"); - assertThat(ctx.getZuulRequestHeaders().get("x-forwarded-prefix")) - .isEqualTo("/api/foo"); - assertThat(getHeader(ctx.getOriginResponseHeaders(), "x-zuul-serviceid")) - .isEqualTo("foo"); - } - - @Test - public void routeNotFound() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null)); - - this.request.setRequestURI("/api/bar/1"); - - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(FORWARD_TO_KEY)).isEqualTo("/api/bar/1"); - } - - @Test - public void routeNotFoundDispatcherServletSpecialPath() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setAddProxyHeaders(true); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null)); - - this.filter = new PreDecorationFilter(this.routeLocator, "/special", - this.properties, this.proxyRequestHelper); - - this.request.setRequestURI("/api/bar/1"); - - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - assertThat(ctx.get(FORWARD_TO_KEY)).isEqualTo("/special/api/bar/1"); - } - - @Test - public void routeNotFoundZuulRequest() throws Exception { - setTestRequestContext(); - RequestContext ctx = RequestContext.getCurrentContext(); - RequestContext.getCurrentContext().setZuulEngineRan(); - this.request.setRequestURI("/zuul/api/bar/1"); - ctx.setRequest(this.request); - - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setServletPath("/zuul"); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null)); - - this.filter.run(); - - assertThat(ctx.get(FORWARD_TO_KEY)).isEqualTo("/api/bar/1"); - } - - @Test - public void routeNotFoundZuulRequestDispatcherServletSpecialPath() throws Exception { - setTestRequestContext(); - RequestContext ctx = RequestContext.getCurrentContext(); - RequestContext.getCurrentContext().setZuulEngineRan(); - this.request.setRequestURI("/zuul/api/bar/1"); - ctx.setRequest(this.request); - - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setServletPath("/zuul"); - this.properties.setAddProxyHeaders(true); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null)); - this.filter = new PreDecorationFilter(this.routeLocator, "/special", - this.properties, this.proxyRequestHelper); - - this.filter.run(); - - assertThat(ctx.get(FORWARD_TO_KEY)).isEqualTo("/special/api/bar/1"); - } - - @Test - public void routeNotFoundZuulRequestZuulHomeMapping() throws Exception { - setTestRequestContext(); - RequestContext ctx = RequestContext.getCurrentContext(); - RequestContext.getCurrentContext().setZuulEngineRan(); - this.request.setRequestURI("/api/bar/1"); - ctx.setRequest(this.request); - - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setServletPath("/"); - this.properties.setAddProxyHeaders(true); - this.routeLocator.addRoute( - new ZuulRoute("foo", "/foo/**", null, "forward:/foo", true, null, null)); - - this.filter = new PreDecorationFilter(this.routeLocator, "/special", - this.properties, this.proxyRequestHelper); - - this.filter.run(); - - assertThat(ctx.get(FORWARD_TO_KEY)).isEqualTo("/special/api/bar/1"); - } - - @Test - public void sensitiveHeadersOverride() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setSensitiveHeaders(Collections.singleton("x-bar")); - this.request.setRequestURI("/api/foo/1"); - ZuulRoute route = new ZuulRoute("/foo/**", "foo"); - route.setSensitiveHeaders(Collections.singleton("x-foo")); - this.routeLocator.addRoute(route); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - @SuppressWarnings("unchecked") - Set sensitiveHeaders = (Set) ctx - .get(ProxyRequestHelper.IGNORED_HEADERS); - assertThat(sensitiveHeaders.containsAll(Collections.singletonList("x-foo"))) - .as("sensitiveHeaders is wrong: " + sensitiveHeaders).isTrue(); - assertThat(sensitiveHeaders.contains("Cookie")) - .as("sensitiveHeaders is wrong: " + sensitiveHeaders).isFalse(); - } - - @Test - public void sensitiveHeadersOverrideEmpty() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setSensitiveHeaders(Collections.singleton("x-bar")); - this.request.setRequestURI("/api/foo/1"); - ZuulRoute route = new ZuulRoute("/foo/**", "foo"); - route.setSensitiveHeaders(Collections.emptySet()); - this.routeLocator.addRoute(route); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - @SuppressWarnings("unchecked") - Set sensitiveHeaders = (Set) ctx - .get(ProxyRequestHelper.IGNORED_HEADERS); - assertThat(sensitiveHeaders.isEmpty()) - .as("sensitiveHeaders is wrong: " + sensitiveHeaders).isTrue(); - } - - @Test - public void sensitiveHeadersDefaults() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setSensitiveHeaders(Collections.singleton("x-bar")); - this.request.setRequestURI("/api/foo/1"); - this.routeLocator.addRoute("/foo/**", "foo"); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - @SuppressWarnings("unchecked") - Set sensitiveHeaders = (Set) ctx - .get(ProxyRequestHelper.IGNORED_HEADERS); - assertThat(sensitiveHeaders.containsAll(Collections.singletonList("x-bar"))) - .as("sensitiveHeaders is wrong: " + sensitiveHeaders).isTrue(); - assertThat(sensitiveHeaders.contains("Cookie")).as("sensitiveHeaders is wrong") - .isFalse(); - } - - @Test - public void sensitiveHeadersCaseInsensitive() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setSensitiveHeaders(Collections.singleton("X-bAr")); - this.request.setRequestURI("/api/foo/1"); - this.routeLocator.addRoute("/foo/**", "foo"); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - @SuppressWarnings("unchecked") - Set sensitiveHeaders = (Set) ctx - .get(ProxyRequestHelper.IGNORED_HEADERS); - assertThat(sensitiveHeaders.containsAll(Collections.singletonList("x-bar"))) - .as("sensitiveHeaders is wrong: " + sensitiveHeaders).isTrue(); - } - - @Test - public void sensitiveHeadersOverrideCaseInsensitive() throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setSensitiveHeaders(Collections.singleton("X-bAr")); - this.request.setRequestURI("/api/foo/1"); - ZuulRoute route = new ZuulRoute("/foo/**", "foo"); - route.setSensitiveHeaders(Collections.singleton("X-Foo")); - this.routeLocator.addRoute(route); - this.filter.run(); - RequestContext ctx = RequestContext.getCurrentContext(); - @SuppressWarnings("unchecked") - Set sensitiveHeaders = (Set) ctx - .get(ProxyRequestHelper.IGNORED_HEADERS); - assertThat(sensitiveHeaders.containsAll(Collections.singletonList("x-foo"))) - .as("sensitiveHeaders is wrong: " + sensitiveHeaders).isTrue(); - } - - @Test - public void ignoredHeadersAlreadySetInRequestContextDontGetOverridden() - throws Exception { - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.properties.setSensitiveHeaders(Collections.singleton("x-bar")); - this.request.setRequestURI("/api/foo/1"); - this.routeLocator.addRoute("/foo/**", "foo"); - RequestContext ctx = RequestContext.getCurrentContext(); - ctx.set(ProxyRequestHelper.IGNORED_HEADERS, - new HashSet<>(Arrays.asList("x-foo"))); - this.filter.run(); - @SuppressWarnings("unchecked") - Set sensitiveHeaders = (Set) ctx - .get(ProxyRequestHelper.IGNORED_HEADERS); - assertThat(sensitiveHeaders.containsAll(Arrays.asList("x-bar", "x-foo"))) - .as("sensitiveHeaders is wrong: " + sensitiveHeaders).isTrue(); - } - - @Test - public void urlProperlyDecodedWhenCharacterEncodingIsSet() throws Exception { - this.request.setCharacterEncoding("UTF-8"); - this.properties.setPrefix("/api"); - this.properties.setStripPrefix(true); - this.request.setRequestURI("/api/foo/ol%C3%A9%D7%93%D7%A8%D7%A2%D7%A7"); - this.routeLocator.addRoute("/foo/**", "foo"); - RequestContext ctx = RequestContext.getCurrentContext(); - this.filter.run(); - String decodedRequestURI = (String) ctx.get(REQUEST_URI_KEY); - assertThat(decodedRequestURI.equals("/oléדרעק")).isTrue(); - } - - @Test - public void headersAreProperlyIgnored() throws Exception { - proxyRequestHelper.addIgnoredHeaders("x-forwarded-host", "x-forwarded-port"); - request.addHeader("x-forwarded-host", "B,127.0.0.1:8080"); - request.addHeader("x-forwarded-port", "A,8080"); - request.addHeader("x-forwarded-proto", "C,http"); - - MultiValueMap result = proxyRequestHelper - .buildZuulRequestHeaders(request); - - assertThat(result.containsKey("x-forwarded-proto")).isTrue(); - assertThat(result.containsKey("x-forwarded-host")).isFalse(); - assertThat(result.containsKey("x-forwarded-port")).isFalse(); - } - - @Test - public void nullDispatcherServletPath() { - this.filter = new PreDecorationFilter(this.routeLocator, null, this.properties, - this.proxyRequestHelper); - - String forwardUri = this.filter.getForwardUri("/mypath"); - assertThat(forwardUri).isEqualTo("/mypath"); - } - - private Object getHeader(List> headers, String key) { - String value = null; - for (Pair pair : headers) { - if (pair.first().toLowerCase().equals(key.toLowerCase())) { - value = pair.second(); - break; - } - } - return value; - } - - private void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/EagerLoadOfZuulConfigurationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/EagerLoadOfZuulConfigurationTests.java deleted file mode 100644 index eb9f69c69..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/EagerLoadOfZuulConfigurationTests.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.zuul.filters.route; - -import java.util.concurrent.atomic.AtomicInteger; - -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringRunner.class) -@SpringBootTest(properties = { "zuul.routes.eagerroute.service-id=eager", - "zuul.ribbon.eager-load.enabled=true" }) -@DirtiesContext -public class EagerLoadOfZuulConfigurationTests { - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void testEagerLoading() { - // Child context FooConfig should have been eagerly instantiated.. - assertThat(Foo.getInstanceCount()).isEqualTo(1); - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - @EnableZuulProxy - @RibbonClients(@RibbonClient(name = "eager", configuration = FooConfig.class)) - static class TestConfig { - - } - - static class Foo { - - private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger(); - - Foo() { - INSTANCE_COUNT.incrementAndGet(); - } - - public static int getInstanceCount() { - return INSTANCE_COUNT.get(); - } - - } - - static class FooConfig { - - @Bean - public Foo foo() { - return new Foo(); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/LazyLoadOfZuulConfigurationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/LazyLoadOfZuulConfigurationTests.java deleted file mode 100644 index b8c89b800..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/LazyLoadOfZuulConfigurationTests.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route; - -import java.util.concurrent.atomic.AtomicInteger; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - properties = { "zuul.routes.lazyroute.service-id=lazy", - "zuul.routes.lazyroute.path=/lazy/**", - "zuul.ribbon.eager-load.enabled=false" }) -@DirtiesContext -public class LazyLoadOfZuulConfigurationTests { - - @LocalServerPort - protected int port; - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void testLazyLoading() { - // Child context FooConfig should be lazily created.. - assertThat(Foo.getInstanceCount()).isEqualTo(0); - - String uri = String.format("http://localhost:%d/lazy/sample", this.port); - - ResponseEntity result = new TestRestTemplate().getForEntity(uri, - String.class); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - - // the instance should be available now.. - assertThat(Foo.getInstanceCount()).isEqualTo(1); - - assertThat(result.getBody()).isEqualTo("sample"); - } - - @EnableAutoConfiguration - @SpringBootConfiguration - @EnableZuulProxy - @RestController - @RibbonClient(name = "lazy", configuration = FooConfig.class) - @Import(NoSecurityConfiguration.class) - static class TestConfig { - - @RequestMapping("/sample") - public String sampleEndpoint() { - return "sample"; - } - - } - - static class Foo { - - private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger(); - - Foo() { - INSTANCE_COUNT.incrementAndGet(); - } - - public static int getInstanceCount() { - return INSTANCE_COUNT.get(); - } - - } - - static class FooConfig { - - @Bean - public Foo foo() { - return new Foo(); - } - - @LocalServerPort - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommandTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommandTests.java deleted file mode 100644 index 14f203441..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommandTests.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.net.URI; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Collections; - -import com.netflix.client.http.HttpRequest; -import com.netflix.client.http.HttpRequest.Verb; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.StreamUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - */ -public class RestClientRibbonCommandTests { - - private ZuulProperties zuulProperties; - - @Before - public void setUp() { - zuulProperties = new ZuulProperties(); - } - - /** - * Tests old constructors kept for backwards compatibility with Spring Cloud Sleuth - * 1.x versions - */ - @Test - @Deprecated - public void testNullEntityWithOldConstruct() throws Exception { - String uri = "https://example.com"; - LinkedMultiValueMap headers = new LinkedMultiValueMap<>(); - headers.add("my-header", "my-value"); - LinkedMultiValueMap params = new LinkedMultiValueMap<>(); - params.add("myparam", "myparamval"); - RestClientRibbonCommand command = new RestClientRibbonCommand("cmd", null, - Verb.GET, uri, false, headers, params, null); - - HttpRequest request = command.createRequest(); - - assertThat(request.getUri().toString()).as("uri is wrong").startsWith(uri); - assertThat(request.getHttpHeaders().getFirstValue("my-header")) - .as("my-header is wrong").isEqualTo("my-value"); - assertThat(request.getQueryParams().get("myparam").iterator().next()) - .as("myparam is missing").isEqualTo("myparamval"); - - command = new RestClientRibbonCommand("cmd", null, new RibbonCommandContext( - "example", "GET", uri, false, headers, params, null), zuulProperties); - - request = command.createRequest(); - - assertThat(request.getUri().toString()).as("uri is wrong").startsWith(uri); - assertThat(request.getHttpHeaders().getFirstValue("my-header")) - .as("my-header is wrong").isEqualTo("my-value"); - assertThat(request.getQueryParams().get("myparam").iterator().next()) - .as("myparam is missing").isEqualTo("myparamval"); - } - - @Test - public void testNullEntity() throws Exception { - String uri = "https://example.com"; - LinkedMultiValueMap headers = new LinkedMultiValueMap<>(); - headers.add("my-header", "my-value"); - LinkedMultiValueMap params = new LinkedMultiValueMap<>(); - params.add("myparam", "myparamval"); - RestClientRibbonCommand command = new RestClientRibbonCommand( - "cmd", null, new RibbonCommandContext("example", "GET", uri, false, - headers, params, null, new ArrayList()), - zuulProperties); - - HttpRequest request = command.createRequest(); - - assertThat(request.getUri().toString()).as("uri is wrong").startsWith(uri); - assertThat(request.getHttpHeaders().getFirstValue("my-header")) - .as("my-header is wrong").isEqualTo("my-value"); - assertThat(request.getQueryParams().get("myparam").iterator().next()) - .as("myparam is missing").isEqualTo("myparamval"); - } - - @Test - // this situation happens, see - // https://github.com/spring-cloud/spring-cloud-netflix/issues/1042#issuecomment-227723877 - public void testEmptyEntityGet() throws Exception { - String entityValue = ""; - testEntity(entityValue, new ByteArrayInputStream(entityValue.getBytes()), false, - "GET"); - } - - @Test - public void testNonEmptyEntityPost() throws Exception { - String entityValue = "abcd"; - testEntity(entityValue, new ByteArrayInputStream(entityValue.getBytes()), true, - "POST"); - } - - @Test - public void testNonEmptyEntityDelete() throws Exception { - String entityValue = "abcd"; - testEntity(entityValue, new ByteArrayInputStream(entityValue.getBytes()), true, - "DELETE"); - } - - void testEntity(String entityValue, ByteArrayInputStream requestEntity, - boolean addContentLengthHeader, String method) throws Exception { - String lengthString = String.valueOf(entityValue.length()); - Long length = null; - URI uri = URI.create("https://example.com"); - LinkedMultiValueMap headers = new LinkedMultiValueMap<>(); - if (addContentLengthHeader) { - headers.add("Content-Length", lengthString); - length = (long) entityValue.length(); - } - - RibbonRequestCustomizer requestCustomizer = new RibbonRequestCustomizer() { - @Override - public boolean accepts(Class builderClass) { - return builderClass == HttpRequest.Builder.class; - } - - @Override - public void customize(HttpRequest.Builder builder) { - builder.header("from-customizer", "foo"); - } - }; - RibbonCommandContext context = new RibbonCommandContext("example", method, - uri.toString(), false, headers, new LinkedMultiValueMap(), - requestEntity, Collections.singletonList(requestCustomizer)); - context.setContentLength(length); - RestClientRibbonCommand command = new RestClientRibbonCommand("cmd", null, - context, zuulProperties); - - HttpRequest request = command.createRequest(); - - assertThat(request.getUri().toString()).as("uri is wrong") - .startsWith(uri.toString()); - if (addContentLengthHeader) { - assertThat(request.getHttpHeaders().getFirstValue("Content-Length")) - .as("Content-Length is wrong").isEqualTo(lengthString); - } - assertThat(request.getHttpHeaders().getFirstValue("from-customizer")) - .as("from-customizer is wrong").isEqualTo("foo"); - - if (method.equalsIgnoreCase("DELETE")) { - assertThat(request.getEntity()).as("entity is was non-null").isNull(); - } - else { - assertThat(request.getEntity()).as("entity is missing").isNotNull(); - assertThat(InputStream.class.isAssignableFrom(request.getEntity().getClass())) - .as("entity is wrong type").isTrue(); - InputStream entity = (InputStream) request.getEntity(); - String string = StreamUtils.copyToString(entity, Charset.forName("UTF-8")); - assertThat(string).as("content is wrong").isEqualTo(entityValue); - } - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilterLoadBalancerKeyIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilterLoadBalancerKeyIntegrationTests.java deleted file mode 100644 index d75c123ec..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilterLoadBalancerKeyIntegrationTests.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.loadbalancer.AvailabilityFilteringRule; -import com.netflix.loadbalancer.IRule; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.LOAD_BALANCER_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; - -/** - * @author Yongsung Yoon - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = CanaryTestZuulProxyApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - value = { "zuul.routes.simple.path: /simple/**" }) -@DirtiesContext -public class RibbonRoutingFilterLoadBalancerKeyIntegrationTests { - - @Autowired - private TestRestTemplate testRestTemplate; - - @Before - public void setTestRequestContext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - @Test - public void invokeWithUserDefinedCanaryHeader() { - HttpHeaders headers = new HttpHeaders(); - headers.set("X-Canary-Test", "true"); - - ResponseEntity result = testRestTemplate.exchange("/simple/hello", - HttpMethod.GET, new HttpEntity<>(headers), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("canary"); - } - - @Test - public void invokeWithoutUserDefinedCanaryHeader() { - HttpHeaders headers = new HttpHeaders(); - ResponseEntity result = testRestTemplate.exchange("/simple/hello", - HttpMethod.GET, new HttpEntity<>(headers), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - } - -} - -@Configuration(proxyBeanMethods = false) -@EnableAutoConfiguration -@RestController -@EnableZuulProxy -@RibbonClient(name = "simple", configuration = CanaryTestRibbonClientConfiguration.class) -@Import(NoSecurityConfiguration.class) -class CanaryTestZuulProxyApplication { - - @RequestMapping(value = "/hello", method = RequestMethod.GET) - public String hello() { - return "canary"; - } - - @Bean - public ZuulFilter testCanarySupportPreFilter() { - return new ZuulFilter() { - @Override - public Object run() { - RequestContext context = RequestContext.getCurrentContext(); - if (checkIfCanaryRequest(context)) { - context.set(LOAD_BALANCER_KEY, "canary"); // set loadBalancerKey for - // IRule - } - return null; - } - - private boolean checkIfCanaryRequest(RequestContext context) { - HttpServletRequest request = context.getRequest(); - String canaryHeader = request.getHeader("X-Canary-Test"); // user defined - // header - - if ((canaryHeader != null) && (canaryHeader.equalsIgnoreCase("true"))) { - return true; - } - return false; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public int filterOrder() { - return 0; - } - }; - } - -} - -@Configuration(proxyBeanMethods = false) -class CanaryTestRibbonClientConfiguration { - - @LocalServerPort - private int port; - - private static Server testCanaryInstance; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>( - new Server("normal-routing-notexist-localhost", this.port)); - } - - @Bean - public IRule canaryTestRule() { - if (testCanaryInstance == null) { - testCanaryInstance = new Server("localhost", port); // use test server as a - // canary instance - } - return new TestCanaryRule(); - } - - public static class TestCanaryRule extends AvailabilityFilteringRule { - - @Override - public Server choose(Object key) { - if ((key != null) && (key.equals("canary"))) { - return testCanaryInstance; // choose test canary server instead of normal - // servers. - } - return super.choose(key); // normal routing - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilterTests.java deleted file mode 100644 index 364ca050a..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilterTests.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collections; - -import javax.servlet.http.HttpServletResponse; - -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.ribbon.support.RibbonRequestCustomizer; -import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.LOAD_BALANCER_KEY; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_KEY; - -/** - * @author Spencer Gibb - * @author Yongsung Yoon - * @author Gang Li - */ -public class RibbonRoutingFilterTests { - - private RequestContext requestContext; - - private RibbonRoutingFilter filter; - - @Before - public void setUp() throws Exception { - setUpRequestContext(); - setupRibbonRoutingFilter(); - } - - @After - public void tearDown() throws Exception { - requestContext.unset(); - } - - @Test - public void useServlet31Works() { - assertThat(filter.isUseServlet31()).isTrue(); - } - - @Test - public void testLoadBalancerKeyToRibbonCommandContext() throws Exception { - final String testKey = "testLoadBalancerKey"; - requestContext.set(LOAD_BALANCER_KEY, testKey); - RibbonCommandContext commandContext = filter.buildCommandContext(requestContext); - - assertThat(commandContext.getLoadBalancerKey()).isEqualTo(testKey); - } - - @Test - public void testNullLoadBalancerKeyToRibbonCommandContext() throws Exception { - requestContext.set(LOAD_BALANCER_KEY, null); - RibbonCommandContext commandContext = filter.buildCommandContext(requestContext); - - assertThat(commandContext.getLoadBalancerKey()).isNull(); - } - - @Test - public void testSetResponseWithNonHttpStatusCode() throws Exception { - ClientHttpResponse response = this.createClientHttpResponseWithNonStatus(); - this.filter.setResponse(response); - assertThat(517).isEqualTo(this.requestContext.get("responseStatusCode")); - } - - @Test - public void testSetResponseWithHttpStatusCode() throws Exception { - ClientHttpResponse response = this.createClientHttpResponse(); - this.filter.setResponse(response); - assertThat(200).isEqualTo(this.requestContext.get("responseStatusCode")); - } - - private void setUpRequestContext() { - requestContext = RequestContext.getCurrentContext(); - MockHttpServletRequest mockRequest = new MockHttpServletRequest(); - HttpServletResponse httpServletResponse = new MockHttpServletResponse(); - mockRequest.setMethod("GET"); - mockRequest.setRequestURI("/foo/bar"); - requestContext.setRequest(mockRequest); - requestContext.setRequestQueryParams(Collections.EMPTY_MAP); - requestContext.set(SERVICE_ID_KEY, "testServiceId"); - requestContext.set("response", httpServletResponse); - } - - private void setupRibbonRoutingFilter() { - RibbonCommandFactory factory = mock(RibbonCommandFactory.class); - filter = new RibbonRoutingFilter(new ProxyRequestHelper(new ZuulProperties()), - factory, Collections.emptyList()); - } - - private ClientHttpResponse createClientHttpResponseWithNonStatus() { - return new ClientHttpResponse() { - @Override - public HttpStatus getStatusCode() throws IOException { - return null; - } - - @Override - public int getRawStatusCode() throws IOException { - return 517; - } - - @Override - public String getStatusText() throws IOException { - return "Fail"; - } - - @Override - public void close() { - - } - - @Override - public InputStream getBody() throws IOException { - return new ByteArrayInputStream("Fail".getBytes()); - } - - @Override - public HttpHeaders getHeaders() { - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.setContentType(MediaType.APPLICATION_JSON); - return httpHeaders; - } - }; - } - - private ClientHttpResponse createClientHttpResponse() { - return new ClientHttpResponse() { - @Override - public HttpStatus getStatusCode() throws IOException { - return HttpStatus.OK; - } - - @Override - public int getRawStatusCode() throws IOException { - return 200; - } - - @Override - public String getStatusText() throws IOException { - return "OK"; - } - - @Override - public void close() { - - } - - @Override - public InputStream getBody() throws IOException { - return new ByteArrayInputStream("OK".getBytes()); - } - - @Override - public HttpHeaders getHeaders() { - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.setContentType(MediaType.APPLICATION_JSON); - return httpHeaders; - } - }; - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SendForwardFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SendForwardFilterTests.java deleted file mode 100644 index 2479164c3..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SendForwardFilterTests.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.zuul.context.RequestContext; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_TO_KEY; - -/** - * @author Dave Syer - */ -public class SendForwardFilterTests { - - @After - public void reset() { - RequestContext.getCurrentContext().clear(); - } - - @Before - public void setTestRequestcontext() { - RequestContext context = new RequestContext(); - RequestContext.testSetCurrentContext(context); - } - - @Test - public void runsNormally() { - SendForwardFilter filter = createSendForwardFilter(new MockHttpServletRequest()); - assertThat(filter.shouldFilter()).as("shouldFilter returned false").isTrue(); - filter.run(); - } - - private SendForwardFilter createSendForwardFilter(HttpServletRequest request) { - RequestContext context = new RequestContext(); - context.setRequest(request); - context.setResponse(new MockHttpServletResponse()); - context.set(FORWARD_TO_KEY, "/foo"); - RequestContext.testSetCurrentContext(context); - SendForwardFilter filter = new SendForwardFilter(); - return filter; - } - - @Test - public void doesNotRunTwice() { - SendForwardFilter filter = createSendForwardFilter(new MockHttpServletRequest()); - assertThat(filter.shouldFilter()).as("shouldFilter returned false").isTrue(); - filter.run(); - assertThat(filter.shouldFilter()).as("shouldFilter returned true").isFalse(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterIntegrationTests.java deleted file mode 100644 index e25c4f6b5..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterIntegrationTests.java +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.zip.GZIPOutputStream; - -import javax.servlet.MultipartConfigElement; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpHeaders; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Andreas Kluth - * @author Spencer Gibb - * @author Gang Li - */ -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, - properties = { "server.servlet.context-path: /app" }) -@DirtiesContext -public class SimpleHostRoutingFilterIntegrationTests { - - @LocalServerPort - private int port; - - /* - * @Autowired private SimpleHostRoutingFilter filter; - * - * @Before public void setup() { CounterFactory.initialize(new EmptyCounterFactory()); - * RequestContext.testSetCurrentContext(new RequestContext()); } - * - * @After public void clear() { CounterFactory.initialize(null); - * - * RequestContext.testSetCurrentContext(null); - * RequestContext.getCurrentContext().clear(); } - * - * @Test public void contentLengthNegativeTest() throws IOException { - * contentLengthTest(-1000L); } - * - * @Test public void contentLengthNegativeOneTest() throws IOException { - * contentLengthTest(-1L); } - * - * @Test public void contentLengthZeroTest() throws IOException { - * contentLengthTest(0L); } - * - * @Test public void contentLengthOneTest() throws IOException { - * contentLengthTest(1L); } - * - * @Test public void contentLength1KbTest() throws IOException { - * contentLengthTest(1000L); } - * - * @Test public void contentLength1MbTest() throws IOException { - * contentLengthTest(1000000L); } - * - * @Test public void contentLength1GbTest() throws IOException { - * contentLengthTest(1000000000L); } - * - * @Test public void contentLength2GbTest() throws IOException { - * contentLengthTest(2000000000L); } - * - * @Test public void contentLength3GbTest() throws IOException { - * contentLengthTest(3000000000L); } - * - * @Test public void contentLength4GbTest() throws IOException { - * contentLengthTest(4000000000L); } - * - * @Test public void contentLength5GbTest() throws IOException { - * contentLengthTest(5000000000L); } - * - * @Test public void contentLength6GbTest() throws IOException { - * contentLengthTest(6000000000L); } - * - * @Test public void contentLengthServlet30WithHeaderNegativeTest() throws IOException - * { contentLengthServlet30WithHeaderTest(-1000L); } - * - * @Test public void contentLengthServlet30WithHeaderNegativeOneTest() throws - * IOException { contentLengthServlet30WithHeaderTest(-1L); } - * - * @Test public void contentLengthServlet30WithHeaderZeroTest() throws IOException { - * contentLengthServlet30WithHeaderTest(0L); } - * - * @Test public void contentLengthServlet30WithHeaderOneTest() throws IOException { - * contentLengthServlet30WithHeaderTest(1L); } - * - * @Test public void contentLengthServlet30WithHeader1KbTest() throws IOException { - * contentLengthServlet30WithHeaderTest(1000L); } - * - * @Test public void contentLengthServlet30WithHeader1MbTest() throws IOException { - * contentLengthServlet30WithHeaderTest(1000000L); } - * - * @Test public void contentLengthServlet30WithHeader1GbTest() throws IOException { - * contentLengthServlet30WithHeaderTest(1000000000L); } - * - * @Test public void contentLengthServlet30WithHeader2GbTest() throws IOException { - * contentLengthServlet30WithHeaderTest(2000000000L); } - * - * @Test public void contentLengthServlet30WithHeader3GbTest() throws IOException { - * contentLengthServlet30WithHeaderTest(3000000000L); } - * - * @Test public void contentLengthServlet30WithHeader4GbTest() throws IOException { - * contentLengthServlet30WithHeaderTest(4000000000L); } - * - * @Test public void contentLengthServlet30WithHeader5GbTest() throws IOException { - * contentLengthServlet30WithHeaderTest(5000000000L); } - * - * @Test public void contentLengthServlet30WithHeader6GbTest() throws IOException { - * contentLengthServlet30WithHeaderTest(6000000000L); } - * - * @Test public void contentLengthServlet30WithInvalidLongHeaderTest() throws - * IOException { setupContext(); MockMultipartHttpServletRequest request = - * getMockedReqest(-1L); request.addHeader(HttpHeaders.CONTENT_LENGTH, "InvalidLong"); - * contentLengthTest(-1L, getServlet30Filter(), request); } - * - * @Test public void contentLengthServlet30WithoutHeaderNegativeTest() throws - * IOException { contentLengthServlet30WithoutHeaderTest(-1000L); } - * - * @Test public void contentLengthServlet30WithoutHeaderNegativeOneTest() throws - * IOException { contentLengthServlet30WithoutHeaderTest(-1L); } - * - * @Test public void contentLengthServlet30WithoutHeaderZeroTest() throws IOException - * { contentLengthServlet30WithoutHeaderTest(0L); } - * - * @Test public void contentLengthServlet30WithoutHeaderOneTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(1L); } - * - * @Test public void contentLengthServlet30WithoutHeader1KbTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(1000L); } - * - * @Test public void contentLengthServlet30WithoutHeader1MbTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(1000000L); } - * - * @Test public void contentLengthServlet30WithoutHeader1GbTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(1000000000L); } - * - * @Test public void contentLengthServlet30WithoutHeader2GbTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(2000000000L); } - * - * @Test public void contentLengthServlet30WithoutHeader3GbTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(3000000000L); } - * - * @Test public void contentLengthServlet30WithoutHeader4GbTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(4000000000L); } - * - * @Test public void contentLengthServlet30WithoutHeader5GbTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(5000000000L); } - * - * @Test public void contentLengthServlet30WithoutHeader6GbTest() throws IOException { - * contentLengthServlet30WithoutHeaderTest(6000000000L); } - * - * public void contentLengthTest(Long contentLength) throws IOException { - * setupContext(); - * - * contentLengthTest(contentLength, getFilter(), getMockedReqest(contentLength)); } - * - * public void contentLengthServlet30WithHeaderTest(Long contentLength) throws - * IOException { setupContext(); MockMultipartHttpServletRequest request = - * getMockedReqest(contentLength); request.addHeader(HttpHeaders.CONTENT_LENGTH, - * contentLength); contentLengthTest(contentLength, getServlet30Filter(), request); } - * - * public void contentLengthServlet30WithoutHeaderTest(Long contentLength) throws - * IOException { setupContext(); - * - * //Although contentLength.intValue is not always equals to contentLength, that's the - * expected result when calling // request.getContentLength() from servlet 3.0 - * implementation. contentLengthTest(Long.parseLong("" + contentLength.intValue()), - * getServlet30Filter(), getMockedReqest(contentLength)); } - * - * public MockMultipartHttpServletRequest getMockedReqest(final Long contentLength) - * throws IOException { - * - * MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest() { - * - * @Override public int getContentLength() { return contentLength.intValue(); } - * - * @Override public long getContentLengthLong() { return contentLength; } }; - * - * return request; } - * - * public void contentLengthTest(Long expectedContentLength, SimpleHostRoutingFilter - * filter, MockMultipartHttpServletRequest request) throws IOException { byte[] data = - * "poprqwueproqiwuerpoqweiurpo".getBytes(); MockMultipartFile file = new - * MockMultipartFile("test.zip", "test.zip", "application/zip", data); String boundary - * = "q1w2e3r4t5y6u7i8o9"; request.setContentType("multipart/form-data; boundary=" + - * boundary); request.setContent( createFileContent(data, boundary, "application/zip", - * "test.zip")); request.addFile(file); request.setMethod("POST"); - * request.setParameter("variant", "php"); request.setParameter("os", "mac"); - * request.setParameter("version", "3.4"); request.setRequestURI("/app/echo"); - * - * MockHttpServletResponse response = new MockHttpServletResponse(); - * RequestContext.getCurrentContext().setRequest(request); - * RequestContext.getCurrentContext().setResponse(response); URL url = new - * URL("http://localhost:" + this.port); - * RequestContext.getCurrentContext().set("routeHost", url); filter.run(); - * - * CloseableHttpResponse httpResponse = (CloseableHttpResponse) - * RequestContext.getCurrentContext() .get("zuulResponse"); - * assertThat(httpResponse.getStatusLine().getStatusCode(), equalTo(200)); InputStream - * zuulResponse = httpResponse.getEntity().getContent(); assertThat(zuulResponse, - * not(instanceOf(EmptyInputStream.class))); String responseString = - * IOUtils.toString(new GZIPInputStream( zuulResponse)); - * assertTrue(!responseString.isEmpty()); if (expectedContentLength < 0) { - * assertThat(responseString, containsString("\"" + - * HttpHeaders.TRANSFER_ENCODING.toLowerCase() + "\":\"chunked\"")); - * assertThat(responseString, - * not(containsString(HttpHeaders.CONTENT_LENGTH.toLowerCase()))); } else { - * assertThat(responseString, containsString("\"" + - * HttpHeaders.CONTENT_LENGTH.toLowerCase() + "\":\"" + expectedContentLength + - * "\"")); } } - * - * public byte[] createFileContent(byte[] data, String boundary, String contentType, - * String fileName) { String start = "--" + boundary + - * "\r\n Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + - * "\"\r\n" + "Content-type: " + contentType + "\r\n\r\n"; ; - * - * String end = "\r\n--" + boundary + "--"; // correction suggested @butfly return - * ArrayUtils.addAll(start.getBytes(), ArrayUtils.addAll(data, end.getBytes())); } - * - * @Test public void httpClientDoesNotDecompressEncodedData() throws Exception { - * setupContext(); InputStreamEntity inputStreamEntity = new InputStreamEntity(new - * ByteArrayInputStream(new byte[]{1})); HttpRequest httpRequest = - * getFilter().buildHttpRequest("GET", "/app/compressed/get/1", inputStreamEntity, new - * LinkedMultiValueMap<>(), new LinkedMultiValueMap<>(), new - * MockHttpServletRequest()); - * - * CloseableHttpResponse response = getFilter().newClient().execute(new - * HttpHost("localhost", this.port), httpRequest); assertEquals(200, - * response.getStatusLine().getStatusCode()); byte[] responseBytes = - * copyToByteArray(response.getEntity().getContent()); - * assertTrue(Arrays.equals(GZIPCompression.compress("Get 1"), responseBytes)); } - * - * @Test public void httpClientPreservesUnencodedData() throws Exception { - * setupContext(); InputStreamEntity inputStreamEntity = new InputStreamEntity(new - * ByteArrayInputStream(new byte[]{1})); HttpRequest httpRequest = - * getFilter().buildHttpRequest("GET", "/app/get/1", inputStreamEntity, new - * LinkedMultiValueMap<>(), new LinkedMultiValueMap<>(), new - * MockHttpServletRequest()); - * - * CloseableHttpResponse response = getFilter().newClient().execute(new - * HttpHost("localhost", this.port), httpRequest); assertEquals(200, - * response.getStatusLine().getStatusCode()); String responseString = - * copyToString(response.getEntity().getContent(), Charset.forName("UTF-8")); - * assertTrue("Get 1".equals(responseString)); } - * - * @Test public void redirectTest() throws IOException { setupContext(); - * InputStreamEntity inputStreamEntity = new InputStreamEntity(new - * ByteArrayInputStream(new byte[]{})); HttpRequest httpRequest = - * getFilter().buildHttpRequest("GET", "/app/redirect", inputStreamEntity, new - * LinkedMultiValueMap<>(), new LinkedMultiValueMap<>(), new - * MockHttpServletRequest()); - * - * CloseableHttpResponse response = getFilter().newClient().execute(new - * HttpHost("localhost", this.port), httpRequest); assertEquals(302, - * response.getStatusLine().getStatusCode()); String responseString = - * copyToString(response.getEntity().getContent(), Charset.forName("UTF-8")); - * assertTrue(response.getLastHeader("Location").getValue().contains("/app/get/5")); } - * - * @Test(expected = ZuulRuntimeException.class) public void run() throws Exception { - * setupContext(); MockHttpServletRequest request = new MockHttpServletRequest("POST", - * "/"); request.setContent("{1}".getBytes()); request.addHeader("singleName", - * "singleValue"); request.addHeader("multiName", "multiValue1"); - * request.addHeader("multiName", "multiValue2"); - * RequestContext.getCurrentContext().setRequest(request); URL url = new - * URL("http://localhost:8080"); RequestContext.getCurrentContext().set("routeHost", - * url); getFilter().run(); } - * - * private void setupContext() { } - * - * private SimpleHostRoutingFilter getFilter() { return this.filter; } - * - * private SimpleHostRoutingFilter getServlet30Filter() { SimpleHostRoutingFilter - * filter = getFilter(); filter.setUseServlet31(false); return filter; } - */ - /* - * @Configuration - * - * @EnableConfigurationProperties protected static class TestConfiguration { - * - * @Bean ZuulProperties zuulProperties() { return new ZuulProperties(); } - * - * @Bean ApacheHttpClientFactory clientFactory() {return new - * DefaultApacheHttpClientFactory(HttpClientBuilder.create()); } - * - * @Bean ApacheHttpClientConnectionManagerFactory connectionManagerFactory() { return - * new DefaultApacheHttpClientConnectionManagerFactory(); } - * - * @Bean SimpleHostRoutingFilter simpleHostRoutingFilter(ZuulProperties - * zuulProperties, ApacheHttpClientConnectionManagerFactory connectionManagerFactory, - * ApacheHttpClientFactory clientFactory) { return new SimpleHostRoutingFilter(new - * ProxyRequestHelper(), zuulProperties, connectionManagerFactory, clientFactory); } } - */ - - @Test - public void test() { - - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @RestController - @Import(NoSecurityConfiguration.class) - static class SampleApplication { - - @RequestMapping(value = "/compressed/get/{id}", method = RequestMethod.GET) - public byte[] getCompressed(@PathVariable String id, HttpServletResponse response) - throws IOException { - response.setHeader("content-encoding", "gzip"); - return GZIPCompression.compress("Get " + id); - } - - @RequestMapping(value = "/get/{id}", method = RequestMethod.GET) - public String getString(@PathVariable String id, HttpServletResponse response) - throws IOException { - return "Get " + id; - } - - @RequestMapping(value = "/redirect", method = RequestMethod.GET) - public String redirect(HttpServletResponse response) throws IOException { - response.sendRedirect("/app/get/5"); - return null; - } - - @RequestMapping("/echo") - public Map echoRequestAttributes( - @RequestHeader HttpHeaders httpHeaders, HttpServletRequest request) - throws IOException { - Map result = new HashMap<>(); - result.put("headers", httpHeaders.toSingleValueMap()); - - return result; - } - - @Bean - MultipartConfigElement multipartConfigElement() { - long maxSize = 10L * 1024 * 1024 * 1024; - return new MultipartConfigElement("", maxSize, maxSize, 0); - } - - } - - static class GZIPCompression { - - public static byte[] compress(final String str) throws IOException { - if ((str == null) || (str.length() == 0)) { - return null; - } - ByteArrayOutputStream obj = new ByteArrayOutputStream(); - GZIPOutputStream gzip = new GZIPOutputStream(obj); - gzip.write(str.getBytes("UTF-8")); - gzip.close(); - return obj.toByteArray(); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterTests.java deleted file mode 100644 index 9493c2e9d..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterTests.java +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.net.URL; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.monitoring.CounterFactory; -import org.apache.http.HttpEntityEnclosingRequest; -import org.apache.http.HttpRequest; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.Configurable; -import org.apache.http.client.methods.HttpPatch; -import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.entity.InputStreamEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.assertj.core.api.Assertions; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; -import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientConnectionManagerFactory; -import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientFactory; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.metrics.EmptyCounterFactory; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.ReflectionUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.util.StreamUtils.copyToByteArray; - -/** - * @author Andreas Kluth - * @author Spencer Gibb - * @author Gang Li - * @author Denys Ivano - */ -public class SimpleHostRoutingFilterTests { - - private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - - @Before - public void setup() { - CounterFactory.initialize(new EmptyCounterFactory()); - RequestContext.testSetCurrentContext(new RequestContext()); - } - - @After - public void clear() { - if (this.context != null) { - this.context.close(); - } - CounterFactory.initialize(null); - - RequestContext.testSetCurrentContext(null); - RequestContext.getCurrentContext().clear(); - } - - @Test - public void timeoutPropertiesAreApplied() { - TestPropertyValues - .of("zuul.host.socket-timeout-millis=11000", - "zuul.host.connect-timeout-millis=2100", - "zuul.host.connection-request-timeout-millis=2500") - .applyTo(this.context); - setupContext(); - CloseableHttpClient httpClient = getFilter().newClient(); - Assertions.assertThat(httpClient).isInstanceOf(Configurable.class); - RequestConfig config = ((Configurable) httpClient).getConfig(); - assertThat(config.getSocketTimeout()).isEqualTo(11000); - assertThat(config.getConnectTimeout()).isEqualTo(2100); - assertThat(config.getConnectionRequestTimeout()).isEqualTo(2500); - } - - @Test - public void connectionPropertiesAreApplied() { - TestPropertyValues.of("zuul.host.maxTotalConnections=100", - "zuul.host.maxPerRouteConnections=10", "zuul.host.timeToLive=5", - "zuul.host.timeUnit=SECONDS").applyTo(this.context); - setupContext(); - PoolingHttpClientConnectionManager connMgr = (PoolingHttpClientConnectionManager) getFilter() - .getConnectionManager(); - assertThat(connMgr.getMaxTotal()).isEqualTo(100); - assertThat(connMgr.getDefaultMaxPerRoute()).isEqualTo(10); - Object pool = getField(connMgr, "pool"); - assertThat(pool).hasFieldOrPropertyWithValue("timeToLive", 5L); - assertThat(pool).hasFieldOrPropertyWithValue("timeUnit", TimeUnit.SECONDS); - } - - @SuppressWarnings("unchecked") - private T getField(Object target, String name) { - Field field = ReflectionUtils.findField(target.getClass(), name); - if (field == null) { - throw new IllegalArgumentException( - target.getClass() + " does not have field " + name); - } - ReflectionUtils.makeAccessible(field); - Object value = ReflectionUtils.getField(field, target); - return (T) value; - } - - @Test - public void validateSslHostnamesByDefault() { - setupContext(); - assertThat(getFilter().isSslHostnameValidationEnabled()) - .as("Hostname verification should be enabled by default").isTrue(); - } - - @Test - public void validationOfSslHostnamesCanBeDisabledViaProperty() { - TestPropertyValues.of("zuul.sslHostnameValidationEnabled=false") - .applyTo(this.context); - setupContext(); - assertThat(getFilter().isSslHostnameValidationEnabled()) - .as("Hostname verification should be disabled via property").isFalse(); - } - - @Test - public void defaultPropertiesAreApplied() { - setupContext(); - PoolingHttpClientConnectionManager connMgr = (PoolingHttpClientConnectionManager) getFilter() - .getConnectionManager(); - - assertThat(connMgr.getMaxTotal()).isEqualTo(200); - assertThat(connMgr.getDefaultMaxPerRoute()).isEqualTo(20); - } - - @Test - public void deleteRequestBuiltWithBody() { - setupContext(); - InputStreamEntity inputStreamEntity = new InputStreamEntity( - new ByteArrayInputStream(new byte[] { 1 })); - HttpRequest httpRequest = getFilter().buildHttpRequest("DELETE", "uri", - inputStreamEntity, new LinkedMultiValueMap<>(), - new LinkedMultiValueMap<>(), new MockHttpServletRequest()); - - assertThat(httpRequest instanceof HttpEntityEnclosingRequest).isTrue(); - HttpEntityEnclosingRequest httpEntityEnclosingRequest = (HttpEntityEnclosingRequest) httpRequest; - assertThat(httpEntityEnclosingRequest.getEntity() != null).isTrue(); - } - - @Test - public void zuulHostKeysUpdateHttpClient() { - setupContext(); - SimpleHostRoutingFilter filter = getFilter(); - CloseableHttpClient httpClient = extractHttpClient(filter); - EnvironmentChangeEvent event = new EnvironmentChangeEvent( - Collections.singleton("zuul.host.mykey")); - filter.onApplicationEvent(event); - CloseableHttpClient newhttpClient = extractHttpClient(filter); - Assertions.assertThat(httpClient).isNotEqualTo(newhttpClient); - } - - private CloseableHttpClient extractHttpClient(SimpleHostRoutingFilter filter) { - return (CloseableHttpClient) ReflectionTestUtils.getField(filter, "httpClient"); - } - - @Test - public void zuulHostKeysUpdateHttpClientConnectionManagerIsNotShutDown() { - setupContext(); - SimpleHostRoutingFilter filter = getFilter(); - EnvironmentChangeEvent event = new EnvironmentChangeEvent( - Collections.singleton("zuul.host.mykey")); - filter.onApplicationEvent(event); - - CloseableHttpClient httpClient = extractHttpClient(filter); - PoolingHttpClientConnectionManager connMgr = (PoolingHttpClientConnectionManager) extractConnectionManager( - httpClient); - AtomicBoolean isShutDown = getField(connMgr, "isShutDown"); - assertThat(isShutDown.get()).as("Connection manager shut down").isFalse(); - Object pool = getField(connMgr, "pool"); - assertThat(pool).hasFieldOrPropertyWithValue("isShutDown", false); - } - - private HttpClientConnectionManager extractConnectionManager( - CloseableHttpClient httpClient) { - // Default implementation is org.apache.http.impl.client.InternalHttpClient - return getField(httpClient, "connManager"); - } - - @Test - public void zuulHostKeysUpdateHttpClientUsesNewConnectionManager() { - setupContext(); - SimpleHostRoutingFilter filter = getFilter(); - PoolingHttpClientConnectionManager connMgr = (PoolingHttpClientConnectionManager) filter - .getConnectionManager(); - EnvironmentChangeEvent event = new EnvironmentChangeEvent( - Collections.singleton("zuul.host.mykey")); - filter.onApplicationEvent(event); - - PoolingHttpClientConnectionManager newConnMgr = (PoolingHttpClientConnectionManager) filter - .getConnectionManager(); - CloseableHttpClient httpClient = extractHttpClient(filter); - HttpClientConnectionManager usedConnMgr = extractConnectionManager(httpClient); - assertThat(usedConnMgr).isNotEqualTo(connMgr); - assertThat(usedConnMgr).isEqualTo(newConnMgr); - } - - @Test - public void zuulHostKeysUpdateConnectionManagerPropertiesAreChanged() { - setupContext(); - SimpleHostRoutingFilter filter = getFilter(); - ZuulProperties.Host host = context.getBean(ZuulProperties.class).getHost(); - host.setMaxTotalConnections(50); - host.setMaxPerRouteConnections(10); - host.setTimeToLive(10); - host.setTimeUnit(TimeUnit.SECONDS); - EnvironmentChangeEvent event = new EnvironmentChangeEvent( - new HashSet<>(Arrays.asList("zuul.host.maxTotalConnections", - "zuul.host.maxPerRouteConnections", "zuul.host.timeToLive", - "zuul.host.timeUnit"))); - filter.onApplicationEvent(event); - - PoolingHttpClientConnectionManager connMgr = (PoolingHttpClientConnectionManager) filter - .getConnectionManager(); - assertThat(connMgr.getMaxTotal()).isEqualTo(50); - assertThat(connMgr.getDefaultMaxPerRoute()).isEqualTo(10); - Object pool = getField(connMgr, "pool"); - assertThat(pool).hasFieldOrPropertyWithValue("timeToLive", 10L); - assertThat(pool).hasFieldOrPropertyWithValue("timeUnit", TimeUnit.SECONDS); - } - - @Test - public void getRequestBody() throws Exception { - setupContext(); - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); - request.setContent("{1}".getBytes()); - request.addHeader("singleName", "singleValue"); - request.addHeader("multiName", "multiValue1"); - request.addHeader("multiName", "multiValue2"); - RequestContext.getCurrentContext().setRequest(request); - InputStream inputStream = getFilter().getRequestBody(request); - assertThat(Arrays.equals("{1}".getBytes(), copyToByteArray(inputStream))) - .isTrue(); - } - - @Test - public void putRequestBuiltWithBody() { - setupContext(); - InputStreamEntity inputStreamEntity = new InputStreamEntity( - new ByteArrayInputStream(new byte[] { 1 })); - HttpRequest httpRequest = getFilter().buildHttpRequest("PUT", "uri", - inputStreamEntity, new LinkedMultiValueMap<>(), - new LinkedMultiValueMap<>(), new MockHttpServletRequest()); - - assertThat(httpRequest instanceof HttpEntityEnclosingRequest).isTrue(); - HttpEntityEnclosingRequest httpEntityEnclosingRequest = (HttpEntityEnclosingRequest) httpRequest; - assertThat(httpEntityEnclosingRequest.getEntity() != null).isTrue(); - } - - @Test - public void postRequestBuiltWithBody() { - setupContext(); - InputStreamEntity inputStreamEntity = new InputStreamEntity( - new ByteArrayInputStream(new byte[] { 1 })); - HttpRequest httpRequest = getFilter().buildHttpRequest("POST", "uri", - inputStreamEntity, new LinkedMultiValueMap<>(), - new LinkedMultiValueMap<>(), new MockHttpServletRequest()); - - assertThat(httpRequest instanceof HttpEntityEnclosingRequest).isTrue(); - HttpEntityEnclosingRequest httpEntityEnclosingRequest = (HttpEntityEnclosingRequest) httpRequest; - assertThat(httpEntityEnclosingRequest.getEntity() != null).isTrue(); - } - - @Test - public void pathRequestBuiltWithBody() { - setupContext(); - InputStreamEntity inputStreamEntity = new InputStreamEntity( - new ByteArrayInputStream(new byte[] { 1 })); - HttpRequest httpRequest = getFilter().buildHttpRequest("PATCH", "uri", - inputStreamEntity, new LinkedMultiValueMap<>(), - new LinkedMultiValueMap<>(), new MockHttpServletRequest()); - - HttpPatch basicHttpRequest = (HttpPatch) httpRequest; - assertThat(basicHttpRequest.getEntity() != null).isTrue(); - } - - @Test - public void shouldFilterFalse() { - setupContext(); - assertThat(getFilter().shouldFilter()).isEqualTo(false); - } - - @Test - public void shouldFilterTrue() throws Exception { - setupContext(); - RequestContext.getCurrentContext().set("routeHost", - new URL("http://localhost:8080")); - RequestContext.getCurrentContext().set("sendZuulResponse", true); - assertThat(getFilter().shouldFilter()).isEqualTo(true); - } - - @Test - public void filterOrder() { - setupContext(); - assertThat(getFilter().filterOrder()).isEqualTo(100); - } - - private void setupContext() { - this.context.register(PropertyPlaceholderAutoConfiguration.class, - TestConfiguration.class); - this.context.refresh(); - } - - private SimpleHostRoutingFilter getFilter() { - return this.context.getBean(SimpleHostRoutingFilter.class); - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties - protected static class TestConfiguration { - - @Bean - ZuulProperties zuulProperties() { - return new ZuulProperties(); - } - - @Bean - ApacheHttpClientFactory clientFactory() { - return new DefaultApacheHttpClientFactory(HttpClientBuilder.create()); - } - - @Bean - ApacheHttpClientConnectionManagerFactory connectionManagerFactory() { - return new DefaultApacheHttpClientConnectionManagerFactory(); - } - - @Bean - SimpleHostRoutingFilter simpleHostRoutingFilter(ZuulProperties zuulProperties, - ApacheHttpClientConnectionManagerFactory connectionManagerFactory, - ApacheHttpClientFactory clientFactory) { - return new SimpleHostRoutingFilter(new ProxyRequestHelper(zuulProperties), - zuulProperties, connectionManagerFactory, clientFactory); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactoryTest.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactoryTest.java deleted file mode 100644 index f834472a4..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactoryTest.java +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.zuul.filters.route.apache; - -import java.util.HashSet; - -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.client.config.IClientConfigKey; -import com.netflix.config.ConfigurationManager; -import com.netflix.hystrix.strategy.properties.HystrixPropertiesFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * @author Ryan Baxter - * @author Gang Li - */ -public class HttpClientRibbonCommandFactoryTest { - - SpringClientFactory springClientFactory; - - ZuulProperties zuulProperties; - - HttpClientRibbonCommandFactory ribbonCommandFactory; - - @Before - public void setup() { - this.springClientFactory = mock(SpringClientFactory.class); - this.zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - doReturn(loadBalancingHttpClient).when(this.springClientFactory) - .getClient(anyString(), eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(this.springClientFactory) - .getClientConfig(anyString()); - this.ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - } - - @After - public void after() { - ConfigurationManager.getConfigInstance().clear(); - HystrixPropertiesFactory.reset(); - } - - @Test - public void testHystrixTimeoutValue() throws Exception { - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = this.ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(4000); - } - - @Test - public void testHystrixTimeoutValueSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 50); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = this.ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(50); - } - - @Test - public void testHystrixTimeoutValueCommandSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.service.execution.isolation.thread.timeoutInMilliseconds", - 50); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = this.ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(50); - } - - @Test - public void testHystrixTimeoutValueCommandAndDefaultSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 30); - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.service.execution.isolation.thread.timeoutInMilliseconds", - 50); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = this.ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(50); - } - - @Test - public void testHystrixTimeoutValueRibbonTimeouts() throws Exception { - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(1200); - } - - @Test - public void testHystrixDefaultAndRibbonSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 30); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(30); - } - - @Test - public void testHystrixCommandAndRibbonSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 30); - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.service.execution.isolation.thread.timeoutInMilliseconds", - 50); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(50); - } - - @Test - public void testDefaultRibbonSetting() throws Exception { - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory commandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(4000); - } - - @Test - public void testRibbonTimeoutAndRibbonRetriesDefaultAndNameSpaceSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.test.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.test.ReadTimeout", - 1000); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(1200); - } - - @Test - public void testRibbonTimeoutAndRibbonRetriesDefaultAndDefaultSpaceSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(4000); - } - - @Test - public void testRibbonTimeoutAndRibbonNameSpaceRetriesDefaultAndDefaultSpaceSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.test.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(4000); - } - - @Test - public void testRibbonRetriesAndRibbonTimeoutSetting() throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(3600); - } - - @Test - public void testRibbonCommandRetriesAndRibbonCommandTimeoutSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(12000); - } - - @Test - public void testRibbonCommandRetriesAndRibbonCommandTimeoutPartOfSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - RibbonLoadBalancingHttpClient loadBalancingHttpClient = mock( - RibbonLoadBalancingHttpClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(RibbonLoadBalancingHttpClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - HttpClientRibbonCommandFactory ribbonCommandFactory = new HttpClientRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - HttpClientRibbonCommand ribbonCommand = ribbonCommandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(6000); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFallbackTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFallbackTests.java deleted file mode 100644 index f7ff2cef7..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFallbackTests.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2016-2019 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 - * - * https://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.zuul.filters.route.apache; - -import com.netflix.zuul.context.RequestContext; -import org.junit.Before; -import org.junit.runner.RunWith; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.filters.route.support.RibbonCommandFallbackTests; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = RibbonCommandFallbackTests.TestConfig.class, - webEnvironment = RANDOM_PORT, properties = { "zuul.routes.simple: /simple/**", - "zuul.routes.another: /another/twolevel/**", "ribbon.ReadTimeout: 1" }) -@DirtiesContext -public class HttpClientRibbonCommandFallbackTests extends RibbonCommandFallbackTests { - - @Before - public void init() { - RequestContext.getCurrentContext().clear(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandIntegrationTests.java deleted file mode 100644 index de6c7c2f0..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandIntegrationTests.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route.apache; - -import java.util.Collections; -import java.util.Set; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.netflix.client.RetryHandler; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.support.ZuulProxyTestBase; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.util.WebUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.http.HttpHeaders.SET_COOKIE; - -/** - * @author Spencer Gibb - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = HttpClientRibbonCommandIntegrationTests.TestConfig.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "zuul.routes.other: /test/**=http://localhost:7777/local", - "zuul.routes.another: /another/twolevel/**", - "zuul.routes.simple: /simple/**", "zuul.routes.singleton.id: singleton", - "zuul.routes.singleton.path: /singleton/**", - "zuul.routes.singleton.sensitiveHeaders: ", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase { - - @Before - public void init() { - super.setTestRequestcontext(); - } - - @Test - public void patchOnSelfViaRibbonRoutingFilter() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/local/1", HttpMethod.PATCH, - new HttpEntity<>("TestPatch"), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Patched 1!"); - } - - @Test - public void postOnSelfViaRibbonRoutingFilter() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/local/1", HttpMethod.POST, - new HttpEntity<>("TestPost"), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted 1!"); - } - - @Test - public void deleteOnSelfViaRibbonRoutingFilter() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/local/1", HttpMethod.DELETE, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Deleted 1!"); - } - - @Test - public void ribbonLoadBalancingHttpClientCookiePolicy() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/downstream_cookie", - HttpMethod.POST, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Cookie 434354454!"); - assertThat(result.getHeaders().getFirst(SET_COOKIE)).isNull(); - - // if new instance of RibbonLoadBalancingHttpClient is getting created every time - // and HttpClient is not reused then there are no concerns for the shared cookie - // storage - // but since https://github.com/spring-cloud/spring-cloud-netflix/issues/1150 is - // on the way a - result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/singleton/downstream_cookie", - HttpMethod.POST, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Cookie 434354454!"); - assertThat(result.getHeaders().getFirst(SET_COOKIE)) - .isEqualTo("jsessionid=434354454"); - - result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/singleton/downstream_cookie", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Cookie null!"); - } - - @Test - public void ribbonCommandFactoryOverridden() { - assertThat(this.ribbonCommandFactory instanceof HttpClientRibbonCommandFactory) - .as("ribbonCommandFactory not a HttpClientRibbonCommandFactory").isTrue(); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @RibbonClients({ @RibbonClient(name = "simple", - configuration = ZuulProxyTestBase.SimpleRibbonClientConfiguration.class), - @RibbonClient(name = "another", - configuration = ZuulProxyTestBase.AnotherRibbonClientConfiguration.class), - @RibbonClient(name = "singleton", - configuration = SingletonRibbonClientConfiguration.class) }) - @Import(NoSecurityConfiguration.class) - static class TestConfig extends ZuulProxyTestBase.AbstractZuulProxyApplication { - - @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); - - @RequestMapping(value = "/local/{id}", method = RequestMethod.PATCH) - public String patch(@PathVariable final String id, - @RequestBody final String body) { - return "Patched " + id + "!"; - } - - @RequestMapping(value = "/downstream_cookie", method = RequestMethod.POST) - public String setDownstreamCookie(HttpServletResponse response) { - response.addCookie(new Cookie("jsessionid", "434354454")); - return "Cookie 434354454!"; - } - - @RequestMapping(value = "/downstream_cookie", method = RequestMethod.GET) - public String readDownstreamCookie(HttpServletRequest request) { - final Cookie cookie = WebUtils.getCookie(request, "jsessionid"); - return "Cookie " + cookie + "!"; - } - - @Bean - public RibbonCommandFactory ribbonCommandFactory( - final SpringClientFactory clientFactory) { - return new HttpClientRibbonCommandFactory(clientFactory, new ZuulProperties(), - zuulFallbackProviders); - } - - @Bean - public ZuulProxyTestBase.MyErrorController myErrorController( - ErrorAttributes errorAttributes) { - return new ZuulProxyTestBase.MyErrorController(errorAttributes); - } - - } - - // Load balancer with fixed server list and defined ribbon rest client - @Configuration(proxyBeanMethods = false) - public static class SingletonRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - @Bean - public RibbonLoadBalancingHttpClient ribbonClient(IClientConfig config, - ILoadBalancer loadBalancer, RetryHandler retryHandler) { - final RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient( - config, new DefaultServerIntrospector()); - client.setLoadBalancer(loadBalancer); - client.setRetryHandler(retryHandler); - return client; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonRetryIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonRetryIntegrationTests.java deleted file mode 100644 index cb188798b..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonRetryIntegrationTests.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route.apache; - -import org.junit.runner.RunWith; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.filters.route.support.RibbonRetryIntegrationTestBase; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = RibbonRetryIntegrationTestBase.RetryableTestConfig.class, - // - webEnvironment = RANDOM_PORT, properties = { "zuul.retryable: false", /* - * Disable - * retry - * by - * default, - * have - * each - * route - * enable - * it - */ - "hystrix.command.default.execution.timeout.enabled: false", /* - * Disable - * hystrix so - * its timeout - * doesnt get - * in the way - */ - "ribbon.ReadTimeout: 1000", /* - * Make sure ribbon will timeout before the - * thread is done sleeping - */ - "zuul.routes.retryable.id: retryable", - "zuul.routes.retryable.path: /retryable/**", - "zuul.routes.retryable.retryable: true", - "retryable.ribbon.OkToRetryOnAllOperations: true", - "retryable.ribbon.MaxAutoRetries: 1", - "retryable.ribbon.MaxAutoRetriesNextServer: 1", - "zuul.routes.getretryable.id: getretryable", - "zuul.routes.getretryable.path: /getretryable/**", - "zuul.routes.getretryable.retryable: true", - "getretryable.ribbon.MaxAutoRetries: 1", - "getretryable.ribbon.MaxAutoRetriesNextServer: 1", - "zuul.routes.disableretry.id: disableretry", - "zuul.routes.disableretry.path: /disableretry/**", - "zuul.routes.disableretry.retryable: false", /* - * This will override the - * global - */ - "disableretry.ribbon.MaxAutoRetries: 1", - "disableretry.ribbon.MaxAutoRetriesNextServer: 1", - "zuul.routes.globalretrydisabled: /globalretrydisabled/**", - "globalretrydisabled.ribbon.MaxAutoRetries: 1", - "globalretrydisabled.ribbon.MaxAutoRetriesNextServer: 1", - "retryable.ribbon.retryableStatusCodes: 404,403" }) -@DirtiesContext -public class HttpClientRibbonRetryIntegrationTests - extends RibbonRetryIntegrationTestBase { - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactoryTest.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactoryTest.java deleted file mode 100644 index 2ed90fc7c..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactoryTest.java +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.zuul.filters.route.okhttp; - -import java.util.HashSet; - -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.client.config.IClientConfigKey; -import com.netflix.config.ConfigurationManager; -import com.netflix.hystrix.strategy.properties.HystrixPropertiesFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * @author Ryan Baxter - * @author Gang Li - */ -public class OkHttpRibbonCommandFactoryTest { - - SpringClientFactory springClientFactory; - - ZuulProperties zuulProperties; - - OkHttpRibbonCommandFactory commandFactory; - - @Before - public void setup() { - this.springClientFactory = mock(SpringClientFactory.class); - this.zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - doReturn(loadBalancingHttpClient).when(this.springClientFactory) - .getClient(anyString(), eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(this.springClientFactory) - .getClientConfig(anyString()); - commandFactory = new OkHttpRibbonCommandFactory(springClientFactory, - zuulProperties, new HashSet()); - } - - @After - public void after() { - ConfigurationManager.getConfigInstance().clear(); - HystrixPropertiesFactory.reset(); - } - - @Test - public void testHystrixTimeoutValue() throws Exception { - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = this.commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(4000); - } - - @Test - public void testHystrixTimeoutValueSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 50); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = this.commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(50); - } - - @Test - public void testHystrixTimeoutValueCommandSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.service.execution.isolation.thread.timeoutInMilliseconds", - 50); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = this.commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(50); - } - - @Test - public void testHystrixTimeoutValueCommandAndDefaultSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 30); - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.service.execution.isolation.thread.timeoutInMilliseconds", - 50); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = this.commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(50); - } - - @Test - public void testHystrixDefaultAndRibbonSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 30); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(30); - } - - @Test - public void testHystrixCommandAndRibbonSetting() throws Exception { - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds", - 30); - ConfigurationManager.getConfigInstance().setProperty( - "hystrix.command.service.execution.isolation.thread.timeoutInMilliseconds", - 50); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(50); - } - - @Test - public void testDefaultRibbonSetting() throws Exception { - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(4000); - } - - @Test - public void testRibbonAndRibbonRetriesDefaultSetting() throws Exception { - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(1200); - } - - @Test - public void testRibbonTimeoutAndRibbonRetriesDefaultAndNameSpaceSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.test.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.test.ReadTimeout", - 1000); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl("test"); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(4000); - } - - @Test - public void testRibbonTimeoutAndRibbonRetriesDefaultAndDefaultSpaceSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(4000); - } - - @Test - public void testRibbonTimeoutAndRibbonNameSpaceRetriesDefaultAndDefaultSpaceSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.test.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl("test"); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(1800); - } - - @Test - public void testRibbonRetriesAndRibbonTimeoutSetting() throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(3600); - } - - @Test - public void testRibbonCommandRetriesAndRibbonCommandTimeoutSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance().setProperty("service.ribbon.ReadTimeout", - 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetriesNextServer", 2); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(12000); - } - - @Test - public void testRibbonCommandRetriesAndRibbonCommandTimeoutPartOfSetting() - throws Exception { - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.ConnectTimeout", 1000); - ConfigurationManager.getConfigInstance() - .setProperty("service.ribbon.MaxAutoRetries", 1); - SpringClientFactory springClientFactory = mock(SpringClientFactory.class); - ZuulProperties zuulProperties = new ZuulProperties(); - OkHttpLoadBalancingClient loadBalancingHttpClient = mock( - OkHttpLoadBalancingClient.class); - IClientConfig clientConfig = new DefaultClientConfigImpl(); - clientConfig.set(IClientConfigKey.Keys.ConnectTimeout, 100); - clientConfig.set(IClientConfigKey.Keys.ReadTimeout, 500); - doReturn(loadBalancingHttpClient).when(springClientFactory).getClient(anyString(), - eq(OkHttpLoadBalancingClient.class)); - doReturn(clientConfig).when(springClientFactory).getClientConfig(anyString()); - OkHttpRibbonCommandFactory commandFactory = new OkHttpRibbonCommandFactory( - springClientFactory, zuulProperties, new HashSet()); - RibbonCommandContext context = mock(RibbonCommandContext.class); - doReturn("service").when(context).getServiceId(); - OkHttpRibbonCommand ribbonCommand = commandFactory.create(context); - assertThat(ribbonCommand.getProperties().executionTimeoutInMilliseconds().get() - .intValue()).isEqualTo(6000); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFallbackTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFallbackTests.java deleted file mode 100644 index 677b702dc..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFallbackTests.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route.okhttp; - -import com.netflix.zuul.context.RequestContext; -import org.junit.Before; -import org.junit.runner.RunWith; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.filters.route.support.RibbonCommandFallbackTests; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Import; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = RibbonCommandFallbackTests.TestConfig.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - value = { "zuul.routes.simple: /simple/**", - "zuul.routes.another: /another/twolevel/**", "ribbon.ReadTimeout: 1" }) -@DirtiesContext -@Import(NoSecurityConfiguration.class) -public class OkHttpRibbonCommandFallbackTests extends RibbonCommandFallbackTests { - - @Before - public void init() { - RequestContext.getCurrentContext().clear(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandIntegrationTests.java deleted file mode 100644 index b20c19858..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandIntegrationTests.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route.okhttp; - -import java.util.Collections; -import java.util.Set; - -import com.netflix.client.DefaultLoadBalancerRetryHandler; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.support.ZuulProxyTestBase; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = OkHttpRibbonCommandIntegrationTests.TestConfig.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "zuul.routes.other: /test/**=http://localhost:7777/local", - "zuul.routes.another: /another/twolevel/**", - "zuul.routes.simple: /simple/**", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class OkHttpRibbonCommandIntegrationTests extends ZuulProxyTestBase { - - @Before - public void init() { - super.setTestRequestcontext(); - } - - @Test - public void patchOnSelfViaRibbonRoutingFilter() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/local/1", HttpMethod.PATCH, - new HttpEntity<>("TestPatch"), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Patched 1!"); - } - - @Test - public void postOnSelfViaRibbonRoutingFilter() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/local/1", HttpMethod.POST, - new HttpEntity<>("TestPost"), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Posted 1!"); - } - - @Test - public void deleteOnSelfViaRibbonRoutingFilter() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/local/1", HttpMethod.DELETE, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Deleted 1!"); - } - - @Test - public void ribbonCommandFactoryOverridden() { - assertThat(this.ribbonCommandFactory instanceof OkHttpRibbonCommandFactory) - .as("ribbonCommandFactory not a OkHttpRibbonCommandFactory").isTrue(); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @RibbonClients({ - @RibbonClient(name = "simple", - configuration = SimpleRibbonClientConfiguration.class), - @RibbonClient(name = "another", - configuration = AnotherRibbonClientConfiguration.class) }) - @Import(NoSecurityConfiguration.class) - static class TestConfig extends ZuulProxyTestBase.AbstractZuulProxyApplication { - - @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); - - @Bean - public RibbonCommandFactory ribbonCommandFactory( - final SpringClientFactory clientFactory) { - return new OkHttpRibbonCommandFactory(clientFactory, new ZuulProperties(), - zuulFallbackProviders); - } - - @Bean - public MyErrorController myErrorController(ErrorAttributes errorAttributes) { - return new MyErrorController(errorAttributes); - } - - @Bean - public IClientConfig config() { - return new DefaultClientConfigImpl(); - } - - @Bean - public OkHttpLoadBalancingClient okClient(IClientConfig config) { - final OkHttpLoadBalancingClient client = new OkHttpLoadBalancingClient(config, - new DefaultServerIntrospector()); - client.setLoadBalancer(new TestLoadBalancer<>()); - client.setRetryHandler(new DefaultLoadBalancerRetryHandler()); - return client; - } - - } - - static class TestLoadBalancer extends ZoneAwareLoadBalancer { - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonRetryIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonRetryIntegrationTests.java deleted file mode 100644 index aaf7c9705..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonRetryIntegrationTests.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.zuul.filters.route.okhttp; - -import org.junit.runner.RunWith; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.filters.route.support.RibbonRetryIntegrationTestBase; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = RibbonRetryIntegrationTestBase.RetryableTestConfig.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - value = { "zuul.retryable: false", /* - * Disable retry by default, have each route - * enable it - */ - "ribbon.okhttp.enabled: true", - "hystrix.command.default.execution.timeout.enabled: false", /* - * Disable - * hystrix so - * its timeout - * doesnt get - * in the way - */ - "ribbon.ReadTimeout: 1000", /* - * Make sure ribbon will timeout before the - * thread is done sleeping - */ - "zuul.routes.retryable.id: retryable", - "zuul.routes.retryable.path: /retryable/**", - "zuul.routes.retryable.retryable: true", - "retryable.ribbon.OkToRetryOnAllOperations: true", - "retryable.ribbon.retryableStatusCodes: 404", - "retryable.ribbon.MaxAutoRetries: 1", - "retryable.ribbon.MaxAutoRetriesNextServer: 1", - "zuul.routes.getretryable.id: getretryable", - "zuul.routes.getretryable.path: /getretryable/**", - "zuul.routes.getretryable.retryable: true", - "getretryable.ribbon.MaxAutoRetries: 1", - "getretryable.ribbon.MaxAutoRetriesNextServer: 1", - "zuul.routes.disableretry.path: /disableretry/**", - "zuul.routes.disableretry.path: /disableretry/**", - "zuul.routes.disableretry.retryable: false", /* - * This will override the - * global - */ - "disableretry.ribbon.MaxAutoRetries: 1", - "disableretry.ribbon.MaxAutoRetriesNextServer: 1", - "zuul.routes.globalretrydisabled: /globalretrydisabled/**", - "globalretrydisabled.ribbon.MaxAutoRetries: 1", - "globalretrydisabled.ribbon.MaxAutoRetriesNextServer: 1" }) -@DirtiesContext -public class OkHttpRibbonRetryIntegrationTests extends RibbonRetryIntegrationTestBase { - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandFallbackTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandFallbackTests.java deleted file mode 100644 index 9e1b8b1cf..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandFallbackTests.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route.restclient; - -import com.netflix.zuul.context.RequestContext; -import org.junit.Before; -import org.junit.runner.RunWith; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.filters.route.support.RibbonCommandFallbackTests; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = RibbonCommandFallbackTests.TestConfig.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - value = { "zuul.routes.simple: /simple/**", - "zuul.routes.another: /another/twolevel/**", "ribbon.ReadTimeout: 1" }) -@DirtiesContext -public class RestClientRibbonCommandFallbackTests extends RibbonCommandFallbackTests { - - @Before - public void init() { - RequestContext.getCurrentContext().clear(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandIntegrationTests.java deleted file mode 100644 index 7ecbe874d..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandIntegrationTests.java +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route.restclient; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.UUID; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.client.ClientException; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.niws.client.http.RestClient; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.boot.web.servlet.filter.ApplicationContextHeaderFilter; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommand; -import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.support.NoEncodingFormHttpMessageConverter; -import org.springframework.cloud.netflix.zuul.filters.route.support.ZuulProxyTestBase; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.converter.StringHttpMessageConverter; -import org.springframework.mock.http.client.MockClientHttpResponse; -import org.springframework.security.config.annotation.web.WebSecurityConfigurer; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.web.firewall.StrictHttpFirewall; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.bind.annotation.MatrixVariable; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = RestClientRibbonCommandIntegrationTests.TestConfig.class, - webEnvironment = WebEnvironment.RANDOM_PORT, - value = { "zuul.routes.other: /test/**=http://localhost:7777/local", - "zuul.routes.another: /another/twolevel/**", - "zuul.routes.simple: /simple/**", "zuul.routes.badhost: /badhost/**", - "zuul.ignored-headers: X-Header", "zuul.routes.rnd: /rnd/**", - "rnd.ribbon.listOfServers: ${random.value}", - "zuul.remove-semicolon-content: false", "ribbon.restclient.enabled=true", - "management.endpoints.web.exposure.include=*" }) -@DirtiesContext -public class RestClientRibbonCommandIntegrationTests extends ZuulProxyTestBase { - - @Autowired - DiscoveryClientRouteLocator routeLocator; - - @Override - protected boolean supportsPatch() { - return false; - } - - @Override - protected boolean supportsDeleteWithBody() { - return false; - } - - @Test - public void simpleHostRouteWithTrailingSlash() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/trailing-slash", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("/trailing-slash"); - assertThat(this.myErrorController.wasControllerUsed()).isFalse(); - } - - @Test - public void simpleHostRouteWithNonExistentUrl() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - String uri = "/self/nonExistentUrl"; - this.myErrorController.setUriToMatch(uri); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); - assertThat(this.myErrorController.wasControllerUsed()).isFalse(); - } - - @Test - public void simpleHostRouteIgnoredHeader() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/add-header", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getHeaders().get("X-Header")).isNull(); - } - - @Test - public void simpleHostRouteDefaultIgnoredHeader() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/add-header", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - List headers = result.getHeaders().get("X-Application-Context"); - assertThat(headers).as("header was null").isNotNull(); - assertThat(headers.toString()).isEqualTo("[application-1]"); - } - - @Test - public void simpleHostRouteWithQuery() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/query?foo=bar", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("/query?foo=bar"); - } - - @Test - public void simpleHostRouteWithMatrix() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/matrix/my;q=2;p=1/more;x=2", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("my=1-2;more=2"); - } - - @Test - public void simpleHostRouteWithEncodedQuery() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/query?foo={foo}", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class, "weird#chars"); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("/query?foo=weird#chars"); - } - - @Test - public void simpleHostRouteWithColonParamNames() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port - + "/self/colonquery?foo:bar={foobar0}&foobar={foobar1}", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class, "baz", - "bam"); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("/colonquery?foo:bar=baz&foobar=bam"); - } - - @Test - public void simpleHostRouteWithContentType() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/content-type", HttpMethod.POST, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo(""); - } - - @Test - public void ribbonCommandForbidden() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/throwexception/403", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); - } - - @Test - public void ribbonCommandServiceUnavailable() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/throwexception/503", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.SERVICE_UNAVAILABLE); - } - - @Test - public void ribbonCommandBadHost() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/badhost/1", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - // JSON response - assertThat(result.getBody()).contains("\"status\":500"); - } - - @Test - public void ribbonCommandRandomHostFromConfig() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/rnd/1", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - // JSON response - assertThat(result.getBody()).contains("\"status\":500"); - } - - @Test - public void ribbonCommandFactoryOverridden() { - assertThat(this.ribbonCommandFactory instanceof TestConfig.MyRibbonCommandFactory) - .as("ribbonCommandFactory not a MyRibbonCommandFactory").isTrue(); - } - - @Override - @SuppressWarnings("deprecation") - @Test - public void javascriptEncodedFormParams() { - TestRestTemplate testRestTemplate = new TestRestTemplate(); - ArrayList> converters = new ArrayList<>(); - converters.addAll(Arrays.asList(new StringHttpMessageConverter(), - new NoEncodingFormHttpMessageConverter())); - testRestTemplate.getRestTemplate().setMessageConverters(converters); - - MultiValueMap map = new LinkedMultiValueMap<>(); - map.add("foo", "(bar)"); - ResponseEntity result = testRestTemplate.postForEntity( - "http://localhost:" + this.port + "/simple/local", map, String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()) - .isEqualTo("Posted [(bar)] and Content-Length was: -1!"); - } - - @Test - public void routeLocatorOverridden() { - assertThat(this.routeLocator instanceof TestConfig.MyRouteLocator) - .as("routeLocator not a MyRouteLocator").isTrue(); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @RibbonClients({ - @RibbonClient(name = "badhost", - configuration = TestConfig.BadHostRibbonClientConfiguration.class), - @RibbonClient(name = "simple", - configuration = ZuulProxyTestBase.SimpleRibbonClientConfiguration.class), - @RibbonClient(name = "another", - configuration = ZuulProxyTestBase.AnotherRibbonClientConfiguration.class) }) - @Import(NoSecurityConfiguration.class) - static class TestConfig extends ZuulProxyTestBase.AbstractZuulProxyApplication { - - @Autowired(required = false) - private Set fallbackProviders = Collections.emptySet(); - - @RequestMapping("/trailing-slash") - public String trailingSlash(HttpServletRequest request) { - return request.getRequestURI(); - } - - @RequestMapping("/content-type") - public String contentType(HttpServletRequest request) { - String header = request.getHeader("Content-Type"); - return header == null ? "" : header; - } - - @RequestMapping("/add-header") - public ResponseEntity addHeader(HttpServletRequest request) { - HttpHeaders headers = new HttpHeaders(); - headers.set("X-Header", "FOO"); - ResponseEntity result = new ResponseEntity<>(request.getRequestURI(), - headers, HttpStatus.OK); - return result; - } - - @RequestMapping("/query") - public String query(HttpServletRequest request, @RequestParam String foo) { - return request.getRequestURI() + "?foo=" + foo; - } - - @RequestMapping("/colonquery") - public String colonQuery(HttpServletRequest request, - @RequestParam(name = "foo:bar") String foobar0, - @RequestParam(name = "foobar") String foobar1) { - return request.getRequestURI() + "?foo:bar=" + foobar0 + "&foobar=" + foobar1; - } - - @RequestMapping("/matrix/{name}/{another}") - public String matrix(@PathVariable("name") String name, - @MatrixVariable(value = "p", pathVar = "name") int p, - @MatrixVariable(value = "q", pathVar = "name") int q, - @PathVariable("another") String another, - @MatrixVariable(value = "x", pathVar = "another") int x) { - return name + "=" + p + "-" + q + ";" + another + "=" + x; - } - - @Bean - public RibbonCommandFactory ribbonCommandFactory( - SpringClientFactory clientFactory) { - return new MyRibbonCommandFactory(clientFactory, fallbackProviders); - } - - @Bean - public DiscoveryClientRouteLocator discoveryRouteLocator( - DiscoveryClient discoveryClient, ZuulProperties zuulProperties) { - return new MyRouteLocator("/", discoveryClient, zuulProperties); - } - - @Bean - public MyErrorController myErrorController(ErrorAttributes errorAttributes) { - return new MyErrorController(errorAttributes); - } - - @Bean - public ApplicationContextHeaderFilter applicationContextIdFilter( - ApplicationContext context) { - return new ApplicationContextHeaderFilter(context); - } - - public static void main(String[] args) { - SpringApplication.run(TestConfig.class, args); - } - - public static class MyRibbonCommandFactory - extends RestClientRibbonCommandFactory { - - private SpringClientFactory clientFactory; - - MyRibbonCommandFactory(SpringClientFactory clientFactory, - Set fallbackProviders) { - super(clientFactory, new ZuulProperties(), fallbackProviders); - this.clientFactory = clientFactory; - } - - @Override - @SuppressWarnings("deprecation") - public RestClientRibbonCommand create(RibbonCommandContext context) { - String uri = context.getUri(); - if (uri.startsWith("/throwexception/")) { - String code = uri.replace("/throwexception/", ""); - RestClient restClient = clientFactory - .getClient(context.getServiceId(), RestClient.class); - return new MyCommand(Integer.parseInt(code), context.getServiceId(), - restClient, context); - } - return super.create(context); - } - - } - - static class MyCommand extends RestClientRibbonCommand { - - private int errorCode; - - MyCommand(int errorCode, String commandKey, RestClient restClient, - RibbonCommandContext context) { - super(commandKey, restClient, context, new ZuulProperties()); - this.errorCode = errorCode; - } - - @Override - protected ClientHttpResponse run() throws Exception { - if (this.errorCode == 503) { - throw new ClientException(ClientException.ErrorType.SERVER_THROTTLED); - } - return new MockClientHttpResponse(new byte[0], - HttpStatus.valueOf(this.errorCode)); - } - - } - - // Load balancer with fixed server list for "simple" pointing to bad host - @Configuration(proxyBeanMethods = false) - static class BadHostRibbonClientConfiguration { - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>( - new Server(UUID.randomUUID().toString(), 4322)); - } - - } - - // This is needed to allow semicolon separators used in matrix variables - @Configuration(proxyBeanMethods = false) - static class CustomHttpFirewallConfig - implements WebSecurityConfigurer { - - @Override - public void init(WebSecurity webSecurity) throws Exception { - } - - @Override - public void configure(WebSecurity builder) throws Exception { - StrictHttpFirewall firewall = new StrictHttpFirewall(); - firewall.setAllowSemicolon(true); - builder.httpFirewall(firewall); - } - - } - - static class MyRouteLocator extends DiscoveryClientRouteLocator { - - MyRouteLocator(String servletPath, DiscoveryClient discovery, - ZuulProperties properties) { - super(servletPath, discovery, properties); - } - - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/NoEncodingFormHttpMessageConverter.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/NoEncodingFormHttpMessageConverter.java deleted file mode 100644 index 51f77de5b..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/NoEncodingFormHttpMessageConverter.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route.support; - -import java.io.IOException; -import java.util.Iterator; - -import org.springframework.http.HttpOutputMessage; -import org.springframework.http.MediaType; -import org.springframework.http.converter.FormHttpMessageConverter; -import org.springframework.http.converter.HttpMessageNotWritableException; -import org.springframework.util.MultiValueMap; -import org.springframework.util.StreamUtils; - -/** - * @author Jacques-Etienne Beaudet - */ -public class NoEncodingFormHttpMessageConverter extends FormHttpMessageConverter { - - @SuppressWarnings("unchecked") - @Override - public void write(MultiValueMap map, MediaType contentType, - HttpOutputMessage outputMessage) - throws IOException, HttpMessageNotWritableException { - - MultiValueMap form = (MultiValueMap) map; - StringBuilder builder = new StringBuilder(); - for (Iterator nameIterator = form.keySet().iterator(); nameIterator - .hasNext();) { - String name = nameIterator.next(); - for (Iterator valueIterator = form.get(name).iterator(); valueIterator - .hasNext();) { - String value = valueIterator.next(); - builder.append(name); - if (value != null) { - builder.append('='); - builder.append(value); - if (valueIterator.hasNext()) { - builder.append('&'); - } - } - } - if (nameIterator.hasNext()) { - builder.append('&'); - } - } - final byte[] bytes = builder.toString() - .getBytes(FormHttpMessageConverter.DEFAULT_CHARSET); - outputMessage.getHeaders().setContentLength(bytes.length); - outputMessage.getHeaders().setContentType(MediaType.APPLICATION_FORM_URLENCODED); - - StreamUtils.copy(bytes, outputMessage.getBody()); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandCauseFallbackPropagationTest.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandCauseFallbackPropagationTest.java deleted file mode 100644 index c66f03aff..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandCauseFallbackPropagationTest.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.zuul.filters.route.support; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.UUID; - -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.ClientException; -import com.netflix.client.ClientRequest; -import com.netflix.client.IResponse; -import com.netflix.client.RequestSpecificRetryHandler; -import com.netflix.client.config.DefaultClientConfigImpl; -import com.netflix.client.config.IClientConfig; -import com.netflix.client.http.HttpResponse; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.exception.HystrixTimeoutException; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.client.ClientHttpResponse; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -/** - * @author Dominik Mostek - */ -public class RibbonCommandCauseFallbackPropagationTest { - - private RibbonCommandContext context; - - @Before - public void setup() { - context = mock(RibbonCommandContext.class); - doReturn("fooRoute").when(context).getServiceId(); - } - - @Test - public void providerIsCalledInCaseOfException() throws Exception { - FallbackProvider provider = new TestFallbackProvider( - getClientHttpResponse(HttpStatus.INTERNAL_SERVER_ERROR)); - RuntimeException exception = new RuntimeException("Failed!"); - TestRibbonCommand testCommand = new TestRibbonCommand(new TestClient(exception), - provider, context); - - ClientHttpResponse response = testCommand.execute(); - - assertThat(response).isNotNull(); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - } - - @Test - public void causeIsProvidedForNewInterface() throws Exception { - TestFallbackProvider provider = TestFallbackProvider - .withResponse(HttpStatus.NOT_FOUND); - RuntimeException exception = new RuntimeException("Failed!"); - TestRibbonCommand testCommand = new TestRibbonCommand(new TestClient(exception), - provider, context); - - ClientHttpResponse response = testCommand.execute(); - - assertThat(response).isNotNull(); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); - Throwable cause = provider.getCause(); - assertThat(cause.getClass()).isEqualTo(exception.getClass()); - assertThat(cause.getMessage()).isEqualTo(exception.getMessage()); - } - - @Test - public void executionExceptionIsUsedInsteadWhenFailedExceptionIsNull() - throws Exception { - TestFallbackProvider provider = TestFallbackProvider - .withResponse(HttpStatus.BAD_GATEWAY); - final RuntimeException exception = new RuntimeException("Failed!"); - TestRibbonCommand testCommand = new TestRibbonCommand(new TestClient(exception), - provider, context) { - @Override - public Throwable getFailedExecutionException() { - return null; - } - - @Override - public Throwable getExecutionException() { - return exception; - } - }; - - ClientHttpResponse response = testCommand.execute(); - - assertThat(response).isNotNull(); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_GATEWAY); - } - - @Test - public void timeoutExceptionIsPropagated() throws Exception { - TestFallbackProvider provider = TestFallbackProvider - .withResponse(HttpStatus.CONFLICT); - RuntimeException exception = new RuntimeException("Failed!"); - TestRibbonCommand testCommand = new TestRibbonCommand(new TestClient(exception), - provider, 1, context) { - @Override - protected ClientRequest createRequest() throws Exception { - Thread.sleep(5); - return super.createRequest(); - } - }; - - ClientHttpResponse response = testCommand.execute(); - - assertThat(response).isNotNull(); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.CONFLICT); - assertThat(provider.getCause()).isNotNull(); - assertThat(provider.getCause().getClass()) - .isEqualTo(HystrixTimeoutException.class); - } - - private static ClientHttpResponse getClientHttpResponse(final HttpStatus status) { - return new ClientHttpResponse() { - @Override - public HttpStatus getStatusCode() throws IOException { - return status; - } - - @Override - public int getRawStatusCode() throws IOException { - return getStatusCode().value(); - } - - @Override - public String getStatusText() throws IOException { - return getStatusCode().getReasonPhrase(); - } - - @Override - public void close() { - } - - @Override - public InputStream getBody() throws IOException { - return new ByteArrayInputStream("test".getBytes()); - } - - @Override - public HttpHeaders getHeaders() { - return new HttpHeaders(); - } - }; - } - - public static class TestFallbackProvider implements FallbackProvider { - - private final ClientHttpResponse response; - - private Throwable cause; - - public TestFallbackProvider(final ClientHttpResponse response) { - this.response = response; - } - - @Override - public ClientHttpResponse fallbackResponse(String route, final Throwable cause) { - this.cause = cause; - return response; - } - - @Override - public String getRoute() { - return "test-route"; - } - - public Throwable getCause() { - return cause; - } - - public static TestFallbackProvider withResponse(final HttpStatus status) { - return new TestFallbackProvider(getClientHttpResponse(status)); - } - - } - - @SuppressWarnings("rawtypes") - public static class TestClient extends AbstractLoadBalancerAwareClient { - - private final RuntimeException exception; - - public TestClient(RuntimeException exception) { - super(null); - this.exception = exception; - } - - @Override - public IResponse executeWithLoadBalancer(final ClientRequest request, - final IClientConfig requestConfig) throws ClientException { - throw exception; - } - - @Override - public RequestSpecificRetryHandler getRequestSpecificRetryHandler( - final ClientRequest clientRequest, final IClientConfig iClientConfig) { - return null; - } - - @Override - public IResponse execute(final ClientRequest clientRequest, - final IClientConfig iClientConfig) throws Exception { - return null; - } - - } - - public static class TestRibbonCommand extends - AbstractRibbonCommand, ClientRequest, HttpResponse> { - - public TestRibbonCommand( - AbstractLoadBalancerAwareClient client, - FallbackProvider fallbackProvider, RibbonCommandContext context) { - this(client, new ZuulProperties(), fallbackProvider, context); - } - - public TestRibbonCommand( - AbstractLoadBalancerAwareClient client, - ZuulProperties zuulProperties, FallbackProvider fallbackProvider, - RibbonCommandContext context) { - super("testCommand" + UUID.randomUUID(), client, context, zuulProperties, - fallbackProvider); - } - - public TestRibbonCommand( - AbstractLoadBalancerAwareClient client, - FallbackProvider fallbackProvider, int timeout, - RibbonCommandContext context) { - // different name is used because of properties caching - super(getSetter("testCommand" + UUID.randomUUID(), new ZuulProperties(), - new DefaultClientConfigImpl()).andCommandPropertiesDefaults( - defauts(timeout)), - client, context, fallbackProvider, null); - } - - private static HystrixCommandProperties.Setter defauts(final int timeout) { - return HystrixCommandProperties.Setter().withExecutionTimeoutEnabled(true) - .withExecutionIsolationStrategy( - HystrixCommandProperties.ExecutionIsolationStrategy.THREAD) - .withExecutionTimeoutInMilliseconds(timeout); - } - - @Override - protected ClientRequest createRequest() throws Exception { - return null; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandFallbackTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandFallbackTests.java deleted file mode 100644 index 5fc26c6ac..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandFallbackTests.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route.support; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collections; -import java.util.Set; - -import org.junit.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - */ -public abstract class RibbonCommandFallbackTests { - - @LocalServerPort - protected int port; - - @Test - public void fallback() { - String uri = "/simple/slow"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("fallback"); - } - - @Test - public void defaultFallback() { - String uri = "/another/twolevel/slow"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("default fallback"); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @RibbonClients({ @RibbonClient(name = "simple", - configuration = ZuulProxyTestBase.SimpleRibbonClientConfiguration.class), - @RibbonClient(name = "another", - configuration = ZuulProxyTestBase.AnotherRibbonClientConfiguration.class) }) - @Import(NoSecurityConfiguration.class) - public static class TestConfig - extends ZuulProxyTestBase.AbstractZuulProxyApplication { - - @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); - - @Bean - public RibbonCommandFactory ribbonCommandFactory( - final SpringClientFactory clientFactory) { - return new HttpClientRibbonCommandFactory(clientFactory, new ZuulProperties(), - zuulFallbackProviders); - } - - @Bean - public ZuulProxyTestBase.MyErrorController myErrorController( - ErrorAttributes errorAttributes) { - return new ZuulProxyTestBase.MyErrorController(errorAttributes); - } - - @Bean - public FallbackProvider defaultFallbackProvider() { - return new DefaultFallbackProvider(); - } - - } - - public static class DefaultFallbackProvider implements FallbackProvider { - - @Override - public String getRoute() { - return "*"; - } - - @Override - public ClientHttpResponse fallbackResponse(final String route, Throwable cause) { - return new ClientHttpResponse() { - @Override - public HttpStatus getStatusCode() throws IOException { - return HttpStatus.OK; - } - - @Override - public int getRawStatusCode() throws IOException { - if (route.equals("another")) { - return 200; - } - return 500; - } - - @Override - public String getStatusText() throws IOException { - return null; - } - - @Override - public void close() { - - } - - @Override - public InputStream getBody() throws IOException { - return new ByteArrayInputStream("default fallback".getBytes()); - } - - @Override - public HttpHeaders getHeaders() { - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.TEXT_HTML); - return headers; - } - }; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandHystrixThreadPoolKeyTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandHystrixThreadPoolKeyTests.java deleted file mode 100644 index d17bb77c5..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandHystrixThreadPoolKeyTests.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * https://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.zuul.filters.route.support; - -import com.netflix.client.AbstractLoadBalancerAwareClient; -import com.netflix.client.ClientRequest; -import com.netflix.client.http.HttpResponse; -import com.netflix.hystrix.HystrixCommandProperties; -import com.netflix.hystrix.strategy.HystrixPlugins; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Yongsung Yoon - */ -public class RibbonCommandHystrixThreadPoolKeyTests { - - private ZuulProperties zuulProperties; - - @Before - public void setUp() throws Exception { - zuulProperties = new ZuulProperties(); - } - - @After - public void tearDown() throws Exception { - HystrixPlugins.reset(); - } - - @Test - public void testDefaultHystrixThreadPoolKey() throws Exception { - zuulProperties.setRibbonIsolationStrategy( - HystrixCommandProperties.ExecutionIsolationStrategy.THREAD); - - TestRibbonCommand ribbonCommand1 = new TestRibbonCommand("testCommand1", - zuulProperties); - TestRibbonCommand ribbonCommand2 = new TestRibbonCommand("testCommand2", - zuulProperties); - - // CommandGroupKey should be used as ThreadPoolKey as default. - assertThat(ribbonCommand1.getThreadPoolKey().name()) - .isEqualTo(ribbonCommand1.getCommandGroup().name()); - assertThat(ribbonCommand2.getThreadPoolKey().name()) - .isEqualTo(ribbonCommand2.getCommandGroup().name()); - } - - @Test - public void testUseSeparateThreadPools() throws Exception { - zuulProperties.setRibbonIsolationStrategy( - HystrixCommandProperties.ExecutionIsolationStrategy.THREAD); - zuulProperties.getThreadPool().setUseSeparateThreadPools(true); - - TestRibbonCommand ribbonCommand1 = new TestRibbonCommand("testCommand1", - zuulProperties); - TestRibbonCommand ribbonCommand2 = new TestRibbonCommand("testCommand2", - zuulProperties); - - assertThat(ribbonCommand1.getThreadPoolKey().name()).isEqualTo("testCommand1"); - assertThat(ribbonCommand2.getThreadPoolKey().name()).isEqualTo("testCommand2"); - } - - @Test - public void testThreadPoolKeyPrefix() throws Exception { - final String prefix = "zuulgw-"; - - zuulProperties.setRibbonIsolationStrategy( - HystrixCommandProperties.ExecutionIsolationStrategy.THREAD); - zuulProperties.getThreadPool().setUseSeparateThreadPools(true); - zuulProperties.getThreadPool().setThreadPoolKeyPrefix(prefix); - - TestRibbonCommand ribbonCommand1 = new TestRibbonCommand("testCommand1", - zuulProperties); - TestRibbonCommand ribbonCommand2 = new TestRibbonCommand("testCommand2", - zuulProperties); - - assertThat(ribbonCommand1.getThreadPoolKey().name()) - .isEqualTo(prefix + "testCommand1"); - assertThat(ribbonCommand2.getThreadPoolKey().name()) - .isEqualTo(prefix + "testCommand2"); - } - - @Test - public void testNoSideEffectOnSemaphoreIsolation() throws Exception { - final String prefix = "zuulgw-"; - - zuulProperties.setRibbonIsolationStrategy( - HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE); - zuulProperties.getThreadPool().setUseSeparateThreadPools(true); - zuulProperties.getThreadPool().setThreadPoolKeyPrefix(prefix); - - TestRibbonCommand ribbonCommand1 = new TestRibbonCommand("testCommand1", - zuulProperties); - TestRibbonCommand ribbonCommand2 = new TestRibbonCommand("testCommand2", - zuulProperties); - - // There should be no side effect on semaphore isolation - assertThat(ribbonCommand1.getThreadPoolKey().name()) - .isEqualTo(ribbonCommand1.getCommandGroup().name()); - assertThat(ribbonCommand2.getThreadPoolKey().name()) - .isEqualTo(ribbonCommand2.getCommandGroup().name()); - } - - public static class TestRibbonCommand extends - AbstractRibbonCommand, ClientRequest, HttpResponse> { - - public TestRibbonCommand(String commandKey, ZuulProperties zuulProperties) { - super(commandKey, null, null, zuulProperties); - } - - @Override - protected ClientRequest createRequest() throws Exception { - return null; - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonRetryIntegrationTestBase.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonRetryIntegrationTestBase.java deleted file mode 100644 index 0189d5e00..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonRetryIntegrationTestBase.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route.support; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.context.RequestContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryFactory; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicy; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.test.NoSecurityConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Ryan Baxter - */ -public abstract class RibbonRetryIntegrationTestBase { - - private final Log LOG = LogFactory.getLog(RibbonRetryIntegrationTestBase.class); - - @Value("${local.server.port}") - protected int port; - - @Before - public void setup() { - RequestContext.getCurrentContext().clear(); - String uri = "/resetError"; - new TestRestTemplate().exchange("http://localhost:" + this.port + uri, - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - } - - @Test - public void retryable() { - String uri = "/retryable/everyothererror"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void retryableFourOFour() { - String uri = "/retryable/404everyothererror"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void postRetryOK() { - String uri = "/retryable/posteveryothererror"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.POST, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void getRetryable() { - String uri = "/getretryable/everyothererror"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - public void postNotRetryable() { - String uri = "/getretryable/posteveryothererror"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.POST, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - } - - @Test - public void disableRetry() { - String uri = "/disableretry/everyothererror"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - LOG.info("Response Body: " + result.getBody()); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.GATEWAY_TIMEOUT); - } - - @Test - public void globalRetryDisabled() { - String uri = "/globalretrydisabled/everyothererror"; - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - LOG.info("Response Body: " + result.getBody()); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.GATEWAY_TIMEOUT); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - @EnableZuulProxy - @RibbonClients({ - @RibbonClient(name = "retryable", - configuration = RibbonClientConfiguration.class), - @RibbonClient(name = "disableretry", - configuration = RibbonClientConfiguration.class), - @RibbonClient(name = "globalretrydisabled", - configuration = RibbonClientConfiguration.class), - @RibbonClient(name = "getretryable", - configuration = RibbonClientConfiguration.class) }) - @Import(NoSecurityConfiguration.class) - public static class RetryableTestConfig { - - private final Log LOG = LogFactory.getLog(RetryableTestConfig.class); - - private boolean error = true; - - @RequestMapping("/resetError") - public void resetError() { - error = true; - } - - @RequestMapping("/everyothererror") - public ResponseEntity timeout() { - boolean shouldError = error; - error = !error; - try { - if (shouldError) { - Thread.sleep(80000); - } - } - catch (InterruptedException e) { - LOG.info(e); - Thread.currentThread().interrupt(); - } - - return new ResponseEntity("no error", HttpStatus.OK); - } - - @RequestMapping(path = "/posteveryothererror", method = RequestMethod.POST) - public ResponseEntity postTimeout() { - return timeout(); - } - - @RequestMapping("/404everyothererror") - @ResponseStatus(HttpStatus.NOT_FOUND) - public ResponseEntity fourOFourError() { - boolean shouldError = error; - error = !error; - if (shouldError) { - return new ResponseEntity("not found", HttpStatus.NOT_FOUND); - } - return new ResponseEntity("no error", HttpStatus.OK); - } - - } - - @Configuration(proxyBeanMethods = false) - public static class RibbonClientConfiguration { - - @Value("${local.server.port}") - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - - @Configuration(proxyBeanMethods = false) - public static class FourOFourRetryableRibbonConfiguration - extends RibbonClientConfiguration { - - @Bean - public LoadBalancedRetryFactory loadBalancedRetryPolicyFactory( - SpringClientFactory factory) { - return new MyRibbonRetryFactory(factory); - } - - public static class MyRibbonRetryFactory extends RibbonLoadBalancedRetryFactory { - - private SpringClientFactory factory; - - public MyRibbonRetryFactory(SpringClientFactory clientFactory) { - super(clientFactory); - this.factory = clientFactory; - } - - @Override - public LoadBalancedRetryPolicy createRetryPolicy(String serviceId, - ServiceInstanceChooser loadBalanceChooser) { - RibbonLoadBalancerContext lbContext = this.factory - .getLoadBalancerContext(serviceId); - return new MyLoadBalancedRetryPolicy(serviceId, lbContext, - loadBalanceChooser); - } - - class MyLoadBalancedRetryPolicy extends RibbonLoadBalancedRetryPolicy { - - MyLoadBalancedRetryPolicy(String serviceId, - RibbonLoadBalancerContext context, - ServiceInstanceChooser loadBalanceChooser) { - super(serviceId, context, loadBalanceChooser); - } - - @Override - public boolean retryableStatusCode(int statusCode) { - if (statusCode == HttpStatus.NOT_FOUND.value()) { - return true; - } - return super.retryableStatusCode(statusCode); - } - - } - - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/ZuulProxyTestBase.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/ZuulProxyTestBase.java deleted file mode 100644 index b9ef63268..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/ZuulProxyTestBase.java +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.filters.route.support; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; - -import javax.servlet.http.HttpServletRequest; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.web.ErrorProperties; -import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.servlet.error.ErrorAttributes; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.cloud.netflix.zuul.RoutesEndpoint; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; -import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; -import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.support.RibbonRetryIntegrationTestBase.RetryableTestConfig; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.format.support.FormattingConversionService; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.converter.FormHttpMessageConverter; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.converter.StringHttpMessageConverter; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.accept.ContentNegotiationManager; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -import org.springframework.web.servlet.resource.ResourceUrlProvider; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.is; -import static org.junit.Assume.assumeThat; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; - -/** - * @author Spencer Gibb - * @author Ryan Baxter - */ -public abstract class ZuulProxyTestBase { - - @Value("${local.server.port}") - protected int port; - - @Autowired - protected DiscoveryClientRouteLocator routes; - - @Autowired - protected RoutesEndpoint endpoint; - - @Autowired - protected RibbonCommandFactory ribbonCommandFactory; - - @Autowired - protected MyErrorController myErrorController; - - @Before - public void cleanup() { - this.myErrorController.clear(); - } - - @Before - public void setTestRequestcontext() { - RequestContext.testSetCurrentContext(null); - RequestContext.getCurrentContext().unset(); - } - - @After - public void clear() { - RequestContext.getCurrentContext().clear(); - } - - /** - * used to disable patch tests if client doesn't support it - */ - protected boolean supportsPatch() { - return true; - } - - /** - * used to switch delete tests with a boyd if client doesn't support it - */ - protected boolean supportsDeleteWithBody() { - return true; - } - - protected String getRoute(String path) { - for (Route route : this.routes.getRoutes()) { - if (path.equals(route.getFullPath())) { - return route.getLocation(); - } - } - return null; - } - - @Test - public void bindRouteUsingPhysicalRoute() { - assertThat(getRoute("/test/**")).isEqualTo("http://localhost:7777/local"); - } - - @Test - public void bindRouteUsingOnlyPath() { - assertThat(getRoute("/simple/**")).isEqualTo("simple"); - } - - @Test - public void getOnSelfViaRibbonRoutingFilter() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/local/1", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Gotten 1!"); - } - - @Test - public void deleteOnSelfViaSimpleHostRoutingFilter() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/local"); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/1", HttpMethod.DELETE, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Deleted 1!"); - } - - @Test - public void stripPrefixFalseAppendsPath() { - this.routes.addRoute(new ZuulProperties.ZuulRoute("strip", "/strip/**", "strip", - "http://localhost:" + this.port + "/local", false, false, null)); - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/strip", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - // Prefix not stripped to it goes to /local/strip - assertThat(result.getBody()).isEqualTo("Gotten strip!"); - } - - @Test - public void testNotFoundFromApp() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/local/notfound", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); - } - - @Test - public void testNotFoundOnProxy() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/myinvalidpath", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); - } - - @Test - public void getSecondLevel() { - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/another/twolevel/local/1", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Gotten 1!"); - } - - @Test - public void ribbonRouteWithSpace() { - String uri = "/simple/spa ce"; - this.myErrorController.setUriToMatch(uri); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Hello space"); - assertThat(myErrorController.wasControllerUsed()).isFalse(); - } - - @Test - public void ribbonDeleteWithBody() { - this.endpoint.reset(); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/deletewithbody", - HttpMethod.DELETE, new HttpEntity<>("deleterequestbody"), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - if (supportsDeleteWithBody()) { - assertThat(result.getBody()).isEqualTo("Deleted deleterequestbody"); - } - else { - assertThat(result.getBody()).isEqualTo("Deleted null"); - } - } - - @Test - public void ribbonRouteWithNonExistentUri() { - String uri = "/simple/nonExistent"; - this.myErrorController.setUriToMatch(uri); - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); - assertThat(myErrorController.wasControllerUsed()).isFalse(); - } - - @Test - public void simpleHostRouteWithSpace() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port); - this.endpoint.reset(); - - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/spa ce", HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Hello space"); - } - - @Test - public void simpleHostRouteWithOriginalQueryString() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port); - this.endpoint.reset(); - - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port - + "/self/qstring?original=value1&original=value2", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Received {original=[value1, value2]}"); - } - - @Test - public void simpleHostRouteWithOverriddenQString() { - this.routes.addRoute("/self/**", "http://localhost:" + this.port); - this.endpoint.reset(); - - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port - + "/self/qstring?override=true&different=key", - HttpMethod.GET, new HttpEntity<>((Void) null), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Received {key=[overridden]}"); - } - - @Test - public void patchOnSelfViaSimpleHostRoutingFilter() { - assumeThat(supportsPatch(), is(true)); - - this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/local"); - this.endpoint.reset(); - - ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/self/1", HttpMethod.PATCH, - new HttpEntity<>("TestPatch"), String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()).isEqualTo("Patched 1!"); - } - - @SuppressWarnings("deprecation") - @Test - public void javascriptEncodedFormParams() { - TestRestTemplate testRestTemplate = new TestRestTemplate(); - ArrayList> converters = new ArrayList<>(); - converters.addAll(Arrays.asList(new StringHttpMessageConverter(), - new NoEncodingFormHttpMessageConverter())); - testRestTemplate.getRestTemplate().setMessageConverters(converters); - - MultiValueMap map = new LinkedMultiValueMap<>(); - map.add("foo", "(bar)"); - ResponseEntity result = testRestTemplate.postForEntity( - "http://localhost:" + this.port + "/simple/local", map, String.class); - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody()) - .isEqualTo("Posted [(bar)] and Content-Length was: 13!"); - } - - public static abstract class AbstractZuulProxyApplication - extends DelegatingWebMvcConfiguration { - - private final Log LOG = LogFactory.getLog(RetryableTestConfig.class); - - @RequestMapping(value = "/local/{id}", method = RequestMethod.PATCH) - public String patch(@PathVariable final String id, - @RequestBody final String body) { - return "Patched " + id + "!"; - } - - @RequestMapping("/testing123") - public String testing123() { - throw new RuntimeException("myerror"); - } - - @RequestMapping("/local") - public String local() { - return "Hello local"; - } - - @RequestMapping(value = "/local", method = RequestMethod.POST) - public String postWithFormParam(HttpServletRequest request, - @RequestBody MultiValueMap body) { - return "Posted " + body.get("foo") + " and Content-Length was: " - + request.getContentLength() + "!"; - } - - @RequestMapping(value = "/deletewithbody", method = RequestMethod.DELETE) - public String deleteWithBody(@RequestBody(required = false) String body) { - return "Deleted " + body; - } - - @RequestMapping(value = "/local/{id}", method = RequestMethod.DELETE) - public String delete(@PathVariable String id) { - return "Deleted " + id + "!"; - } - - @RequestMapping(value = "/local/{id}", method = RequestMethod.GET) - public ResponseEntity get(@PathVariable String id) { - if ("notfound".equalsIgnoreCase(id)) { - return ResponseEntity.notFound().build(); - } - return ResponseEntity.ok("Gotten " + id + "!"); - } - - @RequestMapping(value = "/local/{id}", method = RequestMethod.POST) - public String post(@PathVariable String id, @RequestBody String body) { - return "Posted " + id + "!"; - } - - @RequestMapping("/qstring") - public String qstring(@RequestParam MultiValueMap params) { - return "Received " + params.toString(); - } - - @RequestMapping("/") - public String home() { - return "Hello world"; - } - - @RequestMapping("/spa ce") - public String space() { - return "Hello space"; - } - - @RequestMapping("/slow") - public String slow() { - try { - Thread.sleep(80000); - } - catch (InterruptedException e) { - LOG.info(e); - Thread.currentThread().interrupt(); - } - return "slow"; - } - - @Bean - public FallbackProvider fallbackProvider() { - return new ZuulFallbackProvider(); - } - - @Bean - public ZuulFilter sampleFilter() { - return new ZuulFilter() { - @Override - public String filterType() { - return PRE_TYPE; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public Object run() { - if (RequestContext.getCurrentContext().getRequest().getParameterMap() - .containsKey("override")) { - Map> overridden = new HashMap<>(); - overridden.put("key", Arrays.asList("overridden")); - RequestContext.getCurrentContext() - .setRequestQueryParams(overridden); - } - return null; - } - - @Override - public int filterOrder() { - return 0; - } - }; - - } - - @Override - public RequestMappingHandlerMapping requestMappingHandlerMapping( - ContentNegotiationManager mvcContentNegotiationManager, - FormattingConversionService mvcConversionService, - ResourceUrlProvider mvcResourceUrlProvider) { - RequestMappingHandlerMapping mapping = super.requestMappingHandlerMapping( - mvcContentNegotiationManager, mvcConversionService, - mvcResourceUrlProvider); - mapping.setRemoveSemicolonContent(false); - return mapping; - } - - } - - public static class ZuulFallbackProvider implements FallbackProvider { - - @Override - public String getRoute() { - return "simple"; - } - - @Override - public ClientHttpResponse fallbackResponse(String route, Throwable cause) { - return new ClientHttpResponse() { - @Override - public HttpStatus getStatusCode() throws IOException { - return HttpStatus.OK; - } - - @Override - public int getRawStatusCode() throws IOException { - return 200; - } - - @Override - public String getStatusText() throws IOException { - return null; - } - - @Override - public void close() { - - } - - @Override - public InputStream getBody() throws IOException { - return new ByteArrayInputStream("fallback".getBytes()); - } - - @Override - public HttpHeaders getHeaders() { - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.TEXT_HTML); - return headers; - } - }; - } - - } - - @Configuration(proxyBeanMethods = false) - public class FormEncodedMessageConverterConfiguration - extends WebMvcConfigurerAdapter { - - @Override - public void configureMessageConverters(List> converters) { - FormHttpMessageConverter converter = new FormHttpMessageConverter(); - MediaType mediaType = new MediaType("application", "x-www-form-urlencoded", - Charset.forName("UTF-8")); - converter.setSupportedMediaTypes(Arrays.asList(mediaType)); - converters.add(converter); - super.configureMessageConverters(converters); - } - - } - - // Load balancer with fixed server list for "simple" pointing to localhost - @Configuration(proxyBeanMethods = false) - public static class SimpleRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - - @Configuration(proxyBeanMethods = false) - public static class AnotherRibbonClientConfiguration { - - @Value("${local.server.port}") - private int port; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } - - } - - public static class MyErrorController extends BasicErrorController { - - ThreadLocal uriToMatch = new ThreadLocal<>(); - - AtomicBoolean controllerUsed = new AtomicBoolean(); - - public MyErrorController(ErrorAttributes errorAttributes) { - super(errorAttributes, new ErrorProperties()); - } - - @Override - public ResponseEntity> error(HttpServletRequest request) { - String errorUri = (String) request - .getAttribute("javax.servlet.error.request_uri"); - - if (errorUri != null && errorUri.equals(this.uriToMatch.get())) { - controllerUsed.set(true); - } - this.uriToMatch.remove(); - return super.error(request); - } - - public void setUriToMatch(String uri) { - this.uriToMatch.set(uri); - } - - public boolean wasControllerUsed() { - return this.controllerUsed.get(); - } - - public void clear() { - this.controllerUsed.set(false); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/DefaultCounterFactoryTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/DefaultCounterFactoryTests.java deleted file mode 100644 index 5d2c4362f..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/DefaultCounterFactoryTests.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.metrics; - -import com.netflix.zuul.monitoring.CounterFactory; -import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.MeterRegistry; -import org.junit.Test; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class DefaultCounterFactoryTests { - - private static final String NAME = "my-super-metric-name"; - - @Test - public void shouldIncrement() throws Exception { - MeterRegistry meterRegistry = mock(MeterRegistry.class); - CounterFactory factory = new DefaultCounterFactory(meterRegistry); - - Counter counter = mock(Counter.class); - when(meterRegistry.counter(NAME)).thenReturn(counter); - - factory.increment(NAME); - - verify(counter).increment(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/ZuulEmptyMetricsApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/ZuulEmptyMetricsApplicationTests.java deleted file mode 100644 index a6ea4c1c4..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/ZuulEmptyMetricsApplicationTests.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.metrics; - -import com.netflix.zuul.monitoring.CounterFactory; -import com.netflix.zuul.monitoring.TracerFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.netflix.zuul.EnableZuulServer; -import org.springframework.cloud.netflix.zuul.test.TestAutoConfiguration; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.cloud.test.ModifiedClassPathRunner; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(ModifiedClassPathRunner.class) -@ClassPathExclusions({ "spring-boot-starter-actuator-*.jar", "spring-boot-actuator-*.jar", - "micrometer-core-*.jar" }) -public class ZuulEmptyMetricsApplicationTests { - - private ConfigurableApplicationContext context; - - @Before - public void setUp() throws Exception { - ConfigurableApplicationContext context = new SpringApplicationBuilder( - ZuulEmptyMetricsApplicationTestsConfiguration.class) - .web(WebApplicationType.NONE).run("--debug"); - this.context = context; - } - - @After - public void tearDown() throws Exception { - if (this.context != null) { - this.context.close(); - } - } - - @Test - public void shouldSetupDefaultCounterFactoryIfCounterServiceIsPresent() - throws Exception { - CounterFactory factory = this.context.getBean(CounterFactory.class); - - assertThat(factory.getClass()).isEqualTo(EmptyCounterFactory.class); - } - - @Test - public void shouldSetupEmptyTracerFactory() throws Exception { - TracerFactory factory = this.context.getBean(TracerFactory.class); - - assertThat(factory.getClass()).isEqualTo(EmptyTracerFactory.class); - } - - @EnableAutoConfiguration(exclude = TestAutoConfiguration.class) - @Configuration(proxyBeanMethods = false) - // @Import(NoSecurityConfiguration.class) - @EnableZuulServer - @EnableConfigurationProperties(ServerProperties.class) - static class ZuulEmptyMetricsApplicationTestsConfiguration { - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/ZuulMetricsApplicationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/ZuulMetricsApplicationTests.java deleted file mode 100644 index 47a8aa88d..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/metrics/ZuulMetricsApplicationTests.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.metrics; - -import com.netflix.zuul.exception.ZuulException; -import com.netflix.zuul.monitoring.CounterFactory; -import com.netflix.zuul.monitoring.TracerFactory; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.MockClock; -import io.micrometer.core.instrument.simple.SimpleConfig; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.netflix.zuul.EnableZuulServer; -import org.springframework.cloud.netflix.zuul.util.ZuulRuntimeException; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = { - ZuulMetricsApplicationTests.ZuulMetricsApplicationTestsConfiguration.class, - ZuulMetricsApplicationTests.ZuulConfig.class }, webEnvironment = RANDOM_PORT) -@DirtiesContext -public class ZuulMetricsApplicationTests { - - @Autowired - private CounterFactory counterFactory; - - @Autowired - private TracerFactory tracerFactory; - - @Autowired - private MeterRegistry meterRegistry; - - @Test - public void shouldSetupDefaultCounterFactoryIfCounterServiceIsPresent() - throws Exception { - assertThat(counterFactory.getClass()).isEqualTo(DefaultCounterFactory.class); - } - - @Test - public void shouldSetupEmptyTracerFactory() throws Exception { - assertThat(tracerFactory.getClass()).isEqualTo(EmptyTracerFactory.class); - } - - @Test - @SuppressWarnings("all") - public void shouldIncrementCounters() throws Exception { - new ZuulRuntimeException(new Exception()); - - Double count = meterRegistry.counter("ZUUL::EXCEPTION:null:500").count(); - assertThat(0L).isEqualTo(count.longValue()); - - new ZuulException("any", 500, "cause"); - new ZuulException("any", 500, "cause"); - - count = meterRegistry.counter("ZUUL::EXCEPTION:cause:500").count(); - assertThat(2L).isEqualTo(count.longValue()); - - new ZuulException("any", 404, "cause2"); - new ZuulException("any", 404, "cause2"); - new ZuulException("any", 404, "cause2"); - - count = meterRegistry.counter("ZUUL::EXCEPTION:cause2:404").count(); - assertThat(3L).isEqualTo(count.longValue()); - } - - // Don't use @SpringBootApplication because we don't want to component scan - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @EnableZuulServer - static class ZuulConfig { - - } - - @Configuration(proxyBeanMethods = false) - static class ZuulMetricsApplicationTestsConfiguration { - - @Bean - public MeterRegistry meterRegistry() { - return new SimpleMeterRegistry(SimpleConfig.DEFAULT, new MockClock()); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/AdhocTestSuite.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/AdhocTestSuite.java deleted file mode 100644 index 14a60e88c..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/AdhocTestSuite.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.test; - -import org.junit.Ignore; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilterIntegrationTests; - -/** - * A test suite for probing weird ordering problems in the zuul tests. - * - * @author Spencer Gibb - */ -@RunWith(Suite.class) -@SuiteClasses({ - org.springframework.cloud.netflix.zuul.ZuulServerAutoConfigurationTests.class, - org.springframework.cloud.netflix.zuul.RoutesEndpointTests.class, - org.springframework.cloud.netflix.zuul.FormZuulServletProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.metrics.DefaultCounterFactoryTests.class, - org.springframework.cloud.netflix.zuul.metrics.ZuulEmptyMetricsApplicationTests.class, - org.springframework.cloud.netflix.zuul.metrics.ZuulMetricsApplicationTests.class, - org.springframework.cloud.netflix.zuul.web.ZuulHandlerMappingTests.class, - org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfigurationTests.class, - org.springframework.cloud.netflix.zuul.RetryableZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.ServletPathZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.FormZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.filters.CompositeRouteLocatorTests.class, - org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFallbackTests.class, - org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactoryTest.class, - org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonRetryIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.LazyLoadOfZuulConfigurationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.EagerLoadOfZuulConfigurationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommandTests.class, - org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilterLoadBalancerKeyIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandFallbackTests.class, - org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonRetryIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandFactoryTest.class, - org.springframework.cloud.netflix.zuul.filters.route.restclient.RestClientRibbonCommandIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.restclient.RestClientRibbonCommandFallbackTests.class, - org.springframework.cloud.netflix.zuul.filters.route.support.RibbonCommandCauseFallbackPropagationTest.class, - org.springframework.cloud.netflix.zuul.filters.route.support.RibbonCommandHystrixThreadPoolKeyTests.class, - SimpleHostRoutingFilterIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelperTests.class, - org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocatorTests.class, - org.springframework.cloud.netflix.zuul.filters.ZuulPropertiesTests.class, - org.springframework.cloud.netflix.zuul.filters.CustomHostRoutingFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapperIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapperTests.class, - org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocatorTests.class, - org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.post.LocationRewriteFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilterIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.post.LocationRewriteFilterIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilterTests.class, - org.springframework.cloud.netflix.zuul.RoutesEndpointDetailsTests.class, - org.springframework.cloud.netflix.zuul.ZuulProxyConfigurationTests.class, - org.springframework.cloud.netflix.zuul.ZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.SimpleZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.ZuulFilterInitializerTests.class, - org.springframework.cloud.netflix.zuul.RoutesEndpointIntegrationTests.class, - org.springframework.cloud.netflix.zuul.test.ZuulApacheHttpClientConfigurationTests.class, - org.springframework.cloud.netflix.zuul.test.ZuulOkHttpClientConfigurationTests.class, - org.springframework.cloud.netflix.zuul.ContextPathZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.SimpleZuulServerApplicationTests.class, - org.springframework.cloud.netflix.zuul.FiltersEndpointTests.class }) -@Ignore -public class AdhocTestSuite { - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/AdhocZuulTestSuite.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/AdhocZuulTestSuite.java deleted file mode 100644 index 2336fc4ee..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/AdhocZuulTestSuite.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.test; - -import org.junit.Ignore; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilterIntegrationTests; - -/** - * A test suite for probing weird ordering problems in the tests. - * - * @author Dave Syer - */ -@RunWith(Suite.class) -@SuiteClasses({ - org.springframework.cloud.netflix.zuul.ContextPathZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.filters.CompositeRouteLocatorTests.class, - org.springframework.cloud.netflix.zuul.filters.CustomHostRoutingFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocatorTests.class, - org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapperIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapperTests.class, - org.springframework.cloud.netflix.zuul.filters.post.LocationRewriteFilterIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.post.LocationRewriteFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilterIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelperTests.class, - org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactoryTest.class, - org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFallbackTests.class, - org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonRetryIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.EagerLoadOfZuulConfigurationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.LazyLoadOfZuulConfigurationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandFactoryTest.class, - org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandFallbackTests.class, - org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonRetryIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.restclient.RestClientRibbonCommandFallbackTests.class, - org.springframework.cloud.netflix.zuul.filters.route.restclient.RestClientRibbonCommandIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommandTests.class, - org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilterTests.class, - org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilterTests.class, - SimpleHostRoutingFilterIntegrationTests.class, - org.springframework.cloud.netflix.zuul.filters.route.support.RibbonCommandCauseFallbackPropagationTest.class, - org.springframework.cloud.netflix.zuul.filters.route.support.RibbonCommandHystrixThreadPoolKeyTests.class, - org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocatorTests.class, - org.springframework.cloud.netflix.zuul.filters.ZuulPropertiesTests.class, - org.springframework.cloud.netflix.zuul.FiltersEndpointTests.class, - org.springframework.cloud.netflix.zuul.FormZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.FormZuulServletProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.metrics.DefaultCounterFactoryTests.class, - org.springframework.cloud.netflix.zuul.metrics.ZuulEmptyMetricsApplicationTests.class, - org.springframework.cloud.netflix.zuul.metrics.ZuulMetricsApplicationTests.class, - org.springframework.cloud.netflix.zuul.RetryableZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.RoutesEndpointDetailsTests.class, - org.springframework.cloud.netflix.zuul.RoutesEndpointIntegrationTests.class, - org.springframework.cloud.netflix.zuul.RoutesEndpointTests.class, - org.springframework.cloud.netflix.zuul.ServletPathZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.SimpleZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.SimpleZuulServerApplicationTests.class, - org.springframework.cloud.netflix.zuul.test.ZuulApacheHttpClientConfigurationTests.class, - org.springframework.cloud.netflix.zuul.test.ZuulOkHttpClientConfigurationTests.class, - org.springframework.cloud.netflix.zuul.web.ZuulHandlerMappingTests.class, - org.springframework.cloud.netflix.zuul.ZuulFilterInitializerTests.class, - org.springframework.cloud.netflix.zuul.ZuulProxyApplicationTests.class, - org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfigurationTests.class, - org.springframework.cloud.netflix.zuul.ZuulProxyConfigurationTests.class, - org.springframework.cloud.netflix.zuul.ZuulServerAutoConfigurationTests.class }) -@Ignore -public class AdhocZuulTestSuite { - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/NoSecurityConfiguration.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/NoSecurityConfiguration.java deleted file mode 100644 index f73bcdb9a..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/NoSecurityConfiguration.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.test; - -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration(proxyBeanMethods = false) -public class NoSecurityConfiguration extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.authorizeRequests().anyRequest().permitAll().and().csrf().disable(); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/TestAutoConfiguration.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/TestAutoConfiguration.java deleted file mode 100644 index 516fcf2dd..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/TestAutoConfiguration.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.test; - -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.web.firewall.StrictHttpFirewall; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@Import({ NoopDiscoveryClientAutoConfiguration.class }) -@AutoConfigureBefore(SecurityAutoConfiguration.class) -public class TestAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - @Order(Ordered.HIGHEST_PRECEDENCE) - protected static class TestSecurityConfiguration - extends WebSecurityConfigurerAdapter { - - TestSecurityConfiguration() { - super(true); - } - - @Override - public void configure(WebSecurity web) { - StrictHttpFirewall httpFirewall = new StrictHttpFirewall(); - httpFirewall.setAllowSemicolon(true); - web.httpFirewall(httpFirewall); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - // super.configure(http); - http.antMatcher("/proxy-username").httpBasic().and().authorizeRequests() - .antMatchers("/**").permitAll(); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/ZuulApacheHttpClientConfigurationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/ZuulApacheHttpClientConfigurationTests.java deleted file mode 100644 index 0e6aa11f5..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/ZuulApacheHttpClientConfigurationTests.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.test; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.ArrayList; - -import org.apache.http.Header; -import org.apache.http.StatusLine; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.message.BasicHeader; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockingDetails; -import org.mockito.Mockito; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory; -import org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientFactory; -import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter; -import org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommand; -import org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.ReflectionUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.mockingDetails; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(properties = { "ribbon.eureka.enabled = false" }) -@DirtiesContext -public class ZuulApacheHttpClientConfigurationTests { - - @Autowired - SimpleHostRoutingFilter simpleHostRoutingFilter; - - @Autowired - HttpClientRibbonCommandFactory httpClientRibbonCommandFactory; - - @Test - public void testHttpClientSimpleHostRoutingFilter() { - CloseableHttpClient httpClient = getField(simpleHostRoutingFilter, "httpClient"); - MockingDetails httpClientDetails = mockingDetails(httpClient); - assertThat(httpClientDetails.isMock()); - } - - @Test - public void testRibbonLoadBalancingHttpClient() { - RibbonCommandContext context = new RibbonCommandContext("foo", " GET", - "http://localhost", false, new LinkedMultiValueMap<>(), - new LinkedMultiValueMap<>(), null, new ArrayList<>(), 0L); - HttpClientRibbonCommand command = httpClientRibbonCommandFactory.create(context); - RibbonLoadBalancingHttpClient ribbonClient = command.getClient(); - CloseableHttpClient httpClient = getField(ribbonClient, "delegate"); - MockingDetails httpClientDetails = mockingDetails(httpClient); - assertThat(httpClientDetails.isMock()); - } - - @SuppressWarnings("unchecked") - protected T getField(Object target, String name) { - Field field = ReflectionUtils.findField(target.getClass(), name); - ReflectionUtils.makeAccessible(field); - Object value = ReflectionUtils.getField(field, target); - return (T) value; - } - - @Bean - public ApacheHttpClientFactory apacheHttpClientFactory(HttpClientBuilder builder) { - return new TestConfig.MyApacheHttpClientFactory(builder); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableZuulProxy - static class TestConfig { - - static class MyApacheHttpClientFactory extends DefaultApacheHttpClientFactory { - - MyApacheHttpClientFactory(HttpClientBuilder builder) { - super(builder); - } - - @Override - public HttpClientBuilder createBuilder() { - CloseableHttpClient client = mock(CloseableHttpClient.class); - CloseableHttpResponse response = mock(CloseableHttpResponse.class); - StatusLine statusLine = mock(StatusLine.class); - doReturn(200).when(statusLine).getStatusCode(); - Mockito.doReturn(statusLine).when(response).getStatusLine(); - Header[] headers = new BasicHeader[0]; - doReturn(headers).when(response).getAllHeaders(); - try { - Mockito.doReturn(response).when(client) - .execute(any(HttpUriRequest.class)); - } - catch (IOException e) { - e.printStackTrace(); - } - HttpClientBuilder builder = mock(HttpClientBuilder.class); - Mockito.doReturn(client).when(builder).build(); - return builder; - } - - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/ZuulOkHttpClientConfigurationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/ZuulOkHttpClientConfigurationTests.java deleted file mode 100644 index 3f2f21cd7..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/test/ZuulOkHttpClientConfigurationTests.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.test; - -import java.lang.reflect.Field; -import java.util.ArrayList; - -import okhttp3.OkHttpClient; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockingDetails; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory; -import org.springframework.cloud.commons.httpclient.OkHttpClientFactory; -import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; -import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; -import org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommand; -import org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.ReflectionUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.mockingDetails; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(properties = { "spring.cloud.httpclientfactories.ok.enabled: true", - "ribbon.eureka.enabled = false", "ribbon.okhttp.enabled: true", - "ribbon.httpclient.enabled: false" }) -@DirtiesContext -public class ZuulOkHttpClientConfigurationTests { - - @Autowired - OkHttpClientFactory okHttpClientFactory; - - @Autowired - OkHttpClientConnectionPoolFactory connectionPoolFactory; - - @Autowired - OkHttpRibbonCommandFactory okHttpRibbonCommandFactory; - - @Test - public void testOkHttpLoadBalancingHttpClient() { - RibbonCommandContext context = new RibbonCommandContext("foo", " GET", - "http://localhost", false, new LinkedMultiValueMap<>(), - new LinkedMultiValueMap<>(), null, new ArrayList<>(), 0L); - OkHttpRibbonCommand command = okHttpRibbonCommandFactory.create(context); - OkHttpLoadBalancingClient ribbonClient = command.getClient(); - OkHttpClient httpClient = getField(ribbonClient, "delegate"); - MockingDetails httpClientDetails = mockingDetails(httpClient); - assertThat(httpClientDetails.isMock()).isTrue(); - } - - protected T getField(Object target, String name) { - Field field = ReflectionUtils.findField(target.getClass(), name); - ReflectionUtils.makeAccessible(field); - Object value = ReflectionUtils.getField(field, target); - return (T) value; - } - - @SpringBootConfiguration - @EnableAutoConfiguration - @EnableZuulProxy - static class TestConfig { - - @Bean - public OkHttpClient client() { - return mock(OkHttpClient.class); - } - - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractorTest.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractorTest.java deleted file mode 100644 index 8145907dd..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/util/RequestContentDataExtractorTest.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.util; - -import java.io.IOException; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import org.springframework.http.HttpEntity; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.multipart.MultipartHttpServletRequest; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.beans.HasPropertyWithValue.hasProperty; -import static org.mockito.Mockito.when; - -/** - * Created by Dmitrii_Priporov on 01.07.18. - */ -@RunWith(MockitoJUnitRunner.class) -public class RequestContentDataExtractorTest { - - @Mock - private MultipartHttpServletRequest request; - - @Test - public void methodExtractShouldReturnNotDuplicatedValuesFromRequest() - throws Exception { - // when - when(request.getMultiFileMap()).thenReturn(new LinkedMultiValueMap<>()); - when(request.getQueryString()).thenReturn("uid=12&uid=34"); - - Map expectedParameterMap = new HashMap() { - { - put("uid", new String[] { "65" }); - } - }; - when(request.getParameterMap()).thenReturn(expectedParameterMap); - - // action - MultiValueMap result = RequestContentDataExtractor - .extract(request); - - // then - assertThat(result).isNotNull(); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get("uid")).isNotNull(); - assertThat(result.get("uid")).hasSize(1); - Assert.assertThat(result.get("uid"), hasItem(hasProperty("body", equalTo("65")))); - Assert.assertThat(result.get("uid"), - hasItem(hasProperty("headers", notNullValue()))); - } - - @Test - public void methodExtractShouldReturnNotDuplicatedValuesFromRequestWhenEncoded() - throws Exception { - // when - when(request.getMultiFileMap()).thenReturn(new LinkedMultiValueMap<>()); - when(request.getQueryString()).thenReturn("uid=hello%20world"); - - Map expectedParameterMap = new HashMap() { - { - put("uid", new String[] { "hello world" }); - } - }; - when(request.getParameterMap()).thenReturn(expectedParameterMap); - - // action - MultiValueMap result = RequestContentDataExtractor - .extract(request); - - // then - assertThat(result).isNotNull(); - assertThat(result.size()).isEqualTo(0); - } - - @Test - public void findQueryParamsGroupedByNameShouldReturnCorrectResult() { - // when - when(request.getQueryString()).thenReturn("uid=12&uid=34"); - - // action - Map> result = RequestContentDataExtractor - .findQueryParamsGroupedByName(request); - - // then - assertThat(result).containsEntry("uid", asList("12", "34")); - assertThat(result.size()).isEqualTo(1); - } - - @Test - public void findQueryParamsGroupedByNameShouldReturnEmptyMapWhenQueryIsEmpty() { - // when - when(request.getQueryString()).thenReturn(""); - - // action - Map> result = RequestContentDataExtractor - .findQueryParamsGroupedByName(request); - - // then - assertThat(result).isNotNull(); - assertThat(result.size()).isEqualTo(0); - } - - @Test - public void findQueryParamsGroupedByNameShouldReturnEmptyMapWhenQueryIsNull() { - // when - when(request.getQueryString()).thenReturn(null); - - // action - Map> result = RequestContentDataExtractor - .findQueryParamsGroupedByName(request); - - // then - assertThat(result).isNotNull(); - assertThat(result.size()).isEqualTo(0); - } - - @Test - public void findQueryParamsGroupedByNameShouldReturnEmptyMapWhenQueryValueIsNull() - throws IOException { - // when - Map paramMap = new HashMap<>(); - paramMap.put("uid", new String[] { "foo", "bar" }); - when(request.getQueryString()).thenReturn("uid"); - when(request.getParameterMap()).thenReturn(paramMap); - when(request.getMultiFileMap()).thenReturn(new LinkedMultiValueMap<>()); - - // action - Map> result = RequestContentDataExtractor.extract(request); - - // then - List uidResult = new LinkedList(); - uidResult.add(new HttpEntity<>("foo")); - uidResult.add(new HttpEntity<>("bar")); - assertThat(result).isNotNull(); - assertThat(result).containsEntry("uid", uidResult); - assertThat(result.size()).isEqualTo(1); - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/web/ZuulHandlerMappingTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/web/ZuulHandlerMappingTests.java deleted file mode 100644 index 571120ea2..000000000 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/web/ZuulHandlerMappingTests.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.zuul.web; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import com.netflix.zuul.context.RequestContext; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; - -import org.springframework.boot.web.servlet.error.ErrorController; -import org.springframework.cloud.netflix.zuul.filters.Route; -import org.springframework.cloud.netflix.zuul.filters.RouteLocator; -import org.springframework.mock.web.MockHttpServletRequest; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * @author Biju Kunjummen - */ -public class ZuulHandlerMappingTests { - - private ZuulHandlerMapping mapping; - - private RouteLocator locator = Mockito.mock(RouteLocator.class); - - private ErrorController errors = Mockito.mock(ErrorController.class); - - private MockHttpServletRequest request = new MockHttpServletRequest(); - - @Before - public void init() { - RequestContext.getCurrentContext().clear(); - this.mapping = new ZuulHandlerMapping(this.locator, new ZuulController()); - this.mapping.setErrorController(this.errors); - Mockito.when(this.errors.getErrorPath()).thenReturn("/error"); - } - - @Test - public void mappedPath() throws Exception { - Mockito.when(this.locator.getRoutes()).thenReturn(Collections - .singletonList(new Route("foo", "/foo/**", "foo", "", null, null))); - this.request.setServletPath("/foo/"); - this.mapping.setDirty(true); - assertThat(this.mapping.getHandler(this.request)).isNotNull(); - } - - @Test - public void defaultPath() throws Exception { - Mockito.when(this.locator.getRoutes()).thenReturn(Collections - .singletonList(new Route("default", "/**", "foo", "", null, null))); - this.request.setServletPath("/"); - this.mapping.setDirty(true); - assertThat(this.mapping.getHandler(this.request)).isNotNull(); - } - - @Test - public void errorPath() throws Exception { - Mockito.when(this.locator.getRoutes()).thenReturn(Collections - .singletonList(new Route("default", "/**", "foo", "", null, null))); - this.request.setServletPath("/error"); - this.mapping.setDirty(true); - assertThat(this.mapping.getHandler(this.request)).isNull(); - } - - @Test - public void ignoredPathsShouldNotReturnAHandler() throws Exception { - assertThat(mappingWithIgnoredPathsAndRoutes(Arrays.asList("/p1/**"), - new Route("p1", "/p1/**", "p1", "", null, null)) - .getHandler(requestForAPath("/p1"))).isNull(); - - assertThat(mappingWithIgnoredPathsAndRoutes(Arrays.asList("/p1/**/p3/"), - new Route("p1", "/p1/**/p3", "p1", "", null, null)) - .getHandler(requestForAPath("/p1/p2/p3"))).isNull(); - - assertThat(mappingWithIgnoredPathsAndRoutes(Arrays.asList("/p1/**/p3/**"), - new Route("p1", "/p1/**/p3", "p1", "", null, null)) - .getHandler(requestForAPath("/p1/p2/p3"))).isNull(); - - assertThat(mappingWithIgnoredPathsAndRoutes(Arrays.asList("/p1/**/p4/"), - new Route("p1", "/p1/**/p4/", "p1", "", null, null)) - .getHandler(requestForAPath("/p1/p2/p3/p4"))).isNull(); - } - - private ZuulHandlerMapping mappingWithIgnoredPathsAndRoutes(List ignoredPaths, - Route route) { - RouteLocator routeLocator = Mockito.mock(RouteLocator.class); - Mockito.when(routeLocator.getIgnoredPaths()).thenReturn(ignoredPaths); - Mockito.when(routeLocator.getRoutes()) - .thenReturn(Collections.singletonList(route)); - ZuulHandlerMapping zuulHandlerMapping = new ZuulHandlerMapping(routeLocator, - new ZuulController()); - return zuulHandlerMapping; - } - - private MockHttpServletRequest requestForAPath(String path) { - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setServletPath(path); - return request; - } - -} diff --git a/spring-cloud-netflix-zuul/src/test/resources/META-INF/spring.factories b/spring-cloud-netflix-zuul/src/test/resources/META-INF/spring.factories deleted file mode 100644 index 9819adfef..000000000 --- a/spring-cloud-netflix-zuul/src/test/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.netflix.zuul.test.TestAutoConfiguration diff --git a/spring-cloud-netflix-zuul/src/test/resources/application.yml b/spring-cloud-netflix-zuul/src/test/resources/application.yml deleted file mode 100644 index de191f824..000000000 --- a/spring-cloud-netflix-zuul/src/test/resources/application.yml +++ /dev/null @@ -1,26 +0,0 @@ -server: - port: 9999 - compression: - enabled: true - min-response-size: 1024 - mime-types: application/xml,application/json -spring: - application: - name: testclient -#zuul: - #prefix: /api - #strip-prefix: true -# routes: -# test: -# serviceId: testclient -# path: /testing123/** -# stores: -# url: http://localhost:8081 -# path: /stores/** -hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000 -management: - context-path: /admin -endpoints.default.web.enabled: true -logging: - level: - org.springframework.cloud.netflix.zuul: DEBUG \ No newline at end of file diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-eureka-client/pom.xml b/spring-cloud-starter-netflix-eureka-client/pom.xml similarity index 69% rename from spring-cloud-starter-netflix/spring-cloud-starter-netflix-eureka-client/pom.xml rename to spring-cloud-starter-netflix-eureka-client/pom.xml index 1433d2286..0b6c8b17a 100644 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-eureka-client/pom.xml +++ b/spring-cloud-starter-netflix-eureka-client/pom.xml @@ -3,8 +3,8 @@ 4.0.0 org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT + spring-cloud-netflix + 3.0.0.BUILD-SNAPSHOT spring-cloud-starter-netflix-eureka-client Spring Cloud Starter Netflix Eureka Client @@ -19,10 +19,6 @@ org.springframework.cloud spring-cloud-starter - - org.springframework.cloud - spring-cloud-netflix-hystrix - org.springframework.cloud spring-cloud-netflix-eureka-client @@ -35,22 +31,10 @@ com.netflix.eureka eureka-core - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - org.springframework.cloud spring-cloud-starter-loadbalancer - - com.netflix.ribbon - ribbon-eureka - com.thoughtworks.xstream xstream diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-eureka-server/pom.xml b/spring-cloud-starter-netflix-eureka-server/pom.xml similarity index 71% rename from spring-cloud-starter-netflix/spring-cloud-starter-netflix-eureka-server/pom.xml rename to spring-cloud-starter-netflix-eureka-server/pom.xml index b57820d4d..ab4ec0e6d 100644 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-eureka-server/pom.xml +++ b/spring-cloud-starter-netflix-eureka-server/pom.xml @@ -2,8 +2,8 @@ 4.0.0 org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT + spring-cloud-netflix + 3.0.0.BUILD-SNAPSHOT spring-cloud-starter-netflix-eureka-server Spring Cloud Starter Netflix Eureka Server @@ -22,22 +22,10 @@ org.springframework.cloud spring-cloud-netflix-eureka-server - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - org.springframework.cloud spring-cloud-starter-loadbalancer - - com.netflix.ribbon - ribbon-eureka - org.glassfish.jaxb diff --git a/spring-cloud-starter-netflix/pom.xml b/spring-cloud-starter-netflix/pom.xml deleted file mode 100644 index d2c7f1644..000000000 --- a/spring-cloud-starter-netflix/pom.xml +++ /dev/null @@ -1,25 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-netflix - 2.2.2.BUILD-SNAPSHOT - .. - - spring-cloud-starter-netflix - pom - Spring Cloud Netflix Starters - Spring Cloud Netflix Starters - - spring-cloud-starter-netflix-archaius - spring-cloud-starter-netflix-eureka-client - spring-cloud-starter-netflix-eureka-server - spring-cloud-starter-netflix-hystrix - spring-cloud-starter-netflix-hystrix-dashboard - spring-cloud-starter-netflix-ribbon - spring-cloud-starter-netflix-turbine - spring-cloud-starter-netflix-turbine-stream - spring-cloud-starter-netflix-zuul - - \ No newline at end of file diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-archaius/pom.xml b/spring-cloud-starter-netflix/spring-cloud-starter-netflix-archaius/pom.xml deleted file mode 100644 index dd6f8b519..000000000 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-archaius/pom.xml +++ /dev/null @@ -1,39 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT - - spring-cloud-starter-netflix-archaius - Spring Cloud Starter Netflix Archaius - Spring Cloud Starter Netflix Archaius - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - - org.springframework.cloud - spring-cloud-starter - - - org.springframework.cloud - spring-cloud-netflix-ribbon - - - org.springframework.cloud - spring-cloud-netflix-archaius - - - com.netflix.archaius - archaius-core - - - commons-configuration - commons-configuration - - - diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-hystrix-dashboard/pom.xml b/spring-cloud-starter-netflix/spring-cloud-starter-netflix-hystrix-dashboard/pom.xml deleted file mode 100644 index 621600c1a..000000000 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-hystrix-dashboard/pom.xml +++ /dev/null @@ -1,35 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT - - spring-cloud-starter-netflix-hystrix-dashboard - Spring Cloud Starter Netflix Hystrix Dashboard - Spring Cloud Starter Netflix Hystrix Dashboard - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.cloud - spring-cloud-starter - - - org.springframework.cloud - spring-cloud-netflix-hystrix-dashboard - - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - - - \ No newline at end of file diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-hystrix/pom.xml b/spring-cloud-starter-netflix/spring-cloud-starter-netflix-hystrix/pom.xml deleted file mode 100644 index bd2d326b0..000000000 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-hystrix/pom.xml +++ /dev/null @@ -1,55 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT - - spring-cloud-starter-netflix-hystrix - Spring Cloud Starter Netflix Hystrix - Spring Cloud Starter Netflix Hystrix - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - - org.springframework.cloud - spring-cloud-starter - - - org.springframework.cloud - spring-cloud-netflix-hystrix - - - org.springframework.cloud - spring-cloud-netflix-ribbon - - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - - - com.netflix.hystrix - hystrix-core - - - com.netflix.hystrix - hystrix-serialization - - - com.netflix.hystrix - hystrix-metrics-event-stream - - - com.netflix.hystrix - hystrix-javanica - - - io.reactivex - rxjava-reactive-streams - - - \ No newline at end of file diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-ribbon/pom.xml b/spring-cloud-starter-netflix/spring-cloud-starter-netflix-ribbon/pom.xml deleted file mode 100644 index cdd753854..000000000 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-ribbon/pom.xml +++ /dev/null @@ -1,61 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT - - spring-cloud-starter-netflix-ribbon - Spring Cloud Starter Netflix Ribbon - Spring Cloud Starter Netflix Ribbon - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - - org.springframework.cloud - spring-cloud-starter - - - org.springframework.cloud - spring-cloud-netflix-ribbon - - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - - - com.netflix.ribbon - ribbon - - - io.netty - netty-codec-http - - - io.netty - netty-transport-native-epoll - - - - - com.netflix.ribbon - ribbon-core - - - com.netflix.ribbon - ribbon-httpclient - - - com.netflix.ribbon - ribbon-loadbalancer - - - io.reactivex - rxjava - - - \ No newline at end of file diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-turbine-stream/pom.xml b/spring-cloud-starter-netflix/spring-cloud-starter-netflix-turbine-stream/pom.xml deleted file mode 100644 index 69e434f5b..000000000 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-turbine-stream/pom.xml +++ /dev/null @@ -1,75 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT - - spring-cloud-starter-netflix-turbine-stream - Spring Cloud Starter Netflix Turbine Stream - Spring Cloud Starter Netflix Turbine Stream - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - 2.0.0-DP.2 - - - - org.springframework.cloud - spring-cloud-starter-netflix-eureka-client - - - spring-boot-starter-tomcat - org.springframework.boot - - - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - - - org.springframework.cloud - spring-cloud-netflix-turbine-stream - - - org.springframework.cloud - spring-cloud-stream - - - com.fasterxml.jackson.core - jackson-databind - - - com.netflix.turbine - turbine-core - ${turbine.version} - - - com.netflix.rxjava - rxjava-core - - - org.slf4j - slf4j-simple - - - - - io.reactivex - rxjava - - - org.apache.tomcat.embed - tomcat-embed-el - - - \ No newline at end of file diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-turbine/pom.xml b/spring-cloud-starter-netflix/spring-cloud-starter-netflix-turbine/pom.xml deleted file mode 100644 index a4ce24716..000000000 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-turbine/pom.xml +++ /dev/null @@ -1,61 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT - - spring-cloud-starter-netflix-turbine - Spring Cloud Starter Netflix Turbine - Spring Cloud Starter Netflix Turbine - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - 1.0.0 - - - - org.springframework.cloud - spring-cloud-starter - - - org.springframework.cloud - spring-cloud-starter-netflix-eureka-client - - - org.springframework.cloud - spring-cloud-netflix-turbine - - - com.netflix.turbine - turbine-core - ${turbine.version} - - - javax.servlet - servlet-api - - - log4j - log4j - - - com.netflix.rxjava - rxjava-core - - - org.slf4j - slf4j-simple - - - org.mockito - mockito-all - - - - - \ No newline at end of file diff --git a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-zuul/pom.xml b/spring-cloud-starter-netflix/spring-cloud-starter-netflix-zuul/pom.xml deleted file mode 100644 index 56dbe043a..000000000 --- a/spring-cloud-starter-netflix/spring-cloud-starter-netflix-zuul/pom.xml +++ /dev/null @@ -1,51 +0,0 @@ - - 4.0.0 - - org.springframework.cloud - spring-cloud-starter-netflix - 2.2.2.BUILD-SNAPSHOT - - spring-cloud-starter-netflix-zuul - Spring Cloud Starter Netflix Zuul - Spring Cloud Starter Netflix Zuul - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - - org.springframework.cloud - spring-cloud-netflix-zuul - - - org.springframework.cloud - spring-cloud-starter - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.cloud - spring-cloud-starter-netflix-hystrix - - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - - - org.springframework.cloud - spring-cloud-starter-netflix-archaius - - - com.netflix.zuul - zuul-core - - - \ No newline at end of file