Improve REST API error response handling. Update swagger api.
This commit is contained in:
		
							parent
							
								
									cd23b85baa
								
							
						
					
					
						commit
						7c2b3a9fbf
					
				@ -339,6 +339,17 @@
 | 
			
		||||
        <resources>
 | 
			
		||||
            <resource>
 | 
			
		||||
                <directory>${project.basedir}/src/main/resources</directory>
 | 
			
		||||
                <filtering>true</filtering>
 | 
			
		||||
                <includes>
 | 
			
		||||
                    <include>thingsboard.yml</include>
 | 
			
		||||
                </includes>
 | 
			
		||||
            </resource>
 | 
			
		||||
            <resource>
 | 
			
		||||
                <directory>${project.basedir}/src/main/resources</directory>
 | 
			
		||||
                <filtering>false</filtering>
 | 
			
		||||
                <excludes>
 | 
			
		||||
                    <exclude>thingsboard.yml</exclude>
 | 
			
		||||
                </excludes>
 | 
			
		||||
            </resource>
 | 
			
		||||
        </resources>
 | 
			
		||||
        <plugins>
 | 
			
		||||
 | 
			
		||||
@ -26,10 +26,12 @@ import org.springframework.core.annotation.Order;
 | 
			
		||||
import org.springframework.http.HttpMethod;
 | 
			
		||||
import org.springframework.http.HttpStatus;
 | 
			
		||||
import org.springframework.http.MediaType;
 | 
			
		||||
import org.thingsboard.server.common.data.StringUtils;
 | 
			
		||||
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
 | 
			
		||||
import org.thingsboard.server.common.data.security.Authority;
 | 
			
		||||
import org.thingsboard.server.exception.ThingsboardCredentialsExpiredResponse;
 | 
			
		||||
import org.thingsboard.server.exception.ThingsboardErrorResponse;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.service.security.auth.rest.LoginRequest;
 | 
			
		||||
import org.thingsboard.server.service.security.auth.rest.LoginResponse;
 | 
			
		||||
import springfox.documentation.builders.ApiInfoBuilder;
 | 
			
		||||
@ -81,6 +83,7 @@ import static springfox.documentation.builders.PathSelectors.regex;
 | 
			
		||||
 | 
			
		||||
@Slf4j
 | 
			
		||||
@Configuration
 | 
			
		||||
@TbCoreComponent
 | 
			
		||||
public class SwaggerConfiguration {
 | 
			
		||||
 | 
			
		||||
    @Value("${swagger.api_path_regex}")
 | 
			
		||||
@ -105,6 +108,8 @@ public class SwaggerConfiguration {
 | 
			
		||||
    private String licenseUrl;
 | 
			
		||||
    @Value("${swagger.version}")
 | 
			
		||||
    private String version;
 | 
			
		||||
    @Value("${app.version:unknown}")
 | 
			
		||||
    private String appVersion;
 | 
			
		||||
 | 
			
		||||
    @Bean
 | 
			
		||||
    public Docket thingsboardApi() {
 | 
			
		||||
@ -231,13 +236,17 @@ public class SwaggerConfiguration {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ApiInfo apiInfo() {
 | 
			
		||||
        String apiVersion = version;
 | 
			
		||||
        if (StringUtils.isEmpty(apiVersion)) {
 | 
			
		||||
            apiVersion = appVersion;
 | 
			
		||||
        }
 | 
			
		||||
        return new ApiInfoBuilder()
 | 
			
		||||
                .title(title)
 | 
			
		||||
                .description(description)
 | 
			
		||||
                .contact(new Contact(contactName, contactUrl, contactEmail))
 | 
			
		||||
                .license(licenseTitle)
 | 
			
		||||
                .licenseUrl(licenseUrl)
 | 
			
		||||
                .version(version)
 | 
			
		||||
                .version(apiVersion)
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -73,7 +73,7 @@ public class AdminController extends BaseController {
 | 
			
		||||
            @PathVariable("key") String key) throws ThingsboardException {
 | 
			
		||||
        try {
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
 | 
			
		||||
            AdminSettings adminSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, key));
 | 
			
		||||
            AdminSettings adminSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, key), "No Administration settings found for key: " + key);
 | 
			
		||||
            if (adminSettings.getKey().equals("mail")) {
 | 
			
		||||
                ((ObjectNode) adminSettings.getJsonValue()).remove("password");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -319,17 +319,25 @@ public abstract class BaseController {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    <T> T checkNotNull(T reference) throws ThingsboardException {
 | 
			
		||||
        return checkNotNull(reference, "Requested item wasn't found!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    <T> T checkNotNull(T reference, String notFoundMessage) throws ThingsboardException {
 | 
			
		||||
        if (reference == null) {
 | 
			
		||||
            throw new ThingsboardException("Requested item wasn't found!", ThingsboardErrorCode.ITEM_NOT_FOUND);
 | 
			
		||||
            throw new ThingsboardException(notFoundMessage, ThingsboardErrorCode.ITEM_NOT_FOUND);
 | 
			
		||||
        }
 | 
			
		||||
        return reference;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    <T> T checkNotNull(Optional<T> reference) throws ThingsboardException {
 | 
			
		||||
        return checkNotNull(reference, "Requested item wasn't found!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    <T> T checkNotNull(Optional<T> reference, String notFoundMessage) throws ThingsboardException {
 | 
			
		||||
        if (reference.isPresent()) {
 | 
			
		||||
            return reference.get();
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new ThingsboardException("Requested item wasn't found!", ThingsboardErrorCode.ITEM_NOT_FOUND);
 | 
			
		||||
            throw new ThingsboardException(notFoundMessage, ThingsboardErrorCode.ITEM_NOT_FOUND);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -389,7 +397,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
 | 
			
		||||
            Tenant tenant = tenantService.findTenantById(tenantId);
 | 
			
		||||
            checkNotNull(tenant);
 | 
			
		||||
            checkNotNull(tenant, "Tenant with id [" + tenantId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.TENANT, operation, tenantId, tenant);
 | 
			
		||||
            return tenant;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -401,7 +409,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
 | 
			
		||||
            TenantInfo tenant = tenantService.findTenantInfoById(tenantId);
 | 
			
		||||
            checkNotNull(tenant);
 | 
			
		||||
            checkNotNull(tenant, "Tenant with id [" + tenantId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.TENANT, operation, tenantId, tenant);
 | 
			
		||||
            return tenant;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -413,7 +421,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(tenantProfileId, "Incorrect tenantProfileId " + tenantProfileId);
 | 
			
		||||
            TenantProfile tenantProfile = tenantProfileService.findTenantProfileById(getTenantId(), tenantProfileId);
 | 
			
		||||
            checkNotNull(tenantProfile);
 | 
			
		||||
            checkNotNull(tenantProfile, "Tenant profile with id [" + tenantProfileId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.TENANT_PROFILE, operation);
 | 
			
		||||
            return tenantProfile;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -429,7 +437,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(customerId, "Incorrect customerId " + customerId);
 | 
			
		||||
            Customer customer = customerService.findCustomerById(getTenantId(), customerId);
 | 
			
		||||
            checkNotNull(customer);
 | 
			
		||||
            checkNotNull(customer, "Customer with id [" + customerId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.CUSTOMER, operation, customerId, customer);
 | 
			
		||||
            return customer;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -441,7 +449,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(userId, "Incorrect userId " + userId);
 | 
			
		||||
            User user = userService.findUserById(getCurrentUser().getTenantId(), userId);
 | 
			
		||||
            checkNotNull(user);
 | 
			
		||||
            checkNotNull(user, "User with id [" + userId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.USER, operation, userId, user);
 | 
			
		||||
            return user;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -460,7 +468,9 @@ public abstract class BaseController {
 | 
			
		||||
 | 
			
		||||
    protected void checkEntityId(EntityId entityId, Operation operation) throws ThingsboardException {
 | 
			
		||||
        try {
 | 
			
		||||
            checkNotNull(entityId);
 | 
			
		||||
            if (entityId == null) {
 | 
			
		||||
                throw new ThingsboardException("Parameter entityId can't be empty!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
 | 
			
		||||
            }
 | 
			
		||||
            validateId(entityId.getId(), "Incorrect entityId " + entityId);
 | 
			
		||||
            switch (entityId.getEntityType()) {
 | 
			
		||||
                case ALARM:
 | 
			
		||||
@ -526,7 +536,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(deviceId, "Incorrect deviceId " + deviceId);
 | 
			
		||||
            Device device = deviceService.findDeviceById(getCurrentUser().getTenantId(), deviceId);
 | 
			
		||||
            checkNotNull(device);
 | 
			
		||||
            checkNotNull(device, "Device with id [" + deviceId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.DEVICE, operation, deviceId, device);
 | 
			
		||||
            return device;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -538,7 +548,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(deviceId, "Incorrect deviceId " + deviceId);
 | 
			
		||||
            DeviceInfo device = deviceService.findDeviceInfoById(getCurrentUser().getTenantId(), deviceId);
 | 
			
		||||
            checkNotNull(device);
 | 
			
		||||
            checkNotNull(device, "Device with id [" + deviceId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.DEVICE, operation, deviceId, device);
 | 
			
		||||
            return device;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -550,7 +560,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(deviceProfileId, "Incorrect deviceProfileId " + deviceProfileId);
 | 
			
		||||
            DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileById(getCurrentUser().getTenantId(), deviceProfileId);
 | 
			
		||||
            checkNotNull(deviceProfile);
 | 
			
		||||
            checkNotNull(deviceProfile, "Device profile with id [" + deviceProfileId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.DEVICE_PROFILE, operation, deviceProfileId, deviceProfile);
 | 
			
		||||
            return deviceProfile;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -562,7 +572,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(entityViewId, "Incorrect entityViewId " + entityViewId);
 | 
			
		||||
            EntityView entityView = entityViewService.findEntityViewById(getCurrentUser().getTenantId(), entityViewId);
 | 
			
		||||
            checkNotNull(entityView);
 | 
			
		||||
            checkNotNull(entityView, "Entity view with id [" + entityViewId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.ENTITY_VIEW, operation, entityViewId, entityView);
 | 
			
		||||
            return entityView;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -574,7 +584,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(entityViewId, "Incorrect entityViewId " + entityViewId);
 | 
			
		||||
            EntityViewInfo entityView = entityViewService.findEntityViewInfoById(getCurrentUser().getTenantId(), entityViewId);
 | 
			
		||||
            checkNotNull(entityView);
 | 
			
		||||
            checkNotNull(entityView, "Entity view with id [" + entityViewId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.ENTITY_VIEW, operation, entityViewId, entityView);
 | 
			
		||||
            return entityView;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -586,7 +596,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(assetId, "Incorrect assetId " + assetId);
 | 
			
		||||
            Asset asset = assetService.findAssetById(getCurrentUser().getTenantId(), assetId);
 | 
			
		||||
            checkNotNull(asset);
 | 
			
		||||
            checkNotNull(asset, "Asset with id [" + assetId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.ASSET, operation, assetId, asset);
 | 
			
		||||
            return asset;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -598,7 +608,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(assetId, "Incorrect assetId " + assetId);
 | 
			
		||||
            AssetInfo asset = assetService.findAssetInfoById(getCurrentUser().getTenantId(), assetId);
 | 
			
		||||
            checkNotNull(asset);
 | 
			
		||||
            checkNotNull(asset, "Asset with id [" + assetId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.ASSET, operation, assetId, asset);
 | 
			
		||||
            return asset;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -610,7 +620,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(alarmId, "Incorrect alarmId " + alarmId);
 | 
			
		||||
            Alarm alarm = alarmService.findAlarmByIdAsync(getCurrentUser().getTenantId(), alarmId).get();
 | 
			
		||||
            checkNotNull(alarm);
 | 
			
		||||
            checkNotNull(alarm, "Alarm with id [" + alarmId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.ALARM, operation, alarmId, alarm);
 | 
			
		||||
            return alarm;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -622,7 +632,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(alarmId, "Incorrect alarmId " + alarmId);
 | 
			
		||||
            AlarmInfo alarmInfo = alarmService.findAlarmInfoByIdAsync(getCurrentUser().getTenantId(), alarmId).get();
 | 
			
		||||
            checkNotNull(alarmInfo);
 | 
			
		||||
            checkNotNull(alarmInfo, "Alarm with id [" + alarmId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.ALARM, operation, alarmId, alarmInfo);
 | 
			
		||||
            return alarmInfo;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -634,7 +644,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(widgetsBundleId, "Incorrect widgetsBundleId " + widgetsBundleId);
 | 
			
		||||
            WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleById(getCurrentUser().getTenantId(), widgetsBundleId);
 | 
			
		||||
            checkNotNull(widgetsBundle);
 | 
			
		||||
            checkNotNull(widgetsBundle, "Widgets bundle with id [" + widgetsBundleId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.WIDGETS_BUNDLE, operation, widgetsBundleId, widgetsBundle);
 | 
			
		||||
            return widgetsBundle;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -646,7 +656,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(widgetTypeId, "Incorrect widgetTypeId " + widgetTypeId);
 | 
			
		||||
            WidgetTypeDetails widgetTypeDetails = widgetTypeService.findWidgetTypeDetailsById(getCurrentUser().getTenantId(), widgetTypeId);
 | 
			
		||||
            checkNotNull(widgetTypeDetails);
 | 
			
		||||
            checkNotNull(widgetTypeDetails, "Widget type with id [" + widgetTypeId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.WIDGET_TYPE, operation, widgetTypeId, widgetTypeDetails);
 | 
			
		||||
            return widgetTypeDetails;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -658,7 +668,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(dashboardId, "Incorrect dashboardId " + dashboardId);
 | 
			
		||||
            Dashboard dashboard = dashboardService.findDashboardById(getCurrentUser().getTenantId(), dashboardId);
 | 
			
		||||
            checkNotNull(dashboard);
 | 
			
		||||
            checkNotNull(dashboard, "Dashboard with id [" + dashboardId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.DASHBOARD, operation, dashboardId, dashboard);
 | 
			
		||||
            return dashboard;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -670,7 +680,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(edgeId, "Incorrect edgeId " + edgeId);
 | 
			
		||||
            Edge edge = edgeService.findEdgeById(getTenantId(), edgeId);
 | 
			
		||||
            checkNotNull(edge);
 | 
			
		||||
            checkNotNull(edge, "Edge with id [" + edgeId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.EDGE, operation, edgeId, edge);
 | 
			
		||||
            return edge;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -682,7 +692,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(edgeId, "Incorrect edgeId " + edgeId);
 | 
			
		||||
            EdgeInfo edge = edgeService.findEdgeInfoById(getCurrentUser().getTenantId(), edgeId);
 | 
			
		||||
            checkNotNull(edge);
 | 
			
		||||
            checkNotNull(edge, "Edge with id [" + edgeId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.EDGE, operation, edgeId, edge);
 | 
			
		||||
            return edge;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -694,7 +704,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(dashboardId, "Incorrect dashboardId " + dashboardId);
 | 
			
		||||
            DashboardInfo dashboardInfo = dashboardService.findDashboardInfoById(getCurrentUser().getTenantId(), dashboardId);
 | 
			
		||||
            checkNotNull(dashboardInfo);
 | 
			
		||||
            checkNotNull(dashboardInfo, "Dashboard with id [" + dashboardId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.DASHBOARD, operation, dashboardId, dashboardInfo);
 | 
			
		||||
            return dashboardInfo;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -732,7 +742,7 @@ public abstract class BaseController {
 | 
			
		||||
    protected RuleChain checkRuleChain(RuleChainId ruleChainId, Operation operation) throws ThingsboardException {
 | 
			
		||||
        validateId(ruleChainId, "Incorrect ruleChainId " + ruleChainId);
 | 
			
		||||
        RuleChain ruleChain = ruleChainService.findRuleChainById(getCurrentUser().getTenantId(), ruleChainId);
 | 
			
		||||
        checkNotNull(ruleChain);
 | 
			
		||||
        checkNotNull(ruleChain, "Rule chain with id [" + ruleChainId + "] is not found");
 | 
			
		||||
        accessControlService.checkPermission(getCurrentUser(), Resource.RULE_CHAIN, operation, ruleChainId, ruleChain);
 | 
			
		||||
        return ruleChain;
 | 
			
		||||
    }
 | 
			
		||||
@ -740,7 +750,7 @@ public abstract class BaseController {
 | 
			
		||||
    protected RuleNode checkRuleNode(RuleNodeId ruleNodeId, Operation operation) throws ThingsboardException {
 | 
			
		||||
        validateId(ruleNodeId, "Incorrect ruleNodeId " + ruleNodeId);
 | 
			
		||||
        RuleNode ruleNode = ruleChainService.findRuleNodeById(getTenantId(), ruleNodeId);
 | 
			
		||||
        checkNotNull(ruleNode);
 | 
			
		||||
        checkNotNull(ruleNode, "Rule node with id [" + ruleNodeId + "] is not found");
 | 
			
		||||
        checkRuleChain(ruleNode.getRuleChainId(), operation);
 | 
			
		||||
        return ruleNode;
 | 
			
		||||
    }
 | 
			
		||||
@ -749,7 +759,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(resourceId, "Incorrect resourceId " + resourceId);
 | 
			
		||||
            TbResource resource = resourceService.findResourceById(getCurrentUser().getTenantId(), resourceId);
 | 
			
		||||
            checkNotNull(resource);
 | 
			
		||||
            checkNotNull(resource, "Resource with id [" + resourceId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.TB_RESOURCE, operation, resourceId, resource);
 | 
			
		||||
            return resource;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -761,7 +771,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(resourceId, "Incorrect resourceId " + resourceId);
 | 
			
		||||
            TbResourceInfo resourceInfo = resourceService.findResourceInfoById(getCurrentUser().getTenantId(), resourceId);
 | 
			
		||||
            checkNotNull(resourceInfo);
 | 
			
		||||
            checkNotNull(resourceInfo, "Resource with id [" + resourceId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.TB_RESOURCE, operation, resourceId, resourceInfo);
 | 
			
		||||
            return resourceInfo;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -773,7 +783,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(otaPackageId, "Incorrect otaPackageId " + otaPackageId);
 | 
			
		||||
            OtaPackage otaPackage = otaPackageService.findOtaPackageById(getCurrentUser().getTenantId(), otaPackageId);
 | 
			
		||||
            checkNotNull(otaPackage);
 | 
			
		||||
            checkNotNull(otaPackage, "OTA package with id [" + otaPackageId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.OTA_PACKAGE, operation, otaPackageId, otaPackage);
 | 
			
		||||
            return otaPackage;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -785,7 +795,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(otaPackageId, "Incorrect otaPackageId " + otaPackageId);
 | 
			
		||||
            OtaPackageInfo otaPackageIn = otaPackageService.findOtaPackageInfoById(getCurrentUser().getTenantId(), otaPackageId);
 | 
			
		||||
            checkNotNull(otaPackageIn);
 | 
			
		||||
            checkNotNull(otaPackageIn, "OTA package with id [" + otaPackageId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.OTA_PACKAGE, operation, otaPackageId, otaPackageIn);
 | 
			
		||||
            return otaPackageIn;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -797,7 +807,7 @@ public abstract class BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            validateId(rpcId, "Incorrect rpcId " + rpcId);
 | 
			
		||||
            Rpc rpc = rpcService.findById(getCurrentUser().getTenantId(), rpcId);
 | 
			
		||||
            checkNotNull(rpc);
 | 
			
		||||
            checkNotNull(rpc, "RPC with id [" + rpcId + "] is not found");
 | 
			
		||||
            accessControlService.checkPermission(getCurrentUser(), Resource.RPC, operation, rpcId, rpc);
 | 
			
		||||
            return rpc;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
 | 
			
		||||
@ -240,7 +240,7 @@ public class CustomerController extends BaseController {
 | 
			
		||||
            @RequestParam String customerTitle) throws ThingsboardException {
 | 
			
		||||
        try {
 | 
			
		||||
            TenantId tenantId = getCurrentUser().getTenantId();
 | 
			
		||||
            return checkNotNull(customerService.findCustomerByTenantIdAndTitle(tenantId, customerTitle));
 | 
			
		||||
            return checkNotNull(customerService.findCustomerByTenantIdAndTitle(tenantId, customerTitle), "Customer with title [" + customerTitle + "] is not found");
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            throw handleException(e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -19,6 +19,9 @@ import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
import com.fasterxml.jackson.databind.node.ObjectNode;
 | 
			
		||||
import io.swagger.annotations.ApiOperation;
 | 
			
		||||
import io.swagger.annotations.ApiParam;
 | 
			
		||||
import io.swagger.annotations.ApiResponse;
 | 
			
		||||
import io.swagger.annotations.Example;
 | 
			
		||||
import io.swagger.annotations.ExampleProperty;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Value;
 | 
			
		||||
import org.springframework.http.HttpStatus;
 | 
			
		||||
import org.springframework.http.MediaType;
 | 
			
		||||
@ -106,6 +109,7 @@ public class DashboardController extends BaseController {
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
 | 
			
		||||
    @RequestMapping(value = "/dashboard/serverTime", method = RequestMethod.GET)
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    @ApiResponse(code = 200, message = "OK", examples = @Example(value = @ExampleProperty(value = "1636023857137", mediaType = "application/json")))
 | 
			
		||||
    public long getServerTime() throws ThingsboardException {
 | 
			
		||||
        return System.currentTimeMillis();
 | 
			
		||||
    }
 | 
			
		||||
@ -118,6 +122,7 @@ public class DashboardController extends BaseController {
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
 | 
			
		||||
    @RequestMapping(value = "/dashboard/maxDatapointsLimit", method = RequestMethod.GET)
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    @ApiResponse(code = 200, message = "OK", examples = @Example(value = @ExampleProperty(value = "5000", mediaType = "application/json")))
 | 
			
		||||
    public long getMaxDatapointsLimit() throws ThingsboardException {
 | 
			
		||||
        return maxDatapointsLimit;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -17,9 +17,13 @@ package org.thingsboard.server.exception;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.databind.ObjectMapper;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.http.HttpHeaders;
 | 
			
		||||
import org.springframework.http.HttpStatus;
 | 
			
		||||
import org.springframework.http.MediaType;
 | 
			
		||||
import org.springframework.http.ResponseEntity;
 | 
			
		||||
import org.springframework.lang.Nullable;
 | 
			
		||||
import org.springframework.security.access.AccessDeniedException;
 | 
			
		||||
import org.springframework.security.authentication.BadCredentialsException;
 | 
			
		||||
import org.springframework.security.authentication.DisabledException;
 | 
			
		||||
@ -30,7 +34,9 @@ import org.springframework.security.web.access.AccessDeniedHandler;
 | 
			
		||||
import org.springframework.web.bind.annotation.ExceptionHandler;
 | 
			
		||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
 | 
			
		||||
import org.springframework.web.client.HttpClientErrorException;
 | 
			
		||||
import org.springframework.web.context.request.WebRequest;
 | 
			
		||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
 | 
			
		||||
import org.springframework.web.util.WebUtils;
 | 
			
		||||
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
 | 
			
		||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
 | 
			
		||||
import org.thingsboard.server.common.msg.tools.TbRateLimitsException;
 | 
			
		||||
@ -42,11 +48,49 @@ import javax.servlet.ServletException;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
@Slf4j
 | 
			
		||||
@RestControllerAdvice
 | 
			
		||||
public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHandler implements AccessDeniedHandler {
 | 
			
		||||
 | 
			
		||||
    private static final Map<HttpStatus, ThingsboardErrorCode> statusToErrorCodeMap = new HashMap<>();
 | 
			
		||||
    static {
 | 
			
		||||
        statusToErrorCodeMap.put(HttpStatus.BAD_REQUEST, ThingsboardErrorCode.BAD_REQUEST_PARAMS);
 | 
			
		||||
        statusToErrorCodeMap.put(HttpStatus.UNAUTHORIZED, ThingsboardErrorCode.AUTHENTICATION);
 | 
			
		||||
        statusToErrorCodeMap.put(HttpStatus.FORBIDDEN, ThingsboardErrorCode.PERMISSION_DENIED);
 | 
			
		||||
        statusToErrorCodeMap.put(HttpStatus.NOT_FOUND, ThingsboardErrorCode.ITEM_NOT_FOUND);
 | 
			
		||||
        statusToErrorCodeMap.put(HttpStatus.METHOD_NOT_ALLOWED, ThingsboardErrorCode.BAD_REQUEST_PARAMS);
 | 
			
		||||
        statusToErrorCodeMap.put(HttpStatus.NOT_ACCEPTABLE, ThingsboardErrorCode.BAD_REQUEST_PARAMS);
 | 
			
		||||
        statusToErrorCodeMap.put(HttpStatus.UNSUPPORTED_MEDIA_TYPE, ThingsboardErrorCode.BAD_REQUEST_PARAMS);
 | 
			
		||||
        statusToErrorCodeMap.put(HttpStatus.TOO_MANY_REQUESTS, ThingsboardErrorCode.TOO_MANY_REQUESTS);
 | 
			
		||||
        statusToErrorCodeMap.put(HttpStatus.INTERNAL_SERVER_ERROR, ThingsboardErrorCode.GENERAL);
 | 
			
		||||
        statusToErrorCodeMap.put(HttpStatus.SERVICE_UNAVAILABLE, ThingsboardErrorCode.GENERAL);
 | 
			
		||||
    }
 | 
			
		||||
    private static final Map<ThingsboardErrorCode, HttpStatus> errorCodeToStatusMap = new HashMap<>();
 | 
			
		||||
    static {
 | 
			
		||||
        errorCodeToStatusMap.put(ThingsboardErrorCode.GENERAL, HttpStatus.INTERNAL_SERVER_ERROR);
 | 
			
		||||
        errorCodeToStatusMap.put(ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED);
 | 
			
		||||
        errorCodeToStatusMap.put(ThingsboardErrorCode.JWT_TOKEN_EXPIRED, HttpStatus.UNAUTHORIZED);
 | 
			
		||||
        errorCodeToStatusMap.put(ThingsboardErrorCode.CREDENTIALS_EXPIRED, HttpStatus.UNAUTHORIZED);
 | 
			
		||||
        errorCodeToStatusMap.put(ThingsboardErrorCode.PERMISSION_DENIED, HttpStatus.FORBIDDEN);
 | 
			
		||||
        errorCodeToStatusMap.put(ThingsboardErrorCode.INVALID_ARGUMENTS, HttpStatus.BAD_REQUEST);
 | 
			
		||||
        errorCodeToStatusMap.put(ThingsboardErrorCode.BAD_REQUEST_PARAMS, HttpStatus.BAD_REQUEST);
 | 
			
		||||
        errorCodeToStatusMap.put(ThingsboardErrorCode.ITEM_NOT_FOUND, HttpStatus.NOT_FOUND);
 | 
			
		||||
        errorCodeToStatusMap.put(ThingsboardErrorCode.TOO_MANY_REQUESTS, HttpStatus.TOO_MANY_REQUESTS);
 | 
			
		||||
        errorCodeToStatusMap.put(ThingsboardErrorCode.TOO_MANY_UPDATES, HttpStatus.TOO_MANY_REQUESTS);
 | 
			
		||||
        errorCodeToStatusMap.put(ThingsboardErrorCode.SUBSCRIPTION_VIOLATION, HttpStatus.FORBIDDEN);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static ThingsboardErrorCode statusToErrorCode(HttpStatus status) {
 | 
			
		||||
        return statusToErrorCodeMap.getOrDefault(status, ThingsboardErrorCode.GENERAL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static HttpStatus errorCodeToStatus(ThingsboardErrorCode errorCode) {
 | 
			
		||||
        return errorCodeToStatusMap.getOrDefault(errorCode, HttpStatus.INTERNAL_SERVER_ERROR);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private ObjectMapper mapper;
 | 
			
		||||
 | 
			
		||||
@ -95,36 +139,22 @@ public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHand
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NotNull
 | 
			
		||||
    @Override
 | 
			
		||||
    protected ResponseEntity<Object> handleExceptionInternal(
 | 
			
		||||
            @NotNull Exception ex, @Nullable Object body,
 | 
			
		||||
            @NotNull HttpHeaders headers, @NotNull HttpStatus status,
 | 
			
		||||
            @NotNull WebRequest request) {
 | 
			
		||||
        if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) {
 | 
			
		||||
            request.setAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE, ex, WebRequest.SCOPE_REQUEST);
 | 
			
		||||
        }
 | 
			
		||||
        ThingsboardErrorCode errorCode = statusToErrorCode(status);
 | 
			
		||||
        return new ResponseEntity<>(ThingsboardErrorResponse.of(ex.getMessage(), errorCode, status), headers, status);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void handleThingsboardException(ThingsboardException thingsboardException, HttpServletResponse response) throws IOException {
 | 
			
		||||
 | 
			
		||||
        ThingsboardErrorCode errorCode = thingsboardException.getErrorCode();
 | 
			
		||||
        HttpStatus status;
 | 
			
		||||
 | 
			
		||||
        switch (errorCode) {
 | 
			
		||||
            case AUTHENTICATION:
 | 
			
		||||
                status = HttpStatus.UNAUTHORIZED;
 | 
			
		||||
                break;
 | 
			
		||||
            case PERMISSION_DENIED:
 | 
			
		||||
                status = HttpStatus.FORBIDDEN;
 | 
			
		||||
                break;
 | 
			
		||||
            case INVALID_ARGUMENTS:
 | 
			
		||||
                status = HttpStatus.BAD_REQUEST;
 | 
			
		||||
                break;
 | 
			
		||||
            case ITEM_NOT_FOUND:
 | 
			
		||||
                status = HttpStatus.NOT_FOUND;
 | 
			
		||||
                break;
 | 
			
		||||
            case BAD_REQUEST_PARAMS:
 | 
			
		||||
                status = HttpStatus.BAD_REQUEST;
 | 
			
		||||
                break;
 | 
			
		||||
            case GENERAL:
 | 
			
		||||
                status = HttpStatus.INTERNAL_SERVER_ERROR;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                status = HttpStatus.INTERNAL_SERVER_ERROR;
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        HttpStatus status = errorCodeToStatus(errorCode);
 | 
			
		||||
        response.setStatus(status.value());
 | 
			
		||||
        mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of(thingsboardException.getMessage(), errorCode, status));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -89,6 +89,11 @@ server:
 | 
			
		||||
      # Default value of the server side RPC timeout.
 | 
			
		||||
      default_timeout: "${DEFAULT_SERVER_SIDE_RPC_TIMEOUT:10000}"
 | 
			
		||||
 | 
			
		||||
# Application info
 | 
			
		||||
app:
 | 
			
		||||
  # Application version
 | 
			
		||||
  version: "@project.version@"
 | 
			
		||||
 | 
			
		||||
# Zookeeper connection parameters. Used for service discovery.
 | 
			
		||||
zk:
 | 
			
		||||
  # Enable/disable zookeeper discovery service.
 | 
			
		||||
@ -859,7 +864,7 @@ swagger:
 | 
			
		||||
  license:
 | 
			
		||||
    title: "${SWAGGER_LICENSE_TITLE:Apache License Version 2.0}"
 | 
			
		||||
    url: "${SWAGGER_LICENSE_URL:https://github.com/thingsboard/thingsboard/blob/master/LICENSE}"
 | 
			
		||||
  version: "${SWAGGER_VERSION:2.0}"
 | 
			
		||||
  version: "${SWAGGER_VERSION:}"
 | 
			
		||||
 | 
			
		||||
queue:
 | 
			
		||||
  type: "${TB_QUEUE_TYPE:in-memory}" # in-memory or kafka (Apache Kafka) or aws-sqs (AWS SQS) or pubsub (PubSub) or service-bus (Azure Service Bus) or rabbitmq (RabbitMQ)
 | 
			
		||||
 | 
			
		||||
@ -58,7 +58,7 @@ public class AdminSettings extends BaseData<AdminSettingsId> {
 | 
			
		||||
        return super.getCreatedTime();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(position = 3, value = "The Administration Settings key, (e.g. 'general' or 'mail')")
 | 
			
		||||
    @ApiModelProperty(position = 3, value = "The Administration Settings key, (e.g. 'general' or 'mail')", example = "mail")
 | 
			
		||||
    public String getKey() {
 | 
			
		||||
        return key;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							@ -83,7 +83,7 @@
 | 
			
		||||
        <rabbitmq.version>4.8.0</rabbitmq.version>
 | 
			
		||||
        <surfire.version>2.19.1</surfire.version>
 | 
			
		||||
        <jar-plugin.version>3.0.2</jar-plugin.version>
 | 
			
		||||
        <springfox-swagger.version>3.0.3</springfox-swagger.version>
 | 
			
		||||
        <springfox-swagger.version>3.0.4</springfox-swagger.version>
 | 
			
		||||
        <swagger-annotations.version>1.6.3</swagger-annotations.version>
 | 
			
		||||
        <spatial4j.version>0.7</spatial4j.version>
 | 
			
		||||
        <jts.version>1.15.0</jts.version>
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user