diff --git a/ballerina-tests/http-advanced-tests/tests/http2_caching_test.bal b/ballerina-tests/http-advanced-tests/tests/http2_caching_test.bal index d0c6247f02..1929216a65 100644 --- a/ballerina-tests/http-advanced-tests/tests/http2_caching_test.bal +++ b/ballerina-tests/http-advanced-tests/tests/http2_caching_test.bal @@ -99,7 +99,7 @@ service /cachingBackend on http2CachingListener2 { //new http:Listener(9240) { isolated resource function 'default .(http:Caller caller, http:Request req) returns error? { http:Response res = new; http:ResponseCacheControl resCC = new; - resCC.maxAge = 60; + resCC.maxAge = 60.54; resCC.isPrivate = false; res.cacheControl = resCC; @@ -158,13 +158,13 @@ function testHttp2BasicCachingBehaviour() returns error? { @test:Config {} function testHttp2RequestCacheControlBuildCacheControlDirectives() { http:RequestCacheControl reqCC = new; - reqCC.maxAge = 60; + reqCC.maxAge = 60.34; reqCC.noCache = true; reqCC.noStore = true; reqCC.noTransform = true; reqCC.onlyIfCached = true; - reqCC.maxStale = 120; - reqCC.minFresh = 6; + reqCC.maxStale = 120.04; + reqCC.minFresh = 6.0; test:assertEquals(reqCC.buildCacheControlDirectives(), "no-cache, no-store, no-transform, only-if-cached, max-age=60, max-stale=120, min-fresh=6"); } @@ -172,14 +172,14 @@ function testHttp2RequestCacheControlBuildCacheControlDirectives() { @test:Config {} function testHttp2ResponseCacheControlBuildCacheControlDirectives() { http:ResponseCacheControl resCC = new; - resCC.maxAge = 60; + resCC.maxAge = 60.54; resCC.isPrivate = false; resCC.mustRevalidate = true; resCC.noCache = true; resCC.noStore = true; resCC.noTransform = true; resCC.proxyRevalidate = true; - resCC.sMaxAge = 60; + resCC.sMaxAge = 60.32; test:assertEquals(resCC.buildCacheControlDirectives(), "must-revalidate, no-cache, no-store, no-transform, public, proxy-revalidate, max-age=60, s-maxage=60"); } diff --git a/ballerina-tests/http-advanced-tests/tests/http_cache_config_annotation_test.bal b/ballerina-tests/http-advanced-tests/tests/http_cache_config_annotation_test.bal index e9afd1a256..973dd0192a 100644 --- a/ballerina-tests/http-advanced-tests/tests/http_cache_config_annotation_test.bal +++ b/ballerina-tests/http-advanced-tests/tests/http_cache_config_annotation_test.bal @@ -117,7 +117,7 @@ service / on new http:Listener(cacheAnnotationTestPort2, httpVersion = http:HTTP } } - resource function default maxAgeBE(http:Request req) returns @http:Cache {maxAge: 5, mustRevalidate: false} xml { + resource function default maxAgeBE(http:Request req) returns @http:Cache {maxAge: 5.32, mustRevalidate: false} xml { int count = 0; lock { maxAgeHitCountNew += 1; diff --git a/ballerina/caching_request_cache_control.bal b/ballerina/caching_request_cache_control.bal index cf4da4b37b..2945586c59 100644 --- a/ballerina/caching_request_cache_control.bal +++ b/ballerina/caching_request_cache_control.bal @@ -61,7 +61,7 @@ public class RequestCacheControl { } if self.maxAge >= 0d { - directives[i] = MAX_AGE + "=" + self.maxAge.toString(); + directives[i] = string `${MAX_AGE}=${decimal:floor(self.maxAge)}`; i += 1; } @@ -69,12 +69,12 @@ public class RequestCacheControl { directives[i] = MAX_STALE; i += 1; } else if self.maxStale >= 0d { - directives[i] = MAX_STALE + "=" + self.maxStale.toString(); + directives[i] = string `${MAX_STALE}=${decimal:floor(self.maxStale)}`; i += 1; } if self.minFresh >= 0d { - directives[i] = MIN_FRESH + "=" + self.minFresh.toString(); + directives[i] = string `${MIN_FRESH}=${decimal:floor(self.minFresh)}`; i += 1; } diff --git a/ballerina/caching_response_cache_control.bal b/ballerina/caching_response_cache_control.bal index 187512bf95..a308780190 100644 --- a/ballerina/caching_response_cache_control.bal +++ b/ballerina/caching_response_cache_control.bal @@ -48,8 +48,8 @@ public class ResponseCacheControl { self.noTransform = cacheConfig.noTransform; self.isPrivate = cacheConfig.isPrivate; self.proxyRevalidate = cacheConfig.proxyRevalidate; - self.maxAge = cacheConfig.maxAge; - self.sMaxAge = cacheConfig.sMaxAge; + self.maxAge = decimal:floor(cacheConfig.maxAge); + self.sMaxAge = decimal:floor(cacheConfig.sMaxAge); self.noCacheFields = cacheConfig.noCacheFields; self.privateFields = cacheConfig.privateFields; } @@ -94,12 +94,12 @@ public class ResponseCacheControl { } if self.maxAge >= 0d { - directives[i] = MAX_AGE + "=" + self.maxAge.toString(); + directives[i] = string `${MAX_AGE}=${decimal:floor(self.maxAge)}`; i += 1; } if self.sMaxAge >= 0d { - directives[i] = S_MAX_AGE + "=" + self.sMaxAge.toString(); + directives[i] = string `${S_MAX_AGE}=${decimal:floor(self.sMaxAge)}`; i += 1; } diff --git a/changelog.md b/changelog.md index 34ff57b0d2..fb7241eee4 100644 --- a/changelog.md +++ b/changelog.md @@ -13,6 +13,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - [Add connection eviction feature to handle connections that receive GO_AWAY from the client](https://github.com/ballerina-platform/ballerina-library/issues/6734) - [Enhanced the configurability of Ballerina access logging by introducing multiple configuration options.](https://github.com/ballerina-platform/ballerina-library/issues/6111) +### Fixed + +- [Fix number format exception with decimal values for cache configuration](https://github.com/ballerina-platform/ballerina-library/issues/6765) + ## [2.11.2] - 2024-06-14 ### Added diff --git a/native/src/main/java/io/ballerina/stdlib/http/api/client/caching/ResponseCacheControlObj.java b/native/src/main/java/io/ballerina/stdlib/http/api/client/caching/ResponseCacheControlObj.java index a46193d1e2..ce3122b74b 100644 --- a/native/src/main/java/io/ballerina/stdlib/http/api/client/caching/ResponseCacheControlObj.java +++ b/native/src/main/java/io/ballerina/stdlib/http/api/client/caching/ResponseCacheControlObj.java @@ -203,6 +203,13 @@ private boolean getBooleanValue(BObject responseCacheControl, BString fieldName) } private long getIntValue(BObject responseCacheControl, BString fieldName) { - return Long.parseLong(responseCacheControl.get(fieldName).toString()); + try { + String value = responseCacheControl.get(fieldName).toString(); + // The value is decimal, and need to compute the floor value + return Long.parseLong(value.split("\\.")[0]); + } catch (NumberFormatException e) { + // Ignore the exception and set 0 as the value + return 0; + } } }