Skip to content

Commit

Permalink
Support for Method level @ratelimiting annoation #250
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcGiffing committed Mar 11, 2024
1 parent 9cea03c commit 74780e8
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.giffing.bucket4j.spring.boot.starter.examples.caffeine;

import com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodTestSuite;
import com.giffing.bucket4j.spring.boot.starter.general.tests.filter.servlet.ServletTestSuite;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;

@Suite
@SelectClasses({
ServletTestSuite.class
ServletTestSuite.class,
MethodTestSuite.class
})
public class CaffeineGeneralSuiteTest {
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.giffing.bucket4j.spring.boot.starter.examples.ehcache;

import com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodTestSuite;
import com.giffing.bucket4j.spring.boot.starter.general.tests.filter.servlet.ServletTestSuite;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;

@Suite
@SelectClasses({
ServletTestSuite.class
ServletTestSuite.class,
MethodTestSuite.class,
})
public class EhcacheGeneralSuiteTest {
}
5 changes: 5 additions & 0 deletions examples/general-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method;

Check failure on line 1 in examples/general-tests/src/main/java/com/giffing/bucket4j/spring/boot/starter/general/tests/filter/method/MethodRateLimitTest.java

View workflow job for this annotation

GitHub Actions / JUnit Test Report

MethodRateLimitTest.assert_no_rate_limit_with_skip_condition_matches

Failed to load ApplicationContext for [WebMergedContextConfiguration@4608876e testClass = com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodRateLimitTest, locations = [], classes = [com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodTestApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["debug=true", "bucket4j.methods[0].name=default", "bucket4j.methods[0].cache-name=buckets", "bucket4j.methods[0].rate-limit.bandwidths[0].capacity=5", "bucket4j.methods[0].rate-limit.bandwidths[0].time=10", "bucket4j.methods[0].rate-limit.bandwidths[0].unit=seconds", "bucket4j.methods[0].rate-limit.bandwidths[0].refill-speed=greedy", "org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7e19ebf0, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@68f4865, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@5a5338df, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@4e423aa2, org.springframework.boot.test.context.SpringBootTestAnnotation@404e24d4], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
Raw output
java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@4608876e testClass = com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodRateLimitTest, locations = [], classes = [com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodTestApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["debug=true", "bucket4j.methods[0].name=default", "bucket4j.methods[0].cache-name=buckets", "bucket4j.methods[0].rate-limit.bandwidths[0].capacity=5", "bucket4j.methods[0].rate-limit.bandwidths[0].time=10", "bucket4j.methods[0].rate-limit.bandwidths[0].unit=seconds", "bucket4j.methods[0].rate-limit.bandwidths[0].refill-speed=greedy", "org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7e19ebf0, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@68f4865, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@5a5338df, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@4e423aa2, org.springframework.boot.test.context.SpringBootTestAnnotation@404e24d4], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:180)
	at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
	at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
	at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
	at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.config.internalAutoProxyCreator': org/aspectj/lang/annotation/Pointcut
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:607)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:265)
	at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:805)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:334)
	at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
	at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
	at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
	at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1454)
	at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:553)
	at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
	at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
	... 17 more
Caused by: java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Pointcut
	at org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory.<clinit>(AbstractAspectJAdvisorFactory.java:61)
	at org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.initBeanFactory(AnnotationAwareAspectJAutoProxyCreator.java:82)
	at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.setBeanFactory(AbstractAdvisorAutoProxyCreator.java:65)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1807)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
	... 37 more
Caused by: java.lang.ClassNotFoundException: org.aspectj.lang.annotation.Pointcut
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
	... 43 more

Check failure on line 1 in examples/general-tests/src/main/java/com/giffing/bucket4j/spring/boot/starter/general/tests/filter/method/MethodRateLimitTest.java

View workflow job for this annotation

GitHub Actions / JUnit Test Report

MethodRateLimitTest.assert_rate_limit_with_fallback_method

ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context for [WebMergedContextConfiguration@4608876e testClass = com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodRateLimitTest, locations = [], classes = [com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodTestApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["debug=true", "bucket4j.methods[0].name=default", "bucket4j.methods[0].cache-name=buckets", "bucket4j.methods[0].rate-limit.bandwidths[0].capacity=5", "bucket4j.methods[0].rate-limit.bandwidths[0].time=10", "bucket4j.methods[0].rate-limit.bandwidths[0].unit=seconds", "bucket4j.methods[0].rate-limit.bandwidths[0].refill-speed=greedy", "org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7e19ebf0, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@68f4865, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@5a5338df, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@4e423aa2, org.springframework.boot.test.context.SpringBootTestAnnotation@404e24d4], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
Raw output
java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context for [WebMergedContextConfiguration@4608876e testClass = com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodRateLimitTest, locations = [], classes = [com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodTestApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["debug=true", "bucket4j.methods[0].name=default", "bucket4j.methods[0].cache-name=buckets", "bucket4j.methods[0].rate-limit.bandwidths[0].capacity=5", "bucket4j.methods[0].rate-limit.bandwidths[0].time=10", "bucket4j.methods[0].rate-limit.bandwidths[0].unit=seconds", "bucket4j.methods[0].rate-limit.bandwidths[0].refill-speed=greedy", "org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7e19ebf0, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@68f4865, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@5a5338df, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@4e423aa2, org.springframework.boot.test.context.SpringBootTestAnnotation@404e24d4], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:145)
	at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
	at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
	at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
	at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

Check failure on line 1 in examples/general-tests/src/main/java/com/giffing/bucket4j/spring/boot/starter/general/tests/filter/method/MethodRateLimitTest.java

View workflow job for this annotation

GitHub Actions / JUnit Test Report

MethodRateLimitTest.assert_rate_limit_with_cache_key

ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context for [WebMergedContextConfiguration@4608876e testClass = com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodRateLimitTest, locations = [], classes = [com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodTestApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["debug=true", "bucket4j.methods[0].name=default", "bucket4j.methods[0].cache-name=buckets", "bucket4j.methods[0].rate-limit.bandwidths[0].capacity=5", "bucket4j.methods[0].rate-limit.bandwidths[0].time=10", "bucket4j.methods[0].rate-limit.bandwidths[0].unit=seconds", "bucket4j.methods[0].rate-limit.bandwidths[0].refill-speed=greedy", "org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7e19ebf0, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@68f4865, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@5a5338df, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@4e423aa2, org.springframework.boot.test.context.SpringBootTestAnnotation@404e24d4], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
Raw output
java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context for [WebMergedContextConfiguration@4608876e testClass = com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodRateLimitTest, locations = [], classes = [com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodTestApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["debug=true", "bucket4j.methods[0].name=default", "bucket4j.methods[0].cache-name=buckets", "bucket4j.methods[0].rate-limit.bandwidths[0].capacity=5", "bucket4j.methods[0].rate-limit.bandwidths[0].time=10", "bucket4j.methods[0].rate-limit.bandwidths[0].unit=seconds", "bucket4j.methods[0].rate-limit.bandwidths[0].refill-speed=greedy", "org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7e19ebf0, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@68f4865, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@5a5338df, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@4e423aa2, org.springframework.boot.test.context.SpringBootTestAnnotation@404e24d4], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:145)
	at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
	at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
	at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
	at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

Check failure on line 1 in examples/general-tests/src/main/java/com/giffing/bucket4j/spring/boot/starter/general/tests/filter/method/MethodRateLimitTest.java

View workflow job for this annotation

GitHub Actions / JUnit Test Report

MethodRateLimitTest.assert_no_rate_limit_with_execute_condition_does_not_match

ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context for [WebMergedContextConfiguration@4608876e testClass = com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodRateLimitTest, locations = [], classes = [com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodTestApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["debug=true", "bucket4j.methods[0].name=default", "bucket4j.methods[0].cache-name=buckets", "bucket4j.methods[0].rate-limit.bandwidths[0].capacity=5", "bucket4j.methods[0].rate-limit.bandwidths[0].time=10", "bucket4j.methods[0].rate-limit.bandwidths[0].unit=seconds", "bucket4j.methods[0].rate-limit.bandwidths[0].refill-speed=greedy", "org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7e19ebf0, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@68f4865, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@5a5338df, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@4e423aa2, org.springframework.boot.test.context.SpringBootTestAnnotation@404e24d4], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
Raw output
java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context for [WebMergedContextConfiguration@4608876e testClass = com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodRateLimitTest, locations = [], classes = [com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodTestApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["debug=true", "bucket4j.methods[0].name=default", "bucket4j.methods[0].cache-name=buckets", "bucket4j.methods[0].rate-limit.bandwidths[0].capacity=5", "bucket4j.methods[0].rate-limit.bandwidths[0].time=10", "bucket4j.methods[0].rate-limit.bandwidths[0].unit=seconds", "bucket4j.methods[0].rate-limit.bandwidths[0].refill-speed=greedy", "org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7e19ebf0, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@68f4865, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@5a5338df, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@4e423aa2, org.springframework.boot.test.context.SpringBootTestAnnotation@404e24d4], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:145)
	at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
	at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
	at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
	at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

Check failure on line 1 in examples/general-tests/src/main/java/com/giffing/bucket4j/spring/boot/starter/general/tests/filter/method/MethodRateLimitTest.java

View workflow job for this annotation

GitHub Actions / JUnit Test Report

MethodRateLimitTest.assert_rate_limit_with_skip_condition_does_not_match

ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context for [WebMergedContextConfiguration@4608876e testClass = com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodRateLimitTest, locations = [], classes = [com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodTestApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["debug=true", "bucket4j.methods[0].name=default", "bucket4j.methods[0].cache-name=buckets", "bucket4j.methods[0].rate-limit.bandwidths[0].capacity=5", "bucket4j.methods[0].rate-limit.bandwidths[0].time=10", "bucket4j.methods[0].rate-limit.bandwidths[0].unit=seconds", "bucket4j.methods[0].rate-limit.bandwidths[0].refill-speed=greedy", "org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7e19ebf0, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@68f4865, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@5a5338df, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@4e423aa2, org.springframework.boot.test.context.SpringBootTestAnnotation@404e24d4], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
Raw output
java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context for [WebMergedContextConfiguration@4608876e testClass = com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodRateLimitTest, locations = [], classes = [com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodTestApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["debug=true", "bucket4j.methods[0].name=default", "bucket4j.methods[0].cache-name=buckets", "bucket4j.methods[0].rate-limit.bandwidths[0].capacity=5", "bucket4j.methods[0].rate-limit.bandwidths[0].time=10", "bucket4j.methods[0].rate-limit.bandwidths[0].unit=seconds", "bucket4j.methods[0].rate-limit.bandwidths[0].refill-speed=greedy", "org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7e19ebf0, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@68f4865, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@5a5338df, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@4e423aa2, org.springframework.boot.test.context.SpringBootTestAnnotation@404e24d4], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:145)
	at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
	at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
	at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
	at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

Check failure on line 1 in examples/general-tests/src/main/java/com/giffing/bucket4j/spring/boot/starter/general/tests/filter/method/MethodRateLimitTest.java

View workflow job for this annotation

GitHub Actions / JUnit Test Report

MethodRateLimitTest.assert_rate_limit_with_execute_condition_matches

ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context for [WebMergedContextConfiguration@4608876e testClass = com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodRateLimitTest, locations = [], classes = [com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodTestApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["debug=true", "bucket4j.methods[0].name=default", "bucket4j.methods[0].cache-name=buckets", "bucket4j.methods[0].rate-limit.bandwidths[0].capacity=5", "bucket4j.methods[0].rate-limit.bandwidths[0].time=10", "bucket4j.methods[0].rate-limit.bandwidths[0].unit=seconds", "bucket4j.methods[0].rate-limit.bandwidths[0].refill-speed=greedy", "org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7e19ebf0, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@68f4865, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@5a5338df, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@4e423aa2, org.springframework.boot.test.context.SpringBootTestAnnotation@404e24d4], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
Raw output
java.lang.IllegalStateException: ApplicationContext failure threshold (1) exceeded: skipping repeated attempt to load context for [WebMergedContextConfiguration@4608876e testClass = com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodRateLimitTest, locations = [], classes = [com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method.MethodTestApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["debug=true", "bucket4j.methods[0].name=default", "bucket4j.methods[0].cache-name=buckets", "bucket4j.methods[0].rate-limit.bandwidths[0].capacity=5", "bucket4j.methods[0].rate-limit.bandwidths[0].time=10", "bucket4j.methods[0].rate-limit.bandwidths[0].unit=seconds", "bucket4j.methods[0].rate-limit.bandwidths[0].refill-speed=greedy", "org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7e19ebf0, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@68f4865, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@5a5338df, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@4e423aa2, org.springframework.boot.test.context.SpringBootTestAnnotation@404e24d4], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:145)
	at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
	at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
	at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
	at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

import com.giffing.bucket4j.spring.boot.starter.context.RateLimitException;
import lombok.RequiredArgsConstructor;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest(properties = {
"debug=true",
"bucket4j.methods[0].name=default",
"bucket4j.methods[0].cache-name=buckets",
"bucket4j.methods[0].rate-limit.bandwidths[0].capacity=5",
"bucket4j.methods[0].rate-limit.bandwidths[0].time=10",
"bucket4j.methods[0].rate-limit.bandwidths[0].unit=seconds",
"bucket4j.methods[0].rate-limit.bandwidths[0].refill-speed=greedy",
})
@RequiredArgsConstructor
@DirtiesContext
public class MethodRateLimitTest {

@Autowired
private TestService testService;


@Test
public void assert_rate_limit_with_execute_condition_matches() {
for(int i = 0; i < 5; i++) {
// rate limit executed because it's not the admin
testService.withExecuteCondition("normal_user");
}
assertThrows(RateLimitException.class, () -> testService.withExecuteCondition("normal_user"));
}

@Test
public void assert_no_rate_limit_with_execute_condition_does_not_match() {
assertAll(() -> {
for(int i = 0; i < 10; i++) {
// rate limit not executed for admin parameter
testService.withExecuteCondition("admin");
}
});
}

@Test
public void assert_rate_limit_with_fallback_method() {
for(int i = 0; i < 5; i++) {
assertEquals("normal-method-executed;param:my-test", testService.withFallbackMethod("my-test"));
}
// no exception is thrown. fall back method is executed
assertEquals("fallback-method-executed;param:my-test", testService.withFallbackMethod("my-test"));
}

@Test
public void assert_rate_limit_with_skip_condition_does_not_match() {
for(int i = 0; i < 5; i++) {
// skip condition does not match. rate limit is performed
testService.withSkipCondition("normal_user");
}
assertThrows(RateLimitException.class, () -> testService.withSkipCondition("normal_user"));
}

@Test
public void assert_no_rate_limit_with_skip_condition_matches() {
assertAll(() -> {
for(int i = 0; i < 10; i++) {
// no token consumption. admin is skipped
testService.withSkipCondition("admin");
}
});
}

@Test
public void assert_rate_limit_with_cache_key() {
for(int i = 0; i < 5; i++) {
// rate limit by parameter value
testService.withCacheKey("key1");
testService.withCacheKey("key2");
// all tokens consumed
}
assertThrows(RateLimitException.class, () -> testService.withCacheKey("key1"));
assertThrows(RateLimitException.class, () -> testService.withCacheKey("key2"));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@SpringBootApplication
@EnableCaching
@EnableAspectJAutoProxy
public class MethodTestApplication {

public static void main(String[] args) {
SpringApplication.run(MethodTestApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method;

import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;

@Suite
@SelectClasses({
MethodRateLimitTest.class
})
public class MethodTestSuite {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.giffing.bucket4j.spring.boot.starter.general.tests.filter.method;

import com.giffing.bucket4j.spring.boot.starter.context.RateLimiting;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class TestService {


@RateLimiting(
name = "default",
executeCondition = "#myParamName != 'admin'")
public String withExecuteCondition(String myParamName) {
log.info("Method withExecuteCondition with Param {} executed", myParamName);
return myParamName;
}

@RateLimiting(
name = "default",
skipCondition = "#myParamName eq 'admin'")
public String withSkipCondition(String myParamName) {
log.info("Method withSkipCondition with Param {} executed", myParamName);
return myParamName;
}

@RateLimiting(
name = "default",
cacheKey = "#cacheKey")
public String withCacheKey(String cacheKey) {
log.info("Method withCacheKey with Param {} executed", cacheKey);
return cacheKey;
}

@RateLimiting(name = "default", cacheKey = "'normal'", fallbackMethodName = "fallbackMethod")
public String withFallbackMethod(String myParamName) {
return "normal-method-executed;param:" + myParamName;
}

public String fallbackMethod(String myParamName) {
return "fallback-method-executed;param:" + myParamName;
}

}

0 comments on commit 74780e8

Please sign in to comment.