Skip to content

Commit a94a6c5

Browse files
authored
Merge pull request #185 from ing-bank/fix/check-bucket-location-rate-limiting
Fix/check bucket location rate limiting
2 parents f6bf874 + b5f69db commit a94a6c5

File tree

6 files changed

+68
-2
lines changed

6 files changed

+68
-2
lines changed

docker-compose-extra.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
version: "3"
2+
services:
3+
4+
mockServer:
5+
image: mockserver/mockserver:5.14.0
6+
ports:
7+
- 1080:1080
8+
extra_hosts:
9+
- "host.docker.internal:host-gateway"
10+
environment:
11+
MOCKSERVER_WATCH_INITIALIZATION_JSON: "true"
12+
MOCKSERVER_INITIALIZATION_JSON_PATH: /config/simulateBucketNotFoundDuringMultipartUpload.jsonc
13+
genericJVMOptions: "-Xmx1024m -Xms512m"
14+
volumes:
15+
- type: bind
16+
source: ./mockServer
17+
target: /config
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// To use this configuration make sure it is selected as MOCKSERVER_INITIALIZATION_JSON_PATH and switch rokku to go through proxy port: 1080
2+
// Remember to comment out `updateBucketCredentials` in `NamespacesHandler.scala:52` so rokku will try to refetch bucket location before each request and to enable rokku multiple namespace feature
3+
[
4+
{
5+
// Allow first few requests to start multipart upload
6+
"httpRequest": {
7+
"method": "GET"
8+
},
9+
"httpForward": {
10+
"host": "host.docker.internal",
11+
"port": 8010,
12+
"scheme": "HTTP"
13+
},
14+
"times": {
15+
"remainingTimes": 4,
16+
"unlimited": false
17+
},
18+
"priority": 20,
19+
},
20+
{
21+
// Simulate rate limiting
22+
"httpRequest": {
23+
"method": "GET"
24+
},
25+
"httpResponse": {
26+
"statusCode": 503,
27+
},
28+
"priority": 10,
29+
},
30+
{
31+
// allow all other requests
32+
"httpForward": {
33+
"host": "host.docker.internal",
34+
"port": 8010,
35+
"scheme": "HTTP"
36+
},
37+
"priority": 0,
38+
},
39+
]

src/main/resources/application.conf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ rokku {
2424
}
2525
region = ${?ROKKU_STORAGE_S3_AWS_REGION}
2626
v2SignatureEnabled = ${?ROKKU_STORAGE_S3_V2_ENABLED}
27-
27+
# To add more then one code, seperate them with comma
28+
slowdownCodes = ${?ROKKU_STORAGE_S3_SLOWDOWN_CODES}
2829
healthCheck {
2930
# can be one of:
3031
# s3ListBucket - uses AWS S3 client to list single bucket

src/main/resources/reference.conf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ rokku {
3131
}
3232
region = "us-east-1"
3333
v2SignatureEnabled = false
34-
34+
# To add more then one code, seperate them with comma
35+
slowdownCodes = "502, 503"
3536
healthCheck {
3637
# can be one of:
3738
# s3ListBucket - uses AWS S3 client to list single bucket

src/main/scala/com/ing/wbaa/rokku/proxy/config/StorageS3Settings.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class StorageS3Settings(config: Config) extends Extension {
1414
val storageS3AdminSecretkey: String = config.getString("rokku.storage.s3.admin.secretkey")
1515
val awsRegion: String = config.getString("rokku.storage.s3.region")
1616
val v2SignatureEnabled: Boolean = config.getBoolean("rokku.storage.s3.v2SignatureEnabled")
17+
val slowdownCodes: Array[Int] = config.getString("rokku.storage.s3.slowdownCodes").split(",").map(o => o.trim.toInt)
1718
val isRequestUserQueueEnabled: Boolean = config.getBoolean("rokku.storage.s3.request.queue.enable")
1819
private val hcMethodString = config.getString("rokku.storage.s3.healthCheck.method")
1920
val hcMethod: HCMethod = hcMethodString match {

src/main/scala/com/ing/wbaa/rokku/proxy/handler/namespace/NamespacesHandler.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import akka.http.scaladsl.model.HttpRequest
44
import com.amazonaws.auth.BasicAWSCredentials
55
import com.amazonaws.services.s3.model.AmazonS3Exception
66
import com.ing.wbaa.rokku.proxy.config.NamespaceSettings
7+
import com.ing.wbaa.rokku.proxy.config.StorageS3Settings
78
import com.ing.wbaa.rokku.proxy.data.RequestId
89
import com.ing.wbaa.rokku.proxy.handler.LoggerHandlerWithId
10+
import com.ing.wbaa.rokku.proxy.handler.exception.RokkuThrottlingException
911
import com.ing.wbaa.rokku.proxy.metrics.MetricsFactory.{ incrementBucketNamespaceCacheHit, incrementBucketNamespacesNotFound, incrementBucketNamespacesSearch }
1012
import com.ing.wbaa.rokku.proxy.util.S3Utils
1113

@@ -21,6 +23,7 @@ trait NamespacesHandler {
2123
private val bucketCredentials: scala.collection.concurrent.Map[BucketName, BasicAWSCredentials] = scala.collection.concurrent.TrieMap[BucketName, BasicAWSCredentials]()
2224

2325
protected[this] val namespaceSettings: NamespaceSettings
26+
protected[this] def storageS3Settings: StorageS3Settings
2427

2528
private def namespaceCredentials: ListMap[NamespaceName, BasicAWSCredentials] = namespaceSettings.namespaceCredentialsMap
2629

@@ -72,6 +75,10 @@ trait NamespacesHandler {
7275
logger.info("bucket {} in namespace {} return 403 for credentials {} so bucket exist but the credentials cannot see location ", bucketName.name, namespaceName, ex, credentials.getAWSAccessKeyId)
7376
return true
7477
}
78+
if (storageS3Settings.slowdownCodes contains ex.asInstanceOf[AmazonS3Exception].getStatusCode) {
79+
logger.info("throttling, cannot check bucket location")
80+
throw new RokkuThrottlingException("cannot check bucket location")
81+
}
7582
if (ex.asInstanceOf[AmazonS3Exception].getStatusCode != 404) {
7683
logger.error("namespace {} returned exception {} for credentials {} but should only status code 404", namespaceName, ex, credentials.getAWSAccessKeyId)
7784
}

0 commit comments

Comments
 (0)