Browse Source

created alias ApiUsageState

pull/3615/head
YevhenBondarenko 6 years ago
parent
commit
7e88376030
  1. 6
      application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java
  2. 7
      application/src/main/java/org/thingsboard/server/service/apiusage/TenantApiUsageState.java
  3. 3
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java
  4. 27
      application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java
  5. 3
      application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java
  6. 1
      application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java
  7. 3
      common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java
  8. 2
      common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java
  9. 28
      common/data/src/main/java/org/thingsboard/server/common/data/query/ApiUsageStateFilter.java
  10. 1
      common/data/src/main/java/org/thingsboard/server/common/data/query/EntityFilter.java
  11. 3
      common/data/src/main/java/org/thingsboard/server/common/data/query/EntityFilterType.java
  12. 4
      dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java
  13. 8
      dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiApiUsageStateServiceImpl.java
  14. 3
      ui-ngx/src/app/core/http/entity.service.ts
  15. 9
      ui-ngx/src/app/shared/models/alias.models.ts
  16. 1
      ui-ngx/src/assets/locale/locale.constant-en_US.json

6
application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java

@ -62,7 +62,7 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService {
@Value("${usage.stats.report.enabled:true}")
private boolean enabled;
@Value("${usage.stats.check.cycle:60000}")
@Value("${usage.stats.check.cycle:6000}")
private long nextCycleCheckInterval;
private final Lock updateLock = new ReentrantLock();
@ -107,7 +107,7 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService {
} finally {
updateLock.unlock();
}
tsService.save(tenantId, tenantState.getEntityId(), updatedEntries, 0L);
tsService.save(tenantId, tenantState.getId(), updatedEntries, 0L);
}
@Override
@ -150,7 +150,7 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService {
dbStateEntity = apiUsageStateService.findTenantApiUsageState(tenantId);
}
}
tenantState = new TenantApiUsageState(dbStateEntity.getEntityId());
tenantState = new TenantApiUsageState(dbStateEntity.getId());
try {
List<TsKvEntry> dbValues = tsService.findAllLatest(tenantId, dbStateEntity.getEntityId()).get();
for (ApiUsageRecordKey key : ApiUsageRecordKey.values()) {

7
application/src/main/java/org/thingsboard/server/service/apiusage/TenantApiUsageState.java

@ -17,6 +17,7 @@ package org.thingsboard.server.service.apiusage;
import lombok.Getter;
import org.thingsboard.server.common.data.ApiUsageRecordKey;
import org.thingsboard.server.common.data.id.ApiUsageStateId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.msg.tools.SchedulerUtils;
@ -29,7 +30,7 @@ public class TenantApiUsageState {
private final Map<ApiUsageRecordKey, Long> currentHourValues = new ConcurrentHashMap<>();
@Getter
private final EntityId entityId;
private final ApiUsageStateId id;
@Getter
private volatile long currentCycleTs;
@Getter
@ -37,8 +38,8 @@ public class TenantApiUsageState {
@Getter
private volatile long currentHourTs;
public TenantApiUsageState(EntityId entityId) {
this.entityId = entityId;
public TenantApiUsageState(ApiUsageStateId id) {
this.id = id;
this.currentCycleTs = SchedulerUtils.getStartOfCurrentMonth();
this.nextCycleTs = SchedulerUtils.getStartOfNextMonth();
this.currentHourTs = SchedulerUtils.getStartOfCurrentHour();

3
application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java

@ -396,6 +396,9 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
if (mainConsumer != null) {
mainConsumer.unsubscribe();
}
if (usageStatsConsumer != null) {
usageStatsConsumer.unsubscribe();
}
}
}

27
application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java

@ -25,6 +25,7 @@ import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.async.DeferredResult;
import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.common.data.ApiUsageState;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
@ -33,6 +34,7 @@ import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.ApiUsageStateId;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
@ -55,6 +57,7 @@ import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.usagerecord.ApiUsageStateService;
import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.permission.AccessControlService;
@ -111,6 +114,9 @@ public class AccessValidator {
@Autowired
protected AccessControlService accessControlService;
@Autowired
protected ApiUsageStateService apiUsageStateService;
private ExecutorService executor;
@PostConstruct
@ -193,6 +199,9 @@ public class AccessValidator {
case ENTITY_VIEW:
validateEntityView(currentUser, operation, entityId, callback);
return;
case API_USAGE_STATE:
validateApiUsageState(currentUser, operation, entityId, callback);
return;
default:
//TODO: add support of other entities
throw new IllegalStateException("Not Implemented!");
@ -237,6 +246,24 @@ public class AccessValidator {
}
}
private void validateApiUsageState(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) {
if (currentUser.isSystemAdmin()) {
callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else {
ApiUsageState apiUsageState = apiUsageStateService.findApiUsageStateById(currentUser.getTenantId(), new ApiUsageStateId(entityId.getId()));
if (apiUsageState == null) {
callback.onSuccess(ValidationResult.entityNotFound("Api Usage State with requested id wasn't found!"));
} else {
try {
accessControlService.checkPermission(currentUser, Resource.API_USAGE_STATE, operation, entityId, apiUsageState);
} catch (ThingsboardException e) {
callback.onSuccess(ValidationResult.accessDenied(e.getMessage()));
}
callback.onSuccess(ValidationResult.ok(apiUsageState));
}
}
}
private void validateAsset(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) {
if (currentUser.isSystemAdmin()) {
callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));

3
application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java

@ -35,7 +35,8 @@ public enum Resource {
OAUTH2_CONFIGURATION_INFO(),
OAUTH2_CONFIGURATION_TEMPLATE(),
TENANT_PROFILE(EntityType.TENANT_PROFILE),
DEVICE_PROFILE(EntityType.DEVICE_PROFILE);
DEVICE_PROFILE(EntityType.DEVICE_PROFILE),
API_USAGE_STATE(EntityType.API_USAGE_STATE);
private final EntityType entityType;

1
application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java

@ -40,6 +40,7 @@ public class TenantAdminPermissions extends AbstractPermissions {
put(Resource.WIDGETS_BUNDLE, widgetsPermissionChecker);
put(Resource.WIDGET_TYPE, widgetsPermissionChecker);
put(Resource.DEVICE_PROFILE, tenantEntityPermissionChecker);
put(Resource.API_USAGE_STATE, tenantEntityPermissionChecker);
}
public static final PermissionChecker tenantEntityPermissionChecker = new PermissionChecker() {

3
common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/ApiUsageStateService.java

@ -16,6 +16,7 @@
package org.thingsboard.server.dao.usagerecord;
import org.thingsboard.server.common.data.ApiUsageState;
import org.thingsboard.server.common.data.id.ApiUsageStateId;
import org.thingsboard.server.common.data.id.TenantId;
public interface ApiUsageStateService {
@ -25,4 +26,6 @@ public interface ApiUsageStateService {
void deleteApiUsageStateByTenantId(TenantId tenantId);
ApiUsageState createDefaultApiUsageState(TenantId id);
ApiUsageState findApiUsageStateById(TenantId tenantId, ApiUsageStateId id);
}

2
common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java

@ -66,6 +66,8 @@ public class EntityIdFactory {
return new DeviceProfileId(uuid);
case TENANT_PROFILE:
return new TenantProfileId(uuid);
case API_USAGE_STATE:
return new ApiUsageStateId(uuid);
}
throw new IllegalArgumentException("EntityType " + type + " is not supported!");
}

28
common/data/src/main/java/org/thingsboard/server/common/data/query/ApiUsageStateFilter.java

@ -0,0 +1,28 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.query;
import lombok.Data;
import org.thingsboard.server.common.data.id.EntityId;
@Data
public class ApiUsageStateFilter implements EntityFilter {
@Override
public EntityFilterType getType() {
return EntityFilterType.API_USAGE_STATE;
}
}

1
common/data/src/main/java/org/thingsboard/server/common/data/query/EntityFilter.java

@ -32,6 +32,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonSubTypes.Type(value = AssetTypeFilter.class, name = "assetType"),
@JsonSubTypes.Type(value = DeviceTypeFilter.class, name = "deviceType"),
@JsonSubTypes.Type(value = EntityViewTypeFilter.class, name = "entityViewType"),
@JsonSubTypes.Type(value = ApiUsageStateFilter.class, name = "apiUsageState"),
@JsonSubTypes.Type(value = RelationsQueryFilter.class, name = "relationsQuery"),
@JsonSubTypes.Type(value = AssetSearchQueryFilter.class, name = "assetSearchQuery"),
@JsonSubTypes.Type(value = DeviceSearchQueryFilter.class, name = "deviceSearchQuery"),

3
common/data/src/main/java/org/thingsboard/server/common/data/query/EntityFilterType.java

@ -25,7 +25,8 @@ public enum EntityFilterType {
RELATIONS_QUERY("relationsQuery"),
ASSET_SEARCH_QUERY("assetSearchQuery"),
DEVICE_SEARCH_QUERY("deviceSearchQuery"),
ENTITY_VIEW_SEARCH_QUERY("entityViewSearchQuery");
ENTITY_VIEW_SEARCH_QUERY("entityViewSearchQuery"),
API_USAGE_STATE("apiUsageState");
private final String label;

4
dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java

@ -210,6 +210,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
entityTableMap.put(EntityType.CUSTOMER, "customer");
entityTableMap.put(EntityType.USER, "tb_user");
entityTableMap.put(EntityType.TENANT, "tenant");
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)");
}
public static EntityType[] RELATION_QUERY_ENTITY_TYPES = new EntityType[]{
@ -431,6 +432,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
case DEVICE_SEARCH_QUERY:
case ASSET_SEARCH_QUERY:
case ENTITY_VIEW_SEARCH_QUERY:
case API_USAGE_STATE:
return "";
default:
throw new RuntimeException("Not implemented!");
@ -682,6 +684,8 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
return EntityType.ENTITY_VIEW;
case RELATIONS_QUERY:
return ((RelationsQueryFilter) entityFilter).getRootEntity().getEntityType();
case API_USAGE_STATE:
return EntityType.API_USAGE_STATE;
default:
throw new RuntimeException("Not implemented!");
}

8
dao/src/main/java/org/thingsboard/server/dao/usagerecord/ApiApiUsageStateServiceImpl.java

@ -20,6 +20,7 @@ import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.ApiUsageState;
import org.thingsboard.server.common.data.id.ApiUsageStateId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.exception.DataValidationException;
@ -66,6 +67,13 @@ public class ApiApiUsageStateServiceImpl extends AbstractEntityService implement
return apiUsageStateDao.findTenantApiUsageState(tenantId.getId());
}
@Override
public ApiUsageState findApiUsageStateById(TenantId tenantId, ApiUsageStateId id) {
log.trace("Executing findApiUsageStateById, tenantId [{}], apiUsageStateId [{}]", tenantId, id);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validateId(id, "Incorrect apiUsageStateId " + id);
return apiUsageStateDao.findById(tenantId, id.getId()); }
private DataValidator<ApiUsageState> apiUsageStateValidator =
new DataValidator<ApiUsageState>() {
@Override

3
ui-ngx/src/app/core/http/entity.service.ts

@ -753,6 +753,9 @@ export class EntityService {
case AliasFilterType.entityViewType:
result.entityFilter = deepClone(filter);
return of(result);
case AliasFilterType.apiUsageState:
result.entityFilter = deepClone(filter);
return of(result);
case AliasFilterType.relationsQuery:
result.stateEntity = filter.rootStateEntity;
let rootEntityType;

9
ui-ngx/src/app/shared/models/alias.models.ts

@ -28,6 +28,7 @@ export enum AliasFilterType {
assetType = 'assetType',
deviceType = 'deviceType',
entityViewType = 'entityViewType',
apiUsageState = 'apiUsageState',
relationsQuery = 'relationsQuery',
assetSearchQuery = 'assetSearchQuery',
deviceSearchQuery = 'deviceSearchQuery',
@ -43,6 +44,7 @@ export const aliasFilterTypeTranslationMap = new Map<AliasFilterType, string>(
[ AliasFilterType.assetType, 'alias.filter-type-asset-type' ],
[ AliasFilterType.deviceType, 'alias.filter-type-device-type' ],
[ AliasFilterType.entityViewType, 'alias.filter-type-entity-view-type' ],
[ AliasFilterType.apiUsageState, 'alias.filter-type-apiUsageState' ],
[ AliasFilterType.relationsQuery, 'alias.filter-type-relations-query' ],
[ AliasFilterType.assetSearchQuery, 'alias.filter-type-asset-search-query' ],
[ AliasFilterType.deviceSearchQuery, 'alias.filter-type-device-search-query' ],
@ -106,6 +108,10 @@ export interface EntitySearchQueryFilter {
fetchLastLevelOnly?: boolean;
}
export interface ApiUsageStateFilter {
}
export interface AssetSearchQueryFilter extends EntitySearchQueryFilter {
assetTypes?: string[];
}
@ -129,7 +135,8 @@ export type EntityFilters =
RelationsQueryFilter &
AssetSearchQueryFilter &
DeviceSearchQueryFilter &
EntityViewSearchQueryFilter;
EntityViewSearchQueryFilter &
EntitySearchQueryFilter;
export interface EntityAliasFilter extends EntityFilters {
type?: AliasFilterType;

1
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -288,6 +288,7 @@
"filter-type-device-search-query-description": "Devices with types {{deviceTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}",
"filter-type-entity-view-search-query": "Entity view search query",
"filter-type-entity-view-search-query-description": "Entity views with types {{entityViewTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}",
"filter-type-apiUsageState": "Api Usage State",
"entity-filter": "Entity filter",
"resolve-multiple": "Resolve as multiple entities",
"filter-type": "Filter type",

Loading…
Cancel
Save