Showing
16 changed files
with
100 additions
and
9 deletions
application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java
@@ -62,7 +62,7 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { | @@ -62,7 +62,7 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { | ||
62 | @Value("${usage.stats.report.enabled:true}") | 62 | @Value("${usage.stats.report.enabled:true}") |
63 | private boolean enabled; | 63 | private boolean enabled; |
64 | 64 | ||
65 | - @Value("${usage.stats.check.cycle:60000}") | 65 | + @Value("${usage.stats.check.cycle:6000}") |
66 | private long nextCycleCheckInterval; | 66 | private long nextCycleCheckInterval; |
67 | 67 | ||
68 | private final Lock updateLock = new ReentrantLock(); | 68 | private final Lock updateLock = new ReentrantLock(); |
@@ -107,7 +107,7 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { | @@ -107,7 +107,7 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { | ||
107 | } finally { | 107 | } finally { |
108 | updateLock.unlock(); | 108 | updateLock.unlock(); |
109 | } | 109 | } |
110 | - tsService.save(tenantId, tenantState.getEntityId(), updatedEntries, 0L); | 110 | + tsService.save(tenantId, tenantState.getId(), updatedEntries, 0L); |
111 | } | 111 | } |
112 | 112 | ||
113 | @Override | 113 | @Override |
@@ -150,7 +150,7 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { | @@ -150,7 +150,7 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { | ||
150 | dbStateEntity = apiUsageStateService.findTenantApiUsageState(tenantId); | 150 | dbStateEntity = apiUsageStateService.findTenantApiUsageState(tenantId); |
151 | } | 151 | } |
152 | } | 152 | } |
153 | - tenantState = new TenantApiUsageState(dbStateEntity.getEntityId()); | 153 | + tenantState = new TenantApiUsageState(dbStateEntity.getId()); |
154 | try { | 154 | try { |
155 | List<TsKvEntry> dbValues = tsService.findAllLatest(tenantId, dbStateEntity.getEntityId()).get(); | 155 | List<TsKvEntry> dbValues = tsService.findAllLatest(tenantId, dbStateEntity.getEntityId()).get(); |
156 | for (ApiUsageRecordKey key : ApiUsageRecordKey.values()) { | 156 | for (ApiUsageRecordKey key : ApiUsageRecordKey.values()) { |
@@ -17,6 +17,7 @@ package org.thingsboard.server.service.apiusage; | @@ -17,6 +17,7 @@ package org.thingsboard.server.service.apiusage; | ||
17 | 17 | ||
18 | import lombok.Getter; | 18 | import lombok.Getter; |
19 | import org.thingsboard.server.common.data.ApiUsageRecordKey; | 19 | import org.thingsboard.server.common.data.ApiUsageRecordKey; |
20 | +import org.thingsboard.server.common.data.id.ApiUsageStateId; | ||
20 | import org.thingsboard.server.common.data.id.EntityId; | 21 | import org.thingsboard.server.common.data.id.EntityId; |
21 | import org.thingsboard.server.common.msg.tools.SchedulerUtils; | 22 | import org.thingsboard.server.common.msg.tools.SchedulerUtils; |
22 | 23 | ||
@@ -29,7 +30,7 @@ public class TenantApiUsageState { | @@ -29,7 +30,7 @@ public class TenantApiUsageState { | ||
29 | private final Map<ApiUsageRecordKey, Long> currentHourValues = new ConcurrentHashMap<>(); | 30 | private final Map<ApiUsageRecordKey, Long> currentHourValues = new ConcurrentHashMap<>(); |
30 | 31 | ||
31 | @Getter | 32 | @Getter |
32 | - private final EntityId entityId; | 33 | + private final ApiUsageStateId id; |
33 | @Getter | 34 | @Getter |
34 | private volatile long currentCycleTs; | 35 | private volatile long currentCycleTs; |
35 | @Getter | 36 | @Getter |
@@ -37,8 +38,8 @@ public class TenantApiUsageState { | @@ -37,8 +38,8 @@ public class TenantApiUsageState { | ||
37 | @Getter | 38 | @Getter |
38 | private volatile long currentHourTs; | 39 | private volatile long currentHourTs; |
39 | 40 | ||
40 | - public TenantApiUsageState(EntityId entityId) { | ||
41 | - this.entityId = entityId; | 41 | + public TenantApiUsageState(ApiUsageStateId id) { |
42 | + this.id = id; | ||
42 | this.currentCycleTs = SchedulerUtils.getStartOfCurrentMonth(); | 43 | this.currentCycleTs = SchedulerUtils.getStartOfCurrentMonth(); |
43 | this.nextCycleTs = SchedulerUtils.getStartOfNextMonth(); | 44 | this.nextCycleTs = SchedulerUtils.getStartOfNextMonth(); |
44 | this.currentHourTs = SchedulerUtils.getStartOfCurrentHour(); | 45 | this.currentHourTs = SchedulerUtils.getStartOfCurrentHour(); |
@@ -396,6 +396,9 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | @@ -396,6 +396,9 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore | ||
396 | if (mainConsumer != null) { | 396 | if (mainConsumer != null) { |
397 | mainConsumer.unsubscribe(); | 397 | mainConsumer.unsubscribe(); |
398 | } | 398 | } |
399 | + if (usageStatsConsumer != null) { | ||
400 | + usageStatsConsumer.unsubscribe(); | ||
401 | + } | ||
399 | } | 402 | } |
400 | 403 | ||
401 | } | 404 | } |
@@ -25,6 +25,7 @@ import org.springframework.http.ResponseEntity; | @@ -25,6 +25,7 @@ import org.springframework.http.ResponseEntity; | ||
25 | import org.springframework.stereotype.Component; | 25 | import org.springframework.stereotype.Component; |
26 | import org.springframework.web.context.request.async.DeferredResult; | 26 | import org.springframework.web.context.request.async.DeferredResult; |
27 | import org.thingsboard.common.util.ThingsBoardThreadFactory; | 27 | import org.thingsboard.common.util.ThingsBoardThreadFactory; |
28 | +import org.thingsboard.server.common.data.ApiUsageState; | ||
28 | import org.thingsboard.server.common.data.Customer; | 29 | import org.thingsboard.server.common.data.Customer; |
29 | import org.thingsboard.server.common.data.Device; | 30 | import org.thingsboard.server.common.data.Device; |
30 | import org.thingsboard.server.common.data.DeviceProfile; | 31 | import org.thingsboard.server.common.data.DeviceProfile; |
@@ -33,6 +34,7 @@ import org.thingsboard.server.common.data.Tenant; | @@ -33,6 +34,7 @@ import org.thingsboard.server.common.data.Tenant; | ||
33 | import org.thingsboard.server.common.data.User; | 34 | import org.thingsboard.server.common.data.User; |
34 | import org.thingsboard.server.common.data.asset.Asset; | 35 | import org.thingsboard.server.common.data.asset.Asset; |
35 | import org.thingsboard.server.common.data.exception.ThingsboardException; | 36 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
37 | +import org.thingsboard.server.common.data.id.ApiUsageStateId; | ||
36 | import org.thingsboard.server.common.data.id.AssetId; | 38 | import org.thingsboard.server.common.data.id.AssetId; |
37 | import org.thingsboard.server.common.data.id.CustomerId; | 39 | import org.thingsboard.server.common.data.id.CustomerId; |
38 | import org.thingsboard.server.common.data.id.DeviceId; | 40 | import org.thingsboard.server.common.data.id.DeviceId; |
@@ -55,6 +57,7 @@ import org.thingsboard.server.dao.device.DeviceService; | @@ -55,6 +57,7 @@ import org.thingsboard.server.dao.device.DeviceService; | ||
55 | import org.thingsboard.server.dao.entityview.EntityViewService; | 57 | import org.thingsboard.server.dao.entityview.EntityViewService; |
56 | import org.thingsboard.server.dao.rule.RuleChainService; | 58 | import org.thingsboard.server.dao.rule.RuleChainService; |
57 | import org.thingsboard.server.dao.tenant.TenantService; | 59 | import org.thingsboard.server.dao.tenant.TenantService; |
60 | +import org.thingsboard.server.dao.usagerecord.ApiUsageStateService; | ||
58 | import org.thingsboard.server.dao.user.UserService; | 61 | import org.thingsboard.server.dao.user.UserService; |
59 | import org.thingsboard.server.service.security.model.SecurityUser; | 62 | import org.thingsboard.server.service.security.model.SecurityUser; |
60 | import org.thingsboard.server.service.security.permission.AccessControlService; | 63 | import org.thingsboard.server.service.security.permission.AccessControlService; |
@@ -111,6 +114,9 @@ public class AccessValidator { | @@ -111,6 +114,9 @@ public class AccessValidator { | ||
111 | @Autowired | 114 | @Autowired |
112 | protected AccessControlService accessControlService; | 115 | protected AccessControlService accessControlService; |
113 | 116 | ||
117 | + @Autowired | ||
118 | + protected ApiUsageStateService apiUsageStateService; | ||
119 | + | ||
114 | private ExecutorService executor; | 120 | private ExecutorService executor; |
115 | 121 | ||
116 | @PostConstruct | 122 | @PostConstruct |
@@ -193,6 +199,9 @@ public class AccessValidator { | @@ -193,6 +199,9 @@ public class AccessValidator { | ||
193 | case ENTITY_VIEW: | 199 | case ENTITY_VIEW: |
194 | validateEntityView(currentUser, operation, entityId, callback); | 200 | validateEntityView(currentUser, operation, entityId, callback); |
195 | return; | 201 | return; |
202 | + case API_USAGE_STATE: | ||
203 | + validateApiUsageState(currentUser, operation, entityId, callback); | ||
204 | + return; | ||
196 | default: | 205 | default: |
197 | //TODO: add support of other entities | 206 | //TODO: add support of other entities |
198 | throw new IllegalStateException("Not Implemented!"); | 207 | throw new IllegalStateException("Not Implemented!"); |
@@ -237,6 +246,24 @@ public class AccessValidator { | @@ -237,6 +246,24 @@ public class AccessValidator { | ||
237 | } | 246 | } |
238 | } | 247 | } |
239 | 248 | ||
249 | + private void validateApiUsageState(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) { | ||
250 | + if (currentUser.isSystemAdmin()) { | ||
251 | + callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION)); | ||
252 | + } else { | ||
253 | + ApiUsageState apiUsageState = apiUsageStateService.findApiUsageStateById(currentUser.getTenantId(), new ApiUsageStateId(entityId.getId())); | ||
254 | + if (apiUsageState == null) { | ||
255 | + callback.onSuccess(ValidationResult.entityNotFound("Api Usage State with requested id wasn't found!")); | ||
256 | + } else { | ||
257 | + try { | ||
258 | + accessControlService.checkPermission(currentUser, Resource.API_USAGE_STATE, operation, entityId, apiUsageState); | ||
259 | + } catch (ThingsboardException e) { | ||
260 | + callback.onSuccess(ValidationResult.accessDenied(e.getMessage())); | ||
261 | + } | ||
262 | + callback.onSuccess(ValidationResult.ok(apiUsageState)); | ||
263 | + } | ||
264 | + } | ||
265 | + } | ||
266 | + | ||
240 | private void validateAsset(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) { | 267 | private void validateAsset(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) { |
241 | if (currentUser.isSystemAdmin()) { | 268 | if (currentUser.isSystemAdmin()) { |
242 | callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION)); | 269 | callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION)); |
@@ -35,7 +35,8 @@ public enum Resource { | @@ -35,7 +35,8 @@ public enum Resource { | ||
35 | OAUTH2_CONFIGURATION_INFO(), | 35 | OAUTH2_CONFIGURATION_INFO(), |
36 | OAUTH2_CONFIGURATION_TEMPLATE(), | 36 | OAUTH2_CONFIGURATION_TEMPLATE(), |
37 | TENANT_PROFILE(EntityType.TENANT_PROFILE), | 37 | TENANT_PROFILE(EntityType.TENANT_PROFILE), |
38 | - DEVICE_PROFILE(EntityType.DEVICE_PROFILE); | 38 | + DEVICE_PROFILE(EntityType.DEVICE_PROFILE), |
39 | + API_USAGE_STATE(EntityType.API_USAGE_STATE); | ||
39 | 40 | ||
40 | private final EntityType entityType; | 41 | private final EntityType entityType; |
41 | 42 |
@@ -40,6 +40,7 @@ public class TenantAdminPermissions extends AbstractPermissions { | @@ -40,6 +40,7 @@ public class TenantAdminPermissions extends AbstractPermissions { | ||
40 | put(Resource.WIDGETS_BUNDLE, widgetsPermissionChecker); | 40 | put(Resource.WIDGETS_BUNDLE, widgetsPermissionChecker); |
41 | put(Resource.WIDGET_TYPE, widgetsPermissionChecker); | 41 | put(Resource.WIDGET_TYPE, widgetsPermissionChecker); |
42 | put(Resource.DEVICE_PROFILE, tenantEntityPermissionChecker); | 42 | put(Resource.DEVICE_PROFILE, tenantEntityPermissionChecker); |
43 | + put(Resource.API_USAGE_STATE, tenantEntityPermissionChecker); | ||
43 | } | 44 | } |
44 | 45 | ||
45 | public static final PermissionChecker tenantEntityPermissionChecker = new PermissionChecker() { | 46 | public static final PermissionChecker tenantEntityPermissionChecker = new PermissionChecker() { |
@@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
16 | package org.thingsboard.server.dao.usagerecord; | 16 | package org.thingsboard.server.dao.usagerecord; |
17 | 17 | ||
18 | import org.thingsboard.server.common.data.ApiUsageState; | 18 | import org.thingsboard.server.common.data.ApiUsageState; |
19 | +import org.thingsboard.server.common.data.id.ApiUsageStateId; | ||
19 | import org.thingsboard.server.common.data.id.TenantId; | 20 | import org.thingsboard.server.common.data.id.TenantId; |
20 | 21 | ||
21 | public interface ApiUsageStateService { | 22 | public interface ApiUsageStateService { |
@@ -25,4 +26,6 @@ public interface ApiUsageStateService { | @@ -25,4 +26,6 @@ public interface ApiUsageStateService { | ||
25 | void deleteApiUsageStateByTenantId(TenantId tenantId); | 26 | void deleteApiUsageStateByTenantId(TenantId tenantId); |
26 | 27 | ||
27 | ApiUsageState createDefaultApiUsageState(TenantId id); | 28 | ApiUsageState createDefaultApiUsageState(TenantId id); |
29 | + | ||
30 | + ApiUsageState findApiUsageStateById(TenantId tenantId, ApiUsageStateId id); | ||
28 | } | 31 | } |
@@ -66,6 +66,8 @@ public class EntityIdFactory { | @@ -66,6 +66,8 @@ public class EntityIdFactory { | ||
66 | return new DeviceProfileId(uuid); | 66 | return new DeviceProfileId(uuid); |
67 | case TENANT_PROFILE: | 67 | case TENANT_PROFILE: |
68 | return new TenantProfileId(uuid); | 68 | return new TenantProfileId(uuid); |
69 | + case API_USAGE_STATE: | ||
70 | + return new ApiUsageStateId(uuid); | ||
69 | } | 71 | } |
70 | throw new IllegalArgumentException("EntityType " + type + " is not supported!"); | 72 | throw new IllegalArgumentException("EntityType " + type + " is not supported!"); |
71 | } | 73 | } |
common/data/src/main/java/org/thingsboard/server/common/data/query/ApiUsageStateFilter.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2020 The Thingsboard Authors | ||
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 org.thingsboard.server.common.data.query; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import org.thingsboard.server.common.data.id.EntityId; | ||
20 | + | ||
21 | +@Data | ||
22 | +public class ApiUsageStateFilter implements EntityFilter { | ||
23 | + @Override | ||
24 | + public EntityFilterType getType() { | ||
25 | + return EntityFilterType.API_USAGE_STATE; | ||
26 | + } | ||
27 | + | ||
28 | +} |
@@ -32,6 +32,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; | @@ -32,6 +32,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; | ||
32 | @JsonSubTypes.Type(value = AssetTypeFilter.class, name = "assetType"), | 32 | @JsonSubTypes.Type(value = AssetTypeFilter.class, name = "assetType"), |
33 | @JsonSubTypes.Type(value = DeviceTypeFilter.class, name = "deviceType"), | 33 | @JsonSubTypes.Type(value = DeviceTypeFilter.class, name = "deviceType"), |
34 | @JsonSubTypes.Type(value = EntityViewTypeFilter.class, name = "entityViewType"), | 34 | @JsonSubTypes.Type(value = EntityViewTypeFilter.class, name = "entityViewType"), |
35 | + @JsonSubTypes.Type(value = ApiUsageStateFilter.class, name = "apiUsageState"), | ||
35 | @JsonSubTypes.Type(value = RelationsQueryFilter.class, name = "relationsQuery"), | 36 | @JsonSubTypes.Type(value = RelationsQueryFilter.class, name = "relationsQuery"), |
36 | @JsonSubTypes.Type(value = AssetSearchQueryFilter.class, name = "assetSearchQuery"), | 37 | @JsonSubTypes.Type(value = AssetSearchQueryFilter.class, name = "assetSearchQuery"), |
37 | @JsonSubTypes.Type(value = DeviceSearchQueryFilter.class, name = "deviceSearchQuery"), | 38 | @JsonSubTypes.Type(value = DeviceSearchQueryFilter.class, name = "deviceSearchQuery"), |
@@ -25,7 +25,8 @@ public enum EntityFilterType { | @@ -25,7 +25,8 @@ public enum EntityFilterType { | ||
25 | RELATIONS_QUERY("relationsQuery"), | 25 | RELATIONS_QUERY("relationsQuery"), |
26 | ASSET_SEARCH_QUERY("assetSearchQuery"), | 26 | ASSET_SEARCH_QUERY("assetSearchQuery"), |
27 | DEVICE_SEARCH_QUERY("deviceSearchQuery"), | 27 | DEVICE_SEARCH_QUERY("deviceSearchQuery"), |
28 | - ENTITY_VIEW_SEARCH_QUERY("entityViewSearchQuery"); | 28 | + ENTITY_VIEW_SEARCH_QUERY("entityViewSearchQuery"), |
29 | + API_USAGE_STATE("apiUsageState"); | ||
29 | 30 | ||
30 | private final String label; | 31 | private final String label; |
31 | 32 |
@@ -210,6 +210,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -210,6 +210,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
210 | entityTableMap.put(EntityType.CUSTOMER, "customer"); | 210 | entityTableMap.put(EntityType.CUSTOMER, "customer"); |
211 | entityTableMap.put(EntityType.USER, "tb_user"); | 211 | entityTableMap.put(EntityType.USER, "tb_user"); |
212 | entityTableMap.put(EntityType.TENANT, "tenant"); | 212 | entityTableMap.put(EntityType.TENANT, "tenant"); |
213 | + entityTableMap.put(EntityType.API_USAGE_STATE, "(select aus.id, aus.created_time, aus.tenant_id, '' as name, '' as additional_info from api_usage_state as aus)"); | ||
213 | } | 214 | } |
214 | 215 | ||
215 | public static EntityType[] RELATION_QUERY_ENTITY_TYPES = new EntityType[]{ | 216 | public static EntityType[] RELATION_QUERY_ENTITY_TYPES = new EntityType[]{ |
@@ -431,6 +432,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -431,6 +432,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
431 | case DEVICE_SEARCH_QUERY: | 432 | case DEVICE_SEARCH_QUERY: |
432 | case ASSET_SEARCH_QUERY: | 433 | case ASSET_SEARCH_QUERY: |
433 | case ENTITY_VIEW_SEARCH_QUERY: | 434 | case ENTITY_VIEW_SEARCH_QUERY: |
435 | + case API_USAGE_STATE: | ||
434 | return ""; | 436 | return ""; |
435 | default: | 437 | default: |
436 | throw new RuntimeException("Not implemented!"); | 438 | throw new RuntimeException("Not implemented!"); |
@@ -682,6 +684,8 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | @@ -682,6 +684,8 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { | ||
682 | return EntityType.ENTITY_VIEW; | 684 | return EntityType.ENTITY_VIEW; |
683 | case RELATIONS_QUERY: | 685 | case RELATIONS_QUERY: |
684 | return ((RelationsQueryFilter) entityFilter).getRootEntity().getEntityType(); | 686 | return ((RelationsQueryFilter) entityFilter).getRootEntity().getEntityType(); |
687 | + case API_USAGE_STATE: | ||
688 | + return EntityType.API_USAGE_STATE; | ||
685 | default: | 689 | default: |
686 | throw new RuntimeException("Not implemented!"); | 690 | throw new RuntimeException("Not implemented!"); |
687 | } | 691 | } |
@@ -20,6 +20,7 @@ import org.springframework.stereotype.Service; | @@ -20,6 +20,7 @@ import org.springframework.stereotype.Service; | ||
20 | import org.thingsboard.server.common.data.EntityType; | 20 | import org.thingsboard.server.common.data.EntityType; |
21 | import org.thingsboard.server.common.data.Tenant; | 21 | import org.thingsboard.server.common.data.Tenant; |
22 | import org.thingsboard.server.common.data.ApiUsageState; | 22 | import org.thingsboard.server.common.data.ApiUsageState; |
23 | +import org.thingsboard.server.common.data.id.ApiUsageStateId; | ||
23 | import org.thingsboard.server.common.data.id.TenantId; | 24 | import org.thingsboard.server.common.data.id.TenantId; |
24 | import org.thingsboard.server.dao.entity.AbstractEntityService; | 25 | import org.thingsboard.server.dao.entity.AbstractEntityService; |
25 | import org.thingsboard.server.dao.exception.DataValidationException; | 26 | import org.thingsboard.server.dao.exception.DataValidationException; |
@@ -66,6 +67,13 @@ public class ApiApiUsageStateServiceImpl extends AbstractEntityService implement | @@ -66,6 +67,13 @@ public class ApiApiUsageStateServiceImpl extends AbstractEntityService implement | ||
66 | return apiUsageStateDao.findTenantApiUsageState(tenantId.getId()); | 67 | return apiUsageStateDao.findTenantApiUsageState(tenantId.getId()); |
67 | } | 68 | } |
68 | 69 | ||
70 | + @Override | ||
71 | + public ApiUsageState findApiUsageStateById(TenantId tenantId, ApiUsageStateId id) { | ||
72 | + log.trace("Executing findApiUsageStateById, tenantId [{}], apiUsageStateId [{}]", tenantId, id); | ||
73 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
74 | + validateId(id, "Incorrect apiUsageStateId " + id); | ||
75 | + return apiUsageStateDao.findById(tenantId, id.getId()); } | ||
76 | + | ||
69 | private DataValidator<ApiUsageState> apiUsageStateValidator = | 77 | private DataValidator<ApiUsageState> apiUsageStateValidator = |
70 | new DataValidator<ApiUsageState>() { | 78 | new DataValidator<ApiUsageState>() { |
71 | @Override | 79 | @Override |
@@ -753,6 +753,9 @@ export class EntityService { | @@ -753,6 +753,9 @@ export class EntityService { | ||
753 | case AliasFilterType.entityViewType: | 753 | case AliasFilterType.entityViewType: |
754 | result.entityFilter = deepClone(filter); | 754 | result.entityFilter = deepClone(filter); |
755 | return of(result); | 755 | return of(result); |
756 | + case AliasFilterType.apiUsageState: | ||
757 | + result.entityFilter = deepClone(filter); | ||
758 | + return of(result); | ||
756 | case AliasFilterType.relationsQuery: | 759 | case AliasFilterType.relationsQuery: |
757 | result.stateEntity = filter.rootStateEntity; | 760 | result.stateEntity = filter.rootStateEntity; |
758 | let rootEntityType; | 761 | let rootEntityType; |
@@ -28,6 +28,7 @@ export enum AliasFilterType { | @@ -28,6 +28,7 @@ export enum AliasFilterType { | ||
28 | assetType = 'assetType', | 28 | assetType = 'assetType', |
29 | deviceType = 'deviceType', | 29 | deviceType = 'deviceType', |
30 | entityViewType = 'entityViewType', | 30 | entityViewType = 'entityViewType', |
31 | + apiUsageState = 'apiUsageState', | ||
31 | relationsQuery = 'relationsQuery', | 32 | relationsQuery = 'relationsQuery', |
32 | assetSearchQuery = 'assetSearchQuery', | 33 | assetSearchQuery = 'assetSearchQuery', |
33 | deviceSearchQuery = 'deviceSearchQuery', | 34 | deviceSearchQuery = 'deviceSearchQuery', |
@@ -43,6 +44,7 @@ export const aliasFilterTypeTranslationMap = new Map<AliasFilterType, string>( | @@ -43,6 +44,7 @@ export const aliasFilterTypeTranslationMap = new Map<AliasFilterType, string>( | ||
43 | [ AliasFilterType.assetType, 'alias.filter-type-asset-type' ], | 44 | [ AliasFilterType.assetType, 'alias.filter-type-asset-type' ], |
44 | [ AliasFilterType.deviceType, 'alias.filter-type-device-type' ], | 45 | [ AliasFilterType.deviceType, 'alias.filter-type-device-type' ], |
45 | [ AliasFilterType.entityViewType, 'alias.filter-type-entity-view-type' ], | 46 | [ AliasFilterType.entityViewType, 'alias.filter-type-entity-view-type' ], |
47 | + [ AliasFilterType.apiUsageState, 'alias.filter-type-apiUsageState' ], | ||
46 | [ AliasFilterType.relationsQuery, 'alias.filter-type-relations-query' ], | 48 | [ AliasFilterType.relationsQuery, 'alias.filter-type-relations-query' ], |
47 | [ AliasFilterType.assetSearchQuery, 'alias.filter-type-asset-search-query' ], | 49 | [ AliasFilterType.assetSearchQuery, 'alias.filter-type-asset-search-query' ], |
48 | [ AliasFilterType.deviceSearchQuery, 'alias.filter-type-device-search-query' ], | 50 | [ AliasFilterType.deviceSearchQuery, 'alias.filter-type-device-search-query' ], |
@@ -106,6 +108,10 @@ export interface EntitySearchQueryFilter { | @@ -106,6 +108,10 @@ export interface EntitySearchQueryFilter { | ||
106 | fetchLastLevelOnly?: boolean; | 108 | fetchLastLevelOnly?: boolean; |
107 | } | 109 | } |
108 | 110 | ||
111 | +export interface ApiUsageStateFilter { | ||
112 | + | ||
113 | +} | ||
114 | + | ||
109 | export interface AssetSearchQueryFilter extends EntitySearchQueryFilter { | 115 | export interface AssetSearchQueryFilter extends EntitySearchQueryFilter { |
110 | assetTypes?: string[]; | 116 | assetTypes?: string[]; |
111 | } | 117 | } |
@@ -129,7 +135,8 @@ export type EntityFilters = | @@ -129,7 +135,8 @@ export type EntityFilters = | ||
129 | RelationsQueryFilter & | 135 | RelationsQueryFilter & |
130 | AssetSearchQueryFilter & | 136 | AssetSearchQueryFilter & |
131 | DeviceSearchQueryFilter & | 137 | DeviceSearchQueryFilter & |
132 | - EntityViewSearchQueryFilter; | 138 | + EntityViewSearchQueryFilter & |
139 | + EntitySearchQueryFilter; | ||
133 | 140 | ||
134 | export interface EntityAliasFilter extends EntityFilters { | 141 | export interface EntityAliasFilter extends EntityFilters { |
135 | type?: AliasFilterType; | 142 | type?: AliasFilterType; |
@@ -288,6 +288,7 @@ | @@ -288,6 +288,7 @@ | ||
288 | "filter-type-device-search-query-description": "Devices with types {{deviceTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", | 288 | "filter-type-device-search-query-description": "Devices with types {{deviceTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", |
289 | "filter-type-entity-view-search-query": "Entity view search query", | 289 | "filter-type-entity-view-search-query": "Entity view search query", |
290 | "filter-type-entity-view-search-query-description": "Entity views with types {{entityViewTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", | 290 | "filter-type-entity-view-search-query-description": "Entity views with types {{entityViewTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", |
291 | + "filter-type-apiUsageState": "Api Usage State", | ||
291 | "entity-filter": "Entity filter", | 292 | "entity-filter": "Entity filter", |
292 | "resolve-multiple": "Resolve as multiple entities", | 293 | "resolve-multiple": "Resolve as multiple entities", |
293 | "filter-type": "Filter type", | 294 | "filter-type": "Filter type", |