From 10e9bb16cba3f40c3ceaca4fd394a20ef0cf5f5a Mon Sep 17 00:00:00 2001 From: Xavier FACQ Date: Tue, 17 Oct 2023 19:33:57 +0200 Subject: [PATCH 1/6] Fix inconsistency of the data returned by the API --- .../net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt index be6586170..9055bc393 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt @@ -89,7 +89,7 @@ class DownloadStatsResource { @GET @Schema(hidden = true) @Path("/total/{feature_version}/{release_name}") - @Operation(summary = "Get download stats for feature verson", description = "stats", hidden = true) + @Operation(summary = "Get download stats for feature version", description = "stats", hidden = true) fun getTotalDownloadStatsForTag( @Parameter(name = "feature_version", description = "Feature version (i.e 8, 9, 10...)", required = true) @PathParam("feature_version") @@ -102,6 +102,7 @@ class DownloadStatsResource { ?: throw BadRequestException("Unable to find version $featureVersion") return getAdoptReleases(release) + .filter { it.release_type == ReleaseType.ga } .filter { it.release_name == releaseName } .flatMap { it.binaries.asSequence() } .flatMap { From 4cda2fb7e72b47cb19cd637f85c6ca624dd0e974 Mon Sep 17 00:00:00 2001 From: Xavier FACQ Date: Tue, 17 Oct 2023 21:16:28 +0200 Subject: [PATCH 2/6] Fix the test --- .../src/test/kotlin/net/adoptium/api/DownloadStatsPathTest.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/DownloadStatsPathTest.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/DownloadStatsPathTest.kt index 011de8147..4a6d25e7e 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/DownloadStatsPathTest.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/DownloadStatsPathTest.kt @@ -21,6 +21,7 @@ import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.extension.ExtendWith import java.time.format.DateTimeFormatter import jakarta.ws.rs.BadRequestException +import net.adoptium.api.v3.models.ReleaseType @ExtendWith(value = [DbExtension::class]) @TestInstance(TestInstance.Lifecycle.PER_CLASS) @@ -174,6 +175,7 @@ class DownloadStatsPathTest : FrontendTest() { val releases = getReleases() val release = releases + .filter { it.release_type == ReleaseType.ga } .filter { it.vendor == Vendor.getDefault() } .first() From 5a44a25a7bfb33a26b997c1b24e00e023e71aff8 Mon Sep 17 00:00:00 2001 From: Xavier FACQ Date: Wed, 18 Oct 2023 15:11:18 +0200 Subject: [PATCH 3/6] Add parameter to endpoints with: releaseType: ReleaseType = ReleaseType.ga --- .../v3/routes/stats/DownloadStatsResource.kt | 36 ++++++++++++------- .../net/adoptium/api/v3/models/ReleaseType.kt | 3 +- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt index 9055bc393..178758412 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt @@ -63,17 +63,19 @@ class DownloadStatsResource { @GET @Schema(hidden = true) @Path("/total/{feature_version}") - @Operation(summary = "Get download stats for feature verson", description = "stats", hidden = true) + @Operation(summary = "Get download stats for feature version", description = "stats", hidden = true) fun getTotalDownloadStats( @Parameter(name = "feature_version", description = "Feature version (i.e 8, 9, 10...)", required = true) @PathParam("feature_version") - featureVersion: Int + featureVersion: Int, + @Parameter(name = "release_type", description = "Release type (i.e all, ga, ea)", required = false) + @PathParam("release_type") + releaseType: ReleaseType = ReleaseType.ga ): Map { val release = apiDataStore.getAdoptRepos().getFeatureRelease(featureVersion) ?: throw BadRequestException("Unable to find version $featureVersion") - return getAdoptReleases(release) - .filter { it.release_type == ReleaseType.ga } + return getAdoptReleases(release, releaseType, null) .map { grouped -> Pair( grouped.release_name, @@ -96,14 +98,15 @@ class DownloadStatsResource { featureVersion: Int, @Parameter(name = "release_name", description = "Release Name i.e jdk-11.0.4+11", required = true) @PathParam("release_name") - releaseName: String + releaseName: String, + @Parameter(name = "release_type", description = "Release type (i.e all, ga, ea)", required = false) + @PathParam("release_type") + releaseType: ReleaseType = ReleaseType.ga ): Map { val release = apiDataStore.getAdoptRepos().getFeatureRelease(featureVersion) ?: throw BadRequestException("Unable to find version $featureVersion") - return getAdoptReleases(release) - .filter { it.release_type == ReleaseType.ga } - .filter { it.release_name == releaseName } + return getAdoptReleases(release, releaseType, releaseName) .flatMap { it.binaries.asSequence() } .flatMap { val archive = Pair(it.`package`.name, it.download_count) @@ -116,17 +119,26 @@ class DownloadStatsResource { .toMap() } - private fun getAdoptReleases(release: FeatureRelease): Sequence { - return release + private fun getAdoptReleases(release: FeatureRelease, releaseType: ReleaseType, releaseName: String?): Sequence { + var releases = release .releases .getReleases() + + if(releaseType != ReleaseType.all) { + releases = releases.filter { it.release_type == releaseType } + } + if(releaseName != null) { + releases = releases.filter { it.release_name == releaseName } + } + + return releases .filter { it.vendor == Vendor.getDefault() } } @GET @Schema(hidden = true) @Path("/tracking") - @Operation(summary = "Get download stats for feature verson", description = "stats", hidden = true) + @Operation(summary = "Get download stats for feature version", description = "stats", hidden = true) fun tracking( @Parameter(name = "days", description = "Number of days to display, if used in conjunction with from/to then this will limit the request to x days before the end of the given period", schema = Schema(defaultValue = "30", type = SchemaType.INTEGER), required = false) @QueryParam("days") @@ -166,7 +178,7 @@ class DownloadStatsResource { @GET @Schema(hidden = true) @Path("/monthly") - @Operation(summary = "Get download stats for feature verson", description = "stats", hidden = true) + @Operation(summary = "Get download stats for feature version", description = "stats", hidden = true) fun monthly( @Parameter(name = "source", description = "Stats data source", schema = Schema(defaultValue = "all"), required = false) @QueryParam("source") diff --git a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/ReleaseType.kt b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/ReleaseType.kt index 3f7825dce..7e5e3883d 100644 --- a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/ReleaseType.kt +++ b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/ReleaseType.kt @@ -3,8 +3,9 @@ package net.adoptium.api.v3.models import org.eclipse.microprofile.openapi.annotations.enums.SchemaType import org.eclipse.microprofile.openapi.annotations.media.Schema -@Schema(type = SchemaType.STRING, defaultValue = "ga", enumeration = ["ga", "ea"]) +@Schema(type = SchemaType.STRING, defaultValue = "ga", enumeration = ["all", "ga", "ea"]) enum class ReleaseType { + all, ga, ea; } From 932606fb4f1df582a30018777207742fa5147325 Mon Sep 17 00:00:00 2001 From: Xavier FACQ Date: Wed, 18 Oct 2023 17:07:10 +0200 Subject: [PATCH 4/6] Use List of ReleaseType as parameter --- .../v3/routes/stats/DownloadStatsResource.kt | 20 +++++++++---------- .../net/adoptium/api/v3/models/ReleaseType.kt | 3 +-- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt index 178758412..171036201 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt @@ -68,14 +68,13 @@ class DownloadStatsResource { @Parameter(name = "feature_version", description = "Feature version (i.e 8, 9, 10...)", required = true) @PathParam("feature_version") featureVersion: Int, - @Parameter(name = "release_type", description = "Release type (i.e all, ga, ea)", required = false) - @PathParam("release_type") - releaseType: ReleaseType = ReleaseType.ga + @Parameter(name = "release_types", description = "List of release types to include in computation (i.e &release_types=ga,ea)", required = false) + @QueryParam("release_types") releaseTypes: List = listOf(ReleaseType.ga) ): Map { val release = apiDataStore.getAdoptRepos().getFeatureRelease(featureVersion) ?: throw BadRequestException("Unable to find version $featureVersion") - return getAdoptReleases(release, releaseType, null) + return getAdoptReleases(release, releaseTypes, null) .map { grouped -> Pair( grouped.release_name, @@ -99,14 +98,13 @@ class DownloadStatsResource { @Parameter(name = "release_name", description = "Release Name i.e jdk-11.0.4+11", required = true) @PathParam("release_name") releaseName: String, - @Parameter(name = "release_type", description = "Release type (i.e all, ga, ea)", required = false) - @PathParam("release_type") - releaseType: ReleaseType = ReleaseType.ga + @Parameter(name = "release_types", description = "List of release types to include in computation (i.e &release_types=ga,ea)", required = false) + @QueryParam("release_types") releaseTypes: List = listOf(ReleaseType.ga) ): Map { val release = apiDataStore.getAdoptRepos().getFeatureRelease(featureVersion) ?: throw BadRequestException("Unable to find version $featureVersion") - return getAdoptReleases(release, releaseType, releaseName) + return getAdoptReleases(release, releaseTypes, releaseName) .flatMap { it.binaries.asSequence() } .flatMap { val archive = Pair(it.`package`.name, it.download_count) @@ -119,13 +117,13 @@ class DownloadStatsResource { .toMap() } - private fun getAdoptReleases(release: FeatureRelease, releaseType: ReleaseType, releaseName: String?): Sequence { + private fun getAdoptReleases(release: FeatureRelease, releaseTypes: List, releaseName: String?): Sequence { var releases = release .releases .getReleases() - if(releaseType != ReleaseType.all) { - releases = releases.filter { it.release_type == releaseType } + if(releaseTypes.isNotEmpty()) { + releases = releases.filter { releaseTypes.contains(it.release_type) } } if(releaseName != null) { releases = releases.filter { it.release_name == releaseName } diff --git a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/ReleaseType.kt b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/ReleaseType.kt index 7e5e3883d..3f7825dce 100644 --- a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/ReleaseType.kt +++ b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/ReleaseType.kt @@ -3,9 +3,8 @@ package net.adoptium.api.v3.models import org.eclipse.microprofile.openapi.annotations.enums.SchemaType import org.eclipse.microprofile.openapi.annotations.media.Schema -@Schema(type = SchemaType.STRING, defaultValue = "ga", enumeration = ["all", "ga", "ea"]) +@Schema(type = SchemaType.STRING, defaultValue = "ga", enumeration = ["ga", "ea"]) enum class ReleaseType { - all, ga, ea; } From 68ab2eda6b27474a52dd4525989fee1167310273 Mon Sep 17 00:00:00 2001 From: Xavier FACQ Date: Wed, 18 Oct 2023 17:14:47 +0200 Subject: [PATCH 5/6] Improve readability --- .../net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt index 171036201..bb8d3862e 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt @@ -121,16 +121,17 @@ class DownloadStatsResource { var releases = release .releases .getReleases() + .filter { it.vendor == Vendor.getDefault() } if(releaseTypes.isNotEmpty()) { releases = releases.filter { releaseTypes.contains(it.release_type) } } + if(releaseName != null) { releases = releases.filter { it.release_name == releaseName } } return releases - .filter { it.vendor == Vendor.getDefault() } } @GET From 118228fa57ab6d9bcc594940ba8a1202c390b585 Mon Sep 17 00:00:00 2001 From: Xavier FACQ Date: Thu, 19 Oct 2023 10:52:07 +0200 Subject: [PATCH 6/6] Add parameter with default value --- .../v3/routes/stats/DownloadStatsResource.kt | 20 +++++++++++++------ .../net/adoptium/api/DownloadStatsPathTest.kt | 8 ++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt index bb8d3862e..c48d545b8 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt @@ -21,6 +21,7 @@ import java.util.concurrent.CompletionStage import jakarta.enterprise.context.ApplicationScoped import jakarta.inject.Inject import jakarta.ws.rs.BadRequestException +import jakarta.ws.rs.DefaultValue import jakarta.ws.rs.GET import jakarta.ws.rs.Path import jakarta.ws.rs.PathParam @@ -68,8 +69,11 @@ class DownloadStatsResource { @Parameter(name = "feature_version", description = "Feature version (i.e 8, 9, 10...)", required = true) @PathParam("feature_version") featureVersion: Int, - @Parameter(name = "release_types", description = "List of release types to include in computation (i.e &release_types=ga,ea)", required = false) - @QueryParam("release_types") releaseTypes: List = listOf(ReleaseType.ga) + + @Parameter(name = "release_types", description = "List of release types to include in computation (i.e &release_types=ga&release_types=ea)", required = false) + @QueryParam("release_types") + @DefaultValue("ga") + releaseTypes: List? ): Map { val release = apiDataStore.getAdoptRepos().getFeatureRelease(featureVersion) ?: throw BadRequestException("Unable to find version $featureVersion") @@ -95,11 +99,15 @@ class DownloadStatsResource { @Parameter(name = "feature_version", description = "Feature version (i.e 8, 9, 10...)", required = true) @PathParam("feature_version") featureVersion: Int, + @Parameter(name = "release_name", description = "Release Name i.e jdk-11.0.4+11", required = true) @PathParam("release_name") releaseName: String, - @Parameter(name = "release_types", description = "List of release types to include in computation (i.e &release_types=ga,ea)", required = false) - @QueryParam("release_types") releaseTypes: List = listOf(ReleaseType.ga) + + @Parameter(name = "release_types", description = "List of release types to include in computation (i.e &release_types=ga&release_types=ea)", required = false) + @QueryParam("release_types") + @DefaultValue("ga") + releaseTypes: List? ): Map { val release = apiDataStore.getAdoptRepos().getFeatureRelease(featureVersion) ?: throw BadRequestException("Unable to find version $featureVersion") @@ -117,13 +125,13 @@ class DownloadStatsResource { .toMap() } - private fun getAdoptReleases(release: FeatureRelease, releaseTypes: List, releaseName: String?): Sequence { + private fun getAdoptReleases(release: FeatureRelease, releaseTypes: List?, releaseName: String?): Sequence { var releases = release .releases .getReleases() .filter { it.vendor == Vendor.getDefault() } - if(releaseTypes.isNotEmpty()) { + if(releaseTypes != null && releaseTypes.isNotEmpty()) { releases = releases.filter { releaseTypes.contains(it.release_type) } } diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/DownloadStatsPathTest.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/DownloadStatsPathTest.kt index 4a6d25e7e..947d05586 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/DownloadStatsPathTest.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/DownloadStatsPathTest.kt @@ -158,14 +158,14 @@ class DownloadStatsPathTest : FrontendTest() { @Test fun totalVersionReturnsSaneData() { - val stats = downloadStatsResource.getTotalDownloadStats(8) + val stats = downloadStatsResource.getTotalDownloadStats(8, listOf(ReleaseType.ga)) assertTrue { return@assertTrue stats.isNotEmpty() && !stats.containsValue(0L) } } @Test fun badTotalVersionReturnsSaneData() { assertThrows { - downloadStatsResource.getTotalDownloadStats(101) + downloadStatsResource.getTotalDownloadStats(101, listOf(ReleaseType.ga)) } } @@ -179,7 +179,7 @@ class DownloadStatsPathTest : FrontendTest() { .filter { it.vendor == Vendor.getDefault() } .first() - val stats = downloadStatsResource.getTotalDownloadStatsForTag(release.version_data.major, release.release_name) + val stats = downloadStatsResource.getTotalDownloadStatsForTag(release.version_data.major, release.release_name, listOf(ReleaseType.ga)) assertTrue { return@assertTrue stats.isNotEmpty() && !stats.containsValue(0L) } } } @@ -187,7 +187,7 @@ class DownloadStatsPathTest : FrontendTest() { @Test fun badTotalTagReturnsSaneData() { assertThrows { - downloadStatsResource.getTotalDownloadStatsForTag(101, "fooBar") + downloadStatsResource.getTotalDownloadStatsForTag(101, "fooBar", listOf(ReleaseType.ga)) } }