├── .gitignore
├── bucket4j-spring-boot-starter-example-caffeine
├── .gitignore
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── giffing
│ │ │ └── bucket4j
│ │ │ └── spring
│ │ │ └── boot
│ │ │ └── starter
│ │ │ └── examples
│ │ │ └── caffeine
│ │ │ ├── CaffeineApplication.java
│ │ │ └── TestController.java
│ └── resources
│ │ └── application.yml
│ └── test
│ ├── java
│ └── com
│ │ └── giffing
│ │ └── bucket4j
│ │ └── spring
│ │ └── boot
│ │ └── starter
│ │ └── examples
│ │ └── caffeine
│ │ └── ServletRateLimitTest.java
│ └── resources
│ └── application-servlet.yml
├── bucket4j-spring-boot-starter-example-ehcache
├── .gitignore
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── giffing
│ │ └── bucket4j
│ │ └── spring
│ │ └── boot
│ │ └── starter
│ │ └── examples
│ │ └── ehcache
│ │ ├── EhcacheApplication.java
│ │ ├── config
│ │ └── security
│ │ │ ├── SecurityConfig.java
│ │ │ └── SecurityService.java
│ │ └── controller
│ │ ├── DebugMetricHandler.java
│ │ └── TestController.java
│ └── resources
│ ├── application.yml
│ └── ehcache.xml
├── bucket4j-spring-boot-starter-example-gateway
├── .gitignore
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── giffing
│ │ └── bucket4j
│ │ └── spring
│ │ └── boot
│ │ └── starter
│ │ └── examples
│ │ └── gateway
│ │ ├── GatewayMetricHandler.java
│ │ ├── GatewayMetricHandler2.java
│ │ ├── GatewaySampleApplication.java
│ │ └── MyController.java
│ └── resources
│ ├── application.yml
│ └── hazelcast.xml
├── bucket4j-spring-boot-starter-example-hazelcast
├── .gitignore
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── giffing
│ │ └── bucket4j
│ │ └── spring
│ │ └── boot
│ │ └── starter
│ │ └── examples
│ │ └── hazelcast
│ │ ├── HazelcastApplication.java
│ │ └── TestController.java
│ └── resources
│ ├── application.yml
│ └── hazelcast.xml
├── bucket4j-spring-boot-starter-example-webflux
├── .gitignore
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── giffing
│ │ │ │ └── bucket4j
│ │ │ │ └── spring
│ │ │ │ └── boot
│ │ │ │ └── starter
│ │ │ │ └── examples
│ │ │ │ └── webflux
│ │ │ │ ├── MyController.java
│ │ │ │ └── WebfluxApplication.java
│ │ └── resources
│ │ │ ├── application.yml
│ │ │ ├── ehcache.xml
│ │ │ └── hazelcast.xml
│ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── giffing
│ │ │ └── bucket4j
│ │ │ └── spring
│ │ │ └── boot
│ │ │ └── starter
│ │ │ └── examples
│ │ │ └── webflux
│ │ │ └── WebfluxRateLimitTest.java
│ │ └── resources
│ │ └── application-webflux.yml
└── target
│ └── classes
│ └── application.yml
├── bucket4j-spring-boot-starter-example-zuul
├── .gitignore
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── giffing
│ │ └── bucket4j
│ │ └── spring
│ │ └── boot
│ │ └── starter
│ │ └── examples
│ │ └── zuul
│ │ ├── MyController.java
│ │ └── ZuulApplication.java
│ └── resources
│ ├── application.yml
│ └── ehcache.xml
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | /.settings/
3 | .classpath
4 | .project
5 | .idea/
6 | *.iml
7 | .factorypath
8 | .apt_generated
9 | .springBeans
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-caffeine/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | /.settings/
3 | .classpath
4 | .project
5 | .idea/
6 | *.iml
7 | .factorypath
8 | .apt_generated
9 | .springBeans
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-caffeine/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 |
6 | com.giffing.bucket4j.spring.boot.starter
7 | bucket4j-spring-boot-starter-examples
8 | ${revision}
9 | ..
10 |
11 | bucket4j-spring-boot-starter-example-caffeine
12 |
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-web
17 |
18 |
19 | org.springframework.boot
20 | spring-boot-starter-cache
21 |
22 |
23 | com.giffing.bucket4j.spring.boot.starter
24 | bucket4j-spring-boot-starter
25 |
26 |
27 | javax.cache
28 | cache-api
29 |
30 |
31 | com.github.ben-manes.caffeine
32 | caffeine
33 |
34 |
35 | com.github.ben-manes.caffeine
36 | jcache
37 |
38 |
39 | org.springframework.boot
40 | spring-boot-starter-test
41 |
42 |
43 |
44 |
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-maven-plugin
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-caffeine/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/caffeine/CaffeineApplication.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.caffeine;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cache.annotation.EnableCaching;
6 |
7 | @SpringBootApplication
8 | @EnableCaching
9 | public class CaffeineApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(CaffeineApplication.class, args);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-caffeine/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/caffeine/TestController.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.caffeine;
2 |
3 | import org.springframework.http.ResponseEntity;
4 | import org.springframework.web.bind.annotation.GetMapping;
5 | import org.springframework.web.bind.annotation.RestController;
6 |
7 | @RestController
8 | public class TestController {
9 |
10 | @GetMapping("hello")
11 | public ResponseEntity hello() {
12 | return ResponseEntity.ok("Hello World");
13 | }
14 |
15 | @GetMapping("world")
16 | public ResponseEntity world() {
17 | return ResponseEntity.ok("Hello World");
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-caffeine/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | management:
2 | endpoints:
3 | web:
4 | exposure:
5 | include: "*"
6 | security:
7 | enabled: false
8 | spring:
9 | cache:
10 | jcache:
11 | provider: org.ehcache.jsr107.EhcacheCachingProvider
12 | cache-names:
13 | - buckets
14 | caffeine:
15 | spec: maximumSize=1000000,expireAfterAccess=3600s
16 | bucket4j:
17 | enabled: true
18 | filters:
19 | - cache-name: buckets
20 | url: .*
21 | hide-http-response-headers: true
22 | rate-limits:
23 | - bandwidths:
24 | - capacity: 5
25 | time: 1
26 | unit: minutes
27 | fixed-refill-interval: 1
28 | fixed-refill-interval-unit: minutes
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-caffeine/src/test/java/com/giffing/bucket4j/spring/boot/starter/examples/caffeine/ServletRateLimitTest.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.caffeine;
2 |
3 | import static org.assertj.core.api.Assertions.fail;
4 | import static org.hamcrest.Matchers.containsString;
5 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
6 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
7 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
8 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
9 |
10 | import java.util.Collections;
11 | import java.util.stream.IntStream;
12 |
13 | import org.junit.jupiter.api.Test;
14 | import org.junit.jupiter.api.extension.ExtendWith;
15 | import org.springframework.beans.factory.annotation.Autowired;
16 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
17 | import org.springframework.boot.test.context.SpringBootTest;
18 | import org.springframework.http.HttpStatus;
19 | import org.springframework.test.context.ActiveProfiles;
20 | import org.springframework.test.context.junit.jupiter.SpringExtension;
21 | import org.springframework.test.web.servlet.MockMvc;
22 |
23 | @ExtendWith(SpringExtension.class)
24 | @SpringBootTest
25 | @AutoConfigureMockMvc
26 | @ActiveProfiles("servlet") // Like this
27 | public class ServletRateLimitTest {
28 |
29 | @Autowired
30 | private MockMvc mockMvc;
31 |
32 | @Test
33 | public void helloTest() throws Exception {
34 | String url = "/hello";
35 | IntStream.rangeClosed(1, 5)
36 | .boxed()
37 | .sorted(Collections.reverseOrder())
38 | .forEach(counter -> {
39 | successfulWebRequest(url, counter - 1);
40 | });
41 |
42 | blockedWebRequestDueToRateLimit(url);
43 | }
44 |
45 |
46 | @Test
47 | public void worldTest() throws Exception {
48 | String url = "/world";
49 | IntStream.rangeClosed(1, 10)
50 | .boxed()
51 | .sorted(Collections.reverseOrder())
52 | .forEach(counter -> {
53 | successfulWebRequest(url, counter - 1);
54 | });
55 |
56 | blockedWebRequestDueToRateLimit(url);
57 | }
58 |
59 | private void successfulWebRequest(String url, Integer remainingTries) {
60 | try {
61 | this.mockMvc
62 | .perform(get(url))
63 | .andExpect(status().isOk())
64 | .andExpect(header().longValue("X-Rate-Limit-Remaining", remainingTries))
65 | .andExpect(content().string(containsString("Hello World")));
66 | } catch (Exception e) {
67 | e.printStackTrace();
68 | fail(e.getMessage());
69 | }
70 | }
71 |
72 | private void blockedWebRequestDueToRateLimit(String url) throws Exception {
73 | this.mockMvc
74 | .perform(get(url))
75 | .andExpect(status().is(HttpStatus.TOO_MANY_REQUESTS.value()))
76 | .andExpect(content().string(containsString("{ \"message\": \"Too many requests!\" }")));
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-caffeine/src/test/resources/application-servlet.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | cache:
3 | cache-names:
4 | - buckets_test
5 | caffeine:
6 | spec: maximumSize=1000000,expireAfterAccess=3600s
7 | bucket4j:
8 | enabled: true
9 | filters:
10 | - cache-name: buckets_test
11 | url: ^(/hello).*
12 | rate-limits:
13 | - bandwidths:
14 | - capacity: 5
15 | time: 10
16 | unit: seconds
17 | - cache-name: buckets_test
18 | url: ^(/world).*
19 | rate-limits:
20 | - bandwidths:
21 | - capacity: 10
22 | time: 10
23 | unit: seconds
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-ehcache/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | /.settings/
3 | .classpath
4 | .project
5 | .idea/
6 | *.iml
7 | .factorypath
8 | .apt_generated
9 | .springBeans
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-ehcache/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.giffing.bucket4j.spring.boot.starter
5 | bucket4j-spring-boot-starter-examples
6 | ${revision}
7 | ..
8 |
9 | bucket4j-spring-boot-starter-example-ehcache
10 |
11 |
12 |
13 | com.giffing.bucket4j.spring.boot.starter
14 | bucket4j-spring-boot-starter
15 |
16 |
17 | org.springframework.boot
18 | spring-boot-starter-actuator
19 |
20 |
21 | io.micrometer
22 | micrometer-registry-prometheus
23 |
24 |
25 | org.springframework.boot
26 | spring-boot-starter-cache
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-web
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-security
35 |
36 |
37 | com.fasterxml.jackson.core
38 | jackson-core
39 |
40 |
41 | com.fasterxml.jackson.core
42 | jackson-databind
43 |
44 |
45 | org.ehcache
46 | ehcache
47 |
48 |
49 | org.projectlombok
50 | lombok
51 | true
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | org.apache.maven.plugins
60 | maven-deploy-plugin
61 |
62 | true
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-ehcache/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/ehcache/EhcacheApplication.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.ehcache;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cache.annotation.EnableCaching;
6 |
7 | @SpringBootApplication
8 | @EnableCaching
9 | public class EhcacheApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(EhcacheApplication.class, args);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-ehcache/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/ehcache/config/security/SecurityConfig.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.ehcache.config.security;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
7 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
8 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
9 |
10 | @Configuration
11 | @EnableWebSecurity
12 | public class SecurityConfig extends WebSecurityConfigurerAdapter {
13 |
14 | @Override
15 | protected void configure(HttpSecurity http) throws Exception {
16 | http.authorizeRequests().antMatchers("/unsecure").permitAll();
17 | http.authorizeRequests().antMatchers("/login").permitAll();
18 | http.authorizeRequests().antMatchers("/secure").hasAnyRole("ADMIN", "USER");
19 | }
20 |
21 | @Autowired
22 | public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
23 | auth.inMemoryAuthentication().withUser("admin").password("123").roles("ADMIN");
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-ehcache/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/ehcache/config/security/SecurityService.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.ehcache.config.security;
2 |
3 | import org.springframework.security.core.Authentication;
4 | import org.springframework.security.core.context.SecurityContextHolder;
5 | import org.springframework.stereotype.Service;
6 |
7 | @Service
8 | public class SecurityService {
9 |
10 | public String username() {
11 | Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
12 | if(authentication == null) {
13 | return null;
14 | }
15 | String name = authentication.getName();
16 | if(name == "anonymousUser") {
17 | return null;
18 | }
19 | return name;
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-ehcache/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/ehcache/controller/DebugMetricHandler.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.ehcache.controller;
2 |
3 | import java.util.List;
4 | import java.util.stream.Collectors;
5 |
6 | import org.springframework.stereotype.Component;
7 |
8 | import com.giffing.bucket4j.spring.boot.starter.context.metrics.MetricHandler;
9 | import com.giffing.bucket4j.spring.boot.starter.context.metrics.MetricTagResult;
10 | import com.giffing.bucket4j.spring.boot.starter.context.metrics.MetricType;
11 |
12 | @Component
13 | public class DebugMetricHandler implements MetricHandler {
14 |
15 | @Override
16 | public void handle(MetricType type, String name, long tokens, List tags) {
17 | System.out.println(String.format("type: %s; name: %s; tags: %s",
18 | type,
19 | name,
20 | tags
21 | .stream()
22 | .map(mtr -> mtr.getKey() + ":" + mtr.getValue())
23 | .collect(Collectors.joining(","))));
24 |
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-ehcache/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/ehcache/controller/TestController.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.ehcache.controller;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Collection;
5 |
6 | import org.springframework.http.ResponseEntity;
7 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
8 | import org.springframework.security.core.Authentication;
9 | import org.springframework.security.core.GrantedAuthority;
10 | import org.springframework.security.core.context.SecurityContextHolder;
11 | import org.springframework.web.bind.annotation.GetMapping;
12 | import org.springframework.web.bind.annotation.RequestMapping;
13 | import org.springframework.web.bind.annotation.RestController;
14 |
15 | @RestController
16 | @RequestMapping("/")
17 | public class TestController {
18 | // http.authorizeRequests().antMatchers("/unsecure").permitAll();
19 | // http.authorizeRequests().antMatchers("/login").permitAll();
20 | // http.authorizeRequests().antMatchers("/secure").hasAnyRole("ADMIN","USER").
21 |
22 | @GetMapping("unsecure")
23 | public ResponseEntity unsecure() {
24 | Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
25 | return ResponseEntity.ok().build();
26 | }
27 |
28 | @GetMapping("login")
29 | public ResponseEntity login() {
30 |
31 | Collection grantedAuthorities = new ArrayList();
32 | GrantedAuthority grantedAuthority = new GrantedAuthority() {
33 | //anonymous inner type
34 | public String getAuthority() {
35 | return "ROLE_USER";
36 | }
37 | };
38 | grantedAuthorities.add(grantedAuthority);
39 |
40 | Authentication auth = new UsernamePasswordAuthenticationToken(new User("admin"), null, grantedAuthorities);
41 | SecurityContextHolder.getContext().setAuthentication(auth);
42 |
43 | return ResponseEntity.ok().build();
44 | }
45 |
46 | @GetMapping("secure")
47 | public ResponseEntity secure() {
48 | return ResponseEntity.ok().build();
49 | }
50 |
51 | public static class User {
52 | public String username;
53 |
54 | public User(String username) {
55 | this.username = username;
56 | }
57 |
58 | public String getUsername() {
59 | return username;
60 | }
61 |
62 | public void setUsername(String username) {
63 | this.username = username;
64 | }
65 |
66 | @Override
67 | public String toString() {
68 | return username;
69 | }
70 |
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-ehcache/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | management:
2 | endpoints:
3 | web:
4 | exposure:
5 | include: "*"
6 | prometheus:
7 | enabled: true
8 | spring:
9 | cache:
10 | jcache:
11 | config: classpath:ehcache.xml
12 | bucket4j:
13 | enabled: true
14 | filters:
15 | - cache-name: buckets
16 | filter-method: servlet
17 | filter-order: -10
18 | url: .*
19 | metrics:
20 | tags:
21 | - key: USERNAME
22 | expression: "@securityService.username() != null ? @securityService.username() : 'anonym'"
23 | - key: URL
24 | expression: getRequestURI()
25 | rate-limits:
26 | - bandwidths:
27 | - capacity: 30
28 | time: 1
29 | unit: minutes
30 | - cache-name: buckets
31 | filter-method: servlet
32 | filter-order: 1
33 | url: .*
34 | metrics:
35 | tags:
36 | - key: USERNAME
37 | expression: "@securityService.username() != null ? @securityService.username() : 'anonym'"
38 | - key: URL
39 | expression: getRequestURI()
40 | rate-limits:
41 | - execute-condition: "@securityService.username() == 'admin'"
42 | expression: "@securityService.username()?: getRemoteAddr()"
43 | bandwidths:
44 | - capacity: 30
45 | time: 1
46 | unit: minutes
47 | - execute-condition: "@securityService.username() != 'admin'"
48 | expression: "@securityService.username()?: getRemoteAddr()"
49 | bandwidths:
50 | - capacity: 5
51 | time: 1
52 | unit: minutes
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-ehcache/src/main/resources/ehcache.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 | 3600
9 |
10 | 1000000
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-gateway/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | /.settings/
3 | .classpath
4 | .project
5 | .idea/
6 | *.iml
7 | .factorypath
8 | .apt_generated
9 | .springBeans
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-gateway/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | org.springframework.boot
9 | spring-boot-starter-parent
10 | 2.6.2
11 |
12 |
13 |
14 | com.giffing.bucket4j.spring.boot.starter
15 | bucket4j-spring-boot-starter-example-gateway
16 | 0.0.1-SNAPSHOT
17 |
18 | 11
19 | 2021.0.0
20 |
21 |
22 |
23 |
24 | org.springframework.boot
25 | spring-boot-starter-actuator
26 |
27 |
28 | org.springframework.boot
29 | spring-boot-starter-webflux
30 |
31 |
32 | org.springframework.cloud
33 | spring-cloud-starter-gateway
34 |
35 |
36 | com.giffing.bucket4j.spring.boot.starter
37 | bucket4j-spring-boot-starter
38 | 0.5.2
39 |
40 |
41 | org.springframework.boot
42 | spring-boot-starter-cache
43 |
44 |
45 | javax.cache
46 | cache-api
47 |
48 |
49 | com.github.vladimir-bukhtoyarov
50 | bucket4j-hazelcast
51 | 7.0.0
52 |
53 |
54 | com.hazelcast
55 | hazelcast
56 |
57 |
58 |
59 | org.springframework.boot
60 | spring-boot-devtools
61 | runtime
62 | true
63 |
64 |
65 | org.springframework.boot
66 | spring-boot-starter-test
67 | test
68 |
69 |
70 |
71 |
72 |
73 |
74 | org.springframework.cloud
75 | spring-cloud-dependencies
76 | ${spring-cloud.version}
77 | pom
78 | import
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | org.springframework.boot
87 | spring-boot-maven-plugin
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-gateway/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/gateway/GatewayMetricHandler.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.gateway;
2 |
3 | import java.util.List;
4 |
5 | import org.springframework.stereotype.Component;
6 |
7 | import com.giffing.bucket4j.spring.boot.starter.context.metrics.MetricHandler;
8 | import com.giffing.bucket4j.spring.boot.starter.context.metrics.MetricTagResult;
9 | import com.giffing.bucket4j.spring.boot.starter.context.metrics.MetricType;
10 |
11 |
12 | @Component
13 | public class GatewayMetricHandler implements MetricHandler {
14 |
15 | @Override
16 | public void handle(MetricType type, String name, long tokens, List tags) {
17 | System.out.println(type);
18 | System.out.println(name);
19 | System.out.println(tokens);
20 | System.out.println("################");
21 |
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-gateway/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/gateway/GatewayMetricHandler2.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.gateway;
2 |
3 | import java.util.List;
4 |
5 | import org.springframework.stereotype.Component;
6 |
7 | import com.giffing.bucket4j.spring.boot.starter.context.metrics.MetricHandler;
8 | import com.giffing.bucket4j.spring.boot.starter.context.metrics.MetricTagResult;
9 | import com.giffing.bucket4j.spring.boot.starter.context.metrics.MetricType;
10 |
11 |
12 | @Component
13 | public class GatewayMetricHandler2 implements MetricHandler {
14 |
15 | @Override
16 | public void handle(MetricType type, String name, long tokens, List tags) {
17 | System.out.println(type);
18 | System.out.println(name);
19 | System.out.println(tokens);
20 | System.out.println("################");
21 |
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-gateway/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/gateway/GatewaySampleApplication.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.gateway;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cache.annotation.EnableCaching;
6 | import org.springframework.cloud.gateway.route.RouteLocator;
7 | import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
8 | import org.springframework.context.annotation.Bean;
9 |
10 | @SpringBootApplication
11 | @EnableCaching
12 | public class GatewaySampleApplication {
13 |
14 |
15 | public static void main(String[] args) {
16 | SpringApplication.run(GatewaySampleApplication.class, args);
17 | }
18 |
19 | @Bean
20 | public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
21 | //@formatter:off
22 | return builder.routes()
23 | .route(p -> p
24 | .path("/get")
25 | .filters(f -> f.addRequestHeader("Hello", "World"))
26 | .uri("http://httpbin.org:80"))
27 | .build();
28 | //@formatter:on
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-gateway/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/gateway/MyController.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.gateway;
2 |
3 | import org.springframework.web.bind.annotation.GetMapping;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RequestParam;
6 | import org.springframework.web.bind.annotation.RestController;
7 |
8 | import reactor.core.publisher.Mono;
9 |
10 | @RestController
11 | @RequestMapping
12 | public class MyController {
13 |
14 | @GetMapping("/hello")
15 | public Mono hello(
16 | @RequestParam(defaultValue = "World") String name) {
17 | return Mono.just("Hello")
18 | .flatMap(s -> Mono
19 | .just(s + ", " + name + "!\n")
20 | );
21 | }
22 |
23 | @GetMapping("/world")
24 | public Mono world(
25 | @RequestParam(defaultValue = "World") String name) {
26 | return Mono.just("Hello")
27 | .flatMap(s -> Mono
28 | .just(s + ", " + name + "!\n")
29 | );
30 | }
31 |
32 | }
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-gateway/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
cache:
type: jcache
jcache:
provider: com.hazelcast.cache.impl.HazelcastServerCachingProvider
config: classpath:hazelcast.xml
2 | management:
3 | endpoints:
4 | web:
5 | exposure:
6 | include: "*"
7 | bucket4j:
8 | filters:
9 | - metrics:
10 | types:
11 | - consumed-counter
12 | - rejected-counter
13 | - cache-name: buckets
14 | filter-method: gateway
15 | url: .*
16 | filter-order: -100000
17 | rate-limits:
18 | - bandwidths:
19 | - capacity: 5
20 | time: 10
21 | unit: seconds
fixed-refill-interval: 1
fixed-refill-interval-unit: minutes
22 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-gateway/src/main/resources/hazelcast.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-hazelcast/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | /.settings/
3 | .classpath
4 | .project
5 | .idea/
6 | *.iml
7 | .factorypath
8 | .apt_generated
9 | .springBeans
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-hazelcast/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 |
6 | com.giffing.bucket4j.spring.boot.starter
7 | bucket4j-spring-boot-starter-examples
8 | ${revision}
9 | ..
10 |
11 | bucket4j-spring-boot-starter-example-hazelcast
12 |
13 |
14 |
15 |
16 | org.springframework.boot
17 | spring-boot-starter-web
18 |
19 |
20 | org.springframework.boot
21 | spring-boot-starter-cache
22 |
23 |
24 | com.giffing.bucket4j.spring.boot.starter
25 | bucket4j-spring-boot-starter
26 |
27 |
28 | com.hazelcast
29 | hazelcast
30 |
31 |
32 | com.hazelcast
33 | hazelcast-spring
34 |
35 |
36 | com.hazelcast
37 | hazelcast-client
38 | 3.12.12
39 |
40 |
41 | org.springframework.boot
42 | spring-boot-starter-actuator
43 |
44 |
45 |
46 |
47 |
48 |
49 | org.springframework.boot
50 | spring-boot-maven-plugin
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-hazelcast/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/hazelcast/HazelcastApplication.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.hazelcast;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cache.annotation.EnableCaching;
6 |
7 | @SpringBootApplication
8 | @EnableCaching
9 | public class HazelcastApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(HazelcastApplication.class, args);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-hazelcast/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/hazelcast/TestController.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.hazelcast;
2 |
3 | import org.springframework.http.ResponseEntity;
4 | import org.springframework.web.bind.annotation.GetMapping;
5 | import org.springframework.web.bind.annotation.RequestMapping;
6 | import org.springframework.web.bind.annotation.RestController;
7 |
8 | @RestController
9 | @RequestMapping("/")
10 | public class TestController {
11 |
12 | @GetMapping
13 | public ResponseEntity helloWorld() {
14 | return ResponseEntity.ok().build();
15 | }
16 |
17 |
18 |
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-hazelcast/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | management:
2 | security:
3 | enabled: false
4 | spring:
5 | main:
allow-bean-definition-overriding: true
6 | cache:
7 | type: jcache
8 | jcache:
9 | provider: com.hazelcast.cache.impl.HazelcastServerCachingProvider
10 | config: classpath:hazelcast.xml
11 | bucket4j:
12 | enabled: true
13 | filters:
14 | - cache-name: buckets
15 | url: .*
16 | rate-limits:
17 | - bandwidths:
18 | - capacity: 5
19 | time: 10
20 | unit: seconds
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-hazelcast/src/main/resources/hazelcast.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-webflux/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | /.settings/
3 | .classpath
4 | .project
5 | .idea/
6 | *.iml
7 | .factorypath
8 | .apt_generated
9 | .springBeans
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-webflux/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 |
6 | com.giffing.bucket4j.spring.boot.starter
7 | bucket4j-spring-boot-starter-examples
8 | ${revision}
9 | ..
10 |
11 | bucket4j-spring-boot-starter-example-webflux
12 |
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-webflux
17 |
18 |
19 | org.springframework.boot
20 | spring-boot-starter-cache
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-actuator
25 |
26 |
27 | com.giffing.bucket4j.spring.boot.starter
28 | bucket4j-spring-boot-starter
29 |
30 |
31 | javax.cache
32 | cache-api
33 |
34 |
35 | com.github.vladimir-bukhtoyarov
36 | bucket4j-hazelcast
37 |
38 |
39 | com.hazelcast
40 | hazelcast
41 |
42 |
43 | org.springframework.boot
44 | spring-boot-starter-test
45 |
46 |
47 |
48 |
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-maven-plugin
53 |
54 |
55 | generate build info
56 |
57 | build-info
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-webflux/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/webflux/MyController.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.webflux;
2 |
3 | import org.springframework.web.bind.annotation.GetMapping;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RequestParam;
6 | import org.springframework.web.bind.annotation.RestController;
7 |
8 | import reactor.core.publisher.Mono;
9 |
10 | @RestController
11 | @RequestMapping
12 | public class MyController {
13 |
14 | @GetMapping("/hello")
15 | public Mono hello(
16 | @RequestParam(defaultValue = "World") String name) {
17 | return Mono.just("Hello")
18 | .flatMap(s -> Mono
19 | .just(s + ", " + name + "!\n")
20 | );
21 | }
22 |
23 | @GetMapping("/world")
24 | public Mono world(
25 | @RequestParam(defaultValue = "World") String name) {
26 | return Mono.just("Hello")
27 | .flatMap(s -> Mono
28 | .just(s + ", " + name + "!\n")
29 | );
30 | }
31 |
32 | }
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-webflux/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/webflux/WebfluxApplication.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.webflux;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cache.annotation.EnableCaching;
6 |
7 | @SpringBootApplication
8 | @EnableCaching
9 | public class WebfluxApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(WebfluxApplication.class, args);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-webflux/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | management:
2 | endpoints:
3 | web:
4 | exposure:
5 | include: "*"
6 | bucket4j:
7 | enabled: true
8 | filters:
9 | - metrics:
10 | types:
11 | - consumed-counter
12 | - rejected-counter
13 | - cache-name: buckets
14 | filter-method: webflux
15 | url: .*
16 | filter-order: 1
17 | rate-limits:
18 | - bandwidths:
19 | - capacity: 5
20 | time: 10
21 | unit: seconds
22 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-webflux/src/main/resources/ehcache.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 | 3600
9 |
10 | 1000000
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-webflux/src/main/resources/hazelcast.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-webflux/src/test/java/com/giffing/bucket4j/spring/boot/starter/examples/webflux/WebfluxRateLimitTest.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.webflux;
2 |
3 | import java.util.Collections;
4 | import java.util.stream.IntStream;
5 |
6 | import org.junit.jupiter.api.BeforeEach;
7 | import org.junit.jupiter.api.Test;
8 | import org.junit.jupiter.api.extension.ExtendWith;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.boot.test.context.SpringBootTest;
11 | import org.springframework.context.ApplicationContext;
12 | import org.springframework.http.HttpStatus;
13 | import org.springframework.test.context.ActiveProfiles;
14 | import org.springframework.test.context.junit.jupiter.SpringExtension;
15 | import org.springframework.test.web.reactive.server.WebTestClient;
16 |
17 | @ExtendWith(SpringExtension.class)
18 | @SpringBootTest
19 | @ActiveProfiles("webflux") // Like this
20 | public class WebfluxRateLimitTest {
21 |
22 | @Autowired
23 | ApplicationContext context;
24 |
25 | WebTestClient rest;
26 |
27 | @BeforeEach
28 | public void setup() {
29 | this.rest = WebTestClient
30 | .bindToApplicationContext(this.context)
31 | .configureClient()
32 | .build();
33 | }
34 |
35 | @Test
36 | public void helloTest() throws Exception {
37 | String url = "/hello";
38 | IntStream.rangeClosed(1, 5)
39 | .boxed()
40 | .sorted(Collections.reverseOrder())
41 | .forEach(counter -> {
42 | successfulWebRequest(url, counter - 1);
43 | });
44 |
45 | blockedWebRequestDueToRateLimit(url);
46 | }
47 |
48 |
49 | @Test
50 | public void worldTest() throws Exception {
51 | String url = "/world";
52 | IntStream.rangeClosed(1, 10)
53 | .boxed()
54 | .sorted(Collections.reverseOrder())
55 | .forEach(counter -> {
56 | System.out.println(counter);
57 | successfulWebRequest(url, counter - 1);
58 | });
59 |
60 | blockedWebRequestDueToRateLimit(url);
61 | }
62 |
63 | private void successfulWebRequest(String url, Integer remainingTries) {
64 | rest
65 | .get()
66 | .uri(url)
67 | .exchange()
68 | .expectStatus().isOk()
69 | .expectHeader().valueEquals("X-Rate-Limit-Remaining", String.valueOf(remainingTries));
70 | }
71 |
72 | private void blockedWebRequestDueToRateLimit(String url) throws Exception {
73 | rest
74 | .get()
75 | .uri(url)
76 | .exchange()
77 | .expectStatus().isEqualTo(HttpStatus.TOO_MANY_REQUESTS)
78 | .expectBody().jsonPath("error", "Too many requests!");
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-webflux/src/test/resources/application-webflux.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | cache:
3 | cache-names:
4 | - buckets_test
5 | caffeine:
6 | spec: maximumSize=1000000,expireAfterAccess=3600s
7 | bucket4j:
8 | enabled: true
9 | filters:
10 | - cache-name: buckets_test
11 | filter-method: webflux
12 | url: ^(/hello).*
13 | rate-limits:
14 | - bandwidths:
15 | - capacity: 5
16 | time: 10
17 | unit: seconds
18 | - cache-name: buckets_test
19 | filter-method: webflux
20 | url: ^(/world).*
21 | rate-limits:
22 | - bandwidths:
23 | - capacity: 10
24 | time: 10
25 | unit: seconds
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-webflux/target/classes/application.yml:
--------------------------------------------------------------------------------
1 | management:
2 | endpoints:
3 | web:
4 | exposure:
5 | include: "*"
6 | bucket4j:
7 | enabled: true
8 | filters:
9 | - metrics:
10 | types:
11 | - consumed-counter
12 | - rejected-counter
13 | - cache-name: buckets
14 | filter-method: webflux
15 | url: .*
16 | filter-order: 1
17 | rate-limits:
18 | - bandwidths:
19 | - capacity: 5
20 | time: 10
21 | unit: seconds
22 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-zuul/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | /.settings/
3 | .classpath
4 | .project
5 | .idea/
6 | *.iml
7 | .factorypath
8 | .apt_generated
9 | .springBeans
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-zuul/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | com.giffing.bucket4j.spring.boot.starter
6 | bucket4j-spring-boot-starter-examples
7 | ${revision}
8 | ..
9 |
10 | bucket4j-spring-boot-starter-example-zuul
11 |
12 |
13 | Finchley.SR7
14 |
15 |
16 |
17 |
18 | com.giffing.bucket4j.spring.boot.starter
19 | bucket4j-spring-boot-starter
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter-actuator
24 |
25 |
26 | org.springframework.boot
27 | spring-boot-starter-cache
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-starter-web
32 |
33 |
34 | org.springframework.cloud
35 | spring-cloud-netflix-core
36 | 1.4.4.RELEASE
37 |
38 |
39 | org.ehcache
40 | ehcache
41 |
42 |
43 | org.projectlombok
44 | lombok
45 | true
46 |
47 |
48 | org.springframework.boot
49 | spring-boot-devtools
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-zuul/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/zuul/MyController.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.zuul;
2 |
3 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RestController;
6 |
7 | @RestController
8 | @EnableZuulProxy
9 | @RequestMapping
10 | public class MyController {
11 |
12 | @RequestMapping
13 | public String available() {
14 | return "Spring in Action";
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-zuul/src/main/java/com/giffing/bucket4j/spring/boot/starter/examples/zuul/ZuulApplication.java:
--------------------------------------------------------------------------------
1 | package com.giffing.bucket4j.spring.boot.starter.examples.zuul;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cache.annotation.EnableCaching;
6 |
7 | @SpringBootApplication
8 | @EnableCaching
9 | public class ZuulApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(ZuulApplication.class, args);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-zuul/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | management:
2 | endpoints:
3 | web:
4 | exposure:
5 | include: "*"
6 | spring:
7 | application:
8 | name: myservice
9 | cache:
10 | jcache:
11 | config: classpath:ehcache.xml
12 | bucket4j:
13 | enabled: true
14 | filters:
15 | - cache-name: buckets
16 | filter-method: zuul
17 | url: /myservice
18 | filter-order: -10000
19 | rate-limits:
20 | - filter-key-type: ip
21 | expression: "@securityService.username()?: getRemoteAddr()"
22 | bandwidths:
23 | - capacity: 10
24 | time: 1
25 | unit: minutes
26 | zuul:
27 | routes:
28 | myservice:
29 | url: http://localhost:8090
30 |
--------------------------------------------------------------------------------
/bucket4j-spring-boot-starter-example-zuul/src/main/resources/ehcache.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 | 3600
9 |
10 | 1000000
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | com.giffing.bucket4j.spring.boot.starter
6 | bucket4j-spring-boot-starter-examples
7 | ${revision}
8 | pom
9 |
10 | bucket4j-spring-boot-starter-examples
11 | Spring Boot Starter für Bucket4J
12 |
13 |
14 | org.springframework.boot
15 | spring-boot-starter-parent
16 | 2.6.2
17 |
18 |
19 |
20 |
21 | bucket4j-spring-boot-starter-example-ehcache
22 | bucket4j-spring-boot-starter-example-zuul
23 | bucket4j-spring-boot-starter-example-hazelcast
24 | bucket4j-spring-boot-starter-example-caffeine
25 | bucket4j-spring-boot-starter-example-webflux
26 | bucket4j-spring-boot-starter-example-gateway
27 |
28 |
29 |
30 | 0.0.1-SNAPSHOT
31 | UTF-8
32 | UTF-8
33 | 1.8
34 |
35 |
36 |
37 |
38 |
39 | com.giffing.bucket4j.spring.boot.starter
40 | bucket4j-spring-boot-starter
41 | 0.5.2
42 |
43 |
44 | com.github.vladimir-bukhtoyarov
45 | bucket4j-core
46 | 7.0.0
47 |
48 |
49 | com.github.vladimir-bukhtoyarov
50 | bucket4j-jcache
51 | 7.0.0
52 |
53 |
54 | com.github.vladimir-bukhtoyarov
55 | bucket4j-hazelcast
56 | 7.0.0
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | org.springframework.boot
66 | spring-boot-maven-plugin
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------