Skip to content

Commit

Permalink
allegro-internal/flex-roadmap#687 Added http compression filter confi…
Browse files Browse the repository at this point in the history
…guration (added a white list of services)
  • Loading branch information
nastassia-dailidava committed Jul 25, 2024
1 parent 0035a56 commit 18b890e
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class PathNormalizationProperties {
var mergeSlashes = true
var pathWithEscapedSlashesAction = "KEEP_UNCHANGED"
}

class MetricsProperties {
var cacheSetSnapshot = false
}
Expand All @@ -65,7 +66,7 @@ class AccessLogProperties {
var enabled = false
var timeFormat = "%START_TIME(%FT%T.%3fZ)%"
var messageFormat = "%PROTOCOL% %REQ(:METHOD)% %REQ(:authority)% %REQ(:PATH)% " +
"%DOWNSTREAM_REMOTE_ADDRESS% -> %UPSTREAM_HOST%"
"%DOWNSTREAM_REMOTE_ADDRESS% -> %UPSTREAM_HOST%"
var level = "TRACE"
var logger = "envoy.AccessLog"
var customFields = mapOf<String, String>()
Expand Down Expand Up @@ -131,6 +132,7 @@ class ClientsListsProperties {
var defaultClientsList: List<String> = emptyList()
var customClientsLists: Map<String, List<String>> = mapOf()
}

class TlsProtocolProperties {
var cipherSuites: List<String> = listOf("ECDHE-ECDSA-AES128-GCM-SHA256", "ECDHE-RSA-AES128-GCM-SHA256")
var minimumVersion = TlsParameters.TlsProtocol.TLSv1_2
Expand Down Expand Up @@ -385,6 +387,7 @@ class CompressionProperties {
var disableOnEtagHeader = true
var requestCompressionEnabled = false
var responseCompressionEnabled = false
var enableForServices: List<String> = emptyList()
}

class BrotliProperties {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import io.envoyproxy.envoy.extensions.compression.brotli.compressor.v3.Brotli
import io.envoyproxy.envoy.extensions.compression.gzip.compressor.v3.Gzip
import io.envoyproxy.envoy.extensions.filters.http.compressor.v3.Compressor
import io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpFilter
import pl.allegro.tech.servicemesh.envoycontrol.groups.Group
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.SnapshotProperties

class CompressionFilterFactory(val properties: SnapshotProperties) {
Expand Down Expand Up @@ -40,14 +41,14 @@ class CompressionFilterFactory(val properties: SnapshotProperties) {
properties.compression.gzip.chooseFirst
)

fun gzipCompressionFilter(): HttpFilter? {
return if (properties.compression.gzip.enabled) {
fun gzipCompressionFilter(group: Group): HttpFilter? {
return if (properties.compression.gzip.enabled && group.hasCompressionEnabled()) {
gzipCompressionFilter
} else null
}

fun brotliCompressionFilter(): HttpFilter? {
return if (properties.compression.brotli.enabled) {
fun brotliCompressionFilter(group: Group): HttpFilter? {
return if (properties.compression.brotli.enabled && group.hasCompressionEnabled()) {
brotliCompressionFilter
} else null
}
Expand Down Expand Up @@ -89,4 +90,6 @@ class CompressionFilterFactory(val properties: SnapshotProperties) {
.setDefaultValue(BoolValue.of(defaultValue))
)
.setMinContentLength(UInt32Value.of(properties.compression.minContentLength))

private fun Group.hasCompressionEnabled() = properties.compression.enableForServices.contains(this.serviceName)
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ class EnvoyDefaultFilters(
authorizationHeaderToMetadataFilter()
}

val defaultGzipCompressionFilter = { _: Group, _: GlobalSnapshot ->
compressionFilterFactory.gzipCompressionFilter()
val defaultGzipCompressionFilter = { group: Group, _: GlobalSnapshot ->
compressionFilterFactory.gzipCompressionFilter(group)
}

val defaultBrotliCompressionFilter = { _: Group, _: GlobalSnapshot ->
compressionFilterFactory.brotliCompressionFilter()
val defaultBrotliCompressionFilter = { group: Group, _: GlobalSnapshot ->
compressionFilterFactory.brotliCompressionFilter(group)
}

val defaultEgressFilters = listOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.assertj.core.api.ObjectAssert
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.RegisterExtension
import pl.allegro.tech.servicemesh.envoycontrol.assertions.untilAsserted
import pl.allegro.tech.servicemesh.envoycontrol.config.AdsAllDependencies
import pl.allegro.tech.servicemesh.envoycontrol.config.Xds
import pl.allegro.tech.servicemesh.envoycontrol.config.consul.ConsulExtension
import pl.allegro.tech.servicemesh.envoycontrol.config.envoy.EnvoyExtension
Expand All @@ -17,6 +18,22 @@ import pl.allegro.tech.servicemesh.envoycontrol.config.service.GenericServiceExt
class CompressionFilterTest {

companion object {
private const val SERVICE_NAME = "service-1"
private const val DOWNSTREAM_SERVICE_NAME = "echo2"
private const val LONG_STRING = "Workshallmeantheworkofauthorship,whetherinSourceorObjectform," +
"madeavailableundertheLicensesindicatedbyacopyrightnoticethatisincludedinorattachedto" +
"thework(anexampleisprovidedintheAppendixbelow)."
private val serviceConfig = """
node:
metadata:
proxy_settings:
incoming:
unlistedEndpointsPolicy: log
endpoints: []
""".trimIndent()
private val config = Xds.copy(configOverride = serviceConfig, serviceName = SERVICE_NAME)
private val unListedServiceConfig = AdsAllDependencies
private val longText = LONG_STRING.repeat(100)

@JvmField
@RegisterExtension
Expand All @@ -31,36 +48,32 @@ class CompressionFilterTest {
"envoy-control.envoy.snapshot.compression.brotli.enabled" to true,
"envoy-control.envoy.snapshot.compression.minContentLength" to 100,
"envoy-control.envoy.snapshot.compression.responseCompressionEnabled" to true,
"envoy-control.envoy.snapshot.compression.enableForServices" to listOf(DOWNSTREAM_SERVICE_NAME),
"envoy-control.envoy.snapshot.outgoing-permissions.servicesAllowedToUseWildcard" to "test-service"

)
)
private const val SERVICE_NAME = "service-1"
private const val LONG_STRING = "Workshallmeantheworkofauthorship,whetherinSourceorObjectform," +
"madeavailableundertheLicensesindicatedbyacopyrightnoticethatisincludedinorattachedto" +
"thework(anexampleisprovidedintheAppendixbelow)."

private val serviceConfig = """
node:
metadata:
proxy_settings:
incoming:
unlistedEndpointsPolicy: log
endpoints: []
""".trimIndent()
private val config = Xds.copy(configOverride = serviceConfig, serviceName = SERVICE_NAME)
private val longText = LONG_STRING.repeat(100)

@JvmField
@RegisterExtension
val service =
GenericServiceExtension(EchoContainer(longText))

@JvmField
@RegisterExtension
val noCompressionService = GenericServiceExtension(EchoContainer(longText))

@JvmField
@RegisterExtension
val downstreamService = EchoServiceExtension()

@JvmField
@RegisterExtension
val downstreamEnvoy = EnvoyExtension(envoyControl, downstreamService, config = Xds)
val downstreamEnvoy = EnvoyExtension(envoyControl, downstreamService, Xds)

@JvmField
@RegisterExtension
val noCompressionEnvoy = EnvoyExtension(envoyControl, noCompressionService, unListedServiceConfig)

@JvmField
@RegisterExtension
Expand Down Expand Up @@ -100,6 +113,18 @@ class CompressionFilterTest {
}
}

@Test
fun `should not enable compression on unlisted service`() {
consul.server.operations.registerServiceWithEnvoyOnIngress(serviceEnvoy, name = SERVICE_NAME)
noCompressionEnvoy.waitForReadyServices(SERVICE_NAME)
untilAsserted {
val response =
noCompressionEnvoy.egressOperations.callService(SERVICE_NAME, headers = mapOf("accept-encoding" to "gzip"))
println(response.headers.toString())
assertThat(response).isNotCompressed()
}
}

private fun ObjectAssert<Response>.isCompressedWith(encoding: String): ObjectAssert<Response> {
matches { it.isSuccessful && it.headers.any { x -> x.first == "content-encoding" && x.second == encoding } }
return this
Expand Down

0 comments on commit 18b890e

Please sign in to comment.