Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes Error "Request Entity Too Large" #585

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
39 changes: 39 additions & 0 deletions src/main/groovy/io/seqera/wave/configuration/SurrealConfig.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Wave, containers provisioning service
* Copyright (c) 2024, Seqera Labs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package io.seqera.wave.configuration

import groovy.transform.CompileStatic
import io.micronaut.context.annotation.Requires
import io.micronaut.context.annotation.Value
import jakarta.inject.Singleton

/**
* Surreal DB service settings
*
* @author Munish Chouhan <[email protected]>
*/
@CompileStatic
@Singleton
@Requires(env='surrealdb')
class SurrealConfig {

@Value('${wave.surreal.max_http_request_size:14336}') //14 KB for the file and 2 KB for the rest of the fields
Integer maxHttpRequestSize

}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class WaveContainerRecord {
/**
* The container file (aka Dockerfile) content associated with the request
*/
final String containerFile
String containerFile

/**
* The container config associated with the request
Expand All @@ -70,7 +70,7 @@ class WaveContainerRecord {
/**
* The conda file associated with the request
*/
final String condaFile
String condaFile
pditommaso marked this conversation as resolved.
Show resolved Hide resolved

/**
* The container arch platform
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import io.micronaut.core.annotation.Nullable
import io.micronaut.http.client.exceptions.HttpClientResponseException
import io.micronaut.runtime.event.ApplicationStartupEvent
import io.micronaut.runtime.event.annotation.EventListener
import io.seqera.wave.configuration.SurrealConfig
import io.seqera.wave.core.ContainerDigestPair
import io.seqera.wave.service.builder.BuildRequest
import io.seqera.wave.service.persistence.PersistenceService
Expand Down Expand Up @@ -64,6 +65,9 @@ class SurrealPersistenceService implements PersistenceService {
@Value('${surreal.default.init-db}')
private Boolean initDb

@Inject
private SurrealConfig surrealConfig

@EventListener
void onApplicationStartup(ApplicationStartupEvent event) {
if (initDb)
Expand Down Expand Up @@ -95,6 +99,8 @@ class SurrealPersistenceService implements PersistenceService {

@Override
void saveBuild(WaveBuildRecord build) {
build.condaFile = truncateLargeFile(build.condaFile)
build.dockerFile = truncateLargeFile(build.dockerFile)
surrealDb.insertBuildAsync(getAuthorization(), build).subscribe({ result->
log.trace "Build request with id '$build.buildId' saved record: ${result}"
}, {error->
Expand Down Expand Up @@ -148,6 +154,8 @@ class SurrealPersistenceService implements PersistenceService {

@Override
void saveContainerRequest(String token, WaveContainerRecord data) {
data.condaFile = truncateLargeFile(data.condaFile)
data.containerFile = truncateLargeFile(data.containerFile)
surrealDb.insertContainerRequestAsync(authorization, token, data).subscribe({ result->
log.trace "Container request with token '$token' saved record: ${result}"
}, {error->
Expand Down Expand Up @@ -234,4 +242,16 @@ class SurrealPersistenceService implements PersistenceService {
return result
}

/**
* Surreal allows 16KB as maximum size for a payload
* This method will truncate the payload if it exceeds 14 KB
* Truncate the payload if it exceeds the maximum size
*/
protected truncateLargeFile(String file) {
if( file && file.length() > surrealConfig.maxHttpRequestSize )
return file.substring(0, surrealConfig.maxHttpRequestSize) + "\n[content truncated]"
else
return file

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package io.seqera.wave.service.persistence.impl

import spock.lang.Specification
import spock.lang.Unroll

import java.nio.file.Path
import java.time.Duration
Expand All @@ -29,6 +30,7 @@ import io.micronaut.http.HttpRequest
import io.micronaut.http.client.HttpClient
import io.seqera.wave.api.ContainerConfig
import io.seqera.wave.api.SubmitContainerTokenRequest
import io.seqera.wave.configuration.SurrealConfig
import io.seqera.wave.core.ContainerPlatform
import io.seqera.wave.api.ContainerLayer
import io.seqera.wave.core.ContainerDigestPair
Expand Down Expand Up @@ -296,4 +298,20 @@ class SurrealPersistenceServiceTest extends Specification implements SurrealDBTe
result2 == scanRecord2
}

@Unroll
void "truncateLargeFile should return correct size file"() {
given:
def config = new SurrealConfig(maxHttpRequestSize: 14 * 1024)

expect:
new SurrealPersistenceService(surrealConfig: config).truncateLargeFile(FILE) == RESULT

where:
FILE | RESULT
null | null
"" | ""
"a" * (14 * 1024) | "a" * (14 * 1024)
"a" * (15 * 1024) | "a" * (14 * 1024)+"\n[content truncated]"
}

}