6 changed files with 331 additions and 0 deletions
@ -0,0 +1,45 @@ |
|||
/** |
|||
* Copyright © 2016-2023 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.controller; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.security.access.prepost.PreAuthorize; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RequestMethod; |
|||
import org.springframework.web.bind.annotation.ResponseBody; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
import org.thingsboard.server.common.data.UsageInfo; |
|||
import org.thingsboard.server.common.data.exception.ThingsboardException; |
|||
import org.thingsboard.server.dao.usage.UsageInfoService; |
|||
import org.thingsboard.server.queue.util.TbCoreComponent; |
|||
|
|||
@RestController |
|||
@TbCoreComponent |
|||
@RequestMapping("/api") |
|||
@Slf4j |
|||
public class UsageInfoController extends BaseController { |
|||
|
|||
@Autowired |
|||
private UsageInfoService usageInfoService; |
|||
|
|||
@PreAuthorize("hasAuthority('TENANT_ADMIN')") |
|||
@RequestMapping(value = "/tenant/usageInfo", method = RequestMethod.GET) |
|||
@ResponseBody |
|||
public UsageInfo getTenantUsageInfo() throws ThingsboardException { |
|||
return checkNotNull(usageInfoService.getUsageInfo(getCurrentUser().getTenantId())); |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
/** |
|||
* Copyright © 2016-2023 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.dao.usage; |
|||
|
|||
import org.thingsboard.server.common.data.UsageInfo; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
|
|||
public interface UsageInfoService { |
|||
|
|||
UsageInfo getUsageInfo(TenantId tenantId); |
|||
|
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
/** |
|||
* Copyright © 2016-2023 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; |
|||
|
|||
import lombok.Data; |
|||
|
|||
@Data |
|||
public class UsageInfo { |
|||
private long devices; |
|||
private long maxDevices; |
|||
private long assets; |
|||
private long maxAssets; |
|||
private long customers; |
|||
private long maxCustomers; |
|||
private long users; |
|||
private long maxUsers; |
|||
private long dashboards; |
|||
private long maxDashboards; |
|||
|
|||
private long transportMessages; |
|||
private long maxTransportMessages; |
|||
private long jsExecutions; |
|||
private long maxJsExecutions; |
|||
private long emails; |
|||
private long maxEmails; |
|||
private long sms; |
|||
private long maxSms; |
|||
private long alarms; |
|||
private long maxAlarms; |
|||
} |
|||
@ -0,0 +1,109 @@ |
|||
/** |
|||
* Copyright © 2016-2023 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.dao.usage; |
|||
|
|||
import lombok.RequiredArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.context.annotation.Lazy; |
|||
import org.springframework.stereotype.Service; |
|||
import org.thingsboard.server.common.data.ApiUsageRecordKey; |
|||
import org.thingsboard.server.common.data.ApiUsageState; |
|||
import org.thingsboard.server.common.data.UsageInfo; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.kv.TsKvEntry; |
|||
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; |
|||
import org.thingsboard.server.dao.asset.AssetDao; |
|||
import org.thingsboard.server.dao.customer.CustomerDao; |
|||
import org.thingsboard.server.dao.dashboard.DashboardDao; |
|||
import org.thingsboard.server.dao.device.DeviceDao; |
|||
import org.thingsboard.server.dao.tenant.TbTenantProfileCache; |
|||
import org.thingsboard.server.dao.timeseries.TimeseriesService; |
|||
import org.thingsboard.server.dao.usagerecord.ApiUsageStateService; |
|||
import org.thingsboard.server.dao.user.UserDao; |
|||
|
|||
import java.util.Arrays; |
|||
import java.util.Collection; |
|||
import java.util.List; |
|||
import java.util.Optional; |
|||
import java.util.concurrent.ExecutionException; |
|||
|
|||
@Service |
|||
@Slf4j |
|||
@RequiredArgsConstructor |
|||
public class BasicUsageInfoService implements UsageInfoService { |
|||
|
|||
private final DeviceDao deviceDao; |
|||
private final AssetDao assetDao; |
|||
private final CustomerDao customerDao; |
|||
private final UserDao userDao; |
|||
private final DashboardDao dashboardDao; |
|||
private final ApiUsageStateService apiUsageStateService; |
|||
private final TimeseriesService tsService; |
|||
@Lazy |
|||
private final TbTenantProfileCache tenantProfileCache; |
|||
|
|||
@Override |
|||
public UsageInfo getUsageInfo(TenantId tenantId) { |
|||
DefaultTenantProfileConfiguration profileConfiguration = |
|||
(DefaultTenantProfileConfiguration) tenantProfileCache.get(tenantId).getProfileData().getConfiguration(); |
|||
UsageInfo usageInfo = new UsageInfo(); |
|||
usageInfo.setDevices(deviceDao.countByTenantId(tenantId)); |
|||
usageInfo.setMaxDevices(profileConfiguration.getMaxDevices()); |
|||
usageInfo.setAssets(assetDao.countByTenantId(tenantId)); |
|||
usageInfo.setMaxAssets(profileConfiguration.getMaxAssets()); |
|||
usageInfo.setCustomers(customerDao.countByTenantId(tenantId)); |
|||
usageInfo.setMaxCustomers(profileConfiguration.getMaxCustomers()); |
|||
usageInfo.setUsers(userDao.countByTenantId(tenantId)); |
|||
usageInfo.setMaxUsers(profileConfiguration.getMaxUsers()); |
|||
usageInfo.setDashboards(dashboardDao.countByTenantId(tenantId)); |
|||
usageInfo.setMaxDashboards(profileConfiguration.getMaxDashboards()); |
|||
|
|||
usageInfo.setMaxAlarms(profileConfiguration.getMaxCreatedAlarms()); |
|||
usageInfo.setMaxTransportMessages(profileConfiguration.getMaxTransportMessages()); |
|||
usageInfo.setMaxJsExecutions(profileConfiguration.getMaxJSExecutions()); |
|||
usageInfo.setMaxEmails(profileConfiguration.getMaxEmails()); |
|||
usageInfo.setMaxSms(profileConfiguration.getMaxSms()); |
|||
ApiUsageState apiUsageState = apiUsageStateService.findTenantApiUsageState(tenantId); |
|||
if (apiUsageState != null) { |
|||
Collection<String> keys = Arrays.asList( |
|||
ApiUsageRecordKey.TRANSPORT_MSG_COUNT.getApiCountKey(), |
|||
ApiUsageRecordKey.JS_EXEC_COUNT.getApiCountKey(), |
|||
ApiUsageRecordKey.EMAIL_EXEC_COUNT.getApiCountKey(), |
|||
ApiUsageRecordKey.SMS_EXEC_COUNT.getApiCountKey(), |
|||
ApiUsageRecordKey.CREATED_ALARMS_COUNT.getApiCountKey()); |
|||
try { |
|||
List<TsKvEntry> entries = tsService.findLatest(tenantId, apiUsageState.getId(), keys).get(); |
|||
usageInfo.setTransportMessages(getLongValueFromTsEntries(entries, ApiUsageRecordKey.TRANSPORT_MSG_COUNT.getApiCountKey())); |
|||
usageInfo.setJsExecutions(getLongValueFromTsEntries(entries, ApiUsageRecordKey.JS_EXEC_COUNT.getApiCountKey())); |
|||
usageInfo.setEmails(getLongValueFromTsEntries(entries, ApiUsageRecordKey.EMAIL_EXEC_COUNT.getApiCountKey())); |
|||
usageInfo.setSms(getLongValueFromTsEntries(entries, ApiUsageRecordKey.SMS_EXEC_COUNT.getApiCountKey())); |
|||
usageInfo.setAlarms(getLongValueFromTsEntries(entries, ApiUsageRecordKey.CREATED_ALARMS_COUNT.getApiCountKey())); |
|||
} catch (ExecutionException | InterruptedException e) { |
|||
throw new RuntimeException("Failed to fetch api usage values from timeseries!"); |
|||
} |
|||
} |
|||
return usageInfo; |
|||
} |
|||
|
|||
private long getLongValueFromTsEntries(List<TsKvEntry> entries, String key) { |
|||
Optional<TsKvEntry> entryOpt = entries.stream().filter(e -> e.getKey().equals(key)).findFirst(); |
|||
if (entryOpt.isPresent() && entryOpt.get().getLongValue().isPresent()) { |
|||
return entryOpt.get().getLongValue().get(); |
|||
} else { |
|||
return 0; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue