Skip to content

Commit b2e1172

Browse files
committed
feat: add endpoint to expose analytics definitions
see https://gravitee.atlassian.net/browse/GKO-1579
1 parent 4fc4615 commit b2e1172

File tree

44 files changed

+3372
-2358
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+3372
-2358
lines changed

gravitee-apim-rest-api/gravitee-apim-rest-api-automation/gravitee-apim-rest-api-automation-rest/src/test/java/io/gravitee/apim/rest/api/automation/spring/ResourceContextConfiguration.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@
3737
import inmemory.SharedPolicyGroupCrudServiceInMemory;
3838
import inmemory.SharedPolicyGroupHistoryCrudServiceInMemory;
3939
import inmemory.spring.InMemoryConfiguration;
40+
import io.gravitee.apim.core.analytics.domain_service.engine.definition.AnalyticsDefinition;
41+
import io.gravitee.apim.core.analytics.use_case.engine.definition.GetApiMetricsUseCase;
42+
import io.gravitee.apim.core.analytics.use_case.engine.definition.GetApiSpecsUseCase;
43+
import io.gravitee.apim.core.analytics.use_case.engine.definition.GetMetricFacetsUseCase;
44+
import io.gravitee.apim.core.analytics.use_case.engine.definition.GetMetricFiltersUseCase;
4045
import io.gravitee.apim.core.api.domain_service.ApiExportDomainService;
4146
import io.gravitee.apim.core.api.domain_service.ApiImportDomainService;
4247
import io.gravitee.apim.core.api.domain_service.ApiMetadataDecoderDomainService;
@@ -129,6 +134,7 @@
129134
import io.gravitee.apim.core.subscription.use_case.RejectSubscriptionUseCase;
130135
import io.gravitee.apim.infra.adapter.SubscriptionAdapter;
131136
import io.gravitee.apim.infra.adapter.SubscriptionAdapterImpl;
137+
import io.gravitee.apim.infra.domain_service.analytics.AnalyticsDefinitionDomainServiceImpl;
132138
import io.gravitee.apim.infra.domain_service.application.ValidateApplicationSettingsDomainServiceImpl;
133139
import io.gravitee.apim.infra.domain_service.documentation.ValidatePageSourceDomainServiceImpl;
134140
import io.gravitee.apim.infra.domain_service.group.ValidateGroupCRDDomainServiceImpl;
@@ -874,4 +880,29 @@ public CockpitPromotionServiceProvider cockpitPromotionServiceProvider() {
874880
public CreatePromotionUseCase createPromotionUseCase() {
875881
return mock(CreatePromotionUseCase.class);
876882
}
883+
884+
@Bean
885+
public AnalyticsDefinition analyticsDefinitionDomainService() {
886+
return new AnalyticsDefinitionDomainServiceImpl();
887+
}
888+
889+
@Bean
890+
public GetApiSpecsUseCase getApiSpecsUseCase(AnalyticsDefinition analyticsDefinition) {
891+
return new GetApiSpecsUseCase(analyticsDefinition);
892+
}
893+
894+
@Bean
895+
public GetApiMetricsUseCase getApiMetricsUseCase(AnalyticsDefinition analyticsDefinition) {
896+
return new GetApiMetricsUseCase(analyticsDefinition);
897+
}
898+
899+
@Bean
900+
public GetMetricFiltersUseCase getMetricFiltersUseCase(AnalyticsDefinition analyticsDefinition) {
901+
return new GetMetricFiltersUseCase(analyticsDefinition);
902+
}
903+
904+
@Bean
905+
public GetMetricFacetsUseCase getMetricFacetsUseCase(AnalyticsDefinition analyticsDefinition) {
906+
return new GetMetricFacetsUseCase(analyticsDefinition);
907+
}
877908
}

gravitee-apim-rest-api/gravitee-apim-rest-api-management-v2/gravitee-apim-rest-api-management-v2-rest/pom.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,18 @@
293293
<inputSpec>${project.basedir}/src/main/resources/openapi/openapi-installation-deprecated.yaml</inputSpec>
294294
</configuration>
295295
</execution>
296+
<execution>
297+
<id>model-analytics</id>
298+
<goals>
299+
<goal>generate</goal>
300+
</goals>
301+
<configuration>
302+
<inputSpec>${project.basedir}/src/main/resources/openapi/openapi-analytics.yaml</inputSpec>
303+
<modelPackage>${openapi.modelPackage}.analytics.engine</modelPackage>
304+
</configuration>
305+
</execution>
296306
</executions>
307+
297308
</plugin>
298309
</plugins>
299310
</build>

gravitee-apim-rest-api/gravitee-apim-rest-api-management-v2/gravitee-apim-rest-api-management-v2-rest/src/main/java/io/gravitee/rest/api/management/v2/rest/GraviteeManagementV2Application.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import io.gravitee.rest.api.management.v2.rest.provider.ObjectMapperResolver;
3434
import io.gravitee.rest.api.management.v2.rest.provider.YamlWriter;
3535
import io.gravitee.rest.api.management.v2.rest.resource.OpenAPIResource;
36+
import io.gravitee.rest.api.management.v2.rest.resource.analytics.definition.AnalyticsDefinitionResource;
3637
import io.gravitee.rest.api.management.v2.rest.resource.api.ApisResource;
3738
import io.gravitee.rest.api.management.v2.rest.resource.application.ApplicationsResource;
3839
import io.gravitee.rest.api.management.v2.rest.resource.asyncjob.AsyncJobsResource;
@@ -73,6 +74,7 @@ public GraviteeManagementV2Application() {
7374
register(EnvironmentsResource.class);
7475
register(ApisResource.class);
7576
register(ApplicationsResource.class);
77+
register(AnalyticsDefinitionResource.class);
7678

7779
// Resources deprecated at root level
7880
register(EndpointsResource.class);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright © 2015 The Gravitee team (http://gravitee.io)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.gravitee.rest.api.management.v2.rest.mapper;
17+
18+
import io.gravitee.rest.api.management.v2.rest.model.analytics.engine.ApiSpec;
19+
import io.gravitee.rest.api.management.v2.rest.model.analytics.engine.ApiSpecsResponse;
20+
import io.gravitee.rest.api.management.v2.rest.model.analytics.engine.FacetSpec;
21+
import io.gravitee.rest.api.management.v2.rest.model.analytics.engine.FacetSpecsResponse;
22+
import io.gravitee.rest.api.management.v2.rest.model.analytics.engine.FilterSpec;
23+
import io.gravitee.rest.api.management.v2.rest.model.analytics.engine.FilterSpecsResponse;
24+
import io.gravitee.rest.api.management.v2.rest.model.analytics.engine.MetricSpec;
25+
import io.gravitee.rest.api.management.v2.rest.model.analytics.engine.MetricSpecsResponse;
26+
import java.util.List;
27+
import org.mapstruct.Mapper;
28+
import org.mapstruct.factory.Mappers;
29+
30+
@Mapper
31+
public interface AnalyticsDefinitionMapper {
32+
AnalyticsDefinitionMapper INSTANCE = Mappers.getMapper(AnalyticsDefinitionMapper.class);
33+
34+
ApiSpec mapApiSpec(io.gravitee.apim.core.analytics.model.engine.definition.ApiSpec apiSpec);
35+
36+
List<ApiSpec> mapApiSpecs(List<io.gravitee.apim.core.analytics.model.engine.definition.ApiSpec> apiSpecs);
37+
38+
default ApiSpecsResponse toApiSpecsResponse(List<io.gravitee.apim.core.analytics.model.engine.definition.ApiSpec> apiSpecs) {
39+
return new ApiSpecsResponse().data(mapApiSpecs(apiSpecs));
40+
}
41+
42+
MetricSpec mapMetricSpec(io.gravitee.apim.core.analytics.model.engine.definition.MetricSpec metricSpec);
43+
44+
List<MetricSpec> mapMetricSpecs(List<io.gravitee.apim.core.analytics.model.engine.definition.MetricSpec> metricSpecs);
45+
46+
default MetricSpecsResponse toMetricSpecsResponse(
47+
List<io.gravitee.apim.core.analytics.model.engine.definition.MetricSpec> metricSpecs
48+
) {
49+
return new MetricSpecsResponse().data(mapMetricSpecs(metricSpecs));
50+
}
51+
52+
FacetSpec mapFacetSpec(io.gravitee.apim.core.analytics.model.engine.definition.FacetSpec facetSpec);
53+
54+
List<FacetSpec> mapFacetSpecs(List<io.gravitee.apim.core.analytics.model.engine.definition.FacetSpec> facetSpecs);
55+
56+
default FacetSpecsResponse toFacetSpecsResponse(List<io.gravitee.apim.core.analytics.model.engine.definition.FacetSpec> facetSpecs) {
57+
return new FacetSpecsResponse().data(mapFacetSpecs(facetSpecs));
58+
}
59+
60+
FilterSpec mapFilterSpec(io.gravitee.apim.core.analytics.model.engine.definition.FilterSpec filterSpec);
61+
62+
List<FilterSpec> mapFilterSpecs(List<io.gravitee.apim.core.analytics.model.engine.definition.FilterSpec> filterSpecs);
63+
64+
default FilterSpecsResponse toFilterSpecsResponse(
65+
List<io.gravitee.apim.core.analytics.model.engine.definition.FilterSpec> filterSpecs
66+
) {
67+
return new FilterSpecsResponse().data(mapFilterSpecs(filterSpecs));
68+
}
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright © 2015 The Gravitee team (http://gravitee.io)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.gravitee.rest.api.management.v2.rest.resource.analytics.definition;
17+
18+
import io.gravitee.apim.core.analytics.use_case.engine.definition.GetApiMetricsUseCase;
19+
import io.gravitee.apim.core.analytics.use_case.engine.definition.GetApiSpecsUseCase;
20+
import io.gravitee.apim.core.analytics.use_case.engine.definition.GetMetricFacetsUseCase;
21+
import io.gravitee.apim.core.analytics.use_case.engine.definition.GetMetricFiltersUseCase;
22+
import io.gravitee.rest.api.management.v2.rest.mapper.AnalyticsDefinitionMapper;
23+
import io.gravitee.rest.api.management.v2.rest.model.analytics.engine.ApiSpecsResponse;
24+
import io.gravitee.rest.api.management.v2.rest.model.analytics.engine.FacetSpecsResponse;
25+
import io.gravitee.rest.api.management.v2.rest.model.analytics.engine.FilterSpecsResponse;
26+
import io.gravitee.rest.api.management.v2.rest.model.analytics.engine.MetricSpecsResponse;
27+
import io.gravitee.rest.api.model.permissions.RolePermission;
28+
import io.gravitee.rest.api.model.permissions.RolePermissionAction;
29+
import io.gravitee.rest.api.rest.annotation.Permission;
30+
import io.gravitee.rest.api.rest.annotation.Permissions;
31+
import jakarta.inject.Inject;
32+
import jakarta.ws.rs.GET;
33+
import jakarta.ws.rs.Path;
34+
import jakarta.ws.rs.PathParam;
35+
import jakarta.ws.rs.Produces;
36+
import jakarta.ws.rs.core.MediaType;
37+
38+
public class AnalyticsDefinitionResource {
39+
40+
@Inject
41+
GetApiSpecsUseCase getApiSpecsUseCase;
42+
43+
@Inject
44+
GetApiMetricsUseCase getApiMetricsUseCase;
45+
46+
@Inject
47+
GetMetricFacetsUseCase getMetricFacetsUseCase;
48+
49+
@Inject
50+
GetMetricFiltersUseCase getMetricFiltersUseCase;
51+
52+
@Path("/apis")
53+
@GET
54+
@Produces(MediaType.APPLICATION_JSON)
55+
@Permissions({ @Permission(value = RolePermission.API_ANALYTICS, acls = { RolePermissionAction.READ }) })
56+
public ApiSpecsResponse getApiSpecs() {
57+
return AnalyticsDefinitionMapper.INSTANCE.toApiSpecsResponse(getApiSpecsUseCase.execute().specs());
58+
}
59+
60+
@Path("/apis/{apiName}/metrics")
61+
@GET
62+
@Produces(MediaType.APPLICATION_JSON)
63+
@Permissions({ @Permission(value = RolePermission.API_ANALYTICS, acls = { RolePermissionAction.READ }) })
64+
public MetricSpecsResponse getApiMetrics(@PathParam("apiName") String apiName) {
65+
return AnalyticsDefinitionMapper.INSTANCE.toMetricSpecsResponse(
66+
getApiMetricsUseCase.execute(new GetApiMetricsUseCase.Input(apiName)).specs()
67+
);
68+
}
69+
70+
@Path("/metrics/{metricName}/facets")
71+
@GET
72+
@Produces(MediaType.APPLICATION_JSON)
73+
@Permissions({ @Permission(value = RolePermission.API_ANALYTICS, acls = { RolePermissionAction.READ }) })
74+
public FacetSpecsResponse getMetricFacets(@PathParam("metricName") String metricName) {
75+
return AnalyticsDefinitionMapper.INSTANCE.toFacetSpecsResponse(
76+
getMetricFacetsUseCase.execute(new GetMetricFacetsUseCase.Input(metricName)).specs()
77+
);
78+
}
79+
80+
@Path("/metrics/{metricName}/filters")
81+
@GET
82+
@Produces(MediaType.APPLICATION_JSON)
83+
@Permissions({ @Permission(value = RolePermission.API_ANALYTICS, acls = { RolePermissionAction.READ }) })
84+
public FilterSpecsResponse getMetricFilters(@PathParam("apiName") String apiName, @PathParam("metricName") String metricName) {
85+
return AnalyticsDefinitionMapper.INSTANCE.toFilterSpecsResponse(
86+
getMetricFiltersUseCase.execute(new GetMetricFiltersUseCase.Input(metricName)).specs()
87+
);
88+
}
89+
}

gravitee-apim-rest-api/gravitee-apim-rest-api-management-v2/gravitee-apim-rest-api-management-v2-rest/src/main/java/io/gravitee/rest/api/management/v2/rest/resource/environment/EnvironmentAnalyticsResource.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
import io.gravitee.rest.api.management.v2.rest.model.EnvironmentAnalyticsTopAppsByRequestCountResponse;
3333
import io.gravitee.rest.api.management.v2.rest.model.EnvironmentAnalyticsTopFailedApisResponse;
3434
import io.gravitee.rest.api.management.v2.rest.model.EnvironmentAnalyticsTopHitsApisResponse;
35+
import io.gravitee.rest.api.management.v2.rest.resource.analytics.definition.AnalyticsDefinitionResource;
3536
import io.gravitee.rest.api.management.v2.rest.resource.environment.param.TimeRangeParam;
37+
import io.gravitee.rest.api.management.v2.rest.resource.plugin.PoliciesResource;
3638
import io.gravitee.rest.api.model.permissions.RolePermission;
3739
import io.gravitee.rest.api.model.permissions.RolePermissionAction;
3840
import io.gravitee.rest.api.rest.annotation.Permission;
@@ -45,13 +47,18 @@
4547
import jakarta.ws.rs.Path;
4648
import jakarta.ws.rs.Produces;
4749
import jakarta.ws.rs.QueryParam;
50+
import jakarta.ws.rs.container.ResourceContext;
51+
import jakarta.ws.rs.core.Context;
4852
import jakarta.ws.rs.core.MediaType;
4953
import java.time.Duration;
5054
import java.time.Instant;
5155
import java.util.Map;
5256

5357
public class EnvironmentAnalyticsResource {
5458

59+
@Context
60+
private ResourceContext resourceContext;
61+
5562
@Inject
5663
SearchEnvironmentResponseStatusRangesUseCase searchEnvironmentResponseStatusRangesUseCase;
5764

@@ -193,4 +200,9 @@ public EnvironmentAnalyticsTopFailedApisResponse getTopFailedApis(@BeanParam @Va
193200

194201
return EnvironmentAnalyticsMapper.INSTANCE.map(topFailedApis);
195202
}
203+
204+
@Path("/definition")
205+
public AnalyticsDefinitionResource getAnalyticsDefinitionApisResource() {
206+
return resourceContext.getResource(AnalyticsDefinitionResource.class);
207+
}
196208
}

0 commit comments

Comments
 (0)