Giter VIP home page Giter VIP logo

zuul's Introduction

Snapshot

Zuul

Zuul is an L7 application gateway that provides capabilities for dynamic routing, monitoring, resiliency, security, and more. Please view the wiki for usage, information, HOWTO, etc https://github.com/Netflix/zuul/wiki

Here are some links to help you learn more about the Zuul Project. Feel free to PR to add any other info, presentations, etc.


Articles from Netflix:

Zuul 1: http://techblog.netflix.com/2013/06/announcing-zuul-edge-service-in-cloud.html

Zuul 2:

https://netflixtechblog.com/open-sourcing-zuul-2-82ea476cb2b3

https://netflixtechblog.com/zuul-2-the-netflix-journey-to-asynchronous-non-blocking-systems-45947377fb5c

https://netflixtechblog.com/the-show-must-go-on-securing-netflix-studios-at-scale-19b801c86479


Netflix presentations about Zuul:

Strange Loop 2017 - Zuul 2: https://youtu.be/2oXqbLhMS_A

AWS re:Invent 2018 - Scaling push messaging for millions of Netflix devices: https://youtu.be/IdR6N9B-S1E


Slides from Netflix presentations about Zuul:

http://www.slideshare.net/MikeyCohen1/zuul-netflix-springone-platform

http://www.slideshare.net/MikeyCohen1/rethinking-cloud-proxies-54923218

https://github.com/strangeloop/StrangeLoop2017/blob/master/slides/ArthurGonigberg-ZuulsJourneyToNonBlocking.pdf

https://www.slideshare.net/SusheelAroskar/scaling-push-messaging-for-millions-of-netflix-devices


Projects Using Zuul:

https://cloud.spring.io/

https://jhipster.github.io/


Info and examples from various projects:

https://cloud.spring.io/spring-cloud-netflix/multi/multi__router_and_filter_zuul

http://www.baeldung.com/spring-rest-with-zuul-proxy

https://blog.heroku.com/using_netflix_zuul_to_proxy_your_microservices

http://blog.ippon.tech/jhipster-3-0-introducing-microservices/


Other blog posts about Zuul:

https://engineering.riotgames.com/news/riot-games-api-fulfilling-zuuls-destiny

https://engineering.riotgames.com/news/riot-games-api-deep-dive

http://instea.sk/2015/04/netflix-zuul-vs-nginx-performance/


How to release Zuul

This project uses a GitHub Action workflow for publishing a new release. The workflow is triggered by a Git tag.

git checkout master
git tag vX.Y.Z
git push --tags

zuul's People

Contributors

alexanderellis avatar argha-c avatar artgon avatar carl-mastrangelo avatar chris-h-phillips avatar cuishuang avatar danielthomas avatar dependabot[bot] avatar gavinbunney avatar gaya3varadhu avatar gzurowski avatar jfernandez avatar jguerra avatar karim-z avatar kerumai avatar kyagna avatar ldayton avatar lindseyreynolds avatar mhawthorne avatar mikeycohen avatar neerajrj avatar niteshkant avatar raksoras avatar redmar avatar rpalcolea avatar rspieldenner avatar sullis avatar susheelaroskar avatar trptcolin avatar vic999 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zuul's Issues

Zuul/Hystrix: HTTP connection leak in case of timeout

See spring-cloud/spring-cloud-netflix#327 for a complete description of the issue and scenarios to reproduce it.

The bottom line is:

It turns out that Zuul leaks HTTP connections if a service takes longer than the Hystrix execution timeout but less than the ReadTimeout. To summarise:

execTime < hystrixTimeout < readTimeout --> OK (no leak)
hystrixTimeout < execTime < readTimeout --> LEAK
hystrixTimeout < readTimeout < execTime --> OK (no leak)
readTimeout < execTime < hystrixTimeout --> OK (no leak)
readTimeout < hystrixTimeout < execTime --> LEAK

The problem has been identified in the RibbonCommand returning an HttpResponse that will never be closed in case of Hystrix timeout. Hence causing connection leaks in the HTTP connection pool.

Although the issue affects SpringCloud's version of the Zuul server, it seems that com.netflix.zuul.dependency.ribbon.hystrix.RibbonCommand would be affected as well.

Question: any ETA on Zuul 2?

We're using Zuul together with spring cloud Netflix as our api gateway and have a custom ZuulFilter for authentication against a remote system.
This is why we are interested in an asynchronous filter mechanism as we fear many concurrent users authenticating at the api gateway would lead to many blocked threads which limits the total concurrent users using the api.

So what's the plan for Zuul 2? Any release coming soon?

Thanks.
Sorry to post as github issue, but I didn't find another possibility to get in touch.

RxNetty and 2.x vs. old-2.x

I had been tracking the RxNetty based version of Zuul that was recently moved to the "old-2.x" branch. Is RxNetty no longer on the roadmap? Is the intention for Zuul 2 to provide some sort of non-blocking semantics - either through Netty/RxNetty or the Servlet 3.1 API?

Thank you

Exception when a filter calls setRouteHost() (in zuul-netflix-webapp)

Routing of requests fails in zuul-netflix-webapp with a filter calls setRouteHost() on the RequestContext. The problem appears to be that the local binding of httpRequest in ZuulHostRequest.forward() shadows the httpRequest() method in the same class.

Renaming the method resolves this issue in my environment. Pull request #94 has been submitted with this fix.

Launching zuul-netflix webapp fails with java.lang.ArrayIndexOutOfBoundsException

When running zuul-netflix-webapp with ../gradlew jettyRun on my system (Ubuntu 14.04.1 with Oracle JDK 1.7.0_72-b14), the launch fails with an ArrayIndexOutOfBoundsException reproduced in full at the end of this issue report. This is apparently due to a dependency on turbine-core that does not fix a particular version; when this started failing on my system on Friday, I traced it to turbine-core-2.0.0-DP.1.jar.

Unlike the other dependencies specified in the netflix-webapp subdirectory (which specify a particular library version), the Turbine dependency is declared as

compile 'com.netflix.turbine:turbine-core:[0.4,)'

Changing this to a fixed, lower version of turbine-core fixes this problem. (I tried 0.5 in my tests, which worked fine.)

> Building > :zuul-netflix-webapp:jettyRun > Starting Jetty > Resolving dependencies ':zuul-netflix-webapp:zuul-netflix-webapp:jettyRun
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/user/.gradle/wrapper/dists/gradle-1.1-bin/13d7lnhcrghv2i5e54el41jpgr/gradle-1.1/lib/logback-classic-1.0.6.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/user/.gradle/caches/artifacts-14/filestore/org.slf4j/slf4j-log4j12/1.7.2/jar/7539c264413b9b1ff9841cd00058c974b7cd1ec9/slf4j-log4j12-1.7.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/user/.gradle/caches/artifacts-14/filestore/org.slf4j/slf4j-simple/1.7.7/jar/8095d0b9f7e0a9cd79a663c740e0f8fb31d0e2c8/slf4j-simple-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
 WARN 16:23:53,061 No URLs will be polled as dynamic configuration sources.
 INFO 16:23:53,174 To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
 INFO 16:23:53,195 DynamicPropertyFactory is initialized with configuration sources: com.netflix.config.ConcurrentCompositeConfiguration@48c5241f
 INFO 16:23:53,207 Loading application properties with app id: zuul and environment: null
 INFO 16:23:53,230 Loaded properties file file:/home/user/foreign-repos/zuul/zuul-netflix-webapp/build/resources/main/zuul.properties
 INFO 16:23:53,233 Creating a new governator classpath scanner with base packages: [com.netflix]
Could not instantiate listener com.netflix.zuul.StartServer
java.lang.ArrayIndexOutOfBoundsException: 23884
    at org.objectweb.asm.ClassReader.<init>(Unknown Source)
    at org.objectweb.asm.ClassReader.<init>(Unknown Source)
    at org.objectweb.asm.ClassReader.<init>(Unknown Source)
    at org.apache.xbean.finder.AnnotationFinder.readClassDef(AnnotationFinder.java:957)
    at org.apache.xbean.finder.AnnotationFinder.<init>(AnnotationFinder.java:120)
    at com.netflix.governator.lifecycle.ClasspathScanner.doScanning(ClasspathScanner.java:141)
    at com.netflix.governator.lifecycle.ClasspathScanner.<init>(ClasspathScanner.java:82)
    at com.netflix.governator.lifecycle.ClasspathScanner.<init>(ClasspathScanner.java:61)
    at com.netflix.governator.guice.LifecycleInjector.createStandardClasspathScanner(LifecycleInjector.java:286)
    at com.netflix.karyon.server.ServerBootstrap.initialize(ServerBootstrap.java:114)
    at com.netflix.karyon.server.KaryonServer.<init>(KaryonServer.java:166)
    at com.netflix.karyon.server.KaryonServer.<init>(KaryonServer.java:138)
    at com.netflix.zuul.StartServer.<init>(StartServer.java:84)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at java.lang.Class.newInstance(Class.java:374)
    at org.mortbay.jetty.webapp.WebXmlConfiguration.newListenerInstance(WebXmlConfiguration.java:650)
    at org.mortbay.jetty.webapp.WebXmlConfiguration.initListener(WebXmlConfiguration.java:631)
    at org.mortbay.jetty.webapp.WebXmlConfiguration.initWebXmlElement(WebXmlConfiguration.java:368)
    at org.mortbay.jetty.plus.webapp.AbstractConfiguration.initWebXmlElement(AbstractConfiguration.java:190)
    at org.mortbay.jetty.webapp.WebXmlConfiguration.initialize(WebXmlConfiguration.java:289)
    at org.mortbay.jetty.plus.webapp.AbstractConfiguration.initialize(AbstractConfiguration.java:133)
    at org.mortbay.jetty.webapp.WebXmlConfiguration.configure(WebXmlConfiguration.java:222)
    at org.mortbay.jetty.plus.webapp.AbstractConfiguration.configure(AbstractConfiguration.java:113)
    at org.mortbay.jetty.webapp.WebXmlConfiguration.configureWebApp(WebXmlConfiguration.java:180)
    at org.mortbay.jetty.plus.webapp.AbstractConfiguration.configureWebApp(AbstractConfiguration.java:96)
    at org.mortbay.jetty.plus.webapp.Configuration.configureWebApp(Configuration.java:149)
    at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1269)
    at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
    at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:489)
    at org.gradle.api.plugins.jetty.internal.JettyPluginWebAppContext.doStart(JettyPluginWebAppContext.java:112)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
    at org.mortbay.jetty.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:156)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
    at org.mortbay.jetty.Server.doStart(Server.java:224)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.gradle.api.plugins.jetty.internal.Jetty6PluginServer.start(Jetty6PluginServer.java:111)
    at org.gradle.api.plugins.jetty.AbstractJettyRunTask.startJettyInternal(AbstractJettyRunTask.java:247)
    at org.gradle.api.plugins.jetty.AbstractJettyRunTask.startJetty(AbstractJettyRunTask.java:198)
    at org.gradle.api.plugins.jetty.AbstractJettyRunTask.start(AbstractJettyRunTask.java:169)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1047)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:877)
    at org.gradle.api.internal.BeanDynamicObject$MetaClassAdapter.invokeMethod(BeanDynamicObject.java:196)
    at org.gradle.api.internal.BeanDynamicObject.invokeMethod(BeanDynamicObject.java:102)
    at org.gradle.api.internal.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:99)
    at org.gradle.api.plugins.jetty.JettyRun_Decorated.invokeMethod(Unknown Source)
    at groovy.lang.GroovyObject$invokeMethod.call(Unknown Source)
    at org.gradle.util.ReflectionUtil.invoke(ReflectionUtil.groovy:23)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$4.execute(AnnotationProcessingTaskFactory.java:150)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$4.execute(AnnotationProcessingTaskFactory.java:145)
    at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:472)
    at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:461)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:60)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
    at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:34)
    at org.gradle.api.internal.changedetection.CacheLockHandlingTaskExecuter$1.run(CacheLockHandlingTaskExecuter.java:34)
    at org.gradle.cache.internal.DefaultCacheAccess$2.create(DefaultCacheAccess.java:200)
    at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(DefaultCacheAccess.java:172)
    at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(DefaultCacheAccess.java:198)
    at org.gradle.cache.internal.DefaultPersistentDirectoryStore.longRunningOperation(DefaultPersistentDirectoryStore.java:137)
    at org.gradle.api.internal.changedetection.DefaultTaskArtifactStateCacheAccess.longRunningOperation(DefaultTaskArtifactStateCacheAccess.java:83)
    at org.gradle.api.internal.changedetection.CacheLockHandlingTaskExecuter.execute(CacheLockHandlingTaskExecuter.java:32)
    at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:55)
    at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:57)
    at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:41)
    at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:51)
    at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:42)
    at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:247)
    at org.gradle.execution.DefaultTaskGraphExecuter.executeTask(DefaultTaskGraphExecuter.java:192)
    at org.gradle.execution.DefaultTaskGraphExecuter.doExecute(DefaultTaskGraphExecuter.java:177)
    at org.gradle.execution.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:83)
    at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:36)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)
    at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
    at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:67)
    at org.gradle.api.internal.changedetection.TaskCacheLockHandlingBuildExecuter$1.run(TaskCacheLockHandlingBuildExecuter.java:31)
    at org.gradle.cache.internal.DefaultCacheAccess$1.create(DefaultCacheAccess.java:111)
    at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:126)
    at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:109)
    at org.gradle.cache.internal.DefaultPersistentDirectoryStore.useCache(DefaultPersistentDirectoryStore.java:129)
    at org.gradle.api.internal.changedetection.DefaultTaskArtifactStateCacheAccess.useCache(DefaultTaskArtifactStateCacheAccess.java:79)
    at org.gradle.api.internal.changedetection.TaskCacheLockHandlingBuildExecuter.execute(TaskCacheLockHandlingBuildExecuter.java:29)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)
    at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
    at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:67)
    at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:54)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:155)
    at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:110)
    at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:78)
    at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:38)
    at org.gradle.launcher.exec.InProcessGradleLauncherActionExecuter.execute(InProcessGradleLauncherActionExecuter.java:39)
    at org.gradle.launcher.exec.InProcessGradleLauncherActionExecuter.execute(InProcessGradleLauncherActionExecuter.java:25)
    at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:50)
    at org.gradle.launcher.cli.ActionAdapter.execute(ActionAdapter.java:30)
    at org.gradle.launcher.cli.ActionAdapter.execute(ActionAdapter.java:22)
    at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:200)
    at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:173)
    at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:169)
    at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:138)
    at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)
    at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)
    at org.gradle.launcher.Main.doAction(Main.java:48)
    at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)
    at org.gradle.launcher.Main.main(Main.java:39)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:50)
    at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:32)
    at org.gradle.launcher.GradleMain.main(GradleMain.java:26)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.gradle.wrapper.BootstrapMainStarter.start(BootstrapMainStarter.java:33)
    at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:130)
    at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:48)
> Building > :zuul-netflix-webapp:jettyRun > Running at http://localhost:8080//

Question: Zuul to behave like a reverse proxy

One of the purposes of Zuul is to act as a reverse proxy.

However Zuul only redirects clients to the destination URL, as opposed to transparently forwarding the requests. As a result the destination URL is exposed to the client through the 302 redirect, which is not how reverse proxies behave.

Is there documentation / workaround to make zuul behave as a true reverse proxy ?

Zuul as file upload proxy

Did anyone use Zuul in the context of file upload proxy?

I would be interested in a filter implementation where the request is simply relayed to the origin server and not as a 2 step operation where the entire content is received in Zuul and a separate connection to the origin is made afterwards.

Thanks

Conflicting module versions groovy-all

Hi,

I'm trying to run the zuul simple webapp example and I get this exception when executing ../gradlew jettyRun:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
failed org.gradle.api.plugins.jetty.internal.JettyPluginWebAppContext@fa8de42{/,/home/gonza/workspace/zuul/zuul-simple-webapp/src/main/webapp}: java.lang.ExceptionInInitializerError
failed ContextHandlerCollection@4d499f71: java.lang.ExceptionInInitializerError
failed HandlerCollection@1c82db5b: java.lang.ExceptionInInitializerError
Error starting handlers
java.lang.ExceptionInInitializerError
at org.codehaus.groovy.runtime.InvokerHelper.(InvokerHelper.java:61)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallStaticSite(CallSiteArray.java:72)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallSite(CallSiteArray.java:159)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
at scripts.preProcess.DebugFilter.(Debug.groovy:27)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at java.lang.Class.newInstance(Class.java:383)
at com.netflix.zuul.DefaultFilterFactory.newInstance(DefaultFilterFactory.java:17)
at com.netflix.zuul.FilterLoader.putFilter(FilterLoader.java:156)
at com.netflix.zuul.FilterFileManager.processGroovyFiles(FilterFileManager.java:170)
at com.netflix.zuul.FilterFileManager.manageFiles(FilterFileManager.java:176)
at com.netflix.zuul.FilterFileManager.init(FilterFileManager.java:81)
at com.netflix.zuul.StartServer.initGroovyFilterManager(StartServer.java:63)
at com.netflix.zuul.StartServer.contextInitialized(StartServer.java:45)
at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1272)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:489)
at org.gradle.api.plugins.jetty.internal.JettyPluginWebAppContext.doStart(JettyPluginWebAppContext.java:112)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
at org.mortbay.jetty.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:156)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
at org.mortbay.jetty.Server.doStart(Server.java:224)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.gradle.api.plugins.jetty.internal.Jetty6PluginServer.start(Jetty6PluginServer.java:111)
at org.gradle.api.plugins.jetty.AbstractJettyRunTask.startJettyInternal(AbstractJettyRunTask.java:238)
at org.gradle.api.plugins.jetty.AbstractJettyRunTask.startJetty(AbstractJettyRunTask.java:191)
at org.gradle.api.plugins.jetty.AbstractJettyRunTask.start(AbstractJettyRunTask.java:162)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:218)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:211)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:200)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:579)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:562)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:305)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:23)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:88)
at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:29)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:68)
at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:55)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:149)
at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:106)
at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:86)
at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:80)
at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:33)
at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:24)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:36)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:51)
at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:171)
at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:237)
at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:210)
at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:35)
at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:24)
at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:206)
at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:169)
at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)
at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)
at org.gradle.launcher.Main.doAction(Main.java:33)
at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:54)
at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:35)
at org.gradle.launcher.GradleMain.main(GradleMain.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.gradle.wrapper.BootstrapMainStarter.start(BootstrapMainStarter.java:30)
at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:127)
at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:56)
Caused by: groovy.lang.GroovyRuntimeException: Conflicting module versions. Module [groovy-all is loaded in version 2.3.6 and you are trying to load version 2.3.1
at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl$DefaultModuleListener.onModule(MetaClassRegistryImpl.java:509)
at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanExtensionModuleFromProperties(ExtensionModuleScanner.java:78)
at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanExtensionModuleFromMetaInf(ExtensionModuleScanner.java:72)
at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanClasspathModules(ExtensionModuleScanner.java:54)
at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.(MetaClassRegistryImpl.java:110)
at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.(MetaClassRegistryImpl.java:71)
at groovy.lang.GroovySystem.(GroovySystem.java:33)
... 105 more

Building remains at 90% and when I query localhost:8080 I get a Jetty error page.

Am I doing something wrong? I've read that Jetty plugin is somewhat outdated so it may be using and older version of groovy-all module

(Documentation) Roadmap

I see the there are 1.x and 2.x branches under SCM.

Is it possible to document a roadmap or list of features in upcoming version?

Thanks.

cannot compile with groovy filters scripts since not in any jar, just the zuul-netflix-webapp .war

There are improvements with the netflix-zuul monitoring plugins we'd like to use, but are having trouble using any version of Zuul after 1.0.18, because zuul-scripts artifact is no longer produced, the scripts we use are in zuul-netflix-webapp.

But zuul-netflix-webapp is a war artifact, not a jar, so we the compiler will not use classes inside of that for our application. zuul-scripts was released as a jar.

So perhaps if you do not want to support zuul-scripts, you could move or pull those groovy scripts into zuul-netflix.

Also, you have released 1.0.24 to the maven repo, but not others up to .27. (Or this could be a separate issue.)

Thanks for your work on this.

When making a get request that should return a Json body, the RequestContext returns nothing

I am testing Zuul out as an edge gateway to a micro service that returns json for a GET request. I used the sample route filter in the simple-webapp, but nothing is returned. When I inspect the HttpResponse in the sendResponse() method I do see the json content in the entity.content , however when it is converted to a httpServerletResponse for the RequestContext all response body, code, and content length is lost. Is the example route filter incorrect or am I doing something wrong?

Enable filter execution summary in request context

Feature to insert filter execution status and latency information into the request context for use in response headers.

This information is useful in identifying the filters that are participating in the lifecycle of a request that is processed by zuul.

please keep Zuul up to date in mvnrepository

The lastest version of Zuul in the mvnrepository is 1.0.0, which is 11 months and 17 versions old. Could you please keep that more up to date with releases in this repo? Or do you have some other policy about how/when you do that?

http://mvnrepository.com/artifact/com.netflix.zuul/

Is there a better place to ask about this kind of Zuul issue? I've looked around but this seemed to be the best place to ask.

Thanks for your work on this.

Hateoas links broken

Hi,
I am trying to make use of zuul in my project. (I am making use of Zuul, Eureka and Spring boot, of course)
I have a service "users" (port: 9002) and another spring boot app, which is the UI part + backend stuff (port: 8080).

My zuul configuration:

zuul:
  routes:
    users:
      serviceId: users 
      path: api/users/**

The problem that I think it's the problem is that I have set on the second app (UI and whatnot) a contextPath: /myContextPath

When I access my service through the proxy I basically access it via http://localhost:8080/myContext/api/users/api
But looking at the hateoas urls, the urls look like http://localhost:8080/api/users/api/blahblah

I presume you can't specify to zuul a relative path (I think I looked a bit over the code while debugging and I saw that it explicitly puts a "/" when you specify a relative path.

Is this a bug or I am missing something?
I presume if I strip out the contextPath for my app it should resolve, but I need the contextPath in my case.

ZuulHostRequest Timer is not daemon so have trouble shutting down

The CONNECTION_MANAGER_TIMER is created as a non-daemon Time (the default), so it will prevent the jvm from shutting down naturally. And just loading the class, not even calling anything, will cause this to be created.

This applies to both zuul-scripts ZuulHostRequest and zuul-simple-webapp SimpleHostRequest.

One ways to fix this that I'm using is to change the following line to: "... Timer(true);" in both files.

private static final Timer CONNECTION_MANAGER_TIMER = new Timer();

The particular place I am running into this is using Zuul from a Clojure program, this causes compile to hang forever. (The classes are loaded during compile, so static initializers are invoked.)

Problem when using HTTP methods other than GET with zuul-netflix-webapp

Hi,

When I tried using zuul-netflix-webapp I hit a problem, when logging in to my application. This was the first POST request, and the following error message was logged.

ERROR 23:40:24,663 Filter threw Exception
com.netflix.zuul.exception.ZuulException: Filter threw Exception
at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:196)
at com.netflix.zuul.FilterProcessor.runFilters(FilterProcessor.java:147)
at com.netflix.zuul.FilterProcessor.route(FilterProcessor.java:106)
at com.netflix.zuul.ZuulRunner.route(ZuulRunner.java:78)
at com.netflix.zuul.http.ZuulServlet.route(ZuulServlet.java:104)
at com.netflix.zuul.http.ZuulServlet.service(ZuulServlet.java:69)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.google.inject.servlet.DefaultFilterPipeline.dispatch(DefaultFilterPipeline.java:43)
at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:113)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.netflix.zuul.context.ContextLifecycleFilter.doFilter(ContextLifecycleFilter.java:40)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:440)
at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Caused by: groovy.lang.MissingPropertyException: No such property: Verb for class: com.netflix.niws.client.http.RestClient
at groovy.lang.MetaClassImpl.invokeStaticMissingProperty(MetaClassImpl.java:895)
at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1605)
at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1581)
at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3326)
at org.codehaus.groovy.runtime.callsite.ClassMetaClassGetPropertySite.getProperty(ClassMetaClassGetPropertySite.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:227)
at scripts.routing.ZuulNFRequest.getVerb(ZuulNFRequest.groovy:228)
at scripts.routing.ZuulNFRequest.getVerb(ZuulNFRequest.groovy:222)
at scripts.routing.ZuulNFRequest$getVerb.callCurrent(Unknown Source)
at scripts.routing.ZuulNFRequest.run(ZuulNFRequest.groovy:79)
at com.netflix.zuul.ZuulFilter.runFilter(ZuulFilter.java:114)
at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:175)
... 28 more

Taking a sneaky peek at the groovy script, it appears that ZuulNFRequest.groovy lines 228-232 should not reference the field Verb in RestClient and instead just reference the Verb enum imported from HttpClientRequest.

When I made this change it worked fine.

Running zuul-netflix-webapp

Hello there,
I have set up Eureka server (checked with sample server and client) for Zuul.
For Running zuul-netflix-webapp, I have following questions:

  1. What changes do I have to do in zuul.properties file in zuul-netflix-webapp\src\main\resources folder?
  2. Is there any other place I need to make any change?
  3. I am providing the IP address of the server where Cassandra is running. Is anything else expected?
  4. I have Eureka (server and service) and Zuul running on different machines. For eureka service running on the Eureka Server, the eureka.serviceUrl.default property reads as http://localhost/eureka/v2. But the same property in zuul.properties reads as http://hostname/eureka/v2. Is that correct?

With all these changes, I am not able to see any integration between zuul and eureka happenning.

Overall, I want to understand the architecture diagram of the Zuul-Eureka-Cassandra together and a case study which describes a minimum set up of Zuul required with Eureka and Cassandra.

Unable to run latest zuul-simple-webapp in tomcat.

Hi,

We have been using Zuul since April, and the version we grabbed on April 9th had worked perfectly with tomcat 7. However, when trying to upgrade to the latest commits from upstream, we've run into an issue that doesn't occur in ../gradlew jettyRun, but does occur in Tomcat 7: when the routing filter attempts to reach out to apache.org here, an exception occurs because the InputStream seems to be empty (inputStream.available() returns 0).

The debug trace shows the error thusly:
ZUUL_DEBUG::Running Filter failed SimpleHostRoutingFilter type:route order:100 Stream closed

Has anyone else seen this or knows of a work around? This issue may be related to #33.

Debug:

ZUUL_DEBUG::Filter pre 5 PreDecorationFilter
ZUUL_DEBUG::Filter {PreDecorationFilter TYPE:pre ORDER:5} Execution time = 27ms
ZUUL_DEBUG::{PreDecorationFilter} added originResponseHeaders=[com.netflix.util.Pair@64edca63]
ZUUL_DEBUG::{PreDecorationFilter} added routeHost=http://apache.org/
ZUUL_DEBUG::{PreDecorationFilter} changed executedFilters=DebugFilter[SUCCESS][34ms], PreDecorationFilter[SUCCESS][27ms]
ZUUL_DEBUG::Filter pre 10000 DebugRequest
ZUUL_DEBUG::Filter {DebugRequest TYPE:pre ORDER:10000} Execution time = 39ms
ZUUL_DEBUG::{DebugRequest} changed executedFilters=DebugFilter[SUCCESS][34ms], PreDecorationFilter[SUCCESS][27ms], DebugRequest[SUCCESS][39ms]
ZUUL_DEBUG::Filter pre 50000
ZUUL_DEBUG::Filter { TYPE:pre ORDER:50000} Execution time = 4ms
ZUUL_DEBUG::{} added javaPreFilter-ran=true
ZUUL_DEBUG::{} changed executedFilters=DebugFilter[SUCCESS][34ms], PreDecorationFilter[SUCCESS][27ms], DebugRequest[SUCCESS][39ms], [SUCCESS][4ms]
ZUUL_DEBUG::Invoking {route} type filters
ZUUL_DEBUG::Filter route 100 SimpleHostRoutingFilter
ZUUL_DEBUG::Running Filter failed SimpleHostRoutingFilter type:route order:100 Stream closed
ZUUL_DEBUG::Invoking {error} type filters
ZUUL_DEBUG::Invoking {post} type filters
ZUUL_DEBUG::Filter post 1000 SendResponseFilter
ZUUL_DEBUG::Filter post 2000 Stats
REQUEST_DEBUG::REQUEST:: http 0:0:0:0:0:0:0:1:52160
REQUEST_DEBUG::REQUEST:: > GET / HTTP/1.1
REQUEST_DEBUG::REQUEST:: > host:localhost:8080
REQUEST_DEBUG::REQUEST:: > connection:keep-alive
REQUEST_DEBUG::REQUEST:: > cache-control:max-age=0
REQUEST_DEBUG::REQUEST:: > accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
REQUEST_DEBUG::REQUEST:: > user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36
REQUEST_DEBUG::REQUEST:: > accept-encoding:gzip, deflate, sdch
REQUEST_DEBUG::REQUEST:: > accept-language:en-US,en;q=0.8
REQUEST_DEBUG::REQUEST:: > if-none-match:"bb15-519476ad19809"
REQUEST_DEBUG::REQUEST:: > if-modified-since:Wed, 24 Jun 2015 18:10:09 GMT
REQUEST_DEBUG::REQUEST:: >
REQUEST_DEBUG::ZUUL:: host=http://apache.org/
REQUEST_DEBUG::ZUUL::> host  localhost:8080
REQUEST_DEBUG::ZUUL::> connection  keep-alive
REQUEST_DEBUG::ZUUL::> cache-control  max-age=0
REQUEST_DEBUG::ZUUL::> accept  text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
REQUEST_DEBUG::ZUUL::> user-agent  Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36
REQUEST_DEBUG::ZUUL::> accept-language  en-US,en;q=0.8
REQUEST_DEBUG::ZUUL::> if-none-match  "bb15-519476ad19809"
REQUEST_DEBUG::ZUUL::> if-modified-since  Wed, 24 Jun 2015 18:10:09 GMT
REQUEST_DEBUG::ZUUL:: > GET  / HTTP/1.1

Stack Trace (the line number is slightly off due to spitting out this message):

java.io.IOException: Stream closed
    at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:312)
    at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:200)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.read1(BufferedReader.java:210)
    at java.io.BufferedReader.read(BufferedReader.java:286)
    at java.io.Reader.read(Reader.java:140)
    at org.codehaus.groovy.runtime.IOGroovyMethods.getText(IOGroovyMethods.java:863)
    at org.codehaus.groovy.runtime.IOGroovyMethods.getText(IOGroovyMethods.java:814)
    at org.codehaus.groovy.runtime.dgm$686.invoke(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
    at SimpleHostRoutingFilter.debugRequestEntity(SimpleHostRequest.groovy:239)
    at SimpleHostRoutingFilter$debugRequestEntity$5.callCurrent(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
    at SimpleHostRoutingFilter.debug(SimpleHostRequest.groovy:229)
    at SimpleHostRoutingFilter$debug$4.callCurrent(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
    at SimpleHostRoutingFilter.forward(SimpleHostRequest.groovy:246)
    at SimpleHostRoutingFilter$forward$3.callCurrent(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
    at SimpleHostRoutingFilter.run(SimpleHostRequest.groovy:203)
    at com.netflix.zuul.ZuulFilter.runFilter(ZuulFilter.java:112)
    at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:197)
    at com.netflix.zuul.FilterProcessor.runFilters(FilterProcessor.java:161)
    at com.netflix.zuul.FilterProcessor.route(FilterProcessor.java:120)
    at com.netflix.zuul.ZuulRunner.route(ZuulRunner.java:96)
    at com.netflix.zuul.http.ZuulServlet.route(ZuulServlet.java:119)
    at com.netflix.zuul.http.ZuulServlet.service(ZuulServlet.java:84)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at com.netflix.zuul.context.ContextLifecycleFilter.doFilter(ContextLifecycleFilter.java:40)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:957)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

gradle jettyRun on zuul-simple-webapp fails with ClassCastException

I am running this in Windows 7 machine. Following is the stacktrace.
FAILURE: Build failed with an exception.

  • Where:
    Script 'D:\Projects\HA Architecture\Tools\zuul-1.x\zuul-1.x\gradle\convention.gradle' line: 27

  • What went wrong:
    A problem occurred evaluating script.

    java.lang.String cannot be cast to org.gradle.api.artifacts.Configuration

  • Try:
    Run with --info or --debug option to get more log output.

  • Exception is:
    org.gradle.api.GradleScriptException: A problem occurred evaluating script.
    at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:54)
    at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:148)
    at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.applyScript(DefaultObjectConfigurationAction.java:93)
    at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.access$000(DefaultObjectConfigurationAction.java:36)
    at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction$1.run(DefaultObjectConfigurationAction.java:62)
    at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.execute(DefaultObjectConfigurationAction.java:131)
    at org.gradle.api.internal.project.AbstractPluginAware.apply(AbstractPluginAware.java:37)
    at org.gradle.api.Project$apply$0.call(Unknown Source)
    at org.gradle.api.internal.project.ProjectScript.apply(ProjectScript.groovy:34)
    at org.gradle.api.Script$apply$0.callCurrent(Unknown Source)
    at build_387zevgzfkz174674edbyc6aq.run(D:\Projects\HA Architecture\Tools\zuul-1.x\zuul-1.x\build.gradle:13)
    at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:52)
    at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:148)
    at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:39)
    at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:26)
    at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:34)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:59)
    at org.gradle.api.internal.project.AbstractProject.evaluate(AbstractProject.java:504)
    at org.gradle.api.internal.project.AbstractProject.evaluate(AbstractProject.java:83)
    at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:42)
    at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:35)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:129)
    at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:106)
    at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:86)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:80)
    at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:33)
    at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:24)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:36)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
    at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:51)
    at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:171)
    at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:237)
    at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:210)
    at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:35)
    at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:24)
    at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:206)
    at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:169)
    at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)
    at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)
    at org.gradle.launcher.Main.doAction(Main.java:33)
    at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)
    at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:54)
    at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:35)
    at org.gradle.launcher.GradleMain.main(GradleMain.java:23)
    Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to org.gradle.api.artifacts.Configuration
    at org.gradle.api.artifacts.Configuration$Namer.determineName(Configuration.java:87)
    at org.gradle.api.internal.DefaultNamedDomainObjectCollection.add(DefaultNamedDomainObjectCollection.java:70)
    at org.gradle.api.NamedDomainObjectCollection$add.call(Unknown Source)
    at convention_cb8mrdarz5v6qz4tjgsw6v14o$_run_closure1.doCall(D:\Projects\HA Architecture\Tools\zuul-1.x\zuul-1.x\gradle\convention.gradle:27)
    at org.gradle.api.internal.ClosureBackedAction.execute(ClosureBackedAction.java:63)
    at org.gradle.util.ConfigureUtil.configure(ConfigureUtil.java:130)
    at org.gradle.util.ConfigureUtil.configure(ConfigureUtil.java:91)
    at org.gradle.api.internal.project.AbstractProject.configure(AbstractProject.java:824)
    at org.gradle.api.internal.project.AbstractProject.configure(AbstractProject.java:829)
    at org.gradle.api.internal.project.AbstractProject.subprojects(AbstractProject.java:812)
    at org.gradle.api.internal.BeanDynamicObject$MetaClassAdapter.invokeMethod(BeanDynamicObject.java:225)
    at org.gradle.api.internal.BeanDynamicObject.invokeMethod(BeanDynamicObject.java:129)
    at org.gradle.api.internal.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:147)
    at org.gradle.groovy.scripts.BasicScript.methodMissing(BasicScript.java:79)
    at convention_cb8mrdarz5v6qz4tjgsw6v14o.run(D:\Projects\HA Architecture\Tools\zuul-1.x\zuul-1.x\gradle\convention.gradle:5)
    at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:52)
    ... 43 more

BUILD FAILED

Total time: 3.651 secs

servlet-3.0 upgrade broke zuul-simple-webapp?

I believe the servlet-3.0 upgrade commit broke the zuul-simple-webapp. I haven't looked into why yet - I will try to, but I figured it's better to report this now.

Repro:

$ git clone https://github.com/Netflix/zuul.git && cd zuul
$ git co df3c33290f0bcc0f0651360bdb2d256983cc4199
$ (cd zuul-simple-webapp && ../gradlew -q jettyRun)&
$ sleep 10 && curl -sq http://localhost:8080 | wc -c
  0
$ kill %1
$ git co df3c33290f0bcc0f0651360bdb2d256983cc4199^
$ (cd zuul-simple-webapp && ../gradlew -q jettyRun)&
$ sleep 10 && curl -sq http://localhost:8080 | wc -c
  41552

I'm being cute with the sleeps and backgrounding in the repro to fit it into a single shell; you can also just wait for the server to come up and curl from another window.

More info:

$ java -version
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
$ uname -a
Darwin XXXXXXXXXXXX.local 13.1.0 Darwin Kernel Version 13.1.0: Thu Jan 16 19:40:37 PST 2014; root:xnu-2422.90.20~2/RELEASE_X86_64 x86_64

Provide for manual filter reloading?

When I'm doing interactive development with Clojure (which I don't have a FilterCompiler for) I'd like to be able to swap out old filters for new versions by providing the name and a new ZuulFilter instance. The problem is that while I can do that in FilterRegistry, FilterLoader maintains a cached listing of each type of filter and won't refresh it unless explicitly told to load a new filter from file.

I currently have the following truly awful code to get around that:

(defn dev-reload-filter-entry
  "Use dirty hacks to reload a filter of the same name as before
by supplying a new filter instance. (Remove the old filter by name and add the
provided instance.)"
  [filter-name filter-inst]
  (let [r (FilterRegistry/instance)]
    (.remove r filter-name)
    (.put r filter-name filter-inst)
    ;; Force a reload by using wall-hacks to clear the cache of filters for one type.
    (let [cache-field (.getDeclaredField FilterLoader "hashFiltersByType")]
      (.setAccessible cache-field true)
      (.remove (.get cache-field (FilterLoader/getInstance))
               (.filterType filter-inst))
      nil)))

I'm considering sending a PR for FilterLoader that clears the cache for a type (and/or for all types), but I'd like to check if that would be welcome before doing so.

Docs

Can you provide more docs on usage and a developer guide.

Zuul filters are running twice after moving af filter to another directory

I have created a simple filter and verified that it's running in my Zuul instance. When I move the filter from the pre to the post directory the filter is reloaded in Zuul. The problem is that the old instance is not removed. So the filter is running from that moment in both pre as in post. I would expect that it wouldn't run in pre any more.

Tested on Zuul-core 1.0.0

filter_code is missing in scripts.txt

I found the scripts.txt to create the cassandra column family for the zuul scripts. But I can't find the filter_code column in there. But the filter_code column is used in the code (in ZuulFilterDAOCassandra for example)

Is the scripts.txt outdated?

FilterPoller - integration with the actual Zuul filter chain

Hi,

I am browsing through the Zuul code and found an interesting feature for polling scripts from a persistent store: ZuulFilterPoller and a web admin.

I don't understand how these filters are actually loaded in the actual zuul filter chain.

Thanks,
Adrian

Intellij IDEA module structure not quite right?

TL;DR: some of IDEA's cool static analysis features don't work right with zuul code. The only solution I can come up with on my own may be too invasive, since it touches on separating test/prod code.

I am using Intellij IDEA 13.1.3 (latest) with the Zuul code, and my main goal is to use the IDE to browse/analyze the code (e.g. Find Usages, Navigate -> Implementations, Navigate -> Call Hierarchy).

There are two probably-related problems I'm having "out of the box" (clean git clone; ./gradlew idea; open zuul.ipr in IDEA [with the Groovy and Gradle plugins active]):

  1. Groovy files are not recognized - e.g. Navigate -> Implementations on ZuulFilter only finds the Java implementors, not any of the Groovy ones).
  2. IDEA's ability to filter test code from production code is hampered by the fact that IDEA thinks all the code is test code.

These may be separate underlying issues; I'm including them both in this entry as I believe they are related enough to discuss together.

To solve #1 we can "repair" the module structures; I say repair because IDEA itself doesn't like the fact that src/main/java appears twice each module, once for test and once for non-test:

$ grep src/main/java */*.iml
zuul-core/zuul-core.iml:      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
zuul-core/zuul-core.iml:      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="true" />
zuul-netflix-webapp/zuul-netflix-webapp.iml:      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
zuul-netflix-webapp/zuul-netflix-webapp.iml:      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="true" />
zuul-netflix/zuul-netflix.iml:      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
zuul-netflix/zuul-netflix.iml:      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="true" />
zuul-simple-webapp/zuul-simple-webapp.iml:      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
zuul-simple-webapp/zuul-simple-webapp.iml:      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="true" />

Without resolving all of those (e.g. remove the "true" entries), any changes to the module structure will cause IDEA to complain (e.g. if you try to apply any change at all) as it doesn't expect duplicate entries. Resolving all of them will satisfy it, and then Problem #1 above seems to go away.

Problem #2 is of course also related to the test/prod distinction. My selfish knee-jerk solution would be to separate test code into src/test/* and remove this one line from build.gradle:

sourceSets.test.java.srcDir 'src/main/java'

However I am aware of Ben Christensen's viewpoint on test/production code, and that not all zuul developers use IDEA and/or value static code analysis as much as I do. I also agree in spirit that code readability should trump tool concerns, if there is indeed an unavoidable tradeoff.

If this can be resolved somehow, I consider it a big win for IDEA users, since the Navigation/Inspection features are so powerful, and help developers come up the learning curve. It's a good complement to learning via debug/breakpoints, which for zuul-netflix-webapp is a bit more non-trivial as it requires getting all the components up and running.

In Zuul2 make it configurable on whether or not to block startup on groovy compile fail.

If a groovy file fails to compile on original startup, I'd much prefer to have the zuul instance bomb out than potentially have an unsafe edge security situation due to an important filter missing.

On the other hand, if a groovy file fails to compile during reload (which is also questionable in general) then it would be okay to skip in order to keep the server running. Ideally, it would be possible to have an atomic operation in case filters are related in some way that would cause a runtime exception or change in behavior if one is loaded and not the other.

ZuulFilter.processFilter should not throw Throwable

As implemented Zuul manages filters as ZuulFilters instead of IZuulFilter. ZuulFilter's runFilter() method throws Throwable necessitating any code that starts filter processing to catch Throwable which is considered bad practice as it catches all errors including JVM ones.

Quite what the fix would be I'm uncertain about. Simply switching Throwable for ZuulException in ZuulFilter and FilterProcessor would do it. There's probably scope for adding ZuulError and some more specific subclasses too.

Dependency version issues

We attempted to upgrade our project's dependency on zuul-core but found issues with the POM for version 1.0.21. Some of the dependency versions in the zuul-core POM appear to be invalid - versions such as + and latest.release, for example, are not accepted by maven 3.0.5 or 3.2.1.

Clean checkout does not compile with "org.junit does not exist" errors

With a fresh checkout of commit 25ee803, Zuul is unable to build on my system (Ubuntu 14.04.1 with Oracle JDK 1.7.0_72). Builds fail with dozens of missing package errors along the lines of

:zuul-netflix:compileJava
warning: [options] bootstrap class path not set in conjunction with -source 1.6
/home/user/foreign-repos/zuul/zuul-netflix/src/main/java/com/netflix/zuul/scriptManager/FilterVerifier.java:22: error: package org.junit does not exist
import org.junit.Before;
                ^
/home/user/foreign-repos/zuul/zuul-netflix/src/main/java/com/netflix/zuul/scriptManager/FilterVerifier.java:23: error: package org.junit does not exist
import org.junit.Test;
                ^
/home/user/foreign-repos/zuul/zuul-netflix/src/main/java/com/netflix/zuul/scriptManager/FilterVerifier.java:26: error: package org.junit does not exist
import static org.junit.Assert.*;
                ^

These failures occur in both the zuul-netflix subdirectory and the zuul-netflix-webapp subdirectory (once the former is fixed). Copying the following line from zuul-core/build.gradle to the build.gradle files in the failing subdirectories allows everything to compile (though I'm not sure if this is the correct way to fix this properly):

provided 'junit:junit-dep:4.10'

Change the default response code

For requests processed by Zuul, the default response code is 200.
Returning a 200 has the potential to mask issues with routing filter changes. Making the default response status a 500 will allow for finding issues earlier.

When a request is proxied to a backend, the status code for the proxy action is set by Zuul based on the response from the backend. However if the filter is not a static response filter and the response never enters the route/proxy filter process an empty response is sent out by zuul with a 200. Changes need to be made to prevent it from happening.

Unable to turn off FollowRedirects

We had a problem with using a namespace other than "ribbon" where the refresh of the dynamic properties was losing our settings. We fixed that.

Even with what looks like a proper IClientConfig getting passed in through ZuulNFRequest, ribbon is still trying to do redirects. How do we get it to stop this? It is really painful to deal with, especially if zuul doesn't have access to the IP named by the redirect, or worse, it is trying to do SSL where it is not appropriate.

Question: NIO

Are there any plans to support non-blocking IO in Zuul?

Thanks

ZUUL- websocket

Hello,

is there a way to communicate using web sockets and MQ with zuul?

Question: Using Zuul for Internal Testing in Production

As part of our production deployment workflow, we would like to introduce a small cluster of new version of a service and we would like to perform an internal smoke test against that service before increasing the capacity and open it up to public.

My understanding is Zuul can be used for it but I can't figure out the best way to do it.

Do we need to deploy the new version of the service using a different name in Eureka (e.g. ServiceX-V2) and have Zuul route the internal requests to that service?

Or do we deploy a new Zuul and Eureka instance alongside the new service, leave that new Zuul out from the LoadBalancer and perform the internal test against that full stack?

Adding Groovy classes that are not a ZuulFilter

As a enhancement I would like to request that it would be possible to add Groovy scripts that are not derived from ZuulFilter. This would allow us to make utility/helper classes that can be used in the filters.

groovy unit tests don't run with `./gradlew test` ?

Repro:

$ git clone -q https://github.com/Netflix/zuul.git zuul-tests && cd zuul-tests
$ ./gradlew -q test
$ grep -oE 'ZuulServletFilter|GroovyCompatibility' zuul-core/build/reports/tests/index.html | uniq
ZuulServletFilter
$ grep -c 'PostDecoration' zuul-netflix-webapp/build/reports/tests/index.html
0

E.g. GroovyCompatibility.groovy and PostDecoration.groovy has unit tests that aren't being run.

Related questions: what should people do to verify a PR is good before submitting (I was assuming ./gradlew test is the main action)? Is there a continuous build for zuul, and if so what does it do?

Question - non blocking / reactive reverse proxy with Zuul

I’ve been looking at the zuul simple example which forwards requests onto http://apache.org. I was expecting this to make use of a non blocking api for scalability. However all the examples block on the call to the API which is proxied. If that service experiences a slow down, then that propogates into zuul by blocking a thread.

All the state in RequestContext is held against a ThreadLocal, so it doesn’t appear like the implementation can respond asynchronously.

What am I missing? How can this be used as a scalable solution for microservice proxying?

Thanks

cassandra creation scripts?

great job, guys. so glad to see this finally get open sourced!

can you provide the cassandra creation scripts for the necessary keyspaces and column families to support the filter storage?

or perhaps they're in the source tree and i don't see them?

thanks!

-chris

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.