Showing
21 changed files
with
642 additions
and
1 deletions
common/dao-api/src/main/java/org/thingsboard/server/dao/usagerecord/UsageRecordService.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.dao.usagerecord; | |
17 | + | |
18 | +import org.thingsboard.server.common.data.UsageRecord; | |
19 | +import org.thingsboard.server.common.data.id.TenantId; | |
20 | + | |
21 | +public interface UsageRecordService { | |
22 | + | |
23 | + UsageRecord findTenantUsageRecord(TenantId tenantId); | |
24 | + | |
25 | + void deleteUsageRecordsByTenantId(TenantId tenantId); | |
26 | + | |
27 | + void createDefaultUsageRecord(TenantId id); | |
28 | +} | ... | ... |
... | ... | @@ -19,5 +19,5 @@ package org.thingsboard.server.common.data; |
19 | 19 | * @author Andrew Shvayka |
20 | 20 | */ |
21 | 21 | public enum EntityType { |
22 | - TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE, TENANT_PROFILE, DEVICE_PROFILE | |
22 | + TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE, TENANT_PROFILE, DEVICE_PROFILE, USAGE_RECORD; | |
23 | 23 | } | ... | ... |
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; | |
17 | + | |
18 | +import lombok.EqualsAndHashCode; | |
19 | +import lombok.ToString; | |
20 | +import org.thingsboard.server.common.data.id.EntityId; | |
21 | +import org.thingsboard.server.common.data.id.TenantId; | |
22 | +import org.thingsboard.server.common.data.id.UsageRecordId; | |
23 | +import org.thingsboard.server.common.data.id.UserId; | |
24 | + | |
25 | +@ToString | |
26 | +@EqualsAndHashCode(callSuper = true) | |
27 | +public class UsageRecord extends BaseData<UsageRecordId> implements HasTenantId { | |
28 | + | |
29 | + private static final long serialVersionUID = 8250339805336035966L; | |
30 | + | |
31 | + private TenantId tenantId; | |
32 | + private EntityId entityId; | |
33 | + | |
34 | + public UsageRecord() { | |
35 | + super(); | |
36 | + } | |
37 | + | |
38 | + public UsageRecord(UsageRecordId id) { | |
39 | + super(id); | |
40 | + } | |
41 | + | |
42 | + public UsageRecord(UsageRecord ur) { | |
43 | + super(ur); | |
44 | + this.tenantId = ur.getTenantId(); | |
45 | + this.entityId = ur.getEntityId(); | |
46 | + } | |
47 | + | |
48 | + @Override | |
49 | + public TenantId getTenantId() { | |
50 | + return tenantId; | |
51 | + } | |
52 | + | |
53 | + public void setTenantId(TenantId tenantId) { | |
54 | + this.tenantId = tenantId; | |
55 | + } | |
56 | + | |
57 | + public EntityId getEntityId() { | |
58 | + return entityId; | |
59 | + } | |
60 | + | |
61 | + public void setEntityId(EntityId entityId) { | |
62 | + this.entityId = entityId; | |
63 | + } | |
64 | + | |
65 | +} | ... | ... |
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; | |
17 | + | |
18 | +public enum UsageRecordKey { | |
19 | + | |
20 | + MSG_COUNT, | |
21 | + MSG_BYTES_COUNT, | |
22 | + DP_TRANSPORT_COUNT, | |
23 | + DP_STORAGE_COUNT, | |
24 | + RE_EXEC_COUNT, | |
25 | + JS_EXEC_COUNT | |
26 | + | |
27 | +} | ... | ... |
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.id; | |
17 | + | |
18 | +import com.fasterxml.jackson.annotation.JsonCreator; | |
19 | +import com.fasterxml.jackson.annotation.JsonIgnore; | |
20 | +import com.fasterxml.jackson.annotation.JsonProperty; | |
21 | +import org.thingsboard.server.common.data.EntityType; | |
22 | + | |
23 | +import java.util.UUID; | |
24 | + | |
25 | +public class UsageRecordId extends UUIDBased implements EntityId { | |
26 | + | |
27 | + @JsonCreator | |
28 | + public UsageRecordId(@JsonProperty("id") UUID id) { | |
29 | + super(id); | |
30 | + } | |
31 | + | |
32 | + public static UsageRecordId fromString(String userId) { | |
33 | + return new UsageRecordId(UUID.fromString(userId)); | |
34 | + } | |
35 | + | |
36 | + @JsonIgnore | |
37 | + @Override | |
38 | + public EntityType getEntityType() { | |
39 | + return EntityType.USAGE_RECORD; | |
40 | + } | |
41 | + | |
42 | +} | ... | ... |
... | ... | @@ -439,6 +439,14 @@ public class ModelConstants { |
439 | 439 | public static final String OAUTH2_TEMPLATE_HELP_LINK_PROPERTY = "help_link"; |
440 | 440 | |
441 | 441 | /** |
442 | + * Usage Record constants. | |
443 | + */ | |
444 | + public static final String UR_TABLE_NAME = "usage_record"; | |
445 | + public static final String UR_TENANT_ID_COLUMN = TENANT_ID_PROPERTY; | |
446 | + public static final String UR_ENTITY_TYPE_COLUMN = ENTITY_TYPE_COLUMN; | |
447 | + public static final String UR_ENTITY_ID_COLUMN = ENTITY_ID_COLUMN; | |
448 | + | |
449 | + /** | |
442 | 450 | * Cassandra attributes and timeseries constants. |
443 | 451 | */ |
444 | 452 | public static final String ATTRIBUTES_KV_CF = "attributes_kv_cf"; | ... | ... |
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.dao.model.sql; | |
17 | + | |
18 | +import com.fasterxml.jackson.databind.JsonNode; | |
19 | +import lombok.Data; | |
20 | +import lombok.EqualsAndHashCode; | |
21 | +import org.hibernate.annotations.Type; | |
22 | +import org.hibernate.annotations.TypeDef; | |
23 | +import org.thingsboard.server.common.data.UsageRecord; | |
24 | +import org.thingsboard.server.common.data.User; | |
25 | +import org.thingsboard.server.common.data.id.CustomerId; | |
26 | +import org.thingsboard.server.common.data.id.EntityIdFactory; | |
27 | +import org.thingsboard.server.common.data.id.TenantId; | |
28 | +import org.thingsboard.server.common.data.id.UsageRecordId; | |
29 | +import org.thingsboard.server.common.data.id.UserId; | |
30 | +import org.thingsboard.server.common.data.security.Authority; | |
31 | +import org.thingsboard.server.dao.model.BaseEntity; | |
32 | +import org.thingsboard.server.dao.model.BaseSqlEntity; | |
33 | +import org.thingsboard.server.dao.model.ModelConstants; | |
34 | +import org.thingsboard.server.dao.model.SearchTextEntity; | |
35 | +import org.thingsboard.server.dao.util.mapping.JsonStringType; | |
36 | + | |
37 | +import javax.persistence.Column; | |
38 | +import javax.persistence.Entity; | |
39 | +import javax.persistence.EnumType; | |
40 | +import javax.persistence.Enumerated; | |
41 | +import javax.persistence.Table; | |
42 | +import java.util.UUID; | |
43 | + | |
44 | +/** | |
45 | + * Created by Valerii Sosliuk on 4/21/2017. | |
46 | + */ | |
47 | +@Data | |
48 | +@EqualsAndHashCode(callSuper = true) | |
49 | +@Entity | |
50 | +@TypeDef(name = "json", typeClass = JsonStringType.class) | |
51 | +@Table(name = ModelConstants.UR_TABLE_NAME) | |
52 | +public class UsageRecordEntity extends BaseSqlEntity<UsageRecord> implements BaseEntity<UsageRecord> { | |
53 | + | |
54 | + @Column(name = ModelConstants.UR_TENANT_ID_COLUMN) | |
55 | + private UUID tenantId; | |
56 | + | |
57 | + @Column(name = ModelConstants.UR_ENTITY_TYPE_COLUMN) | |
58 | + private String entityType; | |
59 | + | |
60 | + @Column(name = ModelConstants.UR_ENTITY_ID_COLUMN) | |
61 | + private UUID entityId; | |
62 | + | |
63 | + public UsageRecordEntity() { | |
64 | + } | |
65 | + | |
66 | + public UsageRecordEntity(UsageRecord ur) { | |
67 | + if (ur.getId() != null) { | |
68 | + this.setUuid(ur.getId().getId()); | |
69 | + } | |
70 | + this.setCreatedTime(ur.getCreatedTime()); | |
71 | + if (ur.getTenantId() != null) { | |
72 | + this.tenantId = ur.getTenantId().getId(); | |
73 | + } | |
74 | + if (ur.getEntityId() != null) { | |
75 | + this.entityType = ur.getEntityId().getEntityType().name(); | |
76 | + this.entityId = ur.getEntityId().getId(); | |
77 | + } | |
78 | + } | |
79 | + | |
80 | + @Override | |
81 | + public UsageRecord toData() { | |
82 | + UsageRecord ur = new UsageRecord(new UsageRecordId(this.getUuid())); | |
83 | + ur.setCreatedTime(createdTime); | |
84 | + if (tenantId != null) { | |
85 | + ur.setTenantId(new TenantId(tenantId)); | |
86 | + } | |
87 | + if (entityId != null) { | |
88 | + ur.setEntityId(EntityIdFactory.getByTypeAndUuid(entityType, entityId)); | |
89 | + } | |
90 | + return ur; | |
91 | + } | |
92 | + | |
93 | +} | ... | ... |
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.dao.sql.usagerecord; | |
17 | + | |
18 | +import org.springframework.data.repository.CrudRepository; | |
19 | +import org.springframework.stereotype.Component; | |
20 | +import org.thingsboard.server.common.data.UsageRecord; | |
21 | +import org.thingsboard.server.common.data.id.TenantId; | |
22 | +import org.thingsboard.server.dao.DaoUtil; | |
23 | +import org.thingsboard.server.dao.model.sql.UsageRecordEntity; | |
24 | +import org.thingsboard.server.dao.sql.JpaAbstractDao; | |
25 | +import org.thingsboard.server.dao.usagerecord.UsageRecordDao; | |
26 | + | |
27 | +import java.util.UUID; | |
28 | + | |
29 | +/** | |
30 | + * @author Andrii Shvaika | |
31 | + */ | |
32 | +@Component | |
33 | +public class JpaUsageRecordDao extends JpaAbstractDao<UsageRecordEntity, UsageRecord> implements UsageRecordDao { | |
34 | + | |
35 | + private final UsageRecordRepository usageRecordRepository; | |
36 | + | |
37 | + public JpaUsageRecordDao(UsageRecordRepository usageRecordRepository) { | |
38 | + this.usageRecordRepository = usageRecordRepository; | |
39 | + } | |
40 | + | |
41 | + @Override | |
42 | + protected Class<UsageRecordEntity> getEntityClass() { | |
43 | + return UsageRecordEntity.class; | |
44 | + } | |
45 | + | |
46 | + @Override | |
47 | + protected CrudRepository<UsageRecordEntity, UUID> getCrudRepository() { | |
48 | + return usageRecordRepository; | |
49 | + } | |
50 | + | |
51 | + @Override | |
52 | + public UsageRecord findTenantUsageRecord(UUID tenantId) { | |
53 | + return DaoUtil.getData(usageRecordRepository.findByTenantId(tenantId)); | |
54 | + } | |
55 | + | |
56 | + @Override | |
57 | + public void deleteUsageRecordsByTenantId(TenantId tenantId) { | |
58 | + usageRecordRepository.deleteUsageRecordsByTenantId(tenantId.getId()); | |
59 | + } | |
60 | +} | ... | ... |
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.dao.sql.usagerecord; | |
17 | + | |
18 | +import org.springframework.data.jpa.repository.Modifying; | |
19 | +import org.springframework.data.jpa.repository.Query; | |
20 | +import org.springframework.data.repository.CrudRepository; | |
21 | +import org.springframework.data.repository.query.Param; | |
22 | +import org.springframework.transaction.annotation.Transactional; | |
23 | +import org.thingsboard.server.common.data.UsageRecord; | |
24 | +import org.thingsboard.server.common.data.id.TenantId; | |
25 | +import org.thingsboard.server.dao.model.sql.UsageRecordEntity; | |
26 | +import org.thingsboard.server.dao.model.sql.UserEntity; | |
27 | + | |
28 | +import java.util.UUID; | |
29 | + | |
30 | +/** | |
31 | + * @author Valerii Sosliuk | |
32 | + */ | |
33 | +public interface UsageRecordRepository extends CrudRepository<UsageRecordEntity, UUID> { | |
34 | + | |
35 | + @Query("SELECT ur FROM UsageRecordEntity ur WHERE ur.tenantId = :tenantId " + | |
36 | + "AND ur.entityId = :tenantId AND ur.entityType = 'TENANT' ") | |
37 | + UsageRecordEntity findByTenantId(@Param("tenantId") UUID tenantId); | |
38 | + | |
39 | + @Transactional | |
40 | + @Modifying | |
41 | + @Query("DELETE FROM UsageRecordEntity ur WHERE ur.tenantId = :tenantId") | |
42 | + void deleteUsageRecordsByTenantId(@Param("tenantId") UUID tenantId); | |
43 | +} | ... | ... |
... | ... | @@ -39,6 +39,7 @@ import org.thingsboard.server.dao.rule.RuleChainService; |
39 | 39 | import org.thingsboard.server.dao.service.DataValidator; |
40 | 40 | import org.thingsboard.server.dao.service.PaginatedRemover; |
41 | 41 | import org.thingsboard.server.dao.service.Validator; |
42 | +import org.thingsboard.server.dao.usagerecord.UsageRecordService; | |
42 | 43 | import org.thingsboard.server.dao.user.UserService; |
43 | 44 | import org.thingsboard.server.dao.widget.WidgetsBundleService; |
44 | 45 | |
... | ... | @@ -73,6 +74,9 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe |
73 | 74 | private DeviceProfileService deviceProfileService; |
74 | 75 | |
75 | 76 | @Autowired |
77 | + private UsageRecordService usageRecordService; | |
78 | + | |
79 | + @Autowired | |
76 | 80 | private EntityViewService entityViewService; |
77 | 81 | |
78 | 82 | @Autowired |
... | ... | @@ -117,6 +121,7 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe |
117 | 121 | Tenant savedTenant = tenantDao.save(tenant.getId(), tenant); |
118 | 122 | if (tenant.getId() == null) { |
119 | 123 | deviceProfileService.createDefaultDeviceProfile(savedTenant.getId()); |
124 | + usageRecordService.createDefaultUsageRecord(savedTenant.getId()); | |
120 | 125 | } |
121 | 126 | return savedTenant; |
122 | 127 | } |
... | ... | @@ -134,6 +139,7 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe |
134 | 139 | deviceProfileService.deleteDeviceProfilesByTenantId(tenantId); |
135 | 140 | userService.deleteTenantAdmins(tenantId); |
136 | 141 | ruleChainService.deleteRuleChainsByTenantId(tenantId); |
142 | + usageRecordService.deleteUsageRecordsByTenantId(tenantId); | |
137 | 143 | tenantDao.removeById(tenantId, tenantId.getId()); |
138 | 144 | deleteEntityRelations(tenantId, tenantId); |
139 | 145 | } | ... | ... |
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.dao.usagerecord; | |
17 | + | |
18 | +import org.thingsboard.server.common.data.UsageRecord; | |
19 | +import org.thingsboard.server.common.data.User; | |
20 | +import org.thingsboard.server.common.data.id.TenantId; | |
21 | +import org.thingsboard.server.common.data.page.PageData; | |
22 | +import org.thingsboard.server.common.data.page.PageLink; | |
23 | +import org.thingsboard.server.dao.Dao; | |
24 | + | |
25 | +import java.util.UUID; | |
26 | + | |
27 | +public interface UsageRecordDao extends Dao<UsageRecord> { | |
28 | + | |
29 | + /** | |
30 | + * Save or update usage record object | |
31 | + * | |
32 | + * @param usageRecord the usage record | |
33 | + * @return saved usage record entity | |
34 | + */ | |
35 | + UsageRecord save(TenantId tenantId, UsageRecord usageRecord); | |
36 | + | |
37 | + /** | |
38 | + * Find usage record by tenantId. | |
39 | + * | |
40 | + * @param tenantId the tenantId | |
41 | + * @return the corresponding usage record | |
42 | + */ | |
43 | + UsageRecord findTenantUsageRecord(UUID tenantId); | |
44 | + | |
45 | + /** | |
46 | + * Delete usage record by tenantId. | |
47 | + * | |
48 | + * @param tenantId the tenantId | |
49 | + */ | |
50 | + void deleteUsageRecordsByTenantId(TenantId tenantId); | |
51 | +} | ... | ... |
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.dao.usagerecord; | |
17 | + | |
18 | +import com.fasterxml.jackson.databind.JsonNode; | |
19 | +import com.fasterxml.jackson.databind.node.ObjectNode; | |
20 | +import com.google.common.util.concurrent.ListenableFuture; | |
21 | +import lombok.extern.slf4j.Slf4j; | |
22 | +import org.apache.commons.lang3.RandomStringUtils; | |
23 | +import org.springframework.beans.factory.annotation.Autowired; | |
24 | +import org.springframework.stereotype.Service; | |
25 | +import org.springframework.util.StringUtils; | |
26 | +import org.thingsboard.server.common.data.Customer; | |
27 | +import org.thingsboard.server.common.data.EntityType; | |
28 | +import org.thingsboard.server.common.data.Tenant; | |
29 | +import org.thingsboard.server.common.data.UsageRecord; | |
30 | +import org.thingsboard.server.common.data.User; | |
31 | +import org.thingsboard.server.common.data.id.CustomerId; | |
32 | +import org.thingsboard.server.common.data.id.TenantId; | |
33 | +import org.thingsboard.server.common.data.id.UserCredentialsId; | |
34 | +import org.thingsboard.server.common.data.id.UserId; | |
35 | +import org.thingsboard.server.common.data.page.PageData; | |
36 | +import org.thingsboard.server.common.data.page.PageLink; | |
37 | +import org.thingsboard.server.common.data.security.UserCredentials; | |
38 | +import org.thingsboard.server.dao.entity.AbstractEntityService; | |
39 | +import org.thingsboard.server.dao.exception.DataValidationException; | |
40 | +import org.thingsboard.server.dao.exception.IncorrectParameterException; | |
41 | +import org.thingsboard.server.dao.model.ModelConstants; | |
42 | +import org.thingsboard.server.dao.service.DataValidator; | |
43 | +import org.thingsboard.server.dao.tenant.TenantDao; | |
44 | + | |
45 | +import java.util.HashMap; | |
46 | +import java.util.Map; | |
47 | + | |
48 | +import static org.thingsboard.server.dao.service.Validator.validateId; | |
49 | +import static org.thingsboard.server.dao.service.Validator.validatePageLink; | |
50 | +import static org.thingsboard.server.dao.service.Validator.validateString; | |
51 | + | |
52 | +@Service | |
53 | +@Slf4j | |
54 | +public class UsageRecordServiceImpl extends AbstractEntityService implements UsageRecordService { | |
55 | + public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; | |
56 | + | |
57 | + private final UsageRecordDao usageRecordDao; | |
58 | + private final TenantDao tenantDao; | |
59 | + | |
60 | + public UsageRecordServiceImpl(TenantDao tenantDao, UsageRecordDao usageRecordDao) { | |
61 | + this.tenantDao = tenantDao; | |
62 | + this.usageRecordDao = usageRecordDao; | |
63 | + } | |
64 | + | |
65 | + @Override | |
66 | + public void deleteUsageRecordsByTenantId(TenantId tenantId) { | |
67 | + log.trace("Executing deleteUsageRecordsByTenantId [{}]", tenantId); | |
68 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | |
69 | + usageRecordDao.deleteUsageRecordsByTenantId(tenantId); | |
70 | + } | |
71 | + | |
72 | + @Override | |
73 | + public void createDefaultUsageRecord(TenantId tenantId) { | |
74 | + log.trace("Executing createDefaultUsageRecord [{}]", tenantId); | |
75 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | |
76 | + UsageRecord usageRecord = new UsageRecord(); | |
77 | + usageRecord.setTenantId(tenantId); | |
78 | + usageRecord.setEntityId(tenantId); | |
79 | + usageRecordValidator.validate(usageRecord, UsageRecord::getTenantId); | |
80 | + usageRecordDao.save(usageRecord.getTenantId(), usageRecord); | |
81 | + } | |
82 | + | |
83 | + @Override | |
84 | + public UsageRecord findTenantUsageRecord(TenantId tenantId) { | |
85 | + log.trace("Executing findTenantUsageRecord, tenantId [{}]", tenantId); | |
86 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | |
87 | + return usageRecordDao.findTenantUsageRecord(tenantId.getId()); | |
88 | + } | |
89 | + | |
90 | + private DataValidator<UsageRecord> usageRecordValidator = | |
91 | + new DataValidator<UsageRecord>() { | |
92 | + @Override | |
93 | + protected void validateDataImpl(TenantId requestTenantId, UsageRecord usageRecord) { | |
94 | + if (usageRecord.getTenantId() == null) { | |
95 | + throw new DataValidationException("UsageRecord should be assigned to tenant!"); | |
96 | + } else { | |
97 | + Tenant tenant = tenantDao.findById(requestTenantId, usageRecord.getTenantId().getId()); | |
98 | + if (tenant == null) { | |
99 | + throw new DataValidationException("Asset is referencing to non-existent tenant!"); | |
100 | + } | |
101 | + } | |
102 | + if (usageRecord.getEntityId() == null) { | |
103 | + throw new DataValidationException("UsageRecord should be assigned to entity!"); | |
104 | + } else if (!EntityType.TENANT.equals(usageRecord.getEntityId().getEntityType())) { | |
105 | + throw new DataValidationException("Only Tenant Usage Records are supported!"); | |
106 | + } else if (!usageRecord.getTenantId().getId().equals(usageRecord.getEntityId().getId())) { | |
107 | + throw new DataValidationException("Can't assign one Usage Record to multiple tenants!"); | |
108 | + } | |
109 | + } | |
110 | + }; | |
111 | + | |
112 | +} | ... | ... |
... | ... | @@ -404,3 +404,12 @@ CREATE TABLE IF NOT EXISTS oauth2_client_registration_template ( |
404 | 404 | help_link varchar(255), |
405 | 405 | CONSTRAINT oauth2_template_provider_id_unq_key UNIQUE (provider_id) |
406 | 406 | ); |
407 | + | |
408 | +CREATE TABLE IF NOT EXISTS usage_record ( | |
409 | + id uuid NOT NULL CONSTRAINT usage_record_pkey PRIMARY KEY, | |
410 | + created_time bigint NOT NULL, | |
411 | + tenant_id uuid, | |
412 | + entity_type varchar(32), | |
413 | + entity_id uuid, | |
414 | + CONSTRAINT usage_record_unq_key UNIQUE (tenant_id, entity_id) | |
415 | +); | ... | ... |
... | ... | @@ -431,6 +431,15 @@ CREATE TABLE IF NOT EXISTS oauth2_client_registration_template ( |
431 | 431 | CONSTRAINT oauth2_template_provider_id_unq_key UNIQUE (provider_id) |
432 | 432 | ); |
433 | 433 | |
434 | +CREATE TABLE IF NOT EXISTS usage_record ( | |
435 | + id uuid NOT NULL CONSTRAINT usage_record_pkey PRIMARY KEY, | |
436 | + created_time bigint NOT NULL, | |
437 | + tenant_id uuid, | |
438 | + entity_type varchar(32), | |
439 | + entity_id uuid, | |
440 | + CONSTRAINT usage_record_unq_key UNIQUE (tenant_id, entity_id) | |
441 | +); | |
442 | + | |
434 | 443 | CREATE OR REPLACE PROCEDURE cleanup_events_by_ttl(IN ttl bigint, IN debug_ttl bigint, INOUT deleted bigint) |
435 | 444 | LANGUAGE plpgsql AS |
436 | 445 | $$ | ... | ... |
... | ... | @@ -61,6 +61,7 @@ import org.thingsboard.server.dao.settings.AdminSettingsService; |
61 | 61 | import org.thingsboard.server.dao.tenant.TenantProfileService; |
62 | 62 | import org.thingsboard.server.dao.tenant.TenantService; |
63 | 63 | import org.thingsboard.server.dao.timeseries.TimeseriesService; |
64 | +import org.thingsboard.server.dao.usagerecord.UsageRecordService; | |
64 | 65 | import org.thingsboard.server.dao.user.UserService; |
65 | 66 | import org.thingsboard.server.dao.widget.WidgetTypeService; |
66 | 67 | import org.thingsboard.server.dao.widget.WidgetsBundleService; |
... | ... | @@ -86,6 +87,9 @@ public abstract class AbstractServiceTest { |
86 | 87 | protected UserService userService; |
87 | 88 | |
88 | 89 | @Autowired |
90 | + protected UsageRecordService usageRecordService; | |
91 | + | |
92 | + @Autowired | |
89 | 93 | protected AdminSettingsService adminSettingsService; |
90 | 94 | |
91 | 95 | @Autowired | ... | ... |
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.dao.service; | |
17 | + | |
18 | +import org.junit.After; | |
19 | +import org.junit.Assert; | |
20 | +import org.junit.Before; | |
21 | +import org.junit.Test; | |
22 | +import org.thingsboard.server.common.data.Customer; | |
23 | +import org.thingsboard.server.common.data.Tenant; | |
24 | +import org.thingsboard.server.common.data.UsageRecord; | |
25 | +import org.thingsboard.server.common.data.User; | |
26 | +import org.thingsboard.server.common.data.id.CustomerId; | |
27 | +import org.thingsboard.server.common.data.id.TenantId; | |
28 | +import org.thingsboard.server.dao.service.AbstractServiceTest; | |
29 | +import org.thingsboard.server.dao.service.DaoSqlTest; | |
30 | + | |
31 | + | |
32 | +public abstract class BaseUsageRecordServiceTest extends AbstractServiceTest { | |
33 | + | |
34 | + private TenantId tenantId; | |
35 | + | |
36 | + @Before | |
37 | + public void before() { | |
38 | + Tenant tenant = new Tenant(); | |
39 | + tenant.setTitle("My tenant"); | |
40 | + Tenant savedTenant = tenantService.saveTenant(tenant); | |
41 | + Assert.assertNotNull(savedTenant); | |
42 | + tenantId = savedTenant.getId(); | |
43 | + } | |
44 | + | |
45 | + @After | |
46 | + public void after() { | |
47 | + tenantService.deleteTenant(tenantId); | |
48 | + } | |
49 | + | |
50 | + @Test | |
51 | + public void testFindUsageRecordByTenantId() { | |
52 | + UsageRecord usageRecord = usageRecordService.findTenantUsageRecord(tenantId); | |
53 | + Assert.assertNotNull(usageRecord); | |
54 | + } | |
55 | + | |
56 | +} | ... | ... |
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.dao.service.sql; | |
17 | + | |
18 | +import org.thingsboard.server.dao.service.BaseUsageRecordServiceTest; | |
19 | +import org.thingsboard.server.dao.service.BaseUserServiceTest; | |
20 | +import org.thingsboard.server.dao.service.DaoSqlTest; | |
21 | + | |
22 | +@DaoSqlTest | |
23 | +public class UsageRecordServiceSqlTest extends BaseUsageRecordServiceTest { | |
24 | +} | ... | ... |
... | ... | @@ -27,4 +27,5 @@ DROP TABLE IF EXISTS rule_chain; |
27 | 27 | DROP TABLE IF EXISTS oauth2_client_registration; |
28 | 28 | DROP TABLE IF EXISTS oauth2_client_registration_info; |
29 | 29 | DROP TABLE IF EXISTS oauth2_client_registration_template; |
30 | +DROP TABLE IF EXISTS usage_record; | |
30 | 31 | DROP FUNCTION IF EXISTS to_uuid; | ... | ... |
... | ... | @@ -28,3 +28,4 @@ DROP TABLE IF EXISTS tb_schema_settings; |
28 | 28 | DROP TABLE IF EXISTS oauth2_client_registration; |
29 | 29 | DROP TABLE IF EXISTS oauth2_client_registration_info; |
30 | 30 | DROP TABLE IF EXISTS oauth2_client_registration_template; |
31 | +DROP TABLE IF EXISTS usage_record; | |
\ No newline at end of file | ... | ... |
... | ... | @@ -28,3 +28,4 @@ DROP TABLE IF EXISTS tb_schema_settings; |
28 | 28 | DROP TABLE IF EXISTS oauth2_client_registration; |
29 | 29 | DROP TABLE IF EXISTS oauth2_client_registration_info; |
30 | 30 | DROP TABLE IF EXISTS oauth2_client_registration_template; |
31 | +DROP TABLE IF EXISTS usage_record; | |
\ No newline at end of file | ... | ... |
... | ... | @@ -340,6 +340,7 @@ final class MqttClientImpl implements MqttClient { |
340 | 340 | MqttPublishVariableHeader variableHeader = new MqttPublishVariableHeader(topic, getNewMessageId().messageId()); |
341 | 341 | MqttPublishMessage message = new MqttPublishMessage(fixedHeader, variableHeader, payload); |
342 | 342 | MqttPendingPublish pendingPublish = new MqttPendingPublish(variableHeader.packetId(), future, payload.retain(), message, qos); |
343 | + | |
343 | 344 | ChannelFuture channelFuture = this.sendAndFlushPacket(message); |
344 | 345 | |
345 | 346 | if (channelFuture != null) { | ... | ... |