Skip to content
This repository has been archived by the owner on Jul 25, 2022. It is now read-only.

Commit

Permalink
Restructure project
Browse files Browse the repository at this point in the history
  • Loading branch information
alek-sys committed Jun 20, 2019
1 parent 1f277bd commit 22ae698
Show file tree
Hide file tree
Showing 13 changed files with 131 additions and 80 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
HELP.md
.gradle
/build/
build/
!gradle/wrapper/gradle-wrapper.jar

### STS ###
Expand All @@ -17,7 +17,7 @@ HELP.md
*.iws
*.iml
*.ipr
/out/
out/

### NetBeans ###
/nbproject/private/
Expand Down
3 changes: 2 additions & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#Thu Jun 20 14:22:08 BST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
18 changes: 9 additions & 9 deletions build.gradle → rate-limiter-hazelcast/build.gradle
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
plugins {
id 'org.springframework.boot' version '2.1.5.RELEASE'
id 'java'
id 'org.springframework.boot' version '2.1.5.RELEASE' apply false
}

apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'

group = 'caching'
sourceCompatibility = '1.8'
group = 'org.springframework.cloud.gateway'

repositories {
mavenCentral()
Expand All @@ -16,14 +16,14 @@ ext {
set('springCloudVersion', "Greenwich.SR1")
}

dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'com.hazelcast:hazelcast:3.12'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}

dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'com.hazelcast:hazelcast:3.12'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
Original file line number Diff line number Diff line change
@@ -1,68 +1,60 @@
package scg.ratelimiter;
package org.springframework.cloud.gateway.ratelimiter;

import com.hazelcast.config.Config;
import com.hazelcast.config.JoinConfig;
import com.hazelcast.config.TcpIpConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.filter.ratelimit.AbstractRateLimiter;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.validation.Validator;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

class HazelcastRateLimiterConfig {
public class HazelcastRateLimiter extends AbstractRateLimiter<HazelcastRateLimiter.RateLimiterConfig> {

private int limit;
static class RateLimiterConfig {

public int getLimit() {
return limit;
}
private int limit;

public void setLimit(int limit) {
this.limit = limit;
}
}
public int getLimit() {
return limit;
}

@Component
class HazelcastRateLimiter extends AbstractRateLimiter<HazelcastRateLimiterConfig> {
public void setLimit(int limit) {
this.limit = limit;
}
}

private final Logger logger = LoggerFactory.getLogger(HazelcastRateLimiter.class);

private IMap<String, Integer> map;
private AtomicBoolean initialized = new AtomicBoolean(false);

protected HazelcastRateLimiter(Validator defaultValidator) {
super(HazelcastRateLimiterConfig.class, "hazelcast-rate-limiter", defaultValidator);
public HazelcastRateLimiter(Validator defaultValidator) {
super(HazelcastRateLimiter.RateLimiterConfig.class, "hazelcast-rate-limiter", defaultValidator);
}

// super hacky - but DNS records X.peer.apps.internal will only be available shortly after application started
// so InitializingBean or any other option to start cluster during app startup won't work
@Scheduled(initialDelay = 3000, fixedDelay = Integer.MAX_VALUE)
public void run() {
public void initialize(List<String> members) {
String groupName = "my-test-group";

Config cfg = new Config();
cfg.getGroupConfig().setName(groupName);

JoinConfig joinConfig = cfg.getNetworkConfig().getJoin();
joinConfig.getMulticastConfig().setEnabled(false);
joinConfig.getTcpIpConfig().setEnabled(true)
.addMember("0.peer.apps.internal")
.addMember("1.peer.apps.internal");
TcpIpConfig tcpIpConfig = joinConfig.getTcpIpConfig().setEnabled(true);
members.forEach(tcpIpConfig::addMember);

HazelcastInstance instance = Hazelcast.newHazelcastInstance(cfg);
map = instance.getMap("rate-limit");
map = instance.getMap("rate-limits");
initialized.set(true);
}

Expand All @@ -77,7 +69,7 @@ public Mono<Response> isAllowed(String routeId, String id) {
}

Integer noRequests = map.getOrDefault(id, 0) + 1;
HazelcastRateLimiterConfig config = getConfig().getOrDefault(routeId, new HazelcastRateLimiterConfig());
HazelcastRateLimiter.RateLimiterConfig config = getConfig().getOrDefault(routeId, new HazelcastRateLimiter.RateLimiterConfig());

logger.info("Current limit is {}, total requests to date {}", config.getLimit(), noRequests);

Expand All @@ -92,23 +84,3 @@ public Mono<Response> isAllowed(String routeId, String id) {
return Mono.just(new Response(true, Collections.singletonMap("X-Remaining-Limit", String.valueOf(remainingRequests))));
}
}

@Component
class HeaderKeyResolver implements KeyResolver {

@Override
public Mono<String> resolve(ServerWebExchange exchange) {
String apiKey = exchange.getRequest().getHeaders().getFirst("X-API-Key");
return apiKey == null ? Mono.empty() : Mono.just(apiKey);
}
}

@SpringBootApplication
@EnableScheduling
public class DemoApplication {

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

}
3 changes: 2 additions & 1 deletion README.md → samples/cf-hazelcast-p2p/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ This is a PoC of using Hazelcast peer-to-peer cluster to implement Spring Cloud
# Build and deploy

```
$ ./gradlew assemble
$ cd samples/cf-hazelcast-p2p
$ ../../gradlew assemble
$ cf push --var cf-apps-domain=<your cf env domain>
$ ./configure-network.sh
```
Expand Down
31 changes: 31 additions & 0 deletions samples/cf-hazelcast-p2p/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
plugins {
id 'org.springframework.boot' version '2.1.5.RELEASE'
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

sourceCompatibility = '1.8'
group = 'org.springframework.cloud.gateway'

repositories {
mavenCentral()
}

ext {
set('springCloudVersion', "Greenwich.SR1")
}

dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'com.hazelcast:hazelcast'
implementation project(":rate-limiter-hazelcast")
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
File renamed without changes.
2 changes: 1 addition & 1 deletion manifest.yml → samples/cf-hazelcast-p2p/manifest.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
applications:
- name: peer
path: build/libs/scg-rate-limiter.jar
path: build/libs/cf-hazelcast-p2p.jar
instances: 2
routes:
- route: peer.apps.internal
Expand Down
39 changes: 39 additions & 0 deletions samples/cf-hazelcast-p2p/src/main/java/sample/DemoApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package sample;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.ratelimiter.HazelcastRateLimiter;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.validation.Validator;

import java.util.Arrays;
import java.util.List;

@SpringBootApplication
@EnableScheduling
public class DemoApplication {

@Autowired
private HazelcastRateLimiter hazelcastRateLimiter;

@Bean
public HazelcastRateLimiter hazelcastRateLimiter(Validator defaultValidator) {
return new HazelcastRateLimiter(defaultValidator);
}

// super hacky - but DNS records X.peer.apps.internal will only be available shortly after application started
// so InitializingBean or any other option to start cluster during app startup won't work
@Scheduled(initialDelay = 3000, fixedDelay = Integer.MAX_VALUE)
void startHazelcastCluster() {
List<String> members = Arrays.asList("0.peer.apps.internal", "1.peer.apps.internal");
hazelcastRateLimiter.initialize(members);
}

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

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package sample;

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class HeaderKeyResolver implements KeyResolver {

@Override
public Mono<String> resolve(ServerWebExchange exchange) {
String apiKey = exchange.getRequest().getHeaders().getFirst("X-API-Key");
return apiKey == null ? Mono.empty() : Mono.just(apiKey);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ spring:
- id: github
uri: https://google.com
predicates:
- Path=/google
- Path=/google/**
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
rate-limiter: "#{@hazelcastRateLimiter}"
Expand Down
8 changes: 7 additions & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,10 @@ pluginManagement {
gradlePluginPortal()
}
}
rootProject.name = 'scg-rate-limiter'
rootProject.name = 'spring-cloud-gateway-rate-limiter'

include(':rate-limiter-hazelcast')

include(":cf-hazelcast-p2p")
project(":cf-hazelcast-p2p").projectDir = new File('./samples/cf-hazelcast-p2p')

16 changes: 0 additions & 16 deletions src/test/java/caching/hzdemo/DemoApplicationTests.java

This file was deleted.

0 comments on commit 22ae698

Please sign in to comment.