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

Added compression properties to node metadata #426

Merged
merged 3 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
Lists all changes with user impact.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).

## [0.20.19]
### Changed
- Added http compression filter properties to node metadata
-
## [0.20.18]
### Changed
- Added http compression filter configuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ sealed class Group {
abstract val proxySettings: ProxySettings
abstract val pathNormalizationConfig: PathNormalizationConfig
abstract val listenersConfig: ListenersConfig?
abstract val compressionConfig: CompressionConfig
}

data class ServicesGroup(
Expand All @@ -18,6 +19,7 @@ data class ServicesGroup(
override val proxySettings: ProxySettings = ProxySettings(),
override val pathNormalizationConfig: PathNormalizationConfig = PathNormalizationConfig(),
override val listenersConfig: ListenersConfig? = null,
override val compressionConfig: CompressionConfig = CompressionConfig(),
) : Group()

data class AllServicesGroup(
Expand All @@ -26,15 +28,26 @@ data class AllServicesGroup(
override val discoveryServiceName: String? = null,
override val proxySettings: ProxySettings = ProxySettings(),
override val pathNormalizationConfig: PathNormalizationConfig = PathNormalizationConfig(),
override val listenersConfig: ListenersConfig? = null
) : Group()
override val listenersConfig: ListenersConfig? = null,
override val compressionConfig: CompressionConfig = CompressionConfig(),
) : Group()

data class PathNormalizationConfig(
val normalizationEnabled: Boolean? = null,
val mergeSlashes: Boolean? = null,
val pathWithEscapedSlashesAction: String? = null
)

data class CompressionConfig(
val gzip: Compressor? = null,
val brotli: Compressor? = null,
)

data class Compressor(
val enabled: Boolean? = null,
val quality: Int? = null,
)

data class ListenersConfig(
val ingressHost: String,
val ingressPort: Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,8 @@ class MetadataNodeGroup(
discoveryServiceName,
proxySettings,
nodeMetadata.pathNormalizationConfig,
listenersConfig
listenersConfig,
nodeMetadata.compressionConfig
)
else ->
ServicesGroup(
Expand All @@ -194,7 +195,8 @@ class MetadataNodeGroup(
discoveryServiceName,
proxySettings,
nodeMetadata.pathNormalizationConfig,
listenersConfig
listenersConfig,
nodeMetadata.compressionConfig
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import io.grpc.Status
import pl.allegro.tech.servicemesh.envoycontrol.groups.ClientWithSelector.Companion.decomposeClient
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.AccessLogFiltersProperties
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.CommonHttpProperties
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.CompressorProperties
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.RetryPolicyProperties
import pl.allegro.tech.servicemesh.envoycontrol.snapshot.SnapshotProperties
import pl.allegro.tech.servicemesh.envoycontrol.utils.AccessLogFilterParser
Expand All @@ -35,6 +36,7 @@ class NodeMetadata(metadata: Struct, properties: SnapshotProperties) {

val pathNormalizationConfig = getPathNormalization(metadata.fieldsMap["path_normalization"], properties)
val proxySettings: ProxySettings = ProxySettings(metadata.fieldsMap["proxy_settings"], properties)
val compressionConfig: CompressionConfig = getCompressionSettings(metadata.fieldsMap["compression"], properties)
}

data class AccessLogFilterSettings(val proto: Value?, val properties: AccessLogFiltersProperties) {
Expand Down Expand Up @@ -86,6 +88,22 @@ fun getPathNormalization(proto: Value?, snapshotProperties: SnapshotProperties):
)
}

fun getCompressionSettings(proto: Value?, snapshotProperties: SnapshotProperties): CompressionConfig {
val defaultCompressionConfig = CompressionConfig(
Compressor(snapshotProperties.compression.gzip.enabled, snapshotProperties.compression.gzip.quality),
Compressor(snapshotProperties.compression.brotli.enabled, snapshotProperties.compression.brotli.quality)
)
if (proto == null) {
return defaultCompressionConfig
}
return CompressionConfig(
proto.field("gzip")?.toCompressorProperties(snapshotProperties.compression.gzip)
?: defaultCompressionConfig.gzip,
proto.field("brotli")?.toCompressorProperties(snapshotProperties.compression.brotli)
?: defaultCompressionConfig.brotli,
)
}

private fun getCommunicationMode(proto: Value?): CommunicationMode {
val ads = proto
?.boolValue
Expand Down Expand Up @@ -344,6 +362,15 @@ fun Value?.toIncoming(properties: SnapshotProperties): Incoming {
)
}

fun Value?.toCompressorProperties(properties: CompressorProperties): Compressor {
val enabled = this?.field("enabled")?.boolValue
val quality = this?.field("quality")?.numberValue?.toInt()
return Compressor(
enabled ?: properties.enabled,
quality ?: properties.quality
)
}

fun Value?.toUnlistedPolicy() = this?.stringValue
?.takeIf { it.isNotEmpty() }
?.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,26 +381,20 @@ class DynamicForwardProxyProperties {
}

class CompressionProperties {
var gzip = GzipProperties()
var brotli = BrotliProperties()
var gzip = CompressorProperties()
var brotli = CompressorProperties()
Comment on lines +384 to +385
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does chooseFirst work now that gzip and brotli use the same properties?

Copy link
Contributor Author

@nastassia-dailidava nastassia-dailidava Jul 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so according to the docs if several filters have chooseFirst = true then the priority will be chosen by their order in configuration, but I'm going to configure as it was before but in aec settings

var minContentLength = 100
var disableOnEtagHeader = true
var requestCompressionEnabled = false
var responseCompressionEnabled = false
var enableForServices: List<String> = emptyList()
}

class BrotliProperties {
class CompressorProperties {
var enabled = false
var quality = 11
var quality = 1
var chooseFirst = true
}

class GzipProperties {
var enabled = false
var chooseFirst = false
}

data class OAuthProvider(
var jwksUri: URI = URI.create("http://localhost"),
var createCluster: Boolean = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,42 +14,43 @@ import pl.allegro.tech.servicemesh.envoycontrol.snapshot.SnapshotProperties

class CompressionFilterFactory(val properties: SnapshotProperties) {

private val brotliCompressionFilter: HttpFilter = compressionFilter(
TypedExtensionConfig.newBuilder()
.setName("envoy.compression.brotli.compressor")
.setTypedConfig(
com.google.protobuf.Any.pack(
Brotli.newBuilder()
.setQuality(UInt32Value.of(properties.compression.brotli.quality))
.build()
)
),
properties.compression.brotli.chooseFirst
)

private val gzipCompressionFilter: HttpFilter = compressionFilter(
TypedExtensionConfig.newBuilder()
.setName("envoy.compression.gzip.compressor")
.setTypedConfig(
com.google.protobuf.Any.pack(
Gzip.newBuilder()
.setCompressionStrategy(Gzip.CompressionStrategy.DEFAULT_STRATEGY)
.setCompressionLevel(Gzip.CompressionLevel.forNumber(BEST_VALUE))
.build()
)
),
properties.compression.gzip.chooseFirst
)

fun gzipCompressionFilter(group: Group): HttpFilter? {
return if (properties.compression.gzip.enabled && group.hasCompressionEnabled()) {
gzipCompressionFilter
val compressionLevel = Gzip.CompressionLevel.forNumber(
group.compressionConfig.gzip?.quality
?: properties.compression.gzip.quality
) ?: Gzip.CompressionLevel.forNumber(BEST_VALUE)
return if (group.compressionConfig.gzip?.enabled == true) {
compressionFilter(
TypedExtensionConfig.newBuilder()
.setName("envoy.compression.gzip.compressor")
.setTypedConfig(
com.google.protobuf.Any.pack(
Gzip.newBuilder()
.setCompressionStrategy(Gzip.CompressionStrategy.DEFAULT_STRATEGY)
.setCompressionLevel(compressionLevel)
.build()
)
),
properties.compression.gzip.chooseFirst
)
} else null
}

fun brotliCompressionFilter(group: Group): HttpFilter? {
return if (properties.compression.brotli.enabled && group.hasCompressionEnabled()) {
brotliCompressionFilter
val compressionLevel = group.compressionConfig.brotli?.quality ?: properties.compression.brotli.quality
return if (group.compressionConfig.brotli?.enabled == true) {
compressionFilter(
TypedExtensionConfig.newBuilder()
.setName("envoy.compression.brotli.compressor")
.setTypedConfig(
com.google.protobuf.Any.pack(
Brotli.newBuilder()
.setQuality(UInt32Value.of(compressionLevel))
.build()
)
),
properties.compression.brotli.chooseFirst
)
} else null
}

Expand Down Expand Up @@ -90,6 +91,4 @@ 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 @@ -30,6 +30,9 @@ class MetadataNodeGroupTest {
mergeSlashes = true,
pathWithEscapedSlashesAction = "KEEP_UNCHANGED"
)
private val defaultCompConfig = Compressor(false, 1)
private val compressionConfig = CompressionConfig(defaultCompConfig, defaultCompConfig)

@Test
fun `should assign to group with all dependencies`() {
// given
Expand All @@ -50,7 +53,8 @@ class MetadataNodeGroupTest {
proxySettings = ProxySettings().with(
serviceDependencies = serviceDependencies("a", "b", "c"),
allServicesDependencies = true
)
),
compressionConfig = compressionConfig
)
)
}
Expand All @@ -68,7 +72,8 @@ class MetadataNodeGroupTest {
ServicesGroup(
proxySettings = ProxySettings().with(serviceDependencies = setOf()),
pathNormalizationConfig = defaultNormalizationConfig,
communicationMode = XDS
communicationMode = XDS,
compressionConfig = compressionConfig
)
)
}
Expand All @@ -87,7 +92,8 @@ class MetadataNodeGroupTest {
ServicesGroup(
proxySettings = ProxySettings().with(serviceDependencies = serviceDependencies("a", "b", "c")),
pathNormalizationConfig = defaultNormalizationConfig,
communicationMode = XDS
communicationMode = XDS,
compressionConfig = compressionConfig
)
)
}
Expand All @@ -106,7 +112,8 @@ class MetadataNodeGroupTest {
AllServicesGroup(
communicationMode = ADS,
pathNormalizationConfig = defaultNormalizationConfig,
proxySettings = ProxySettings().with(allServicesDependencies = true)
proxySettings = ProxySettings().with(allServicesDependencies = true),
compressionConfig = compressionConfig
)
)
}
Expand All @@ -125,7 +132,8 @@ class MetadataNodeGroupTest {
ServicesGroup(
proxySettings = ProxySettings().with(serviceDependencies = serviceDependencies("a", "b", "c")),
pathNormalizationConfig = defaultNormalizationConfig,
communicationMode = ADS
communicationMode = ADS,
compressionConfig = compressionConfig
)
)
}
Expand All @@ -146,7 +154,8 @@ class MetadataNodeGroupTest {
// because service may define different settings for different dependencies (for example retry config)
communicationMode = ADS,
pathNormalizationConfig = defaultNormalizationConfig,
proxySettings = ProxySettings().with(serviceDependencies = serviceDependencies("a", "b", "c"))
proxySettings = ProxySettings().with(serviceDependencies = serviceDependencies("a", "b", "c")),
compressionConfig = compressionConfig
)
)
}
Expand All @@ -170,7 +179,8 @@ class MetadataNodeGroupTest {
proxySettings = ProxySettings().with(serviceDependencies = serviceDependencies("a", "b", "c")),
pathNormalizationConfig = defaultNormalizationConfig,
communicationMode = XDS,
serviceName = "app1"
serviceName = "app1",
compressionConfig = compressionConfig
)
)
}
Expand Down Expand Up @@ -210,7 +220,8 @@ class MetadataNodeGroupTest {
communicationMode = ADS,
serviceName = "app1",
pathNormalizationConfig = defaultNormalizationConfig,
proxySettings = addedProxySettings.with(serviceDependencies = serviceDependencies("a", "b"))
proxySettings = addedProxySettings.with(serviceDependencies = serviceDependencies("a", "b")),
compressionConfig = compressionConfig
)
)
}
Expand All @@ -232,7 +243,8 @@ class MetadataNodeGroupTest {
communicationMode = XDS,
serviceName = "app1",
pathNormalizationConfig = defaultNormalizationConfig,
proxySettings = addedProxySettings.with(allServicesDependencies = true)
proxySettings = addedProxySettings.with(allServicesDependencies = true),
compressionConfig = compressionConfig
)
)
}
Expand Down
Loading
Loading