From ce87bc5e13bf883d5f9e2001244000736bd51249 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Mon, 12 Jun 2023 13:25:37 +0200 Subject: [PATCH] to springdoc migration --- application/pom.xml | 4 +- .../server/ThingsboardInstallApplication.java | 3 +- .../server/config/SwaggerConfiguration.java | 506 +++++++----------- .../config/annotations/ApiOperation.java | 45 ++ .../controller/AbstractRpcController.java | 2 +- .../server/controller/AdminController.java | 24 +- .../controller/AlarmCommentController.java | 31 +- .../server/controller/AlarmController.java | 159 +++--- .../server/controller/AssetController.java | 147 ++--- .../controller/AssetProfileController.java | 57 +- .../server/controller/AuditLogController.java | 89 +-- .../server/controller/AuthController.java | 20 +- .../server/controller/BaseController.java | 6 +- .../ComponentDescriptorController.java | 15 +- .../controller/ControllerConstants.java | 35 +- .../server/controller/CustomerController.java | 29 +- .../controller/DashboardController.java | 145 +++-- .../server/controller/DeviceController.java | 155 +++--- .../controller/DeviceProfileController.java | 69 ++- .../server/controller/EdgeController.java | 139 ++--- .../controller/EdgeEventController.java | 27 +- .../EntitiesVersionControlController.java | 70 +-- .../controller/EntityQueryController.java | 18 +- .../controller/EntityRelationController.java | 98 ++-- .../controller/EntityViewController.java | 94 ++-- .../server/controller/EventController.java | 89 +-- .../server/controller/Lwm2mController.java | 11 +- .../controller/NotificationController.java | 30 +- .../NotificationRuleController.java | 16 +- .../NotificationTargetController.java | 22 +- .../NotificationTemplateController.java | 20 +- .../OAuth2ConfigTemplateController.java | 6 +- .../server/controller/OAuth2Controller.java | 16 +- .../controller/OtaPackageController.java | 69 ++- .../server/controller/QueueController.java | 30 +- .../server/controller/RpcV1Controller.java | 12 +- .../server/controller/RpcV2Controller.java | 56 +- .../controller/RuleChainController.java | 76 +-- .../controller/SystemInfoController.java | 6 +- .../controller/TbResourceController.java | 59 +- .../controller/TelemetryController.java | 253 +++++---- .../server/controller/TenantController.java | 36 +- .../controller/TenantProfileController.java | 38 +- .../TwoFactorAuthConfigController.java | 11 +- .../controller/TwoFactorAuthController.java | 4 +- .../controller/UiSettingsController.java | 2 +- .../server/controller/UserController.java | 97 ++-- .../controller/WidgetTypeController.java | 28 +- .../controller/WidgetsBundleController.java | 23 +- .../controller/plugin/TbWebSocketHandler.java | 8 +- ...ThingsboardCredentialsExpiredResponse.java | 7 +- .../exception/ThingsboardErrorResponse.java | 17 +- .../security/auth/rest/LoginRequest.java | 9 +- .../security/auth/rest/LoginResponse.java | 9 +- .../security/model/ActivateUserRequest.java | 9 +- .../security/model/ChangePasswordRequest.java | 9 +- .../model/ResetPasswordEmailRequest.java | 7 +- .../security/model/ResetPasswordRequest.java | 9 +- .../service/telemetry/AttributeData.java | 11 +- .../server/service/telemetry/TsData.java | 9 +- ...ngfoxHandlerProviderBeanPostProcessor.java | 59 -- .../src/main/resources/thingsboard.yml | 8 +- common/data/pom.xml | 4 +- .../server/common/data/AdminSettings.java | 15 +- .../server/common/data/Customer.java | 31 +- .../server/common/data/Dashboard.java | 6 +- .../server/common/data/DashboardInfo.java | 23 +- .../server/common/data/Device.java | 29 +- .../server/common/data/DeviceInfo.java | 13 +- .../server/common/data/DeviceProfile.java | 41 +- .../server/common/data/DeviceProfileInfo.java | 12 +- .../server/common/data/EntityInfo.java | 9 +- .../server/common/data/EntityView.java | 24 +- .../server/common/data/EntityViewInfo.java | 6 +- .../server/common/data/EventInfo.java | 17 +- .../server/common/data/ExportableEntity.java | 4 +- .../server/common/data/HomeDashboard.java | 7 +- .../server/common/data/HomeDashboardInfo.java | 9 +- .../server/common/data/OtaPackage.java | 7 +- .../server/common/data/OtaPackageInfo.java | 37 +- .../SaveDeviceWithCredentialsRequest.java | 9 +- .../data/SaveOtaPackageInfoRequest.java | 7 +- .../server/common/data/ShortCustomerInfo.java | 11 +- .../server/common/data/SystemInfo.java | 6 +- .../server/common/data/SystemInfoData.java | 18 +- .../server/common/data/TbResource.java | 6 +- .../server/common/data/TbResourceInfo.java | 19 +- .../server/common/data/Tenant.java | 35 +- .../server/common/data/TenantInfo.java | 7 +- .../server/common/data/TenantProfile.java | 19 +- .../server/common/data/UpdateMessage.java | 17 +- .../thingsboard/server/common/data/User.java | 27 +- .../server/common/data/UserEmailInfo.java | 13 +- .../server/common/data/alarm/Alarm.java | 49 +- .../common/data/alarm/AlarmComment.java | 19 +- .../common/data/alarm/AlarmCommentInfo.java | 11 +- .../AlarmCreateOrUpdateActiveRequest.java | 20 +- .../server/common/data/alarm/AlarmInfo.java | 11 +- .../data/alarm/AlarmPropagationInfo.java | 10 +- .../common/data/alarm/AlarmUpdateRequest.java | 16 +- .../server/common/data/asset/Asset.java | 23 +- .../server/common/data/asset/AssetInfo.java | 11 +- .../common/data/asset/AssetProfile.java | 27 +- .../common/data/asset/AssetProfileInfo.java | 8 +- .../common/data/asset/AssetSearchQuery.java | 8 +- .../server/common/data/audit/AuditLog.java | 29 +- .../common/data/device/DeviceSearchQuery.java | 11 +- .../data/DefaultDeviceConfiguration.java | 4 +- .../data/device/data/DeviceConfiguration.java | 4 +- .../common/data/device/data/DeviceData.java | 9 +- .../data/DeviceTransportConfiguration.java | 4 +- .../data/device/profile/AlarmCondition.java | 9 +- .../device/profile/AlarmConditionFilter.java | 13 +- .../profile/AlarmConditionFilterKey.java | 9 +- .../common/data/device/profile/AlarmRule.java | 13 +- .../device/profile/DeviceProfileAlarm.java | 21 +- .../device/profile/DeviceProfileData.java | 13 +- .../bootstrap/LwM2MServerSecurityConfig.java | 43 +- .../LwM2MServerSecurityConfigDefault.java | 9 +- .../server/common/data/edge/Edge.java | 25 +- .../data/edge/EdgeInstallInstructions.java | 7 +- .../common/data/edge/EdgeSearchQuery.java | 8 +- .../entityview/EntityViewSearchQuery.java | 11 +- .../common/data/event/DebugEventFilter.java | 11 +- .../common/data/event/ErrorEventFilter.java | 11 +- .../server/common/data/event/EventFilter.java | 7 +- .../data/event/LifeCycleEventFilter.java | 13 +- .../data/event/RuleChainDebugEventFilter.java | 7 +- .../data/event/RuleNodeDebugEventFilter.java | 21 +- .../data/event/StatisticsEventFilter.java | 15 +- .../server/common/data/id/AlarmCommentId.java | 4 +- .../server/common/data/id/AlarmId.java | 7 +- .../common/data/id/ApiUsageStateId.java | 7 +- .../server/common/data/id/AssetId.java | 7 +- .../server/common/data/id/AssetProfileId.java | 4 +- .../server/common/data/id/CustomerId.java | 7 +- .../server/common/data/id/DashboardId.java | 7 +- .../server/common/data/id/DeviceId.java | 7 +- .../common/data/id/DeviceProfileId.java | 4 +- .../server/common/data/id/EdgeId.java | 4 +- .../server/common/data/id/EntityId.java | 9 +- .../server/common/data/id/EntityViewId.java | 4 +- .../server/common/data/id/OtaPackageId.java | 4 +- .../server/common/data/id/RpcId.java | 4 +- .../server/common/data/id/RuleChainId.java | 4 +- .../server/common/data/id/RuleNodeId.java | 4 +- .../server/common/data/id/TbResourceId.java | 4 +- .../server/common/data/id/TenantId.java | 4 +- .../common/data/id/TenantProfileId.java | 4 +- .../server/common/data/id/UUIDBased.java | 7 +- .../server/common/data/id/UserId.java | 4 +- .../server/common/data/id/WidgetTypeId.java | 4 +- .../common/data/id/WidgetsBundleId.java | 4 +- .../common/data/lwm2m/LwM2mInstance.java | 9 +- .../server/common/data/lwm2m/LwM2mObject.java | 17 +- .../data/lwm2m/LwM2mResourceObserve.java | 17 +- .../data/oauth2/OAuth2BasicMapperConfig.java | 21 +- .../common/data/oauth2/OAuth2ClientInfo.java | 11 +- .../OAuth2ClientRegistrationTemplate.java | 31 +- .../common/data/oauth2/OAuth2DomainInfo.java | 9 +- .../server/common/data/oauth2/OAuth2Info.java | 9 +- .../data/oauth2/OAuth2MapperConfig.java | 12 +- .../common/data/oauth2/OAuth2MobileInfo.java | 9 +- .../common/data/oauth2/OAuth2ParamsInfo.java | 11 +- .../data/oauth2/OAuth2RegistrationInfo.java | 33 +- .../data/objects/AttributesEntityView.java | 11 +- .../data/objects/TelemetryEntityView.java | 9 +- .../server/common/data/page/PageData.java | 13 +- .../data/plugin/ComponentDescriptor.java | 23 +- .../common/data/query/EntityCountQuery.java | 4 +- .../server/common/data/query/EntityKey.java | 4 +- .../server/common/data/query/KeyFilter.java | 4 +- .../common/data/relation/EntityRelation.java | 15 +- .../data/relation/EntityRelationInfo.java | 6 +- .../data/relation/EntityRelationsQuery.java | 9 +- .../relation/RelationEntityTypeFilter.java | 9 +- .../relation/RelationsSearchParameters.java | 17 +- .../server/common/data/rpc/Rpc.java | 23 +- .../rule/DefaultRuleChainCreateRequest.java | 7 +- .../common/data/rule/NodeConnectionInfo.java | 11 +- .../server/common/data/rule/RuleChain.java | 23 +- .../data/rule/RuleChainConnectionInfo.java | 13 +- .../common/data/rule/RuleChainData.java | 9 +- .../common/data/rule/RuleChainMetaData.java | 15 +- .../data/rule/RuleChainOutputLabelsUsage.java | 15 +- .../server/common/data/rule/RuleNode.java | 23 +- .../data/security/DeviceCredentials.java | 17 +- .../common/data/security/model/JwtPair.java | 9 +- .../data/security/model/JwtSettings.java | 13 +- .../data/security/model/SecuritySettings.java | 11 +- .../security/model/UserPasswordPolicy.java | 21 +- .../settings/AbstractUserDashboardInfo.java | 9 +- .../settings/LastVisitedDashboardInfo.java | 9 +- .../data/settings/StarredDashboardInfo.java | 7 +- .../data/settings/UserDashboardsInfo.java | 9 +- .../common/data/settings/UserSettings.java | 11 +- .../AwsSnsSmsProviderConfiguration.java | 11 +- .../config/SmppSmsProviderConfiguration.java | 34 +- .../data/sms/config/TestSmsRequest.java | 11 +- .../TwilioSmsProviderConfiguration.java | 11 +- .../tenant/profile/TenantProfileData.java | 9 +- .../common/data/widget/BaseWidgetType.java | 14 +- .../server/common/data/widget/WidgetType.java | 4 +- .../common/data/widget/WidgetTypeDetails.java | 6 +- .../common/data/widget/WidgetTypeInfo.java | 8 +- .../common/data/widget/WidgetsBundle.java | 21 +- .../transport/http/DeviceApiController.java | 133 ++--- pom.xml | 30 +- 208 files changed, 2462 insertions(+), 2712 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/config/annotations/ApiOperation.java delete mode 100644 application/src/main/java/org/thingsboard/server/springfox/SpringfoxHandlerProviderBeanPostProcessor.java diff --git a/application/pom.xml b/application/pom.xml index 1838c97c65..f473986211 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -262,8 +262,8 @@ opensmpp-core - org.thingsboard - springfox-boot-starter + org.springdoc + springdoc-openapi-starter-webmvc-ui com.sun.winsw diff --git a/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java b/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java index b780f0e8cd..5b80e21fe6 100644 --- a/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java +++ b/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java @@ -33,8 +33,7 @@ import java.util.Arrays; "org.thingsboard.server.dao", "org.thingsboard.server.common.stats", "org.thingsboard.server.common.transport.config.ssl", - "org.thingsboard.server.cache", - "org.thingsboard.server.springfox" + "org.thingsboard.server.cache" }) public class ThingsboardInstallApplication { diff --git a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java index c7616ed865..50104e866d 100644 --- a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java +++ b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java @@ -15,84 +15,58 @@ */ package org.thingsboard.server.config; -import com.fasterxml.classmate.TypeResolver; +import io.swagger.v3.core.converter.AnnotatedType; +import io.swagger.v3.core.converter.ModelConverters; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.PathItem; +import io.swagger.v3.oas.models.examples.Example; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; +import io.swagger.v3.oas.models.media.Content; +import io.swagger.v3.oas.models.media.MediaType; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.parameters.RequestBody; +import io.swagger.v3.oas.models.responses.ApiResponse; +import io.swagger.v3.oas.models.responses.ApiResponses; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; +import io.swagger.v3.oas.models.tags.Tag; import lombok.extern.slf4j.Slf4j; +import org.springdoc.core.customizers.OpenApiCustomizer; +import org.springdoc.core.models.GroupedOpenApi; +import org.springdoc.core.properties.SwaggerUiConfigProperties; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Profile; -import org.springframework.core.annotation.Order; -import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.security.core.annotation.AuthenticationPrincipal; 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; -import springfox.documentation.builders.ExampleBuilder; -import springfox.documentation.builders.OperationBuilder; -import springfox.documentation.builders.RepresentationBuilder; -import springfox.documentation.builders.RequestParameterBuilder; -import springfox.documentation.builders.ResponseBuilder; -import springfox.documentation.schema.Example; -import springfox.documentation.service.ApiDescription; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.ApiListing; -import springfox.documentation.service.AuthorizationScope; -import springfox.documentation.service.Contact; -import springfox.documentation.service.HttpLoginPasswordScheme; -import springfox.documentation.service.ParameterType; -import springfox.documentation.service.Response; -import springfox.documentation.service.SecurityReference; -import springfox.documentation.service.SecurityScheme; -import springfox.documentation.service.Tag; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spi.service.ApiListingBuilderPlugin; -import springfox.documentation.spi.service.ApiListingScannerPlugin; -import springfox.documentation.spi.service.contexts.ApiListingContext; -import springfox.documentation.spi.service.contexts.DocumentationContext; -import springfox.documentation.spi.service.contexts.OperationContext; -import springfox.documentation.spi.service.contexts.SecurityContext; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.spring.web.readers.operation.CachingOperationNameGenerator; -import springfox.documentation.swagger.common.SwaggerPluginSupport; -import springfox.documentation.swagger.web.DocExpansion; -import springfox.documentation.swagger.web.ModelRendering; -import springfox.documentation.swagger.web.OperationsSorter; -import springfox.documentation.swagger.web.UiConfiguration; -import springfox.documentation.swagger.web.UiConfigurationBuilder; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; + import java.util.List; -import java.util.Set; -import java.util.function.Consumer; -import java.util.function.Predicate; +import java.util.Map; -import static com.google.common.collect.Lists.newArrayList; -import static java.util.function.Predicate.not; -import static springfox.documentation.builders.PathSelectors.any; -import static springfox.documentation.builders.PathSelectors.regex; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @Slf4j -//@Configuration +@Configuration @TbCoreComponent @Profile("!test") public class SwaggerConfiguration { - @Value("${swagger.enabled:true}") - private boolean enabled; - @Value("${swagger.api_path_regex}") - private String apiPathRegex; - @Value("${swagger.security_path_regex}") - private String securityPathRegex; + public static final String LOGIN_ENDPOINT = "/api/auth/login"; + + @Value("${swagger.api_path:/api/**}") + private String apiPath; @Value("${swagger.non_security_path_regex}") private String nonSecurityPathRegex; @Value("${swagger.title}") @@ -115,288 +89,206 @@ public class SwaggerConfiguration { private String appVersion; @Bean - public Docket thingsboardApi() { - TypeResolver typeResolver = new TypeResolver(); - return new Docket(DocumentationType.OAS_30) - .enable(enabled) - .groupName("thingsboard") - .apiInfo(apiInfo()) - .additionalModels( - typeResolver.resolve(ThingsboardErrorResponse.class), - typeResolver.resolve(ThingsboardCredentialsExpiredResponse.class), - typeResolver.resolve(LoginRequest.class), - typeResolver.resolve(LoginResponse.class) - ) - .select() - .paths(apiPaths()) - .paths(any()) - .build() - .globalResponses(HttpMethod.GET, - defaultErrorResponses(false) - ) - .globalResponses(HttpMethod.POST, - defaultErrorResponses(true) - ) - .globalResponses(HttpMethod.DELETE, - defaultErrorResponses(false) - ) - .securitySchemes(newArrayList(httpLogin())) - .securityContexts(newArrayList(securityContext())) - .ignoredParameterTypes(AuthenticationPrincipal.class) - .enableUrlTemplating(true); - } + public OpenAPI tbOpenAPI() { + Contact contact = new Contact() + .name(contactName) + .url(contactUrl) + .email(contactEmail); - @Bean - @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER) - ApiListingScannerPlugin loginEndpointListingScanner(final CachingOperationNameGenerator operationNames) { - return new ApiListingScannerPlugin() { - @Override - public List apply(DocumentationContext context) { - return List.of(loginEndpointApiDescription(operationNames)); - } - - @Override - public boolean supports(DocumentationType delimiter) { - return DocumentationType.SWAGGER_2.equals(delimiter) || DocumentationType.OAS_30.equals(delimiter); - } - }; - } + License license = new License() + .name(licenseTitle) + .url(licenseUrl); - @Bean - @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER) - ApiListingBuilderPlugin loginEndpointListingBuilder() { - return new ApiListingBuilderPlugin() { - @Override - public void apply(ApiListingContext apiListingContext) { - if (apiListingContext.getResourceGroup().getGroupName().equals("default")) { - ApiListing apiListing = apiListingContext.apiListingBuilder().build(); - if (apiListing.getResourcePath().equals("/api/auth/login")) { - apiListingContext.apiListingBuilder().tags(Set.of(new Tag("login-endpoint", "Login Endpoint"))); - apiListingContext.apiListingBuilder().description("Login Endpoint"); - } - } - } + String apiVersion = version; + if (StringUtils.isEmpty(apiVersion)) { + apiVersion = appVersion; + } - @Override - public boolean supports(DocumentationType delimiter) { - return DocumentationType.SWAGGER_2.equals(delimiter) || DocumentationType.OAS_30.equals(delimiter); - } - }; + Info info = new Info() + .title(title) + .description(description) + .contact(contact) + .license(license) + .version(apiVersion); + + SecurityScheme securityScheme = new SecurityScheme() + .type(SecurityScheme.Type.HTTP) + .scheme("basic") + .bearerFormat("JWT") + .in(SecurityScheme.In.HEADER) + .description("Enter Username / Password"); + + var openApi = new OpenAPI() + .components(new Components().addSecuritySchemes("HTTP login form", securityScheme)) + .info(info); + addLoginOperation(openApi); + return openApi; } - @Bean - UiConfiguration uiConfig() { - return UiConfigurationBuilder.builder() - .deepLinking(true) - .displayOperationId(false) - .defaultModelsExpandDepth(1) - .defaultModelExpandDepth(1) - .defaultModelRendering(ModelRendering.EXAMPLE) - .displayRequestDuration(false) - .docExpansion(DocExpansion.NONE) - .filter(false) - .maxDisplayedTags(null) - .operationsSorter(OperationsSorter.ALPHA) - .showExtensions(false) - .showCommonExtensions(false) - .supportedSubmitMethods(UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS) - .validatorUrl(null) - .persistAuthorization(true) - .syntaxHighlightActivate(true) - .syntaxHighlightTheme("agate") - .build(); + public void addLoginOperation(OpenAPI openAPI) { + openAPI.getComponents() + .addSchemas("LoginRequest", ModelConverters.getInstance().readAllAsResolvedSchema(new AnnotatedType().type(LoginRequest.class)).schema) + .addSchemas("LoginResponse", ModelConverters.getInstance().readAllAsResolvedSchema(new AnnotatedType().type(LoginResponse.class)).schema) + .addSchemas("ThingsboardErrorResponse", ModelConverters.getInstance().readAllAsResolvedSchema(new AnnotatedType().type(ThingsboardErrorResponse.class)).schema) + .addSchemas("ThingsboardCredentialsExpiredResponse", ModelConverters.getInstance().readAllAsResolvedSchema(new AnnotatedType().type(ThingsboardCredentialsExpiredResponse.class)).schema); + + var operation = new Operation(); + operation.summary("Login method to get user JWT token data"); + operation.description("Login method used to authenticate user and get JWT token data.\n\nValue of the response **token** " + + "field can be used as **X-Authorization** header value:\n\n`X-Authorization: Bearer $JWT_TOKEN_VALUE`."); + var requestBody = new RequestBody().content(new Content().addMediaType(APPLICATION_JSON_VALUE, + new MediaType().schema(new Schema().$ref("#/components/schemas/LoginRequest")))); + operation.requestBody(requestBody); + operation.responses(getResponses()); + operation.addTagsItem("login-endpoint"); + var pathItem = new PathItem().post(operation); + openAPI.path(LOGIN_ENDPOINT, pathItem); } - private SecurityScheme httpLogin() { - return HttpLoginPasswordScheme - .X_AUTHORIZATION_BUILDER - .loginEndpoint("/api/auth/login") - .name("HTTP login form") - .description("Enter Username / Password") - .build(); - } + private ApiResponses getResponses() { + ApiResponses apiResponses = new ApiResponses(); + + apiResponses.addApiResponse("200", new ApiResponse().description("OK") + .content(new Content().addMediaType(APPLICATION_JSON_VALUE, + new MediaType().schema(new Schema().$ref("#/components/schemas/LoginResponse"))))); + + ApiResponse unauthorizedResponse = new ApiResponse().description("Unauthorized"); + Content content = new Content(); + MediaType mediaType = new MediaType().schema(new Schema().$ref("#/components/schemas/ThingsboardErrorResponse")); + + Map examples = Map.of( + "bad-credentials", errorExample("Bad credentials", + ThingsboardErrorResponse.of("Invalid username or password", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)), + "token-expired", errorExample("JWT token expired", + ThingsboardErrorResponse.of("Token has expired", ThingsboardErrorCode.JWT_TOKEN_EXPIRED, HttpStatus.UNAUTHORIZED)), + "account-disabled", errorExample("Disabled account", + ThingsboardErrorResponse.of("User account is not active", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)), + "account-locked", errorExample("Locked account", + ThingsboardErrorResponse.of("User account is locked due to security policy", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)), + "authentication-failed", errorExample("General authentication error", + ThingsboardErrorResponse.of("Authentication failed", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)) + ); - private SecurityContext securityContext() { - return SecurityContext.builder() - .securityReferences(defaultAuth()) - .operationSelector(securityPathOperationSelector()) - .build(); + mediaType.setExamples(examples); + content.addMediaType(APPLICATION_JSON_VALUE, mediaType); + unauthorizedResponse.setContent(content); + apiResponses.addApiResponse("401", unauthorizedResponse); + + ApiResponse expiredCredentialsResponse = new ApiResponse().description("Unauthorized (**Expired credentials**)"); + Content expiredContent = new Content(); + MediaType expiredMediaType = new MediaType().schema(new Schema().$ref("#/components/schemas/ThingsboardCredentialsExpiredResponse")); + expiredMediaType.addExamples("credentials-expired", errorExample("Expired credentials", + ThingsboardCredentialsExpiredResponse.of("User password expired!", StringUtils.randomAlphanumeric(30)))); + expiredContent.addMediaType(APPLICATION_JSON_VALUE, expiredMediaType); + expiredCredentialsResponse.setContent(expiredContent); + apiResponses.addApiResponse("401 ", expiredCredentialsResponse); + + return apiResponses; } - private Predicate apiPaths() { - return regex(apiPathRegex); + private Example errorExample(String summary, ThingsboardErrorResponse example) { + return new Example() + .summary(summary) + .value(example); } - private Predicate securityPathOperationSelector() { - return new SecurityPathOperationSelector(securityPathRegex, nonSecurityPathRegex); + @Bean + public GroupedOpenApi thingsboardApi() { + return GroupedOpenApi.builder() + .group("thingsboard") + .pathsToMatch(apiPath) + .addOpenApiCustomizer(customOpenApiCustomizer()) + .build(); } - List defaultAuth() { - AuthorizationScope[] authorizationScopes = new AuthorizationScope[3]; - authorizationScopes[0] = new AuthorizationScope(Authority.SYS_ADMIN.name(), "System administrator"); - authorizationScopes[1] = new AuthorizationScope(Authority.TENANT_ADMIN.name(), "Tenant administrator"); - authorizationScopes[2] = new AuthorizationScope(Authority.CUSTOMER_USER.name(), "Customer"); - return newArrayList( - new SecurityReference("HTTP login form", authorizationScopes)); + @Bean + @Primary + public SwaggerUiConfigProperties swaggerUiConfig(SwaggerUiConfigProperties uiProperties) { + uiProperties.setDeepLinking(true); + uiProperties.setDisplayOperationId(false); + uiProperties.setDefaultModelsExpandDepth(1); + uiProperties.setDefaultModelExpandDepth(1); + uiProperties.setDefaultModelRendering("example"); + uiProperties.setDisplayRequestDuration(false); + uiProperties.setDocExpansion("none"); + uiProperties.setFilter("false"); + uiProperties.setMaxDisplayedTags(null); + uiProperties.setOperationsSorter("alpha"); + uiProperties.setTagsSorter("alpha"); + uiProperties.setShowExtensions(false); + uiProperties.setShowCommonExtensions(false); + uiProperties.setSupportedSubmitMethods(List.of("get", "put", "post", "delete", "options", "head", "patch", "trace")); + uiProperties.setValidatorUrl(null); + uiProperties.setPersistAuthorization(true); + + var syntaxHighLight = new SwaggerUiConfigProperties.SyntaxHighlight(); + syntaxHighLight.setActivated(true); + syntaxHighLight.setTheme("agate"); + + uiProperties.setSyntaxHighlight(syntaxHighLight); + return uiProperties; } - 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(apiVersion) - .build(); - } + public OpenApiCustomizer customOpenApiCustomizer() { + SecurityRequirement loginForm = new SecurityRequirement().addList("HTTP login form"); - private ApiDescription loginEndpointApiDescription(final CachingOperationNameGenerator operationNames) { - return new ApiDescription(null, "/api/auth/login", "Login method to get user JWT token data", "Login endpoint", Collections.singletonList( - new OperationBuilder(operationNames) - .summary("Login method to get user JWT token data") - .tags(Set.of("login-endpoint")) - .authorizations(new ArrayList<>()) - .position(0) - .codegenMethodNameStem("loginPost") - .method(HttpMethod.POST) - .notes("Login method used to authenticate user and get JWT token data.\n\nValue of the response **token** " + - "field can be used as **X-Authorization** header value:\n\n`X-Authorization: Bearer $JWT_TOKEN_VALUE`.") - .requestParameters( - List.of( - new RequestParameterBuilder() - .in(ParameterType.BODY) - .required(true) - .description("Login request") - .content(c -> - c.requestBody(true) - .representation(MediaType.APPLICATION_JSON) - .apply(classRepresentation(LoginRequest.class, false)) - ) - .build() - ) - ) - .responses(loginResponses()) - .build() - ), false); - } + return openAPI -> openAPI.getPaths().entrySet().stream().peek(entry -> { + if (!(entry.getKey().matches(nonSecurityPathRegex) || entry.getKey().equals(LOGIN_ENDPOINT))) { + entry.getValue() + .readOperationsMap() + .values() + .forEach(operation -> operation.addSecurityItem(loginForm)); + } - private Collection loginResponses() { - List responses = new ArrayList<>(); - responses.add( - new ResponseBuilder() - .code("200") - .description("OK") - .representation(MediaType.APPLICATION_JSON) - .apply(classRepresentation(LoginResponse.class, true)). - build() - ); - responses.addAll(loginErrorResponses()); - return responses; - } + entry.getValue().readOperationsMap().forEach(((httpMethod, operation) -> { + operation.setResponses(getResponses(operation.getResponses(), httpMethod.equals(PathItem.HttpMethod.POST))); + })); - /** Helper methods **/ - - private List defaultErrorResponses(boolean isPost) { - return List.of( - errorResponse("400", "Bad Request", - ThingsboardErrorResponse.of(isPost ? "Invalid request body" : "Invalid UUID string: 123", ThingsboardErrorCode.BAD_REQUEST_PARAMS, HttpStatus.BAD_REQUEST)), - errorResponse("401", "Unauthorized", - ThingsboardErrorResponse.of("Authentication failed", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)), - errorResponse("403", "Forbidden", - ThingsboardErrorResponse.of("You don't have permission to perform this operation!", - ThingsboardErrorCode.PERMISSION_DENIED, HttpStatus.FORBIDDEN)), - errorResponse("404", "Not Found", - ThingsboardErrorResponse.of("Requested item wasn't found!", ThingsboardErrorCode.ITEM_NOT_FOUND, HttpStatus.NOT_FOUND)), - errorResponse("429", "Too Many Requests", - ThingsboardErrorResponse.of("Too many requests for current tenant!", - ThingsboardErrorCode.TOO_MANY_REQUESTS, HttpStatus.TOO_MANY_REQUESTS)) - ); + }).map(entry -> { + String tagItem = entry.getValue().readOperationsMap().values().stream().findAny().get().getTags().get(0); + return tagFromTagItem(tagItem); + }).forEach(openAPI::addTagsItem); } - private List loginErrorResponses() { - return List.of( - errorResponse("401", "Unauthorized", - List.of( - errorExample("bad-credentials", "Bad credentials", - ThingsboardErrorResponse.of("Invalid username or password", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)), - errorExample("token-expired", "JWT token expired", - ThingsboardErrorResponse.of("Token has expired", ThingsboardErrorCode.JWT_TOKEN_EXPIRED, HttpStatus.UNAUTHORIZED)), - errorExample("account-disabled", "Disabled account", - ThingsboardErrorResponse.of("User account is not active", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)), - errorExample("account-locked", "Locked account", - ThingsboardErrorResponse.of("User account is locked due to security policy", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)), - errorExample("authentication-failed", "General authentication error", - ThingsboardErrorResponse.of("Authentication failed", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)) - ) - ), - errorResponse("401 ", "Unauthorized (**Expired credentials**)", - List.of( - errorExample("credentials-expired", "Expired credentials", - ThingsboardCredentialsExpiredResponse.of("User password expired!", StringUtils.randomAlphanumeric(30))) - ), ThingsboardCredentialsExpiredResponse.class - ) - ); - } + private Tag tagFromTagItem(String tagItem) { + String[] words = tagItem.split("-"); + StringBuilder sb = new StringBuilder(); - private Response errorResponse(String code, String description, ThingsboardErrorResponse example) { - return errorResponse(code, description, List.of(errorExample("error-code-" + code, description, example))); - } + for (String word : words) { + sb.append(word.substring(0, 1).toUpperCase()); + sb.append(word.substring(1).toLowerCase()); + sb.append(" "); + } - private Response errorResponse(String code, String description, List examples) { - return errorResponse(code, description, examples, ThingsboardErrorResponse.class); + return new Tag().name(tagItem).description(sb.toString().trim()); } - private Response errorResponse(String code, String description, List examples, - Class errorResponseClass) { - return new ResponseBuilder() - .code(code) - .description(description) - .examples(examples) - .representation(MediaType.APPLICATION_JSON) - .apply(classRepresentation(errorResponseClass, true)) - .build(); - } + private ApiResponses getResponses(ApiResponses apiResponses, boolean isPost) { + if (apiResponses == null) { + apiResponses = new ApiResponses(); + } - private Example errorExample(String id, String summary, ThingsboardErrorResponse example) { - return new ExampleBuilder() - .mediaType(MediaType.APPLICATION_JSON_VALUE) - .summary(summary) - .id(id) - .value(example).build(); - } + apiResponses.addApiResponse("400", new ApiResponse().description("Bad Request") + .content(getErrorContent(ThingsboardErrorResponse.of(isPost ? "Invalid request body" : "Invalid UUID string: 123", ThingsboardErrorCode.BAD_REQUEST_PARAMS, HttpStatus.BAD_REQUEST)))); - private Consumer classRepresentation(Class clazz, boolean isResponse) { - return r -> r.model( - m -> - m.referenceModel(ref -> - ref.key(k -> - k.qualifiedModelName(q -> - q.namespace(clazz.getPackageName()) - .name(clazz.getSimpleName())).isResponse(isResponse))) - ); - } + apiResponses.addApiResponse("401", new ApiResponse().description("Unauthorized") + .content(getErrorContent(ThingsboardErrorResponse.of("Authentication failed", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)))); - private static class SecurityPathOperationSelector implements Predicate { + apiResponses.addApiResponse("403", new ApiResponse().description("Forbidden") + .content(getErrorContent(ThingsboardErrorResponse.of("You don't have permission to perform this operation!", ThingsboardErrorCode.PERMISSION_DENIED, HttpStatus.FORBIDDEN)))); - private final Predicate securityPathSelector; + apiResponses.addApiResponse("404", new ApiResponse().description("Not Found") + .content(getErrorContent(ThingsboardErrorResponse.of("Requested item wasn't found!", ThingsboardErrorCode.ITEM_NOT_FOUND, HttpStatus.NOT_FOUND)))); - SecurityPathOperationSelector(String securityPathRegex, String nonSecurityPathRegex) { - this.securityPathSelector = regex(securityPathRegex).and( - not( - regex(nonSecurityPathRegex) - )); - } + apiResponses.addApiResponse("429", new ApiResponse().description("Too Many Requests") + .content(getErrorContent(ThingsboardErrorResponse.of("Too many requests for current tenant!", ThingsboardErrorCode.TOO_MANY_REQUESTS, HttpStatus.TOO_MANY_REQUESTS)))); - @Override - public boolean test(OperationContext operationContext) { - return this.securityPathSelector.test(operationContext.requestMappingPattern()); - } + return apiResponses; } + private Content getErrorContent(ThingsboardErrorResponse errorResponse) { + return new Content().addMediaType(org.springframework.http.MediaType.APPLICATION_JSON_VALUE, + new MediaType().schema(new Schema().example(errorResponse))); + } } diff --git a/application/src/main/java/org/thingsboard/server/config/annotations/ApiOperation.java b/application/src/main/java/org/thingsboard/server/config/annotations/ApiOperation.java new file mode 100644 index 0000000000..d8710149a6 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/config/annotations/ApiOperation.java @@ -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.config.annotations; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import org.springframework.core.annotation.AliasFor; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Operation +public @interface ApiOperation { + + @AliasFor(annotation = Operation.class, attribute = "summary") + String value(); + + @AliasFor(annotation = Operation.class, attribute = "description") + String notes() default ""; + + boolean hidden() default false; + + RequestBody requestBody() default @RequestBody; + + ApiResponse[] responses() default {}; + +} diff --git a/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java b/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java index 5f33eb951e..faef8edd4a 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java @@ -17,6 +17,7 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.FutureCallback; +import jakarta.annotation.Nullable; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -45,7 +46,6 @@ import org.thingsboard.server.service.security.AccessValidator; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; -import jakarta.annotation.Nullable; import java.util.Optional; import java.util.UUID; diff --git a/application/src/main/java/org/thingsboard/server/controller/AdminController.java b/application/src/main/java/org/thingsboard/server/controller/AdminController.java index 5cf97a7cda..12c5abf47d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AdminController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AdminController.java @@ -19,8 +19,9 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Lazy; import org.springframework.http.HttpStatus; @@ -53,6 +54,7 @@ import org.thingsboard.server.common.data.sync.vc.AutoCommitSettings; import org.thingsboard.server.common.data.sync.vc.RepositorySettings; import org.thingsboard.server.common.data.sync.vc.RepositorySettingsInfo; import org.thingsboard.server.common.data.sync.vc.VcUtils; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.audit.AuditLogService; import org.thingsboard.server.dao.settings.AdminSettingsService; import org.thingsboard.server.queue.util.TbCoreComponent; @@ -96,7 +98,7 @@ public class AdminController extends BaseController { @RequestMapping(value = "/settings/{key}", method = RequestMethod.GET) @ResponseBody public AdminSettings getAdminSettings( - @ApiParam(value = "A string value of the key (e.g. 'general' or 'mail').") + @Parameter(description = "A string value of the key (e.g. 'general' or 'mail').") @PathVariable("key") String key) throws ThingsboardException { accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); AdminSettings adminSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, key), "No Administration settings found for key: " + key); @@ -114,7 +116,7 @@ public class AdminController extends BaseController { @RequestMapping(value = "/settings", method = RequestMethod.POST) @ResponseBody public AdminSettings saveAdminSettings( - @ApiParam(value = "A JSON value representing the Administration Settings.") + @Parameter(description = "A JSON value representing the Administration Settings.") @RequestBody AdminSettings adminSettings) throws ThingsboardException { accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.WRITE); adminSettings.setTenantId(getTenantId()); @@ -144,7 +146,7 @@ public class AdminController extends BaseController { @RequestMapping(value = "/securitySettings", method = RequestMethod.POST) @ResponseBody public SecuritySettings saveSecuritySettings( - @ApiParam(value = "A JSON value representing the Security Settings.") + @Parameter(description = "A JSON value representing the Security Settings.") @RequestBody SecuritySettings securitySettings) throws ThingsboardException { accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.WRITE); securitySettings = checkNotNull(systemSecurityService.saveSecuritySettings(TenantId.SYS_TENANT_ID, securitySettings)); @@ -153,7 +155,7 @@ public class AdminController extends BaseController { @ApiOperation(value = "Get the JWT Settings object (getJwtSettings)", notes = "Get the JWT Settings object that contains JWT token policy, etc. " + SYSTEM_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/jwtSettings", method = RequestMethod.GET) @ResponseBody @@ -164,12 +166,12 @@ public class AdminController extends BaseController { @ApiOperation(value = "Update JWT Settings (saveJwtSettings)", notes = "Updates the JWT Settings object that contains JWT token policy, etc. The tokenSigningKey field is a Base64 encoded string." + SYSTEM_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/jwtSettings", method = RequestMethod.POST) @ResponseBody public JwtPair saveJwtSettings( - @ApiParam(value = "A JSON value representing the JWT Settings.") + @Parameter(description = "A JSON value representing the JWT Settings.") @RequestBody JwtSettings jwtSettings) throws ThingsboardException { SecurityUser securityUser = getCurrentUser(); accessControlService.checkPermission(securityUser, Resource.ADMIN_SETTINGS, Operation.WRITE); @@ -183,7 +185,7 @@ public class AdminController extends BaseController { @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/settings/testMail", method = RequestMethod.POST) public void sendTestMail( - @ApiParam(value = "A JSON value representing the Mail Settings.") + @Parameter(description = "A JSON value representing the Mail Settings.") @RequestBody AdminSettings adminSettings) throws ThingsboardException { accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); adminSettings = checkNotNull(adminSettings); @@ -203,7 +205,7 @@ public class AdminController extends BaseController { @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/settings/testSms", method = RequestMethod.POST) public void sendTestSms( - @ApiParam(value = "A JSON value representing the Test SMS request.") + @Parameter(description = "A JSON value representing the Test SMS request.") @RequestBody TestSmsRequest testSmsRequest) throws ThingsboardException { SecurityUser user = getCurrentUser(); accessControlService.checkPermission(user, Resource.ADMIN_SETTINGS, Operation.READ); @@ -286,7 +288,7 @@ public class AdminController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/repositorySettings/checkAccess", method = RequestMethod.POST) public DeferredResult checkRepositoryAccess( - @ApiParam(value = "A JSON value representing the Repository Settings.") + @Parameter(description = "A JSON value representing the Repository Settings.") @RequestBody RepositorySettings settings) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); settings = checkNotNull(settings); diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java index 92b2cb923f..529b1fe48a 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java @@ -15,8 +15,10 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; @@ -35,17 +37,16 @@ import org.thingsboard.server.common.data.id.AlarmCommentId; import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.alarm.TbAlarmCommentService; import org.thingsboard.server.service.security.permission.Operation; import static org.thingsboard.server.controller.ControllerConstants.ALARM_COMMENT_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.ALARM_COMMENT_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.ALARM_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH; @@ -69,12 +70,12 @@ public class AlarmCommentController extends BaseController { "\n\n To create new Alarm comment entity it is enough to specify 'comment' json element with 'text' node, for example: {\"comment\": { \"text\": \"my comment\"}}. " + "\n\n If comment type is not specified the default value 'OTHER' will be saved. If 'alarmId' or 'userId' specified in body it will be ignored." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH - , produces = MediaType.APPLICATION_JSON_VALUE) + , responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/comment", method = RequestMethod.POST) @ResponseBody - public AlarmComment saveAlarmComment(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) - @PathVariable(ALARM_ID) String strAlarmId, @ApiParam(value = "A JSON value representing the comment.") @RequestBody AlarmComment alarmComment) throws ThingsboardException { + public AlarmComment saveAlarmComment(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) + @PathVariable(ALARM_ID) String strAlarmId, @Parameter(description = "A JSON value representing the comment.") @RequestBody AlarmComment alarmComment) throws ThingsboardException { checkParameter(ALARM_ID, strAlarmId); AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); Alarm alarm = checkAlarmId(alarmId, Operation.WRITE); @@ -83,11 +84,11 @@ public class AlarmCommentController extends BaseController { } @ApiOperation(value = "Delete Alarm comment (deleteAlarmComment)", - notes = "Deletes the Alarm comment. Referencing non-existing Alarm comment Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + notes = "Deletes the Alarm comment. Referencing non-existing Alarm comment Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/comment/{commentId}", method = RequestMethod.DELETE) @ResponseBody - public void deleteAlarmComment(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId, @ApiParam(value = ALARM_COMMENT_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_COMMENT_ID) String strCommentId) throws ThingsboardException { + public void deleteAlarmComment(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId, @Parameter(description = ALARM_COMMENT_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_COMMENT_ID) String strCommentId) throws ThingsboardException { checkParameter(ALARM_ID, strAlarmId); AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); Alarm alarm = checkAlarmId(alarmId, Operation.WRITE); @@ -99,20 +100,20 @@ public class AlarmCommentController extends BaseController { @ApiOperation(value = "Get Alarm comments (getAlarmComments)", notes = "Returns a page of alarm comments for specified alarm. " + - PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/comment", method = RequestMethod.GET) @ResponseBody public PageData getAlarmComments( - @ApiParam(value = ALARM_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ALARM_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ALARM_ID) String strAlarmId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_COMMENT_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "id"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder ) throws Exception { checkParameter(ALARM_ID, strAlarmId); diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java index 44263d19bd..18ad89f1a0 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java @@ -15,8 +15,10 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -45,6 +47,7 @@ import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.alarm.TbAlarmService; import org.thingsboard.server.service.security.permission.Operation; @@ -59,7 +62,6 @@ import java.util.concurrent.ExecutionException; import static org.thingsboard.server.controller.ControllerConstants.ALARM_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ALARM_INFO_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.ALARM_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.ASSIGNEE_ID; import static org.thingsboard.server.controller.ControllerConstants.ASSIGN_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID; @@ -69,7 +71,6 @@ import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE_ import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH; @@ -104,11 +105,11 @@ public class AlarmController extends BaseController { "filled in the AlarmInfo object field: 'originatorName' or will returns as null."; @ApiOperation(value = "Get Alarm (getAlarmById)", - notes = "Fetch the Alarm object based on the provided Alarm Id. " + ALARM_SECURITY_CHECK, produces = MediaType.APPLICATION_JSON_VALUE) + notes = "Fetch the Alarm object based on the provided Alarm Id. " + ALARM_SECURITY_CHECK, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}", method = RequestMethod.GET) @ResponseBody - public Alarm getAlarmById(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) + public Alarm getAlarmById(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { checkParameter(ALARM_ID, strAlarmId); AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); @@ -117,11 +118,11 @@ public class AlarmController extends BaseController { @ApiOperation(value = "Get Alarm Info (getAlarmInfoById)", notes = "Fetch the Alarm Info object based on the provided Alarm Id. " + - ALARM_SECURITY_CHECK + ALARM_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + ALARM_SECURITY_CHECK + ALARM_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/info/{alarmId}", method = RequestMethod.GET) @ResponseBody - public AlarmInfo getAlarmInfoById(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) + public AlarmInfo getAlarmInfoById(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { checkParameter(ALARM_ID, strAlarmId); AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); @@ -139,11 +140,11 @@ public class AlarmController extends BaseController { "If the user clears the alarm (see 'Clear Alarm(clearAlarm)'), than new alarm with the same type and same device may be created. " + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Alarm entity. " + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH - , produces = MediaType.APPLICATION_JSON_VALUE) + , responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm", method = RequestMethod.POST) @ResponseBody - public Alarm saveAlarm(@ApiParam(value = "A JSON value representing the alarm.") @RequestBody Alarm alarm) throws ThingsboardException { + public Alarm saveAlarm(@Parameter(description = "A JSON value representing the alarm.") @RequestBody Alarm alarm) throws ThingsboardException { alarm.setTenantId(getTenantId()); checkNotNull(alarm.getOriginator()); checkEntity(alarm.getId(), alarm, Resource.ALARM); @@ -155,11 +156,11 @@ public class AlarmController extends BaseController { } @ApiOperation(value = "Delete Alarm (deleteAlarm)", - notes = "Deletes the Alarm. Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + notes = "Deletes the Alarm. Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}", method = RequestMethod.DELETE) @ResponseBody - public Boolean deleteAlarm(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { + public Boolean deleteAlarm(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { checkParameter(ALARM_ID, strAlarmId); AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); Alarm alarm = checkAlarmId(alarmId, Operation.DELETE); @@ -169,11 +170,11 @@ public class AlarmController extends BaseController { @ApiOperation(value = "Acknowledge Alarm (ackAlarm)", notes = "Acknowledge the Alarm. " + "Once acknowledged, the 'ack_ts' field will be set to current timestamp and special rule chain event 'ALARM_ACK' will be generated. " + - "Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + "Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/ack", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) - public AlarmInfo ackAlarm(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws Exception { + public AlarmInfo ackAlarm(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws Exception { checkParameter(ALARM_ID, strAlarmId); AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); Alarm alarm = checkAlarmId(alarmId, Operation.WRITE); @@ -184,11 +185,11 @@ public class AlarmController extends BaseController { @ApiOperation(value = "Clear Alarm (clearAlarm)", notes = "Clear the Alarm. " + "Once cleared, the 'clear_ts' field will be set to current timestamp and special rule chain event 'ALARM_CLEAR' will be generated. " + - "Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + "Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/clear", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) - public AlarmInfo clearAlarm(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws Exception { + public AlarmInfo clearAlarm(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws Exception { checkParameter(ALARM_ID, strAlarmId); AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); Alarm alarm = checkAlarmId(alarmId, Operation.WRITE); @@ -200,13 +201,13 @@ public class AlarmController extends BaseController { notes = "Assign the Alarm. " + "Once assigned, the 'assign_ts' field will be set to current timestamp and special rule chain event 'ALARM_ASSIGNED' " + "(or ALARM_REASSIGNED in case of assigning already assigned alarm) will be generated. " + - "Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + "Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/assign/{assigneeId}", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) - public Alarm assignAlarm(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) + public Alarm assignAlarm(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId, - @ApiParam(value = ASSIGN_ID_PARAM_DESCRIPTION) + @Parameter(description = ASSIGN_ID_PARAM_DESCRIPTION) @PathVariable(ASSIGNEE_ID) String strAssigneeId ) throws Exception { checkParameter(ALARM_ID, strAlarmId); @@ -221,11 +222,11 @@ public class AlarmController extends BaseController { @ApiOperation(value = "Unassign Alarm (unassignAlarm)", notes = "Unassign the Alarm. " + "Once unassigned, the 'assign_ts' field will be set to current timestamp and special rule chain event 'ALARM_UNASSIGNED' will be generated. " + - "Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + "Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/assign", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public Alarm unassignAlarm(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) + public Alarm unassignAlarm(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId ) throws Exception { checkParameter(ALARM_ID, strAlarmId); @@ -236,36 +237,36 @@ public class AlarmController extends BaseController { @ApiOperation(value = "Get Alarms (getAlarms)", notes = "Returns a page of alarms for the selected entity. Specifying both parameters 'searchStatus' and 'status' at the same time will cause an error. " + - PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{entityType}/{entityId}", method = RequestMethod.GET) @ResponseBody public PageData getAlarms( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable(ENTITY_TYPE) String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @ApiParam(value = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)) @RequestParam(required = false) String searchStatus, - @ApiParam(value = ALARM_QUERY_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES)) @RequestParam(required = false) String status, - @ApiParam(value = ALARM_QUERY_ASSIGNEE_DESCRIPTION) + @Parameter(description = ALARM_QUERY_ASSIGNEE_DESCRIPTION) @RequestParam(required = false) String assigneeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "startTs", "endTs", "type", "ackTs", "clearTs", "severity", "status"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = ALARM_QUERY_START_TIME_DESCRIPTION) + @Parameter(description = ALARM_QUERY_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = ALARM_QUERY_END_TIME_DESCRIPTION) + @Parameter(description = ALARM_QUERY_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime, - @ApiParam(value = ALARM_QUERY_FETCH_ORIGINATOR_DESCRIPTION) + @Parameter(description = ALARM_QUERY_FETCH_ORIGINATOR_DESCRIPTION) @RequestParam(required = false) Boolean fetchOriginator ) throws ThingsboardException, ExecutionException, InterruptedException { checkParameter("EntityId", strEntityId); @@ -292,32 +293,32 @@ public class AlarmController extends BaseController { "If the user has the authority of 'Tenant Administrator', the server returns alarms that belongs to the tenant of current user. " + "If the user has the authority of 'Customer User', the server returns alarms that belongs to the customer of current user. " + "Specifying both parameters 'searchStatus' and 'status' at the same time will cause an error. " + - PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarms", method = RequestMethod.GET) @ResponseBody public PageData getAllAlarms( - @ApiParam(value = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)) @RequestParam(required = false) String searchStatus, - @ApiParam(value = ALARM_QUERY_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES)) @RequestParam(required = false) String status, - @ApiParam(value = ALARM_QUERY_ASSIGNEE_DESCRIPTION) + @Parameter(description = ALARM_QUERY_ASSIGNEE_DESCRIPTION) @RequestParam(required = false) String assigneeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "startTs", "endTs", "type", "ackTs", "clearTs", "severity", "status"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = ALARM_QUERY_START_TIME_DESCRIPTION) + @Parameter(description = ALARM_QUERY_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = ALARM_QUERY_END_TIME_DESCRIPTION) + @Parameter(description = ALARM_QUERY_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime, - @ApiParam(value = ALARM_QUERY_FETCH_ORIGINATOR_DESCRIPTION) + @Parameter(description = ALARM_QUERY_FETCH_ORIGINATOR_DESCRIPTION) @RequestParam(required = false) Boolean fetchOriginator ) throws ThingsboardException, ExecutionException, InterruptedException { AlarmSearchStatus alarmSearchStatus = StringUtils.isEmpty(searchStatus) ? null : AlarmSearchStatus.valueOf(searchStatus); @@ -341,36 +342,36 @@ public class AlarmController extends BaseController { @ApiOperation(value = "Get Alarms (getAlarmsV2)", notes = "Returns a page of alarms for the selected entity. " + - PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/v2/alarm/{entityType}/{entityId}", method = RequestMethod.GET) @ResponseBody public PageData getAlarmsV2( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable(ENTITY_TYPE) String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @ApiParam(value = ALARM_QUERY_SEARCH_STATUS_ARRAY_DESCRIPTION, allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_SEARCH_STATUS_ARRAY_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)) @RequestParam(required = false) String[] statusList, - @ApiParam(value = ALARM_QUERY_SEVERITY_ARRAY_DESCRIPTION, allowableValues = ALARM_QUERY_SEVERITY_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_SEVERITY_ARRAY_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEVERITY_ALLOWABLE_VALUES)) @RequestParam(required = false) String[] severityList, - @ApiParam(value = ALARM_QUERY_TYPE_ARRAY_DESCRIPTION) + @Parameter(description = ALARM_QUERY_TYPE_ARRAY_DESCRIPTION) @RequestParam(required = false) String[] typeList, - @ApiParam(value = ALARM_QUERY_ASSIGNEE_DESCRIPTION) + @Parameter(description = ALARM_QUERY_ASSIGNEE_DESCRIPTION) @RequestParam(required = false) String assigneeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "startTs", "endTs", "type", "ackTs", "clearTs", "severity", "status"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = ALARM_QUERY_START_TIME_DESCRIPTION) + @Parameter(description = ALARM_QUERY_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = ALARM_QUERY_END_TIME_DESCRIPTION) + @Parameter(description = ALARM_QUERY_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime ) throws ThingsboardException, ExecutionException, InterruptedException { checkParameter("EntityId", strEntityId); @@ -407,32 +408,32 @@ public class AlarmController extends BaseController { notes = "Returns a page of alarms that belongs to the current user owner. " + "If the user has the authority of 'Tenant Administrator', the server returns alarms that belongs to the tenant of current user. " + "If the user has the authority of 'Customer User', the server returns alarms that belongs to the customer of current user. " + - PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/v2/alarms", method = RequestMethod.GET) @ResponseBody public PageData getAllAlarmsV2( - @ApiParam(value = ALARM_QUERY_SEARCH_STATUS_ARRAY_DESCRIPTION, allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_SEARCH_STATUS_ARRAY_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)) @RequestParam(required = false) String[] statusList, - @ApiParam(value = ALARM_QUERY_SEVERITY_ARRAY_DESCRIPTION, allowableValues = ALARM_QUERY_SEVERITY_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_SEVERITY_ARRAY_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEVERITY_ALLOWABLE_VALUES)) @RequestParam(required = false) String[] severityList, - @ApiParam(value = ALARM_QUERY_TYPE_ARRAY_DESCRIPTION) + @Parameter(description = ALARM_QUERY_TYPE_ARRAY_DESCRIPTION) @RequestParam(required = false) String[] typeList, - @ApiParam(value = ALARM_QUERY_ASSIGNEE_DESCRIPTION) + @Parameter(description = ALARM_QUERY_ASSIGNEE_DESCRIPTION) @RequestParam(required = false) String assigneeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "startTs", "endTs", "type", "ackTs", "clearTs", "severity", "status"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = ALARM_QUERY_START_TIME_DESCRIPTION) + @Parameter(description = ALARM_QUERY_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = ALARM_QUERY_END_TIME_DESCRIPTION) + @Parameter(description = ALARM_QUERY_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime ) throws ThingsboardException, ExecutionException, InterruptedException { List alarmStatusList = new ArrayList<>(); @@ -468,20 +469,20 @@ public class AlarmController extends BaseController { @ApiOperation(value = "Get Highest Alarm Severity (getHighestAlarmSeverity)", notes = "Search the alarms by originator ('entityType' and entityId') and optional 'status' or 'searchStatus' filters and returns the highest AlarmSeverity(CRITICAL, MAJOR, MINOR, WARNING or INDETERMINATE). " + "Specifying both parameters 'searchStatus' and 'status' at the same time will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH - , produces = MediaType.APPLICATION_JSON_VALUE) + , responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/highestSeverity/{entityType}/{entityId}", method = RequestMethod.GET) @ResponseBody public AlarmSeverity getHighestAlarmSeverity( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable(ENTITY_TYPE) String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @ApiParam(value = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)) @RequestParam(required = false) String searchStatus, - @ApiParam(value = ALARM_QUERY_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES)) @RequestParam(required = false) String status, - @ApiParam(value = ALARM_QUERY_ASSIGNEE_DESCRIPTION) + @Parameter(description = ALARM_QUERY_ASSIGNEE_DESCRIPTION) @RequestParam(required = false) String assigneeId ) throws ThingsboardException { checkParameter("EntityId", strEntityId); diff --git a/application/src/main/java/org/thingsboard/server/controller/AssetController.java b/application/src/main/java/org/thingsboard/server/controller/AssetController.java index 510fefe305..79d8d88352 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AssetController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AssetController.java @@ -16,8 +16,10 @@ package org.thingsboard.server.controller; import com.google.common.util.concurrent.ListenableFuture; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -49,6 +51,7 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportRequest; import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportResult; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.queue.util.TbCoreComponent; @@ -67,7 +70,6 @@ import static org.thingsboard.server.controller.ControllerConstants.ASSET_ID_PAR import static org.thingsboard.server.controller.ControllerConstants.ASSET_INFO_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ASSET_NAME_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.ASSET_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.ASSET_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ASSET_TYPE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION; @@ -79,7 +81,6 @@ import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIG import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -102,11 +103,11 @@ public class AssetController extends BaseController { notes = "Fetch the Asset object based on the provided Asset Id. " + "If the user has the authority of 'Tenant Administrator', the server checks that the asset is owned by the same tenant. " + "If the user has the authority of 'Customer User', the server checks that the asset is assigned to the same customer." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH - , produces = MediaType.APPLICATION_JSON_VALUE) + , responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/asset/{assetId}", method = RequestMethod.GET) @ResponseBody - public Asset getAssetById(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) + public Asset getAssetById(@Parameter(description = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { checkParameter(ASSET_ID, strAssetId); AssetId assetId = new AssetId(toUUID(strAssetId)); @@ -117,11 +118,11 @@ public class AssetController extends BaseController { notes = "Fetch the Asset Info object based on the provided Asset Id. " + "If the user has the authority of 'Tenant Administrator', the server checks that the asset is owned by the same tenant. " + "If the user has the authority of 'Customer User', the server checks that the asset is assigned to the same customer. " - + ASSET_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + + ASSET_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/asset/info/{assetId}", method = RequestMethod.GET) @ResponseBody - public AssetInfo getAssetInfoById(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) + public AssetInfo getAssetInfoById(@Parameter(description = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { checkParameter(ASSET_ID, strAssetId); AssetId assetId = new AssetId(toUUID(strAssetId)); @@ -134,11 +135,11 @@ public class AssetController extends BaseController { "Specify existing Asset id to update the asset. " + "Referencing non-existing Asset Id will cause 'Not Found' error. " + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Asset entity. " - + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/asset", method = RequestMethod.POST) @ResponseBody - public Asset saveAsset(@ApiParam(value = "A JSON value representing the asset.") @RequestBody Asset asset) throws Exception { + public Asset saveAsset(@Parameter(description = "A JSON value representing the asset.") @RequestBody Asset asset) throws Exception { asset.setTenantId(getTenantId()); checkEntity(asset.getId(), asset, Resource.ASSET); return tbAssetService.save(asset, getCurrentUser()); @@ -149,7 +150,7 @@ public class AssetController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/asset/{assetId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteAsset(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws Exception { + public void deleteAsset(@Parameter(description = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws Exception { checkParameter(ASSET_ID, strAssetId); AssetId assetId = new AssetId(toUUID(strAssetId)); Asset asset = checkAssetId(assetId, Operation.DELETE); @@ -157,12 +158,12 @@ public class AssetController extends BaseController { } @ApiOperation(value = "Assign asset to customer (assignAssetToCustomer)", - notes = "Creates assignment of the asset to customer. Customer will be able to query asset afterwards." + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + notes = "Creates assignment of the asset to customer. Customer will be able to query asset afterwards." + TENANT_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/{customerId}/asset/{assetId}", method = RequestMethod.POST) @ResponseBody - public Asset assignAssetToCustomer(@ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { + public Asset assignAssetToCustomer(@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId, + @Parameter(description = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { checkParameter("customerId", strCustomerId); checkParameter(ASSET_ID, strAssetId); CustomerId customerId = new CustomerId(toUUID(strCustomerId)); @@ -173,11 +174,11 @@ public class AssetController extends BaseController { } @ApiOperation(value = "Unassign asset from customer (unassignAssetFromCustomer)", - notes = "Clears assignment of the asset to customer. Customer will not be able to query asset afterwards." + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + notes = "Clears assignment of the asset to customer. Customer will not be able to query asset afterwards." + TENANT_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/asset/{assetId}", method = RequestMethod.DELETE) @ResponseBody - public Asset unassignAssetFromCustomer(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { + public Asset unassignAssetFromCustomer(@Parameter(description = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { checkParameter(ASSET_ID, strAssetId); AssetId assetId = new AssetId(toUUID(strAssetId)); Asset asset = checkAssetId(assetId, Operation.UNASSIGN_FROM_CUSTOMER); @@ -191,11 +192,11 @@ public class AssetController extends BaseController { @ApiOperation(value = "Make asset publicly available (assignAssetToPublicCustomer)", notes = "Asset will be available for non-authorized (not logged-in) users. " + "This is useful to create dashboards that you plan to share/embed on a publicly available website. " + - "However, users that are logged-in and belong to different tenant will not be able to access the asset." + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + "However, users that are logged-in and belong to different tenant will not be able to access the asset." + TENANT_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/public/asset/{assetId}", method = RequestMethod.POST) @ResponseBody - public Asset assignAssetToPublicCustomer(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { + public Asset assignAssetToPublicCustomer(@Parameter(description = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { checkParameter(ASSET_ID, strAssetId); AssetId assetId = new AssetId(toUUID(strAssetId)); checkAssetId(assetId, Operation.ASSIGN_TO_CUSTOMER); @@ -204,22 +205,22 @@ public class AssetController extends BaseController { @ApiOperation(value = "Get Tenant Assets (getTenantAssets)", notes = "Returns a page of assets owned by tenant. " + - PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/assets", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantAssets( - @ApiParam(value = PAGE_SIZE_DESCRIPTION) + @Parameter(description = PAGE_SIZE_DESCRIPTION) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION) + @Parameter(description = PAGE_NUMBER_DESCRIPTION) @RequestParam int page, - @ApiParam(value = ASSET_TYPE_DESCRIPTION) + @Parameter(description = ASSET_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ASSET_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -232,24 +233,24 @@ public class AssetController extends BaseController { @ApiOperation(value = "Get Tenant Asset Infos (getTenantAssetInfos)", notes = "Returns a page of assets info objects owned by tenant. " + - PAGE_DATA_PARAMETERS + ASSET_INFO_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + ASSET_INFO_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/assetInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantAssetInfos( - @ApiParam(value = PAGE_SIZE_DESCRIPTION) + @Parameter(description = PAGE_SIZE_DESCRIPTION) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION) + @Parameter(description = PAGE_NUMBER_DESCRIPTION) @RequestParam int page, - @ApiParam(value = ASSET_TYPE_DESCRIPTION) + @Parameter(description = ASSET_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = ASSET_PROFILE_ID_PARAM_DESCRIPTION) @RequestParam(required = false) String assetProfileId, - @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ASSET_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -265,12 +266,12 @@ public class AssetController extends BaseController { @ApiOperation(value = "Get Tenant Asset (getTenantAsset)", notes = "Requested asset must be owned by tenant that the user belongs to. " + - "Asset name is an unique property of asset. So it can be used to identify the asset." + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + "Asset name is an unique property of asset. So it can be used to identify the asset." + TENANT_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/assets", params = {"assetName"}, method = RequestMethod.GET) @ResponseBody public Asset getTenantAsset( - @ApiParam(value = ASSET_NAME_DESCRIPTION) + @Parameter(description = ASSET_NAME_DESCRIPTION) @RequestParam String assetName) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); return checkNotNull(assetService.findAssetByTenantIdAndName(tenantId, assetName)); @@ -278,24 +279,24 @@ public class AssetController extends BaseController { @ApiOperation(value = "Get Customer Assets (getCustomerAssets)", notes = "Returns a page of assets objects assigned to customer. " + - PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/customer/{customerId}/assets", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerAssets( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION) + @Parameter(description = PAGE_SIZE_DESCRIPTION) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION) + @Parameter(description = PAGE_NUMBER_DESCRIPTION) @RequestParam int page, - @ApiParam(value = ASSET_TYPE_DESCRIPTION) + @Parameter(description = ASSET_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ASSET_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("customerId", strCustomerId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -311,26 +312,26 @@ public class AssetController extends BaseController { @ApiOperation(value = "Get Customer Asset Infos (getCustomerAssetInfos)", notes = "Returns a page of assets info objects assigned to customer. " + - PAGE_DATA_PARAMETERS + ASSET_INFO_DESCRIPTION, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + ASSET_INFO_DESCRIPTION, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/customer/{customerId}/assetInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerAssetInfos( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION) + @Parameter(description = PAGE_SIZE_DESCRIPTION) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION) + @Parameter(description = PAGE_NUMBER_DESCRIPTION) @RequestParam int page, - @ApiParam(value = ASSET_TYPE_DESCRIPTION) + @Parameter(description = ASSET_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = ASSET_PROFILE_ID_PARAM_DESCRIPTION) @RequestParam(required = false) String assetProfileId, - @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ASSET_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("customerId", strCustomerId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -348,12 +349,12 @@ public class AssetController extends BaseController { } @ApiOperation(value = "Get Assets By Ids (getAssetsByIds)", - notes = "Requested assets must be owned by tenant or assigned to customer which user is performing the request. ", produces = MediaType.APPLICATION_JSON_VALUE) + notes = "Requested assets must be owned by tenant or assigned to customer which user is performing the request. ", responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/assets", params = {"assetIds"}, method = RequestMethod.GET) @ResponseBody public List getAssetsByIds( - @ApiParam(value = "A list of assets ids, separated by comma ','") + @Parameter(description = "A list of assets ids, separated by comma ','") @RequestParam("assetIds") String[] strAssetIds) throws ThingsboardException, ExecutionException, InterruptedException { checkArrayParameter("assetIds", strAssetIds); SecurityUser user = getCurrentUser(); @@ -375,7 +376,7 @@ public class AssetController extends BaseController { @ApiOperation(value = "Find related assets (findByQuery)", notes = "Returns all assets that are related to the specific entity. " + "The entity id, relation type, asset types, depth of the search, and other query parameters defined using complex 'AssetSearchQuery' object. " + - "See 'Model' tab of the Parameters for more info.", produces = MediaType.APPLICATION_JSON_VALUE) + "See 'Model' tab of the Parameters for more info.", responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/assets", method = RequestMethod.POST) @ResponseBody @@ -397,7 +398,7 @@ public class AssetController extends BaseController { } @ApiOperation(value = "Get Asset Types (getAssetTypes)", - notes = "Returns a set of unique asset types based on assets that are either owned by the tenant or assigned to the customer which user is performing the request.", produces = MediaType.APPLICATION_JSON_VALUE) + notes = "Returns a set of unique asset types based on assets that are either owned by the tenant or assigned to the customer which user is performing the request.", responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/asset/types", method = RequestMethod.GET) @ResponseBody @@ -414,12 +415,12 @@ public class AssetController extends BaseController { "Second, remote edge service will receive a copy of assignment asset " + EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once asset will be delivered to edge service, it's going to be available for usage on remote edge instance.", - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/asset/{assetId}", method = RequestMethod.POST) @ResponseBody - public Asset assignAssetToEdge(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { + public Asset assignAssetToEdge(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION) @PathVariable(EDGE_ID) String strEdgeId, + @Parameter(description = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); checkParameter(ASSET_ID, strAssetId); @@ -438,12 +439,12 @@ public class AssetController extends BaseController { "Second, remote edge service will receive an 'unassign' command to remove asset " + EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once 'unassign' command will be delivered to edge service, it's going to remove asset locally.", - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/asset/{assetId}", method = RequestMethod.DELETE) @ResponseBody - public Asset unassignAssetFromEdge(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { + public Asset unassignAssetFromEdge(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION) @PathVariable(EDGE_ID) String strEdgeId, + @Parameter(description = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); checkParameter(ASSET_ID, strAssetId); EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); @@ -457,28 +458,28 @@ public class AssetController extends BaseController { @ApiOperation(value = "Get assets assigned to edge (getEdgeAssets)", notes = "Returns a page of assets assigned to edge. " + - PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/edge/{edgeId}/assets", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getEdgeAssets( - @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION) + @Parameter(description = EDGE_ID_PARAM_DESCRIPTION) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION) + @Parameter(description = PAGE_SIZE_DESCRIPTION) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION) + @Parameter(description = PAGE_NUMBER_DESCRIPTION) @RequestParam int page, - @ApiParam(value = ASSET_TYPE_DESCRIPTION) + @Parameter(description = ASSET_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ASSET_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = "Timestamp. Assets with creation time before it won't be queried") + @Parameter(description = "Timestamp. Assets with creation time before it won't be queried") @RequestParam(required = false) Long startTime, - @ApiParam(value = "Timestamp. Assets with creation time after it won't be queried") + @Parameter(description = "Timestamp. Assets with creation time after it won't be queried") @RequestParam(required = false) Long endTime) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -507,7 +508,7 @@ public class AssetController extends BaseController { } @ApiOperation(value = "Import the bulk of assets (processAssetsBulkImport)", - notes = "There's an ability to import the bulk of assets using the only .csv file.", produces = MediaType.APPLICATION_JSON_VALUE) + notes = "There's an ability to import the bulk of assets using the only .csv file.", responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @PostMapping("/asset/bulk_import") public BulkImportResult processAssetsBulkImport(@RequestBody BulkImportRequest request) throws Exception { diff --git a/application/src/main/java/org/thingsboard/server/controller/AssetProfileController.java b/application/src/main/java/org/thingsboard/server/controller/AssetProfileController.java index 47a7eede4b..0d6f652241 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AssetProfileController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AssetProfileController.java @@ -15,11 +15,14 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -35,6 +38,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.AssetProfileId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.asset.profile.TbAssetProfileService; import org.thingsboard.server.service.security.permission.Operation; @@ -43,13 +47,11 @@ import org.thingsboard.server.service.security.permission.Resource; import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_ID; import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_INFO_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -68,12 +70,12 @@ public class AssetProfileController extends BaseController { @ApiOperation(value = "Get Asset Profile (getAssetProfileById)", notes = "Fetch the Asset Profile object based on the provided Asset Profile Id. " + "The server checks that the asset profile is owned by the same tenant. " + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/assetProfile/{assetProfileId}", method = RequestMethod.GET) @ResponseBody public AssetProfile getAssetProfileById( - @ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = ASSET_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_PROFILE_ID) String strAssetProfileId) throws ThingsboardException { checkParameter(ASSET_PROFILE_ID, strAssetProfileId); AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId)); @@ -83,12 +85,12 @@ public class AssetProfileController extends BaseController { @ApiOperation(value = "Get Asset Profile Info (getAssetProfileInfoById)", notes = "Fetch the Asset Profile Info object based on the provided Asset Profile Id. " + ASSET_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/assetProfileInfo/{assetProfileId}", method = RequestMethod.GET) @ResponseBody public AssetProfileInfo getAssetProfileInfoById( - @ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = ASSET_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_PROFILE_ID) String strAssetProfileId) throws ThingsboardException { checkParameter(ASSET_PROFILE_ID, strAssetProfileId); AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId)); @@ -98,7 +100,7 @@ public class AssetProfileController extends BaseController { @ApiOperation(value = "Get Default Asset Profile (getDefaultAssetProfileInfo)", notes = "Fetch the Default Asset Profile Info object. " + ASSET_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/assetProfileInfo/default", method = RequestMethod.GET) @ResponseBody @@ -114,13 +116,12 @@ public class AssetProfileController extends BaseController { "Asset profile name is unique in the scope of tenant. Only one 'default' asset profile may exist in scope of tenant. " + "Remove 'id', 'tenantId' from the request body example (below) to create new Asset Profile entity. " + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json", - consumes = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/assetProfile", method = RequestMethod.POST) @ResponseBody public AssetProfile saveAssetProfile( - @ApiParam(value = "A JSON value representing the asset profile.") + @Parameter(description = "A JSON value representing the asset profile.") @RequestBody AssetProfile assetProfile) throws Exception { assetProfile.setTenantId(getTenantId()); checkEntity(assetProfile.getId(), assetProfile, Resource.ASSET_PROFILE); @@ -130,12 +131,12 @@ public class AssetProfileController extends BaseController { @ApiOperation(value = "Delete asset profile (deleteAssetProfile)", notes = "Deletes the asset profile. Referencing non-existing asset profile Id will cause an error. " + "Can't delete the asset profile if it is referenced by existing assets." + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/assetProfile/{assetProfileId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) public void deleteAssetProfile( - @ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = ASSET_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_PROFILE_ID) String strAssetProfileId) throws ThingsboardException { checkParameter(ASSET_PROFILE_ID, strAssetProfileId); AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId)); @@ -145,12 +146,12 @@ public class AssetProfileController extends BaseController { @ApiOperation(value = "Make Asset Profile Default (setDefaultAssetProfile)", notes = "Marks asset profile as default within a tenant scope." + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/assetProfile/{assetProfileId}/default", method = RequestMethod.POST) @ResponseBody public AssetProfile setDefaultAssetProfile( - @ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = ASSET_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_PROFILE_ID) String strAssetProfileId) throws ThingsboardException { checkParameter(ASSET_PROFILE_ID, strAssetProfileId); AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId)); @@ -162,20 +163,20 @@ public class AssetProfileController extends BaseController { @ApiOperation(value = "Get Asset Profiles (getAssetProfiles)", notes = "Returns a page of asset profile objects owned by tenant. " + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/assetProfiles", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getAssetProfiles( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ASSET_PROFILE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ASSET_PROFILE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "description", "isDefault"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return checkNotNull(assetProfileService.findAssetProfiles(getTenantId(), pageLink)); @@ -184,20 +185,20 @@ public class AssetProfileController extends BaseController { @ApiOperation(value = "Get Asset Profile infos (getAssetProfileInfos)", notes = "Returns a page of asset profile info objects owned by tenant. " + PAGE_DATA_PARAMETERS + ASSET_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/assetProfileInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getAssetProfileInfos( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ASSET_PROFILE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ASSET_PROFILE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "description", "isDefault"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return checkNotNull(assetProfileService.findAssetProfileInfos(getTenantId(), pageLink)); diff --git a/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java b/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java index 387f0d014b..71113d41fa 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java @@ -15,8 +15,10 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; @@ -35,6 +37,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Arrays; @@ -42,7 +45,6 @@ import java.util.List; import java.util.UUID; import java.util.stream.Collectors; -import static org.thingsboard.server.controller.ControllerConstants.AUDIT_LOG_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.AUDIT_LOG_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID_PARAM_DESCRIPTION; @@ -50,7 +52,6 @@ import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE_ import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; import static org.thingsboard.server.controller.ControllerConstants.USER_ID_PARAM_DESCRIPTION; @@ -74,28 +75,28 @@ public class AuditLogController extends BaseController { notes = "Returns a page of audit logs related to the targeted customer entities (devices, assets, etc.), " + "and users actions (login, logout, etc.) that belong to this customer. " + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/audit/logs/customer/{customerId}", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getAuditLogsByCustomerId( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION) + @Parameter(description = PAGE_SIZE_DESCRIPTION) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION) + @Parameter(description = PAGE_NUMBER_DESCRIPTION) @RequestParam int page, - @ApiParam(value = AUDIT_LOG_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = AUDIT_LOG_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = AUDIT_LOG_SORT_PROPERTY_DESCRIPTION, allowableValues = AUDIT_LOG_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = AUDIT_LOG_SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "entityType", "entityName", "userName", "actionType", "actionStatus"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = AUDIT_LOG_QUERY_START_TIME_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = AUDIT_LOG_QUERY_END_TIME_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime, - @ApiParam(value = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION) @RequestParam(name = "actionTypes", required = false) String actionTypesStr) throws ThingsboardException { checkParameter("CustomerId", strCustomerId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -108,28 +109,28 @@ public class AuditLogController extends BaseController { notes = "Returns a page of audit logs related to the actions of targeted user. " + "For example, RPC call to a particular device, or alarm acknowledgment for a specific device, etc. " + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/audit/logs/user/{userId}", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getAuditLogsByUserId( - @ApiParam(value = USER_ID_PARAM_DESCRIPTION) + @Parameter(description = USER_ID_PARAM_DESCRIPTION) @PathVariable("userId") String strUserId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION) + @Parameter(description = PAGE_SIZE_DESCRIPTION) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION) + @Parameter(description = PAGE_NUMBER_DESCRIPTION) @RequestParam int page, - @ApiParam(value = AUDIT_LOG_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = AUDIT_LOG_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = AUDIT_LOG_SORT_PROPERTY_DESCRIPTION, allowableValues = AUDIT_LOG_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = AUDIT_LOG_SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "entityType", "entityName", "userName", "actionType", "actionStatus"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = AUDIT_LOG_QUERY_START_TIME_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = AUDIT_LOG_QUERY_END_TIME_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime, - @ApiParam(value = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION) @RequestParam(name = "actionTypes", required = false) String actionTypesStr) throws ThingsboardException { checkParameter("UserId", strUserId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -143,30 +144,30 @@ public class AuditLogController extends BaseController { "Basically, this API call is used to get the full lifecycle of some specific entity. " + "For example to see when a device was created, updated, assigned to some customer, or even deleted from the system. " + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/audit/logs/entity/{entityType}/{entityId}", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getAuditLogsByEntityId( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String strEntityId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = AUDIT_LOG_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = AUDIT_LOG_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = AUDIT_LOG_SORT_PROPERTY_DESCRIPTION, allowableValues = AUDIT_LOG_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = AUDIT_LOG_SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "entityType", "entityName", "userName", "actionType", "actionStatus"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = AUDIT_LOG_QUERY_START_TIME_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = AUDIT_LOG_QUERY_END_TIME_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime, - @ApiParam(value = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION) @RequestParam(name = "actionTypes", required = false) String actionTypesStr) throws ThingsboardException { checkParameter("EntityId", strEntityId); checkParameter("EntityType", strEntityType); @@ -179,26 +180,26 @@ public class AuditLogController extends BaseController { @ApiOperation(value = "Get all audit logs (getAuditLogs)", notes = "Returns a page of audit logs related to all entities in the scope of the current user's Tenant. " + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/audit/logs", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getAuditLogs( - @ApiParam(value = PAGE_SIZE_DESCRIPTION) + @Parameter(description = PAGE_SIZE_DESCRIPTION) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION) + @Parameter(description = PAGE_NUMBER_DESCRIPTION) @RequestParam int page, - @ApiParam(value = AUDIT_LOG_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = AUDIT_LOG_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = AUDIT_LOG_SORT_PROPERTY_DESCRIPTION, allowableValues = AUDIT_LOG_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = AUDIT_LOG_SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "entityType", "entityName", "userName", "actionType", "actionStatus"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = AUDIT_LOG_QUERY_START_TIME_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = AUDIT_LOG_QUERY_END_TIME_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime, - @ApiParam(value = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION) @RequestParam(name = "actionTypes", required = false) String actionTypesStr) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); List actionTypes = parseActionTypesStr(actionTypesStr); diff --git a/application/src/main/java/org/thingsboard/server/controller/AuthController.java b/application/src/main/java/org/thingsboard/server/controller/AuthController.java index 5357c0e2a4..86941e2b07 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AuthController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AuthController.java @@ -16,8 +16,8 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.node.ObjectNode; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -48,9 +48,10 @@ import org.thingsboard.server.common.data.security.event.UserSessionInvalidation import org.thingsboard.server.common.data.security.model.JwtPair; import org.thingsboard.server.common.data.security.model.SecuritySettings; import org.thingsboard.server.common.data.security.model.UserPasswordPolicy; -import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.util.limits.LimitedApi; import org.thingsboard.server.dao.util.limits.RateLimitService; +import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.auth.rest.RestAuthenticationDetails; import org.thingsboard.server.service.security.model.ActivateUserRequest; import org.thingsboard.server.service.security.model.ChangePasswordRequest; @@ -61,7 +62,6 @@ import org.thingsboard.server.service.security.model.UserPrincipal; import org.thingsboard.server.service.security.model.token.JwtTokenFactory; import org.thingsboard.server.service.security.system.SystemSecurityService; -import jakarta.servlet.http.HttpServletRequest; import java.net.URI; import java.net.URISyntaxException; @@ -107,7 +107,7 @@ public class AuthController extends BaseController { @RequestMapping(value = "/auth/changePassword", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) public ObjectNode changePassword( - @ApiParam(value = "Change Password Request") + @Parameter(description = "Change Password Request") @RequestBody ChangePasswordRequest changePasswordRequest) throws ThingsboardException { String currentPassword = changePasswordRequest.getCurrentPassword(); String newPassword = changePasswordRequest.getNewPassword(); @@ -148,7 +148,7 @@ public class AuthController extends BaseController { "If token is not valid, returns '409 Conflict'.") @RequestMapping(value = "/noauth/activate", params = {"activateToken"}, method = RequestMethod.GET) public ResponseEntity checkActivateToken( - @ApiParam(value = "The activate token string.") + @Parameter(description = "The activate token string.") @RequestParam(value = "activateToken") String activateToken) { HttpHeaders headers = new HttpHeaders(); HttpStatus responseStatus; @@ -175,7 +175,7 @@ public class AuthController extends BaseController { @RequestMapping(value = "/noauth/resetPasswordByEmail", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) public void requestResetPasswordByEmail( - @ApiParam(value = "The JSON object representing the reset password email request.") + @Parameter(description = "The JSON object representing the reset password email request.") @RequestBody ResetPasswordEmailRequest resetPasswordByEmailRequest, HttpServletRequest request) throws ThingsboardException { try { @@ -198,7 +198,7 @@ public class AuthController extends BaseController { "If token is not valid, returns '409 Conflict'.") @RequestMapping(value = "/noauth/resetPassword", params = {"resetToken"}, method = RequestMethod.GET) public ResponseEntity checkResetToken( - @ApiParam(value = "The reset token string.") + @Parameter(description = "The reset token string.") @RequestParam(value = "resetToken") String resetToken) { HttpHeaders headers = new HttpHeaders(); HttpStatus responseStatus; @@ -234,7 +234,7 @@ public class AuthController extends BaseController { @ResponseStatus(value = HttpStatus.OK) @ResponseBody public JwtPair activateUser( - @ApiParam(value = "Activate user request.") + @Parameter(description = "Activate user request.") @RequestBody ActivateUserRequest activateRequest, @RequestParam(required = false, defaultValue = "true") boolean sendActivationMail, HttpServletRequest request) throws ThingsboardException { @@ -272,7 +272,7 @@ public class AuthController extends BaseController { @ResponseStatus(value = HttpStatus.OK) @ResponseBody public JwtPair resetPassword( - @ApiParam(value = "Reset password request.") + @Parameter(description = "Reset password request.") @RequestBody ResetPasswordRequest resetPasswordRequest, HttpServletRequest request) throws ThingsboardException { String resetToken = resetPasswordRequest.getResetToken(); diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index da2740a3b7..13118645a8 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -20,6 +20,9 @@ import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; +import jakarta.mail.MessagingException; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.ConstraintViolation; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -160,9 +163,6 @@ import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService; import org.thingsboard.server.service.telemetry.AlarmSubscriptionService; import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; -import jakarta.mail.MessagingException; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.ConstraintViolation; import java.util.List; import java.util.Objects; import java.util.Optional; diff --git a/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java b/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java index 33a4edfbe0..b0f1786437 100644 --- a/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java +++ b/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.rule.RuleChainType; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.HashSet; @@ -54,7 +55,7 @@ public class ComponentDescriptorController extends BaseController { @RequestMapping(value = "/component/{componentDescriptorClazz:.+}", method = RequestMethod.GET) @ResponseBody public ComponentDescriptor getComponentDescriptorByClazz( - @ApiParam(value = "Component Descriptor class name", required = true) + @Parameter(description = "Component Descriptor class name", required = true) @PathVariable("componentDescriptorClazz") String strComponentDescriptorClazz) throws ThingsboardException { checkParameter("strComponentDescriptorClazz", strComponentDescriptorClazz); return checkComponentDescriptorByClazz(strComponentDescriptorClazz); @@ -67,9 +68,9 @@ public class ComponentDescriptorController extends BaseController { @RequestMapping(value = "/components/{componentType}", method = RequestMethod.GET) @ResponseBody public List getComponentDescriptorsByType( - @ApiParam(value = "Type of the Rule Node", allowableValues = "ENRICHMENT,FILTER,TRANSFORMATION,ACTION,EXTERNAL", required = true) + @Parameter(description = "Type of the Rule Node", schema = @Schema(allowableValues = "ENRICHMENT,FILTER,TRANSFORMATION,ACTION,EXTERNAL", required = true)) @PathVariable("componentType") String strComponentType, - @ApiParam(value = "Type of the Rule Chain", allowableValues = "CORE,EDGE") + @Parameter(description = "Type of the Rule Chain", schema = @Schema(allowableValues = "CORE,EDGE")) @RequestParam(value = "ruleChainType", required = false) String strRuleChainType) throws ThingsboardException { checkParameter("componentType", strComponentType); return checkComponentDescriptorsByType(ComponentType.valueOf(strComponentType), getRuleChainType(strRuleChainType)); @@ -82,9 +83,9 @@ public class ComponentDescriptorController extends BaseController { @RequestMapping(value = "/components", params = {"componentTypes"}, method = RequestMethod.GET) @ResponseBody public List getComponentDescriptorsByTypes( - @ApiParam(value = "List of types of the Rule Nodes, (ENRICHMENT, FILTER, TRANSFORMATION, ACTION or EXTERNAL)", required = true) + @Parameter(description = "List of types of the Rule Nodes, (ENRICHMENT, FILTER, TRANSFORMATION, ACTION or EXTERNAL)", required = true) @RequestParam("componentTypes") String[] strComponentTypes, - @ApiParam(value = "Type of the Rule Chain", allowableValues = "CORE,EDGE") + @Parameter(description = "Type of the Rule Chain", schema = @Schema(allowableValues = "CORE,EDGE")) @RequestParam(value = "ruleChainType", required = false) String strRuleChainType) throws ThingsboardException { checkArrayParameter("componentTypes", strComponentTypes); Set componentTypes = new HashSet<>(); diff --git a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java index f425bde86c..8f95dbff35 100644 --- a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java +++ b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java @@ -89,33 +89,8 @@ public class ControllerConstants { protected static final String EVENT_TEXT_SEARCH_DESCRIPTION = "The value is not used in searching."; protected static final String AUDIT_LOG_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'substring' filter based on one of the next properties: entityType, entityName, userName, actionType, actionStatus."; protected static final String SORT_PROPERTY_DESCRIPTION = "Property of entity to sort by"; - protected static final String DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title"; - protected static final String CUSTOMER_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, email, country, city"; - protected static final String RPC_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, expirationTime, request, response"; - protected static final String DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, deviceProfileName, label, customerTitle"; - protected static final String ENTITY_VIEW_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type"; - protected static final String ENTITY_VIEW_INFO_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, customerTitle"; - protected static final String USER_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, firstName, lastName, email"; - protected static final String TENANT_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, email, country, state, city, address, address2, zip, phone, email"; - protected static final String TENANT_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, description, isDefault"; - protected static final String TENANT_PROFILE_INFO_SORT_PROPERTY_ALLOWABLE_VALUES = "id, name"; - protected static final String TENANT_INFO_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, tenantProfileName, title, email, country, state, city, address, address2, zip, phone, email"; - protected static final String DEVICE_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, transportType, description, isDefault"; - - protected static final String ASSET_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, description, isDefault"; - protected static final String ASSET_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, label, customerTitle"; - protected static final String ALARM_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, startTs, endTs, type, ackTs, clearTs, severity, status"; - protected static final String ALARM_COMMENT_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, id"; - protected static final String EVENT_SORT_PROPERTY_ALLOWABLE_VALUES = "ts, id"; - protected static final String EDGE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, label, customerTitle"; - protected static final String RULE_CHAIN_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, root"; - protected static final String WIDGET_BUNDLE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, tenantId"; - protected static final String AUDIT_LOG_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, entityType, entityName, userName, actionType, actionStatus"; + protected static final String SORT_ORDER_DESCRIPTION = "Sort order. ASC (ASCENDING) or DESC (DESCENDING)"; - protected static final String SORT_ORDER_ALLOWABLE_VALUES = "ASC, DESC"; - protected static final String RPC_STATUS_ALLOWABLE_VALUES = "QUEUED, SENT, DELIVERED, SUCCESSFUL, TIMEOUT, EXPIRED, FAILED"; - protected static final String RULE_CHAIN_TYPES_ALLOWABLE_VALUES = "CORE, EDGE"; - protected static final String TRANSPORT_TYPE_ALLOWABLE_VALUES = "DEFAULT, MQTT, COAP, LWM2M, SNMP"; protected static final String DEVICE_INFO_DESCRIPTION = "Device Info is an extension of the default Device object that contains information about the assigned customer name and device profile name. "; protected static final String ASSET_INFO_DESCRIPTION = "Asset Info is an extension of the default Asset object that contains information about the assigned customer name. "; protected static final String ALARM_INFO_DESCRIPTION = "Alarm Info is an extension of the default Alarm object that also contains name of the alarm originator."; @@ -125,23 +100,17 @@ public class ControllerConstants { protected static final String ASSET_PROFILE_INFO_DESCRIPTION = "Asset Profile Info is a lightweight object that includes main information about Asset Profile. "; protected static final String QUEUE_SERVICE_TYPE_DESCRIPTION = "Service type (implemented only for the TB-RULE-ENGINE)"; - protected static final String QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES = "TB-RULE-ENGINE, TB-CORE, TB-TRANSPORT, JS-EXECUTOR"; protected static final String QUEUE_QUEUE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'substring' filter based on the queue name."; - protected static final String QUEUE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, topic"; protected static final String QUEUE_ID_PARAM_DESCRIPTION = "A string value representing the queue id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'"; protected static final String QUEUE_NAME_PARAM_DESCRIPTION = "A string value representing the queue id. For example, 'Main'"; protected static final String OTA_PACKAGE_INFO_DESCRIPTION = "OTA Package Info is a lightweight object that includes main information about the OTA Package excluding the heavyweight data. "; protected static final String OTA_PACKAGE_DESCRIPTION = "OTA Package is a heavyweight object that includes main information about the OTA Package and also data. "; - protected static final String OTA_PACKAGE_CHECKSUM_ALGORITHM_ALLOWABLE_VALUES = "MD5, SHA256, SHA384, SHA512, CRC32, MURMUR3_32, MURMUR3_128"; protected static final String OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'substring' filter based on the ota package title."; - protected static final String OTA_PACKAGE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, type, title, version, tag, url, fileName, dataSize, checksum"; protected static final String RESOURCE_INFO_DESCRIPTION = "Resource Info is a lightweight object that includes main information about the Resource excluding the heavyweight data. "; protected static final String RESOURCE_DESCRIPTION = "Resource is a heavyweight object that includes main information about the Resource and also data. "; protected static final String RESOURCE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'substring' filter based on the resource title."; - protected static final String RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, resourceType, tenantId"; protected static final String LWM2M_OBJECT_DESCRIPTION = "LwM2M Object is a object that includes information about the LwM2M model which can be used in transport configuration for the LwM2M device profile. "; - protected static final String LWM2M_OBJECT_SORT_PROPERTY_ALLOWABLE_VALUES = "id, name"; protected static final String DEVICE_NAME_DESCRIPTION = "A string value representing the Device name."; protected static final String ASSET_NAME_DESCRIPTION = "A string value representing the Asset name."; @@ -1439,8 +1408,6 @@ public class ControllerConstants { protected static final String ATTRIBUTES_SCOPE_DESCRIPTION = "A string value representing the attributes scope. For example, 'SERVER_SCOPE'."; protected static final String ATTRIBUTES_KEYS_DESCRIPTION = "A string value representing the comma-separated list of attributes keys. For example, 'active,inactivityAlarmTime'."; - protected static final String ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES = "SERVER_SCOPE, SHARED_SCOPE"; - protected static final String ATTRIBUTES_SCOPE_ALLOWED_VALUES = ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES + ", CLIENT_SCOPE"; protected static final String ATTRIBUTES_JSON_REQUEST_DESCRIPTION = "A string value representing the json object. For example, '{\"key\":\"value\"}'. See API call description for more details."; protected static final String TELEMETRY_KEYS_BASE_DESCRIPTION = "A string value representing the comma-separated list of telemetry keys."; diff --git a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java index dd904add2e..7203f71392 100644 --- a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java +++ b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java @@ -17,8 +17,8 @@ package org.thingsboard.server.controller; 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.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; @@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.customer.TbCustomerService; import org.thingsboard.server.service.security.permission.Operation; @@ -44,13 +45,11 @@ import org.thingsboard.server.service.security.permission.Resource; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.HOME_DASHBOARD; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -76,7 +75,7 @@ public class CustomerController extends BaseController { @RequestMapping(value = "/customer/{customerId}", method = RequestMethod.GET) @ResponseBody public Customer getCustomerById( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); CustomerId customerId = new CustomerId(toUUID(strCustomerId)); @@ -95,7 +94,7 @@ public class CustomerController extends BaseController { @RequestMapping(value = "/customer/{customerId}/shortInfo", method = RequestMethod.GET) @ResponseBody public JsonNode getShortCustomerInfoById( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); CustomerId customerId = new CustomerId(toUUID(strCustomerId)); @@ -113,7 +112,7 @@ public class CustomerController extends BaseController { @RequestMapping(value = "/customer/{customerId}/title", method = RequestMethod.GET, produces = "application/text") @ResponseBody public String getCustomerTitleById( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); CustomerId customerId = new CustomerId(toUUID(strCustomerId)); @@ -131,7 +130,7 @@ public class CustomerController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer", method = RequestMethod.POST) @ResponseBody - public Customer saveCustomer(@ApiParam(value = "A JSON value representing the customer.") @RequestBody Customer customer) throws Exception { + public Customer saveCustomer(@Parameter(description = "A JSON value representing the customer.") @RequestBody Customer customer) throws Exception { customer.setTenantId(getTenantId()); checkEntity(customer.getId(), customer, Resource.CUSTOMER); return tbCustomerService.save(customer, getCurrentUser()); @@ -144,7 +143,7 @@ public class CustomerController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/{customerId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteCustomer(@ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + public void deleteCustomer(@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); CustomerId customerId = new CustomerId(toUUID(strCustomerId)); @@ -159,15 +158,15 @@ public class CustomerController extends BaseController { @RequestMapping(value = "/customers", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomers( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = CUSTOMER_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = CUSTOMER_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = CUSTOMER_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "title", "email", "country, city"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); TenantId tenantId = getCurrentUser().getTenantId(); @@ -180,7 +179,7 @@ public class CustomerController extends BaseController { @RequestMapping(value = "/tenant/customers", params = {"customerTitle"}, method = RequestMethod.GET) @ResponseBody public Customer getTenantCustomer( - @ApiParam(value = "A string value representing the Customer title.") + @Parameter(description = "A string value representing the Customer title.") @RequestParam String customerTitle) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); return checkNotNull(customerService.findCustomerByTenantIdAndTitle(tenantId, customerTitle), "Customer with title [" + customerTitle + "] is not found"); diff --git a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java index afc737ab88..c6678deffe 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -17,11 +17,11 @@ package org.thingsboard.server.controller; 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 io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; @@ -51,6 +51,7 @@ import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.dashboard.TbDashboardService; import org.thingsboard.server.service.security.model.SecurityUser; @@ -66,7 +67,6 @@ import java.util.stream.Collectors; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.DASHBOARD_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.DASHBOARD_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_ASYNC_FIRST_STEP_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION; @@ -77,7 +77,6 @@ import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIG import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; @@ -111,7 +110,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"))) + @ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = "application/json", examples = @ExampleObject(value = "1636023857137"))) public long getServerTime() throws ThingsboardException { return System.currentTimeMillis(); } @@ -124,20 +123,20 @@ 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"))) + @ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = "application/json", examples = @ExampleObject(value = "5000"))) public long getMaxDatapointsLimit() throws ThingsboardException { return maxDatapointsLimit; } @ApiOperation(value = "Get Dashboard Info (getDashboardInfoById)", notes = "Get the information about the dashboard based on 'dashboardId' parameter. " + DASHBOARD_INFO_DEFINITION, - produces = MediaType.APPLICATION_JSON_VALUE + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)) ) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/dashboard/info/{dashboardId}", method = RequestMethod.GET) @ResponseBody public DashboardInfo getDashboardInfoById( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); @@ -146,13 +145,13 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Get Dashboard (getDashboardById)", notes = "Get the dashboard based on 'dashboardId' parameter. " + DASHBOARD_DEFINITION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)) ) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/dashboard/{dashboardId}", method = RequestMethod.GET) @ResponseBody public Dashboard getDashboardById( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); @@ -166,13 +165,12 @@ public class DashboardController extends BaseController { "Referencing non-existing dashboard Id will cause 'Not Found' error. " + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Dashboard entity. " + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE, - consumes = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/dashboard", method = RequestMethod.POST) @ResponseBody public Dashboard saveDashboard( - @ApiParam(value = "A JSON value representing the dashboard.") + @Parameter(description = "A JSON value representing the dashboard.") @RequestBody Dashboard dashboard) throws Exception { dashboard.setTenantId(getTenantId()); checkEntity(dashboard.getId(), dashboard, Resource.DASHBOARD); @@ -185,7 +183,7 @@ public class DashboardController extends BaseController { @RequestMapping(value = "/dashboard/{dashboardId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) public void deleteDashboard( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); @@ -196,14 +194,14 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Assign the Dashboard (assignDashboardToCustomer)", notes = "Assign the Dashboard to specified Customer or do nothing if the Dashboard is already assigned to that Customer. " + "Returns the Dashboard object." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/{customerId}/dashboard/{dashboardId}", method = RequestMethod.POST) @ResponseBody public Dashboard assignDashboardToCustomer( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable(CUSTOMER_ID) String strCustomerId, - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); checkParameter(DASHBOARD_ID, strDashboardId); @@ -219,14 +217,14 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Unassign the Dashboard (unassignDashboardFromCustomer)", notes = "Unassign the Dashboard from specified Customer or do nothing if the Dashboard is already assigned to that Customer. " + "Returns the Dashboard object." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/{customerId}/dashboard/{dashboardId}", method = RequestMethod.DELETE) @ResponseBody public Dashboard unassignDashboardFromCustomer( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable(CUSTOMER_ID) String strCustomerId, - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter("customerId", strCustomerId); checkParameter(DASHBOARD_ID, strDashboardId); @@ -240,16 +238,15 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Update the Dashboard Customers (updateDashboardCustomers)", notes = "Updates the list of Customers that this Dashboard is assigned to. Removes previous assignments to customers that are not in the provided list. " + "Returns the Dashboard object. " + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE, - consumes = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/dashboard/{dashboardId}/customers", method = RequestMethod.POST) @ResponseBody public Dashboard updateDashboardCustomers( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId, - @ApiParam(value = "JSON array with the list of customer ids, or empty to remove all customers") + @Parameter(description = "JSON array with the list of customer ids, or empty to remove all customers") @RequestBody(required = false) String[] strCustomerIds) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); @@ -261,15 +258,14 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Adds the Dashboard Customers (addDashboardCustomers)", notes = "Adds the list of Customers to the existing list of assignments for the Dashboard. Keeps previous assignments to customers that are not in the provided list. " + "Returns the Dashboard object." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE, - consumes = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/dashboard/{dashboardId}/customers/add", method = RequestMethod.POST) @ResponseBody public Dashboard addDashboardCustomers( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId, - @ApiParam(value = "JSON array with the list of customer ids") + @Parameter(description = "JSON array with the list of customer ids") @RequestBody String[] strCustomerIds) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); @@ -281,15 +277,14 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Remove the Dashboard Customers (removeDashboardCustomers)", notes = "Removes the list of Customers from the existing list of assignments for the Dashboard. Keeps other assignments to customers that are not in the provided list. " + "Returns the Dashboard object." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE, - consumes = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/dashboard/{dashboardId}/customers/remove", method = RequestMethod.POST) @ResponseBody public Dashboard removeDashboardCustomers( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId, - @ApiParam(value = "JSON array with the list of customer ids") + @Parameter(description = "JSON array with the list of customer ids") @RequestBody String[] strCustomerIds) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); @@ -305,12 +300,12 @@ public class DashboardController extends BaseController { "Use [assign Asset to Public Customer](#!/asset-controller/assignAssetToPublicCustomerUsingPOST) and " + "[assign Device to Public Customer](#!/device-controller/assignDeviceToPublicCustomerUsingPOST) for this purpose. " + "Returns the Dashboard object." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/public/dashboard/{dashboardId}", method = RequestMethod.POST) @ResponseBody public Dashboard assignDashboardToPublicCustomer( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); @@ -321,12 +316,12 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Unassign the Dashboard from Public Customer (unassignDashboardFromPublicCustomer)", notes = "Unassigns the dashboard from a special, auto-generated 'Public' Customer. Once unassigned, unauthenticated users may no longer browse the dashboard. " + "Returns the Dashboard object." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/public/dashboard/{dashboardId}", method = RequestMethod.DELETE) @ResponseBody public Dashboard unassignDashboardFromPublicCustomer( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); @@ -337,22 +332,22 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Get Tenant Dashboards by System Administrator (getTenantDashboards)", notes = "Returns a page of dashboard info objects owned by tenant. " + DASHBOARD_INFO_DEFINITION + " " + PAGE_DATA_PARAMETERS + SYSTEM_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/tenant/{tenantId}/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantDashboards( - @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = TENANT_ID_PARAM_DESCRIPTION, required = true) @PathVariable(TENANT_ID) String strTenantId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DASHBOARD_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DASHBOARD_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "title"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId)); checkTenantId(tenantId, Operation.READ); @@ -363,22 +358,22 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Get Tenant Dashboards (getTenantDashboards)", notes = "Returns a page of dashboard info objects owned by the tenant of a current user. " + DASHBOARD_INFO_DEFINITION + " " + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantDashboards( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = HIDDEN_FOR_MOBILE) + @Parameter(description = HIDDEN_FOR_MOBILE) @RequestParam(required = false) Boolean mobile, - @ApiParam(value = DASHBOARD_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DASHBOARD_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "title"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -392,24 +387,24 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Get Customer Dashboards (getCustomerDashboards)", notes = "Returns a page of dashboard info objects owned by the specified customer. " + DASHBOARD_INFO_DEFINITION + " " + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/customer/{customerId}/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerDashboards( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) @PathVariable(CUSTOMER_ID) String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = HIDDEN_FOR_MOBILE) + @Parameter(description = HIDDEN_FOR_MOBILE) @RequestParam(required = false) Boolean mobile, - @ApiParam(value = DASHBOARD_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DASHBOARD_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "title"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -428,7 +423,7 @@ public class DashboardController extends BaseController { "If 'homeDashboardId' parameter is not set on the User level and the User has authority 'CUSTOMER_USER', check the same parameter for the corresponding Customer. " + "If 'homeDashboardId' parameter is not set on the User and Customer levels then checks the same parameter for the Tenant that owns the user. " + DASHBOARD_DEFINITION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/dashboard/home", method = RequestMethod.GET) @ResponseBody @@ -461,7 +456,7 @@ public class DashboardController extends BaseController { "If 'homeDashboardId' parameter is not set on the User level and the User has authority 'CUSTOMER_USER', check the same parameter for the corresponding Customer. " + "If 'homeDashboardId' parameter is not set on the User and Customer levels then checks the same parameter for the Tenant that owns the user. " + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/dashboard/home/info", method = RequestMethod.GET) @ResponseBody @@ -492,7 +487,7 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Get Tenant Home Dashboard Info (getTenantHomeDashboardInfo)", notes = "Returns the home dashboard info object that is configured as 'homeDashboardId' parameter in the 'additionalInfo' of the corresponding tenant. " + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/dashboard/home/info", method = RequestMethod.GET) @ResponseBody @@ -514,12 +509,12 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Update Tenant Home Dashboard Info (getTenantHomeDashboardInfo)", notes = "Update the home dashboard assignment for the current tenant. " + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/dashboard/home/info", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) public void setTenantHomeDashboardInfo( - @ApiParam(value = "A JSON object that represents home dashboard id and other parameters", required = true) + @Parameter(description = "A JSON object that represents home dashboard id and other parameters", required = true) @RequestBody HomeDashboardInfo homeDashboardInfo) throws ThingsboardException { if (homeDashboardInfo.getDashboardId() != null) { @@ -582,7 +577,7 @@ public class DashboardController extends BaseController { EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once dashboard will be delivered to edge service, it's going to be available for usage on remote edge instance." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/dashboard/{dashboardId}", method = RequestMethod.POST) @ResponseBody @@ -606,7 +601,7 @@ public class DashboardController extends BaseController { EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once 'unassign' command will be delivered to edge service, it's going to remove dashboard locally." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/dashboard/{dashboardId}", method = RequestMethod.DELETE) @ResponseBody @@ -627,22 +622,22 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Get Edge Dashboards (getEdgeDashboards)", notes = "Returns a page of dashboard info objects assigned to the specified edge. " + DASHBOARD_INFO_DEFINITION + " " + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/edge/{edgeId}/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getEdgeDashboards( - @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DASHBOARD_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DASHBOARD_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "title"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("edgeId", strEdgeId); TenantId tenantId = getCurrentUser().getTenantId(); diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java index 9de6a66041..603409bba0 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java @@ -19,8 +19,11 @@ import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import jakarta.annotation.Nullable; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -62,6 +65,7 @@ import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportRequest; import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportResult; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.device.claim.ClaimResponse; import org.thingsboard.server.dao.device.claim.ClaimResult; import org.thingsboard.server.dao.device.claim.ReclaimResult; @@ -74,7 +78,6 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; -import jakarta.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -90,7 +93,6 @@ import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID_PA import static org.thingsboard.server.controller.ControllerConstants.DEVICE_INFO_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_NAME_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_TYPE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_DESCRIPTION_MARKDOWN; @@ -102,7 +104,6 @@ import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIG import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -133,7 +134,7 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/device/{deviceId}", method = RequestMethod.GET) @ResponseBody - public Device getDeviceById(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + public Device getDeviceById(@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter(DEVICE_ID, strDeviceId); DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); @@ -148,7 +149,7 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/device/info/{deviceId}", method = RequestMethod.GET) @ResponseBody - public DeviceInfo getDeviceInfoById(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + public DeviceInfo getDeviceInfoById(@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter(DEVICE_ID, strDeviceId); DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); @@ -167,8 +168,8 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/device", method = RequestMethod.POST) @ResponseBody - public Device saveDevice(@ApiParam(value = "A JSON value representing the device.") @RequestBody Device device, - @ApiParam(value = "Optional value of the device credentials to be used during device creation. " + + public Device saveDevice(@Parameter(description = "A JSON value representing the device.") @RequestBody Device device, + @Parameter(description = "Optional value of the device credentials to be used during device creation. " + "If omitted, access token will be auto-generated.") @RequestParam(name = "accessToken", required = false) String accessToken) throws Exception { device.setTenantId(getCurrentUser().getTenantId()); Device oldDevice = null; @@ -190,7 +191,7 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/device-with-credentials", method = RequestMethod.POST) @ResponseBody - public Device saveDeviceWithCredentials(@ApiParam(value = "The JSON object with device and credentials. See method description above for example.") + public Device saveDeviceWithCredentials(@Parameter(description = "The JSON object with device and credentials. See method description above for example.") @RequestBody SaveDeviceWithCredentialsRequest deviceAndCredentials) throws ThingsboardException { Device device = checkNotNull(deviceAndCredentials.getDevice()); DeviceCredentials credentials = checkNotNull(deviceAndCredentials.getCredentials()); @@ -204,7 +205,7 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/device/{deviceId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteDevice(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + public void deleteDevice(@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws Exception { checkParameter(DEVICE_ID, strDeviceId); DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); @@ -217,9 +218,9 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/{customerId}/device/{deviceId}", method = RequestMethod.POST) @ResponseBody - public Device assignDeviceToCustomer(@ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + public Device assignDeviceToCustomer(@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter("customerId", strCustomerId); checkParameter(DEVICE_ID, strDeviceId); @@ -235,7 +236,7 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/device/{deviceId}", method = RequestMethod.DELETE) @ResponseBody - public Device unassignDeviceFromCustomer(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + public Device unassignDeviceFromCustomer(@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter(DEVICE_ID, strDeviceId); DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); @@ -256,7 +257,7 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/public/device/{deviceId}", method = RequestMethod.POST) @ResponseBody - public Device assignDeviceToPublicCustomer(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + public Device assignDeviceToPublicCustomer(@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter(DEVICE_ID, strDeviceId); DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); @@ -269,7 +270,7 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/device/{deviceId}/credentials", method = RequestMethod.GET) @ResponseBody - public DeviceCredentials getDeviceCredentialsByDeviceId(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + public DeviceCredentials getDeviceCredentialsByDeviceId(@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter(DEVICE_ID, strDeviceId); DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); @@ -285,7 +286,7 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/device/credentials", method = RequestMethod.POST) @ResponseBody public DeviceCredentials updateDeviceCredentials( - @ApiParam(value = "A JSON value representing the device credentials.") + @Parameter(description = "A JSON value representing the device credentials.") @RequestBody DeviceCredentials deviceCredentials) throws ThingsboardException { checkNotNull(deviceCredentials); Device device = checkDeviceId(deviceCredentials.getDeviceId(), Operation.WRITE_CREDENTIALS); @@ -299,17 +300,17 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/tenant/devices", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantDevices( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DEVICE_TYPE_DESCRIPTION) + @Parameter(description = DEVICE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DEVICE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "deviceProfileName", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -327,21 +328,21 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/tenant/deviceInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantDeviceInfos( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DEVICE_TYPE_DESCRIPTION) + @Parameter(description = DEVICE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @RequestParam(required = false) String deviceProfileId, - @ApiParam(value = DEVICE_ACTIVE_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ACTIVE_PARAM_DESCRIPTION) @RequestParam(required = false) Boolean active, - @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DEVICE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "deviceProfileName", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder ) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); @@ -364,7 +365,7 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/tenant/devices", params = {"deviceName"}, method = RequestMethod.GET) @ResponseBody public Device getTenantDevice( - @ApiParam(value = DEVICE_NAME_DESCRIPTION) + @Parameter(description = DEVICE_NAME_DESCRIPTION) @RequestParam String deviceName) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); return checkNotNull(deviceService.findDeviceByTenantIdAndName(tenantId, deviceName)); @@ -377,19 +378,19 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/customer/{customerId}/devices", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerDevices( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) @PathVariable(CUSTOMER_ID) String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DEVICE_TYPE_DESCRIPTION) + @Parameter(description = DEVICE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DEVICE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "deviceProfileName", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("customerId", strCustomerId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -410,23 +411,23 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/customer/{customerId}/deviceInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerDeviceInfos( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DEVICE_TYPE_DESCRIPTION) + @Parameter(description = DEVICE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @RequestParam(required = false) String deviceProfileId, - @ApiParam(value = DEVICE_ACTIVE_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ACTIVE_PARAM_DESCRIPTION) @RequestParam(required = false) Boolean active, - @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DEVICE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "deviceProfileName", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("customerId", strCustomerId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -451,7 +452,7 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/devices", params = {"deviceIds"}, method = RequestMethod.GET) @ResponseBody public List getDevicesByIds( - @ApiParam(value = "A list of devices ids, separated by comma ','") + @Parameter(description = "A list of devices ids, separated by comma ','") @RequestParam("deviceIds") String[] strDeviceIds) throws ThingsboardException, ExecutionException, InterruptedException { checkArrayParameter("deviceIds", strDeviceIds); SecurityUser user = getCurrentUser(); @@ -478,7 +479,7 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/devices", method = RequestMethod.POST) @ResponseBody public List findByQuery( - @ApiParam(value = "The device search query JSON") + @Parameter(description = "The device search query JSON") @RequestBody DeviceSearchQuery query) throws ThingsboardException, ExecutionException, InterruptedException { checkNotNull(query); checkNotNull(query.getParameters()); @@ -519,9 +520,9 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAuthority('CUSTOMER_USER')") @RequestMapping(value = "/customer/device/{deviceName}/claim", method = RequestMethod.POST) @ResponseBody - public DeferredResult claimDevice(@ApiParam(value = "Unique name of the device which is going to be claimed") + public DeferredResult claimDevice(@Parameter(description = "Unique name of the device which is going to be claimed") @PathVariable(DEVICE_NAME) String deviceName, - @ApiParam(value = "Claiming request which can optionally contain secret key") + @Parameter(description = "Claiming request which can optionally contain secret key") @RequestBody(required = false) ClaimRequest claimRequest) throws ThingsboardException { checkParameter(DEVICE_NAME, deviceName); final DeferredResult deferredResult = new DeferredResult<>(); @@ -568,7 +569,7 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/customer/device/{deviceName}/claim", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public DeferredResult reClaimDevice(@ApiParam(value = "Unique name of the device which is going to be reclaimed") + public DeferredResult reClaimDevice(@Parameter(description = "Unique name of the device which is going to be reclaimed") @PathVariable(DEVICE_NAME) String deviceName) throws ThingsboardException { checkParameter(DEVICE_NAME, deviceName); final DeferredResult deferredResult = new DeferredResult<>(); @@ -608,9 +609,9 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/{tenantId}/device/{deviceId}", method = RequestMethod.POST) @ResponseBody - public Device assignDeviceToTenant(@ApiParam(value = TENANT_ID_PARAM_DESCRIPTION) + public Device assignDeviceToTenant(@Parameter(description = TENANT_ID_PARAM_DESCRIPTION) @PathVariable(TENANT_ID) String strTenantId, - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter(TENANT_ID, strTenantId); checkParameter(DEVICE_ID, strDeviceId); @@ -631,13 +632,13 @@ public class DeviceController extends BaseController { "Second, remote edge service will receive a copy of assignment device " + EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once device will be delivered to edge service, it's going to be available for usage on remote edge instance." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/device/{deviceId}", method = RequestMethod.POST) @ResponseBody - public Device assignDeviceToEdge(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION) + public Device assignDeviceToEdge(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); checkParameter(DEVICE_ID, strDeviceId); @@ -656,13 +657,13 @@ public class DeviceController extends BaseController { "Second, remote edge service will receive an 'unassign' command to remove device " + EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once 'unassign' command will be delivered to edge service, it's going to remove device locally." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/device/{deviceId}", method = RequestMethod.DELETE) @ResponseBody - public Device unassignDeviceFromEdge(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION) + public Device unassignDeviceFromEdge(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); checkParameter(DEVICE_ID, strDeviceId); @@ -681,27 +682,27 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/edge/{edgeId}/devices", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getEdgeDevices( - @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DEVICE_TYPE_DESCRIPTION) + @Parameter(description = DEVICE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @RequestParam(required = false) String deviceProfileId, - @ApiParam(value = DEVICE_ACTIVE_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ACTIVE_PARAM_DESCRIPTION) @RequestParam(required = false) Boolean active, - @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DEVICE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "deviceProfileName", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = "Timestamp. Devices with creation time before it won't be queried") + @Parameter(description = "Timestamp. Devices with creation time before it won't be queried") @RequestParam(required = false) Long startTime, - @ApiParam(value = "Timestamp. Devices with creation time after it won't be queried") + @Parameter(description = "Timestamp. Devices with creation time after it won't be queried") @RequestParam(required = false) Long endTime) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -728,11 +729,11 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/devices/count/{otaPackageType}/{deviceProfileId}", method = RequestMethod.GET) @ResponseBody - public Long countByDeviceProfileAndEmptyOtaPackage - (@ApiParam(value = "OTA package type", allowableValues = "FIRMWARE, SOFTWARE") - @PathVariable("otaPackageType") String otaPackageType, - @ApiParam(value = "Device Profile Id. I.g. '784f394c-42b6-435a-983c-b7beff2784f9'") - @PathVariable("deviceProfileId") String deviceProfileId) throws ThingsboardException { + public Long countByDeviceProfileAndEmptyOtaPackage( + @Parameter(description = "OTA package type", schema = @Schema(allowableValues = {"FIRMWARE", "SOFTWARE"})) + @PathVariable("otaPackageType") String otaPackageType, + @Parameter(description = "Device Profile Id. I.g. '784f394c-42b6-435a-983c-b7beff2784f9'") + @PathVariable("deviceProfileId") String deviceProfileId) throws ThingsboardException { checkParameter("OtaPackageType", otaPackageType); checkParameter("DeviceProfileId", deviceProfileId); return deviceService.countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage( diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java index c888d67252..093f44dcfd 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java @@ -15,12 +15,15 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -37,6 +40,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.timeseries.TimeseriesService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.device.profile.TbDeviceProfileService; @@ -50,18 +54,15 @@ import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFI import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_ID; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_INFO_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH; -import static org.thingsboard.server.controller.ControllerConstants.TRANSPORT_TYPE_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK; @RestController @@ -79,12 +80,12 @@ public class DeviceProfileController extends BaseController { @ApiOperation(value = "Get Device Profile (getDeviceProfileById)", notes = "Fetch the Device Profile object based on the provided Device Profile Id. " + "The server checks that the device profile is owned by the same tenant. " + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/deviceProfile/{deviceProfileId}", method = RequestMethod.GET) @ResponseBody public DeviceProfile getDeviceProfileById( - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_PROFILE_ID) String strDeviceProfileId) throws ThingsboardException { checkParameter(DEVICE_PROFILE_ID, strDeviceProfileId); DeviceProfileId deviceProfileId = new DeviceProfileId(toUUID(strDeviceProfileId)); @@ -94,12 +95,12 @@ public class DeviceProfileController extends BaseController { @ApiOperation(value = "Get Device Profile Info (getDeviceProfileInfoById)", notes = "Fetch the Device Profile Info object based on the provided Device Profile Id. " + DEVICE_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/deviceProfileInfo/{deviceProfileId}", method = RequestMethod.GET) @ResponseBody public DeviceProfileInfo getDeviceProfileInfoById( - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_PROFILE_ID) String strDeviceProfileId) throws ThingsboardException { checkParameter(DEVICE_PROFILE_ID, strDeviceProfileId); DeviceProfileId deviceProfileId = new DeviceProfileId(toUUID(strDeviceProfileId)); @@ -109,7 +110,7 @@ public class DeviceProfileController extends BaseController { @ApiOperation(value = "Get Default Device Profile (getDefaultDeviceProfileInfo)", notes = "Fetch the Default Device Profile Info object. " + DEVICE_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/deviceProfileInfo/default", method = RequestMethod.GET) @ResponseBody @@ -123,12 +124,12 @@ public class DeviceProfileController extends BaseController { "The call is used for auto-complete in the UI forms. " + "The implementation limits the number of devices that participate in search to 100 as a trade of between accurate results and time-consuming queries. " + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/deviceProfile/devices/keys/timeseries", method = RequestMethod.GET) @ResponseBody public List getTimeseriesKeys( - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @RequestParam(name = DEVICE_PROFILE_ID, required = false) String deviceProfileIdStr) throws ThingsboardException { DeviceProfileId deviceProfileId; if (StringUtils.isNotEmpty(deviceProfileIdStr)) { @@ -147,12 +148,12 @@ public class DeviceProfileController extends BaseController { "The call is used for auto-complete in the UI forms. " + "The implementation limits the number of devices that participate in search to 100 as a trade of between accurate results and time-consuming queries. " + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/deviceProfile/devices/keys/attributes", method = RequestMethod.GET) @ResponseBody public List getAttributesKeys( - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @RequestParam(name = DEVICE_PROFILE_ID, required = false) String deviceProfileIdStr) throws ThingsboardException { DeviceProfileId deviceProfileId; if (StringUtils.isNotEmpty(deviceProfileIdStr)) { @@ -173,13 +174,12 @@ public class DeviceProfileController extends BaseController { "Device profile name is unique in the scope of tenant. Only one 'default' device profile may exist in scope of tenant." + DEVICE_PROFILE_DATA + "Remove 'id', 'tenantId' from the request body example (below) to create new Device Profile entity. " + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json", - consumes = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/deviceProfile", method = RequestMethod.POST) @ResponseBody public DeviceProfile saveDeviceProfile( - @ApiParam(value = "A JSON value representing the device profile.") + @Parameter(description = "A JSON value representing the device profile.") @RequestBody DeviceProfile deviceProfile) throws Exception { deviceProfile.setTenantId(getTenantId()); checkEntity(deviceProfile.getId(), deviceProfile, Resource.DEVICE_PROFILE); @@ -188,13 +188,12 @@ public class DeviceProfileController extends BaseController { @ApiOperation(value = "Delete device profile (deleteDeviceProfile)", notes = "Deletes the device profile. Referencing non-existing device profile Id will cause an error. " + - "Can't delete the device profile if it is referenced by existing devices." + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + "Can't delete the device profile if it is referenced by existing devices." + TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/deviceProfile/{deviceProfileId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) public void deleteDeviceProfile( - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_PROFILE_ID) String strDeviceProfileId) throws ThingsboardException { checkParameter(DEVICE_PROFILE_ID, strDeviceProfileId); DeviceProfileId deviceProfileId = new DeviceProfileId(toUUID(strDeviceProfileId)); @@ -204,12 +203,12 @@ public class DeviceProfileController extends BaseController { @ApiOperation(value = "Make Device Profile Default (setDefaultDeviceProfile)", notes = "Marks device profile as default within a tenant scope." + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/deviceProfile/{deviceProfileId}/default", method = RequestMethod.POST) @ResponseBody public DeviceProfile setDefaultDeviceProfile( - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_PROFILE_ID) String strDeviceProfileId) throws ThingsboardException { checkParameter(DEVICE_PROFILE_ID, strDeviceProfileId); DeviceProfileId deviceProfileId = new DeviceProfileId(toUUID(strDeviceProfileId)); @@ -221,20 +220,20 @@ public class DeviceProfileController extends BaseController { @ApiOperation(value = "Get Device Profiles (getDeviceProfiles)", notes = "Returns a page of devices profile objects owned by tenant. " + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/deviceProfiles", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getDeviceProfiles( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DEVICE_PROFILE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "transportType", "description", "isDefault"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return checkNotNull(deviceProfileService.findDeviceProfiles(getTenantId(), pageLink)); @@ -243,22 +242,22 @@ public class DeviceProfileController extends BaseController { @ApiOperation(value = "Get Device Profiles for transport type (getDeviceProfileInfos)", notes = "Returns a page of devices profile info objects owned by tenant. " + PAGE_DATA_PARAMETERS + DEVICE_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/deviceProfileInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getDeviceProfileInfos( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DEVICE_PROFILE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "transportType", "description", "isDefault"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = "Type of the transport", allowableValues = TRANSPORT_TYPE_ALLOWABLE_VALUES) + @Parameter(description = "Type of the transport", schema = @Schema(allowableValues = {"DEFAULT", "MQTT", "COAP", "LWM2M", "SNMP"})) @RequestParam(required = false) String transportType) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return checkNotNull(deviceProfileService.findDeviceProfileInfos(getTenantId(), pageLink, transportType)); diff --git a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java index 0213ae5686..153b760531 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java @@ -16,8 +16,11 @@ package org.thingsboard.server.controller; import com.google.common.util.concurrent.ListenableFuture; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -54,6 +57,7 @@ import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportReques import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportResult; import org.thingsboard.server.common.msg.edge.FromEdgeSyncResponse; import org.thingsboard.server.common.msg.edge.ToEdgeSyncRequest; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.model.ModelConstants; @@ -64,7 +68,6 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; -import jakarta.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -74,14 +77,12 @@ import java.util.stream.Collectors; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.EDGE_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.EDGE_INFO_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.EDGE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.EDGE_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.EDGE_TYPE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -112,11 +113,11 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Edge (getEdgeById)", notes = "Get the Edge object based on the provided Edge Id. " + EDGE_SECURITY_CHECK + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/edge/{edgeId}", method = RequestMethod.GET) @ResponseBody - public Edge getEdgeById(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + public Edge getEdgeById(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); @@ -125,11 +126,11 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Edge Info (getEdgeInfoById)", notes = "Get the Edge Info object based on the provided Edge Id. " + EDGE_SECURITY_CHECK + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/edge/info/{edgeId}", method = RequestMethod.GET) @ResponseBody - public EdgeInfo getEdgeInfoById(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + public EdgeInfo getEdgeInfoById(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); @@ -144,11 +145,11 @@ public class EdgeController extends BaseController { "\n\nEdge name is unique in the scope of tenant. Use unique identifiers like MAC or IMEI for the edge names and non-unique 'label' field for user-friendly visualization purposes." + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Edge entity. " + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge", method = RequestMethod.POST) @ResponseBody - public Edge saveEdge(@ApiParam(value = "A JSON value representing the edge.", required = true) + public Edge saveEdge(@Parameter(description = "A JSON value representing the edge.", required = true) @RequestBody Edge edge) throws Exception { TenantId tenantId = getTenantId(); edge.setTenantId(tenantId); @@ -174,7 +175,7 @@ public class EdgeController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteEdge(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + public void deleteEdge(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); @@ -184,19 +185,19 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Tenant Edges (getEdges)", notes = "Returns a page of edges owned by tenant. " + - PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edges", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody - public PageData getEdges(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public PageData getEdges(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = EDGE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = EDGE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EDGE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); TenantId tenantId = getCurrentUser().getTenantId(); @@ -205,13 +206,13 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Assign edge to customer (assignEdgeToCustomer)", notes = "Creates assignment of the edge to customer. Customer will be able to query edge afterwards." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/{customerId}/edge/{edgeId}", method = RequestMethod.POST) @ResponseBody - public Edge assignEdgeToCustomer(@ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) + public Edge assignEdgeToCustomer(@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException { checkParameter("customerId", strCustomerId); checkParameter(EDGE_ID, strEdgeId); @@ -224,11 +225,11 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Unassign edge from customer (unassignEdgeFromCustomer)", notes = "Clears assignment of the edge to customer. Customer will not be able to query edge afterwards." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/edge/{edgeId}", method = RequestMethod.DELETE) @ResponseBody - public Edge unassignEdgeFromCustomer(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + public Edge unassignEdgeFromCustomer(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); @@ -245,11 +246,11 @@ public class EdgeController extends BaseController { notes = "Edge will be available for non-authorized (not logged-in) users. " + "This is useful to create dashboards that you plan to share/embed on a publicly available website. " + "However, users that are logged-in and belong to different tenant will not be able to access the edge." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/public/edge/{edgeId}", method = RequestMethod.POST) @ResponseBody - public Edge assignEdgeToPublicCustomer(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + public Edge assignEdgeToPublicCustomer(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); @@ -259,22 +260,22 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Tenant Edges (getTenantEdges)", notes = "Returns a page of edges owned by tenant. " + - PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/edges", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantEdges( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = EDGE_TYPE_DESCRIPTION) + @Parameter(description = EDGE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = EDGE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = EDGE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EDGE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -288,22 +289,22 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Tenant Edge Infos (getTenantEdgeInfos)", notes = "Returns a page of edges info objects owned by tenant. " + PAGE_DATA_PARAMETERS + EDGE_INFO_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/edgeInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantEdgeInfos( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = EDGE_TYPE_DESCRIPTION) + @Parameter(description = EDGE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = EDGE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = EDGE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EDGE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -317,11 +318,11 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Tenant Edge (getTenantEdge)", notes = "Requested edge must be owned by tenant or customer that the user belongs to. " + "Edge name is an unique property of edge. So it can be used to identify the edge." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/edges", params = {"edgeName"}, method = RequestMethod.GET) @ResponseBody - public Edge getTenantEdge(@ApiParam(value = "Unique name of the edge", required = true) + public Edge getTenantEdge(@Parameter(description = "Unique name of the edge", required = true) @RequestParam String edgeName) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); return checkNotNull(edgeService.findEdgeByTenantIdAndName(tenantId, edgeName)); @@ -330,13 +331,13 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Set root rule chain for provided edge (setEdgeRootRuleChain)", notes = "Change root rule chain of the edge to the new provided rule chain. \n" + "This operation will send a notification to update root rule chain on remote edge service." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/{ruleChainId}/root", method = RequestMethod.POST) @ResponseBody - public Edge setEdgeRootRuleChain(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + public Edge setEdgeRootRuleChain(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION, required = true) @PathVariable("ruleChainId") String strRuleChainId) throws Exception { checkParameter(EDGE_ID, strEdgeId); checkParameter("ruleChainId", strRuleChainId); @@ -350,24 +351,24 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Customer Edges (getCustomerEdges)", notes = "Returns a page of edges objects assigned to customer. " + - PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/customer/{customerId}/edges", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerEdges( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = EDGE_TYPE_DESCRIPTION) + @Parameter(description = EDGE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = EDGE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = EDGE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EDGE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("customerId", strCustomerId); SecurityUser user = getCurrentUser(); @@ -386,24 +387,24 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Customer Edge Infos (getCustomerEdgeInfos)", notes = "Returns a page of edges info objects assigned to customer. " + - PAGE_DATA_PARAMETERS + EDGE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + EDGE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/customer/{customerId}/edgeInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerEdgeInfos( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = EDGE_TYPE_DESCRIPTION) + @Parameter(description = EDGE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = EDGE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = EDGE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EDGE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("customerId", strCustomerId); SecurityUser user = getCurrentUser(); @@ -422,12 +423,12 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Edges By Ids (getEdgesByIds)", notes = "Requested edges must be owned by tenant or assigned to customer which user is performing the request." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/edges", params = {"edgeIds"}, method = RequestMethod.GET) @ResponseBody public List getEdgesByIds( - @ApiParam(value = "A list of edges ids, separated by comma ','", required = true) + @Parameter(description = "A list of edges ids, separated by comma ','", required = true) @RequestParam("edgeIds") String[] strEdgeIds) throws ThingsboardException, ExecutionException, InterruptedException { checkArrayParameter("edgeIds", strEdgeIds); SecurityUser user = getCurrentUser(); @@ -451,7 +452,7 @@ public class EdgeController extends BaseController { notes = "Returns all edges that are related to the specific entity. " + "The entity id, relation type, edge types, depth of the search, and other query parameters defined using complex 'EdgeSearchQuery' object. " + "See 'Model' tab of the Parameters for more info." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/edges", method = RequestMethod.POST) @ResponseBody @@ -477,7 +478,7 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Edge Types (getEdgeTypes)", notes = "Returns a set of unique edge types based on edges that are either owned by the tenant or assigned to the customer which user is performing the request." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/edge/types", method = RequestMethod.GET) @ResponseBody @@ -493,7 +494,7 @@ public class EdgeController extends BaseController { "All entities that are assigned to particular edge are going to be send to remote edge service." + TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/sync/{edgeId}", method = RequestMethod.POST) - public DeferredResult syncEdge(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + public DeferredResult syncEdge(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("edgeId") String strEdgeId) throws ThingsboardException { checkParameter("edgeId", strEdgeId); final DeferredResult response = new DeferredResult<>(); @@ -523,7 +524,7 @@ public class EdgeController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/missingToRelatedRuleChains/{edgeId}", method = RequestMethod.GET) @ResponseBody - public String findMissingToRelatedRuleChains(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + public String findMissingToRelatedRuleChains(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("edgeId") String strEdgeId) throws ThingsboardException { EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); edgeId = checkNotNull(edgeId); @@ -534,7 +535,7 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Import the bulk of edges (processEdgesBulkImport)", notes = "There's an ability to import the bulk of edges using the only .csv file." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @PostMapping("/edge/bulk_import") public BulkImportResult processEdgesBulkImport(@RequestBody BulkImportRequest request) throws Exception { @@ -549,12 +550,12 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Edge Docker Install Instructions (getEdgeDockerInstallInstructions)", notes = "Get a docker install instructions for provided edge id." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/instructions/{edgeId}", method = RequestMethod.GET) @ResponseBody public EdgeInstallInstructions getEdgeDockerInstallInstructions( - @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("edgeId") String strEdgeId, HttpServletRequest request) throws ThingsboardException { EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); diff --git a/application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java b/application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java index fc85f439e0..fc95c02217 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java @@ -15,8 +15,10 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; @@ -33,16 +35,15 @@ import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.permission.Operation; import static org.thingsboard.server.controller.ControllerConstants.EDGE_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.EDGE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; @@ -59,26 +60,26 @@ public class EdgeEventController extends BaseController { @ApiOperation(value = "Get Edge Events (getEdgeEvents)", notes = "Returns a page of edge events for the requested edge. " + - PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/events", method = RequestMethod.GET) @ResponseBody public PageData getEdgeEvents( - @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = "The case insensitive 'substring' filter based on the edge event type name.") + @Parameter(description = "The case insensitive 'substring' filter based on the edge event type name.") @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EDGE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = "Timestamp. Edge events with creation time before it won't be queried") + @Parameter(description = "Timestamp. Edge events with creation time before it won't be queried") @RequestParam(required = false) Long startTime, - @ApiParam(value = "Timestamp. Edge events with creation time after it won't be queried") + @Parameter(description = "Timestamp. Edge events with creation time after it won't be queried") @RequestParam(required = false) Long endTime) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); TenantId tenantId = getCurrentUser().getTenantId(); diff --git a/application/src/main/java/org/thingsboard/server/controller/EntitiesVersionControlController.java b/application/src/main/java/org/thingsboard/server/controller/EntitiesVersionControlController.java index b5c8e18ed2..b501771a3e 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntitiesVersionControlController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntitiesVersionControlController.java @@ -18,8 +18,8 @@ package org.thingsboard.server.controller; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.GetMapping; @@ -46,6 +46,7 @@ import org.thingsboard.server.common.data.sync.vc.VersionLoadResult; import org.thingsboard.server.common.data.sync.vc.VersionedEntityInfo; import org.thingsboard.server.common.data.sync.vc.request.create.VersionCreateRequest; import org.thingsboard.server.common.data.sync.vc.request.load.VersionLoadRequest; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; @@ -67,7 +68,6 @@ import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -189,7 +189,7 @@ public class EntitiesVersionControlController extends BaseController { MARKDOWN_CODE_BLOCK_END + TENANT_AUTHORITY_PARAGRAPH) @GetMapping(value = "/version/{requestId}/status") - public VersionCreationResult getVersionCreateRequestStatus(@ApiParam(value = VC_REQUEST_ID_PARAM_DESCRIPTION, required = true) + public VersionCreationResult getVersionCreateRequestStatus(@Parameter(description = VC_REQUEST_ID_PARAM_DESCRIPTION, required = true) @PathVariable UUID requestId) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.WRITE); return versionControlService.getVersionCreateStatus(getCurrentUser(), requestId); @@ -232,21 +232,21 @@ public class EntitiesVersionControlController extends BaseController { MARKDOWN_CODE_BLOCK_END + TENANT_AUTHORITY_PARAGRAPH) @GetMapping(value = "/version/{entityType}/{externalEntityUuid}", params = {"branch", "pageSize", "page"}) - public DeferredResult> listEntityVersions(@ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + public DeferredResult> listEntityVersions(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable EntityType entityType, - @ApiParam(value = "A string value representing external entity id. This is `externalId` property of an entity, or otherwise if not set - simply id of this entity.") + @Parameter(description = "A string value representing external entity id. This is `externalId` property of an entity, or otherwise if not set - simply id of this entity.") @PathVariable UUID externalEntityUuid, - @ApiParam(value = BRANCH_PARAM_DESCRIPTION) + @Parameter(description = BRANCH_PARAM_DESCRIPTION) @RequestParam String branch, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ENTITY_VERSION_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ENTITY_VERSION_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = "timestamp") + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = "timestamp")) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); EntityId externalEntityId = EntityIdFactory.getByTypeAndUuid(entityType, externalEntityUuid); @@ -261,19 +261,19 @@ public class EntitiesVersionControlController extends BaseController { "The response structure is the same as for `listEntityVersions` API method." + TENANT_AUTHORITY_PARAGRAPH) @GetMapping(value = "/version/{entityType}", params = {"branch", "pageSize", "page"}) - public DeferredResult> listEntityTypeVersions(@ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + public DeferredResult> listEntityTypeVersions(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable EntityType entityType, - @ApiParam(value = BRANCH_PARAM_DESCRIPTION, required = true) + @Parameter(description = BRANCH_PARAM_DESCRIPTION, required = true) @RequestParam String branch, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ENTITY_VERSION_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ENTITY_VERSION_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = "timestamp") + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = "timestamp")) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -286,17 +286,17 @@ public class EntitiesVersionControlController extends BaseController { "The response format is the same as for `listEntityVersions` API method." + TENANT_AUTHORITY_PARAGRAPH) @GetMapping(value = "/version", params = {"branch", "pageSize", "page"}) - public DeferredResult> listVersions(@ApiParam(value = BRANCH_PARAM_DESCRIPTION, required = true) + public DeferredResult> listVersions(@Parameter(description = BRANCH_PARAM_DESCRIPTION, required = true) @RequestParam String branch, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ENTITY_VERSION_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ENTITY_VERSION_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = "timestamp") + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = "timestamp")) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -310,9 +310,9 @@ public class EntitiesVersionControlController extends BaseController { "Entities order will be the same as in the repository." + TENANT_AUTHORITY_PARAGRAPH) @GetMapping(value = "/entity/{entityType}/{versionId}") - public DeferredResult> listEntitiesAtVersion(@ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + public DeferredResult> listEntitiesAtVersion(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable EntityType entityType, - @ApiParam(value = VERSION_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = VERSION_ID_PARAM_DESCRIPTION, required = true) @PathVariable String versionId) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); return wrapFuture(versionControlService.listEntitiesAtVersion(getTenantId(), versionId, entityType)); @@ -324,7 +324,7 @@ public class EntitiesVersionControlController extends BaseController { "Returned entities order will be the same as in the repository." + TENANT_AUTHORITY_PARAGRAPH) @GetMapping(value = "/entity/{versionId}") - public DeferredResult> listAllEntitiesAtVersion(@ApiParam(value = VERSION_ID_PARAM_DESCRIPTION, required = true) + public DeferredResult> listAllEntitiesAtVersion(@Parameter(description = VERSION_ID_PARAM_DESCRIPTION, required = true) @PathVariable String versionId) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); return wrapFuture(versionControlService.listAllEntitiesAtVersion(getTenantId(), versionId)); @@ -337,11 +337,11 @@ public class EntitiesVersionControlController extends BaseController { "`hasCredentials` (whether stored device data has credentials)." + TENANT_AUTHORITY_PARAGRAPH) @GetMapping("/info/{versionId}/{entityType}/{externalEntityUuid}") - public DeferredResult getEntityDataInfo(@ApiParam(value = VERSION_ID_PARAM_DESCRIPTION, required = true) + public DeferredResult getEntityDataInfo(@Parameter(description = VERSION_ID_PARAM_DESCRIPTION, required = true) @PathVariable String versionId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable EntityType entityType, - @ApiParam(value = "A string value representing external entity id", required = true) + @Parameter(description = "A string value representing external entity id", required = true) @PathVariable UUID externalEntityUuid) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); EntityId entityId = EntityIdFactory.getByTypeAndUuid(entityType, externalEntityUuid); @@ -353,11 +353,11 @@ public class EntitiesVersionControlController extends BaseController { "Entity data structure is the same as stored in a repository. " + TENANT_AUTHORITY_PARAGRAPH) @GetMapping(value = "/diff/{entityType}/{internalEntityUuid}", params = {"versionId"}) - public DeferredResult compareEntityDataToVersion(@ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + public DeferredResult compareEntityDataToVersion(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable EntityType entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable UUID internalEntityUuid, - @ApiParam(value = VERSION_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = VERSION_ID_PARAM_DESCRIPTION, required = true) @RequestParam String versionId) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); EntityId entityId = EntityIdFactory.getByTypeAndUuid(entityType, internalEntityUuid); @@ -466,7 +466,7 @@ public class EntitiesVersionControlController extends BaseController { TENANT_AUTHORITY_PARAGRAPH ) @GetMapping(value = "/entity/{requestId}/status") - public VersionLoadResult getVersionLoadRequestStatus(@ApiParam(value = VC_REQUEST_ID_PARAM_DESCRIPTION, required = true) + public VersionLoadResult getVersionLoadRequestStatus(@Parameter(description = VC_REQUEST_ID_PARAM_DESCRIPTION, required = true) @PathVariable UUID requestId) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.WRITE); return versionControlService.getVersionLoadStatus(getCurrentUser(), requestId); diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityQueryController.java b/application/src/main/java/org/thingsboard/server/controller/EntityQueryController.java index fbb8901ca9..539d6a81f4 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityQueryController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityQueryController.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -38,6 +37,7 @@ import org.thingsboard.server.common.data.query.EntityCountQuery; import org.thingsboard.server.common.data.query.EntityData; import org.thingsboard.server.common.data.query.EntityDataPageLink; import org.thingsboard.server.common.data.query.EntityDataQuery; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.query.EntityQueryService; import org.thingsboard.server.service.security.permission.Operation; @@ -61,7 +61,7 @@ public class EntityQueryController extends BaseController { @RequestMapping(value = "/entitiesQuery/count", method = RequestMethod.POST) @ResponseBody public long countEntitiesByQuery( - @ApiParam(value = "A JSON value representing the entity count query. See API call notes above for more details.") + @Parameter(description = "A JSON value representing the entity count query. See API call notes above for more details.") @RequestBody EntityCountQuery query) throws ThingsboardException { checkNotNull(query); return this.entityQueryService.countEntitiesByQuery(getCurrentUser(), query); @@ -72,7 +72,7 @@ public class EntityQueryController extends BaseController { @RequestMapping(value = "/entitiesQuery/find", method = RequestMethod.POST) @ResponseBody public PageData findEntityDataByQuery( - @ApiParam(value = "A JSON value representing the entity data query. See API call notes above for more details.") + @Parameter(description = "A JSON value representing the entity data query. See API call notes above for more details.") @RequestBody EntityDataQuery query) throws ThingsboardException { checkNotNull(query); return this.entityQueryService.findEntityDataByQuery(getCurrentUser(), query); @@ -83,7 +83,7 @@ public class EntityQueryController extends BaseController { @RequestMapping(value = "/alarmsQuery/find", method = RequestMethod.POST) @ResponseBody public PageData findAlarmDataByQuery( - @ApiParam(value = "A JSON value representing the alarm data query. See API call notes above for more details.") + @Parameter(description = "A JSON value representing the alarm data query. See API call notes above for more details.") @RequestBody AlarmDataQuery query) throws ThingsboardException { checkNotNull(query); checkNotNull(query.getPageLink()); @@ -98,7 +98,7 @@ public class EntityQueryController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarmsQuery/count", method = RequestMethod.POST) @ResponseBody - public long countAlarmsByQuery(@ApiParam(value = "A JSON value representing the alarm count query.") + public long countAlarmsByQuery(@Parameter(description = "A JSON value representing the alarm count query.") @RequestBody AlarmCountQuery query) throws ThingsboardException { checkNotNull(query); UserId assigneeId = query.getAssigneeId(); @@ -114,11 +114,11 @@ public class EntityQueryController extends BaseController { @RequestMapping(value = "/entitiesQuery/find/keys", method = RequestMethod.POST) @ResponseBody public DeferredResult findEntityTimeseriesAndAttributesKeysByQuery( - @ApiParam(value = "A JSON value representing the entity data query. See API call notes above for more details.") + @Parameter(description = "A JSON value representing the entity data query. See API call notes above for more details.") @RequestBody EntityDataQuery query, - @ApiParam(value = "Include all unique time-series keys to the result.") + @Parameter(description = "Include all unique time-series keys to the result.") @RequestParam("timeseries") boolean isTimeseries, - @ApiParam(value = "Include all unique attribute keys to the result.") + @Parameter(description = "Include all unique attribute keys to the result.") @RequestParam("attributes") boolean isAttributes) throws ThingsboardException { TenantId tenantId = getTenantId(); checkNotNull(query); diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java index 08448f1d28..cb17661e4a 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java @@ -15,8 +15,9 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -35,6 +36,7 @@ import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelationInfo; import org.thingsboard.server.common.data.relation.EntityRelationsQuery; import org.thingsboard.server.common.data.relation.RelationTypeGroup; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.entity.relation.TbEntityRelationService; import org.thingsboard.server.service.security.model.SecurityUser; @@ -79,7 +81,7 @@ public class EntityRelationController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relation", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) - public void saveRelation(@ApiParam(value = "A JSON value representing the relation.", required = true) + public void saveRelation(@Parameter(description = "A JSON value representing the relation.", required = true) @RequestBody EntityRelation relation) throws ThingsboardException { checkNotNull(relation); checkCanCreateRelation(relation.getFrom()); @@ -96,12 +98,12 @@ public class EntityRelationController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relation", method = RequestMethod.DELETE, params = {FROM_ID, FROM_TYPE, RELATION_TYPE, TO_ID, TO_TYPE}) @ResponseStatus(value = HttpStatus.OK) - public void deleteRelation(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, - @ApiParam(value = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, - @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType) throws ThingsboardException { + public void deleteRelation(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, + @Parameter(description = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, + @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType) throws ThingsboardException { checkParameter(FROM_ID, strFromId); checkParameter(FROM_TYPE, strFromType); checkParameter(RELATION_TYPE, strRelationType); @@ -123,8 +125,8 @@ public class EntityRelationController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations", method = RequestMethod.DELETE, params = {"entityId", "entityType"}) @ResponseStatus(value = HttpStatus.OK) - public void deleteRelations(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam("entityId") String strId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam("entityType") String strType) throws ThingsboardException { + public void deleteRelations(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam("entityId") String strId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam("entityType") String strType) throws ThingsboardException { checkParameter("entityId", strId); checkParameter("entityType", strType); EntityId entityId = EntityIdFactory.getByTypeAndId(strType, strId); @@ -134,16 +136,16 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Get Relation (getRelation)", notes = "Returns relation object between two specified entities if present. Otherwise throws exception. " + SECURITY_CHECKS_ENTITIES_DESCRIPTION, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relation", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE, RELATION_TYPE, TO_ID, TO_TYPE}) @ResponseBody - public EntityRelation getRelation(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, - @ApiParam(value = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, - @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType) throws ThingsboardException { + public EntityRelation getRelation(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, + @Parameter(description = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, + @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType) throws ThingsboardException { checkParameter(FROM_ID, strFromId); checkParameter(FROM_TYPE, strFromType); checkParameter(RELATION_TYPE, strRelationType); @@ -160,13 +162,13 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Get List of Relations (findByFrom)", notes = "Returns list of relation objects for the specified entity by the 'from' direction. " + SECURITY_CHECKS_ENTITY_DESCRIPTION, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE}) @ResponseBody - public List findByFrom(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, - @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) + public List findByFrom(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, + @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { checkParameter(FROM_ID, strFromId); checkParameter(FROM_TYPE, strFromType); @@ -179,13 +181,13 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Get List of Relation Infos (findInfoByFrom)", notes = "Returns list of relation info objects for the specified entity by the 'from' direction. " + SECURITY_CHECKS_ENTITY_DESCRIPTION + " " + RELATION_INFO_DESCRIPTION, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE}) @ResponseBody - public List findInfoByFrom(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, - @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) + public List findInfoByFrom(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, + @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException, ExecutionException, InterruptedException { checkParameter(FROM_ID, strFromId); checkParameter(FROM_TYPE, strFromType); @@ -198,14 +200,14 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Get List of Relations (findByFrom)", notes = "Returns list of relation objects for the specified entity by the 'from' direction and relation type. " + SECURITY_CHECKS_ENTITY_DESCRIPTION, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE, RELATION_TYPE}) @ResponseBody - public List findByFrom(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, - @ApiParam(value = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, - @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) + public List findByFrom(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, + @Parameter(description = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, + @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { checkParameter(FROM_ID, strFromId); checkParameter(FROM_TYPE, strFromType); @@ -219,13 +221,13 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Get List of Relations (findByTo)", notes = "Returns list of relation objects for the specified entity by the 'to' direction. " + SECURITY_CHECKS_ENTITY_DESCRIPTION, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {TO_ID, TO_TYPE}) @ResponseBody - public List findByTo(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType, - @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) + public List findByTo(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType, + @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { checkParameter(TO_ID, strToId); checkParameter(TO_TYPE, strToType); @@ -238,13 +240,13 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Get List of Relation Infos (findInfoByTo)", notes = "Returns list of relation info objects for the specified entity by the 'to' direction. " + SECURITY_CHECKS_ENTITY_DESCRIPTION + " " + RELATION_INFO_DESCRIPTION, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {TO_ID, TO_TYPE}) @ResponseBody - public List findInfoByTo(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType, - @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) + public List findInfoByTo(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType, + @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException, ExecutionException, InterruptedException { checkParameter(TO_ID, strToId); checkParameter(TO_TYPE, strToType); @@ -257,14 +259,14 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Get List of Relations (findByTo)", notes = "Returns list of relation objects for the specified entity by the 'to' direction and relation type. " + SECURITY_CHECKS_ENTITY_DESCRIPTION, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {TO_ID, TO_TYPE, RELATION_TYPE}) @ResponseBody - public List findByTo(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType, - @ApiParam(value = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, - @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) + public List findByTo(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType, + @Parameter(description = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, + @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { checkParameter(TO_ID, strToId); checkParameter(TO_TYPE, strToType); @@ -278,11 +280,11 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Find related entities (findByQuery)", notes = "Returns all entities that are related to the specific entity. " + "The entity id, relation type, entity types, depth of the search, and other query parameters defined using complex 'EntityRelationsQuery' object. " + - "See 'Model' tab of the Parameters for more info.", produces = MediaType.APPLICATION_JSON_VALUE) + "See 'Model' tab of the Parameters for more info.", responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations", method = RequestMethod.POST) @ResponseBody - public List findByQuery(@ApiParam(value = "A JSON value representing the entity relations query object.", required = true) + public List findByQuery(@Parameter(description = "A JSON value representing the entity relations query object.", required = true) @RequestBody EntityRelationsQuery query) throws ThingsboardException, ExecutionException, InterruptedException { checkNotNull(query); checkNotNull(query.getParameters()); @@ -294,11 +296,11 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Find related entity infos (findInfoByQuery)", notes = "Returns all entity infos that are related to the specific entity. " + "The entity id, relation type, entity types, depth of the search, and other query parameters defined using complex 'EntityRelationsQuery' object. " + - "See 'Model' tab of the Parameters for more info. " + RELATION_INFO_DESCRIPTION, produces = MediaType.APPLICATION_JSON_VALUE) + "See 'Model' tab of the Parameters for more info. " + RELATION_INFO_DESCRIPTION, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations/info", method = RequestMethod.POST) @ResponseBody - public List findInfoByQuery(@ApiParam(value = "A JSON value representing the entity relations query object.", required = true) + public List findInfoByQuery(@Parameter(description = "A JSON value representing the entity relations query object.", required = true) @RequestBody EntityRelationsQuery query) throws ThingsboardException, ExecutionException, InterruptedException { checkNotNull(query); checkNotNull(query.getParameters()); diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java index b2904a0989..bff71bb43b 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java @@ -16,8 +16,10 @@ package org.thingsboard.server.controller; import com.google.common.util.concurrent.ListenableFuture; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -45,6 +47,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.queue.util.TbCoreComponent; @@ -66,15 +69,12 @@ import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIG import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_INFO_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_INFO_SORT_PROPERTY_ALLOWABLE_VALUES; -import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_TYPE; import static org.thingsboard.server.controller.ControllerConstants.MODEL_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -98,12 +98,12 @@ public class EntityViewController extends BaseController { @ApiOperation(value = "Get entity view (getEntityViewById)", notes = "Fetch the EntityView object based on the provided entity view id. " + ENTITY_VIEW_DESCRIPTION + MODEL_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/entityView/{entityViewId}", method = RequestMethod.GET) @ResponseBody public EntityView getEntityViewById( - @ApiParam(value = ENTITY_VIEW_ID_PARAM_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_ID_PARAM_DESCRIPTION) @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { checkParameter(ENTITY_VIEW_ID, strEntityViewId); return checkEntityViewId(new EntityViewId(toUUID(strEntityViewId)), Operation.READ); @@ -112,12 +112,12 @@ public class EntityViewController extends BaseController { @ApiOperation(value = "Get Entity View info (getEntityViewInfoById)", notes = "Fetch the Entity View info object based on the provided Entity View Id. " + ENTITY_VIEW_INFO_DESCRIPTION + MODEL_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/entityView/info/{entityViewId}", method = RequestMethod.GET) @ResponseBody public EntityViewInfo getEntityViewInfoById( - @ApiParam(value = ENTITY_VIEW_ID_PARAM_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_ID_PARAM_DESCRIPTION) @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { checkParameter(ENTITY_VIEW_ID, strEntityViewId); EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId)); @@ -128,12 +128,12 @@ public class EntityViewController extends BaseController { notes = ENTITY_VIEW_DESCRIPTION + MODEL_DESCRIPTION + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Entity View entity." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/entityView", method = RequestMethod.POST) @ResponseBody public EntityView saveEntityView( - @ApiParam(value = "A JSON object representing the entity view.") + @Parameter(description = "A JSON object representing the entity view.") @RequestBody EntityView entityView) throws Exception { entityView.setTenantId(getCurrentUser().getTenantId()); EntityView existingEntityView = null; @@ -153,7 +153,7 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/entityView/{entityViewId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) public void deleteEntityView( - @ApiParam(value = ENTITY_VIEW_ID_PARAM_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_ID_PARAM_DESCRIPTION) @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { checkParameter(ENTITY_VIEW_ID, strEntityViewId); EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId)); @@ -163,12 +163,12 @@ public class EntityViewController extends BaseController { @ApiOperation(value = "Get Entity View by name (getTenantEntityView)", notes = "Fetch the Entity View object based on the tenant id and entity view name. " + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/entityViews", params = {"entityViewName"}, method = RequestMethod.GET) @ResponseBody public EntityView getTenantEntityView( - @ApiParam(value = "Entity View name") + @Parameter(description = "Entity View name") @RequestParam String entityViewName) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); return checkNotNull(entityViewService.findEntityViewByTenantIdAndName(tenantId, entityViewName)); @@ -180,9 +180,9 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/customer/{customerId}/entityView/{entityViewId}", method = RequestMethod.POST) @ResponseBody public EntityView assignEntityViewToCustomer( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable(CUSTOMER_ID) String strCustomerId, - @ApiParam(value = ENTITY_VIEW_ID_PARAM_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_ID_PARAM_DESCRIPTION) @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); checkParameter(ENTITY_VIEW_ID, strEntityViewId); @@ -202,7 +202,7 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/customer/entityView/{entityViewId}", method = RequestMethod.DELETE) @ResponseBody public EntityView unassignEntityViewFromCustomer( - @ApiParam(value = ENTITY_VIEW_ID_PARAM_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_ID_PARAM_DESCRIPTION) @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { checkParameter(ENTITY_VIEW_ID, strEntityViewId); EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId)); @@ -223,19 +223,19 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/customer/{customerId}/entityViews", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerEntityViews( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) @PathVariable(CUSTOMER_ID) String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ENTITY_VIEW_TYPE) + @Parameter(description = ENTITY_VIEW_TYPE) @RequestParam(required = false) String type, - @ApiParam(value = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ENTITY_VIEW_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name, type"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -256,19 +256,19 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/customer/{customerId}/entityViewInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerEntityViewInfos( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) @PathVariable(CUSTOMER_ID) String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ENTITY_VIEW_TYPE) + @Parameter(description = ENTITY_VIEW_TYPE) @RequestParam(required = false) String type, - @ApiParam(value = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ENTITY_VIEW_INFO_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("customerId", strCustomerId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -289,17 +289,17 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/tenant/entityViews", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantEntityViews( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ENTITY_VIEW_TYPE) + @Parameter(description = ENTITY_VIEW_TYPE) @RequestParam(required = false) String type, - @ApiParam(value = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ENTITY_VIEW_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name, type"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -318,17 +318,17 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/tenant/entityViewInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantEntityViewInfos( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ENTITY_VIEW_TYPE) + @Parameter(description = ENTITY_VIEW_TYPE) @RequestParam(required = false) String type, - @ApiParam(value = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ENTITY_VIEW_INFO_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -347,7 +347,7 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/entityViews", method = RequestMethod.POST) @ResponseBody public List findByQuery( - @ApiParam(value = "The entity view search query JSON") + @Parameter(description = "The entity view search query JSON") @RequestBody EntityViewSearchQuery query) throws ThingsboardException, ExecutionException, InterruptedException { checkNotNull(query); checkNotNull(query.getParameters()); @@ -386,7 +386,7 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/customer/public/entityView/{entityViewId}", method = RequestMethod.POST) @ResponseBody public EntityView assignEntityViewToPublicCustomer( - @ApiParam(value = ENTITY_VIEW_ID_PARAM_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_ID_PARAM_DESCRIPTION) @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { checkParameter(ENTITY_VIEW_ID, strEntityViewId); EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId)); @@ -400,7 +400,7 @@ public class EntityViewController extends BaseController { "Second, remote edge service will receive a copy of assignment entity view " + EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once entity view will be delivered to edge service, it's going to be available for usage on remote edge instance.", - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/entityView/{entityViewId}", method = RequestMethod.POST) @ResponseBody @@ -425,7 +425,7 @@ public class EntityViewController extends BaseController { "Second, remote edge service will receive an 'unassign' command to remove entity view " + EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once 'unassign' command will be delivered to edge service, it's going to remove entity view locally.", - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/entityView/{entityViewId}", method = RequestMethod.DELETE) @ResponseBody diff --git a/application/src/main/java/org/thingsboard/server/controller/EventController.java b/application/src/main/java/org/thingsboard/server/controller/EventController.java index ec75f981a7..09ef2e9d05 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EventController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EventController.java @@ -15,8 +15,10 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -39,6 +41,7 @@ import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.event.EventService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.permission.Operation; @@ -52,7 +55,6 @@ import static org.thingsboard.server.controller.ControllerConstants.EVENT_DEBUG_ import static org.thingsboard.server.controller.ControllerConstants.EVENT_END_TIME_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.EVENT_ERROR_FILTER_OBJ; import static org.thingsboard.server.controller.ControllerConstants.EVENT_LC_EVENT_FILTER_OBJ; -import static org.thingsboard.server.controller.ControllerConstants.EVENT_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.EVENT_START_TIME_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.EVENT_STATS_FILTER_OBJ; import static org.thingsboard.server.controller.ControllerConstants.EVENT_TEXT_SEARCH_DESCRIPTION; @@ -60,7 +62,6 @@ import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID; @@ -107,32 +108,32 @@ public class EventController extends BaseController { @ApiOperation(value = "Get Events by type (getEvents)", notes = "Returns a page of events for specified entity by specifying event type. " + - PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/events/{entityType}/{entityId}/{eventType}", method = RequestMethod.GET) @ResponseBody public PageData getEvents( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_TYPE) String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @ApiParam(value = "A string value representing event type", example = "STATS", required = true) + @Parameter(description = "A string value representing event type", example = "STATS", required = true) @PathVariable("eventType") String eventType, - @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = TENANT_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TENANT_ID) String strTenantId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = EVENT_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = EVENT_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EVENT_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"ts", "id"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = EVENT_START_TIME_DESCRIPTION) + @Parameter(description = EVENT_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = EVENT_END_TIME_DESCRIPTION) + @Parameter(description = EVENT_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime) throws ThingsboardException { checkParameter("EntityId", strEntityId); checkParameter("EntityType", strEntityType); @@ -149,30 +150,30 @@ public class EventController extends BaseController { "The call was deprecated to improve the performance of the system. " + "Current implementation will return 'Lifecycle' events only. " + "Use 'Get events by type' or 'Get events by filter' instead. " + - PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.GET) @ResponseBody public PageData getEvents( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_TYPE) String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = TENANT_ID_PARAM_DESCRIPTION, required = true) @RequestParam("tenantId") String strTenantId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = EVENT_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = EVENT_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EVENT_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"ts", "id"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = EVENT_START_TIME_DESCRIPTION) + @Parameter(description = EVENT_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = EVENT_END_TIME_DESCRIPTION) + @Parameter(description = EVENT_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime) throws ThingsboardException { checkParameter("EntityId", strEntityId); checkParameter("EntityType", strEntityType); @@ -190,32 +191,32 @@ public class EventController extends BaseController { notes = "Returns a page of events for the chosen entity by specifying the event filter. " + PAGE_DATA_PARAMETERS + NEW_LINE + EVENT_FILTER_DEFINITION, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.POST) @ResponseBody public PageData getEvents( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_TYPE) String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = TENANT_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TENANT_ID) String strTenantId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = "A JSON value representing the event filter.", required = true) + @Parameter(description = "A JSON value representing the event filter.", required = true) @RequestBody EventFilter eventFilter, - @ApiParam(value = EVENT_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = EVENT_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EVENT_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"ts", "id"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = EVENT_START_TIME_DESCRIPTION) + @Parameter(description = EVENT_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = EVENT_END_TIME_DESCRIPTION) + @Parameter(description = EVENT_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime) throws ThingsboardException { checkParameter("EntityId", strEntityId); checkParameter("EntityType", strEntityType); @@ -232,15 +233,15 @@ public class EventController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/events/{entityType}/{entityId}/clear", method = RequestMethod.POST) @ResponseStatus(HttpStatus.OK) - public void clearEvents(@ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + public void clearEvents(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_TYPE) String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @ApiParam(value = EVENT_START_TIME_DESCRIPTION) + @Parameter(description = EVENT_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = EVENT_END_TIME_DESCRIPTION) + @Parameter(description = EVENT_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime, - @ApiParam(value = EVENT_FILTER_DEFINITION) + @Parameter(description = EVENT_FILTER_DEFINITION) @RequestBody EventFilter eventFilter) throws ThingsboardException { checkParameter("EntityId", strEntityId); checkParameter("EntityType", strEntityType); diff --git a/application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java b/application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java index 8949cd95dd..433eea639e 100644 --- a/application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java +++ b/application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java @@ -15,11 +15,13 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -33,6 +35,7 @@ import org.thingsboard.server.common.data.SaveDeviceWithCredentialsRequest; import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MServerSecurityConfigDefault; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.security.DeviceCredentials; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.service.lwm2m.LwM2MService; import java.util.Map; @@ -57,12 +60,12 @@ public class Lwm2mController extends BaseController { @ApiOperation(value = "Get Lwm2m Bootstrap SecurityInfo (getLwm2mBootstrapSecurityInfo)", notes = "Get the Lwm2m Bootstrap SecurityInfo object (of the current server) based on the provided isBootstrapServer parameter. If isBootstrapServer == true, get the parameters of the current Bootstrap Server. If isBootstrapServer == false, get the parameters of the current Lwm2m Server. Used for client settings when starting the client in Bootstrap mode. " + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/lwm2m/deviceProfile/bootstrap/{isBootstrapServer}", method = RequestMethod.GET) @ResponseBody public LwM2MServerSecurityConfigDefault getLwm2mBootstrapSecurityInfo( - @ApiParam(value = IS_BOOTSTRAP_SERVER_PARAM_DESCRIPTION) + @Parameter(description = IS_BOOTSTRAP_SERVER_PARAM_DESCRIPTION) @PathVariable(IS_BOOTSTRAP_SERVER) boolean bootstrapServer) throws ThingsboardException { return lwM2MService.getServerSecurityInfo(bootstrapServer); } diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationController.java index 5893410b2a..e2a1f1a417 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationController.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; @@ -55,6 +55,7 @@ import org.thingsboard.server.common.data.notification.template.NotificationTemp import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.SortOrder; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.notification.NotificationRequestService; import org.thingsboard.server.dao.notification.NotificationService; import org.thingsboard.server.dao.notification.NotificationSettingsService; @@ -66,7 +67,6 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; -import jakarta.validation.Valid; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; @@ -158,17 +158,17 @@ public class NotificationController extends BaseController { "}\n```") @GetMapping("/notifications") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - public PageData getNotifications(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public PageData getNotifications(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = "Case-insensitive 'substring' filter based on notification subject or text") + @Parameter(description = "Case-insensitive 'substring' filter based on notification subject or text") @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION) + @Parameter(description = SORT_PROPERTY_DESCRIPTION) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION) + @Parameter(description = SORT_ORDER_DESCRIPTION) @RequestParam(required = false) String sortOrder, - @ApiParam(value = "To search for unread notifications only") + @Parameter(description = "To search for unread notifications only") @RequestParam(defaultValue = "false") boolean unreadOnly, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { // no permissions @@ -266,7 +266,7 @@ public class NotificationController extends BaseController { @PostMapping("/notification/request/preview") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public NotificationRequestPreview getNotificationRequestPreview(@RequestBody @Valid NotificationRequest request, - @ApiParam(value = "Amount of the recipients to show in preview") + @Parameter(description = "Amount of the recipients to show in preview") @RequestParam(defaultValue = "20") int recipientsPreviewSize, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { NotificationTemplate template; @@ -361,15 +361,15 @@ public class NotificationController extends BaseController { SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @GetMapping("/notification/requests") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - public PageData getNotificationRequests(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public PageData getNotificationRequests(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = "Case-insensitive 'substring' filed based on the used template name") + @Parameter(description = "Case-insensitive 'substring' filed based on the used template name") @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION) + @Parameter(description = SORT_PROPERTY_DESCRIPTION) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION) + @Parameter(description = SORT_ORDER_DESCRIPTION) @RequestParam(required = false) String sortOrder, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { // generic permission diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java index 06eabbc215..457fac9304 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; @@ -38,12 +38,12 @@ import org.thingsboard.server.common.data.notification.rule.trigger.Notification import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.notification.NotificationRuleService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; -import jakarta.validation.Valid; import java.util.UUID; import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_CODE_BLOCK_END; @@ -150,15 +150,15 @@ public class NotificationRuleController extends BaseController { SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @GetMapping("/rules") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - public PageData getNotificationRules(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public PageData getNotificationRules(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = "Case-insensitive 'substring' filter based on rule's name") + @Parameter(description = "Case-insensitive 'substring' filter based on rule's name") @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION) + @Parameter(description = SORT_PROPERTY_DESCRIPTION) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION) + @Parameter(description = SORT_ORDER_DESCRIPTION) @RequestParam(required = false) String sortOrder, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { // generic permission diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java index 6b13e9de9d..1dd16ea462 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -48,12 +48,12 @@ import org.thingsboard.server.common.data.notification.targets.platform.UserList import org.thingsboard.server.common.data.notification.targets.platform.UsersFilter; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.notification.NotificationTargetService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; -import jakarta.validation.Valid; import java.util.Arrays; import java.util.List; import java.util.UUID; @@ -134,9 +134,9 @@ public class NotificationTargetController extends BaseController { @PostMapping("/target/recipients") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public PageData getRecipientsForNotificationTargetConfig(@RequestBody NotificationTarget notificationTarget, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { // generic permission @@ -156,7 +156,7 @@ public class NotificationTargetController extends BaseController { SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @GetMapping(value = "/targets", params = {"ids"}) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - public List getNotificationTargetsByIds(@ApiParam(value = "Comma-separated list of uuids representing targets ids", required = true) + public List getNotificationTargetsByIds(@Parameter(description = "Comma-separated list of uuids representing targets ids", required = true) @RequestParam("ids") UUID[] ids, @AuthenticationPrincipal SecurityUser user) { // generic permission @@ -170,15 +170,15 @@ public class NotificationTargetController extends BaseController { SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @GetMapping("/targets") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - public PageData getNotificationTargets(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public PageData getNotificationTargets(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = "Case-insensitive 'substring' filed based on the target's name") + @Parameter(description = "Case-insensitive 'substring' filed based on the target's name") @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION) + @Parameter(description = SORT_PROPERTY_DESCRIPTION) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION) + @Parameter(description = SORT_ORDER_DESCRIPTION) @RequestParam(required = false) String sortOrder, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { // generic permission diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java index fef919d710..a28e218809 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.security.access.prepost.PreAuthorize; @@ -42,13 +42,13 @@ import org.thingsboard.server.common.data.notification.targets.slack.SlackConver import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.notification.NotificationSettingsService; import org.thingsboard.server.dao.notification.NotificationTemplateService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; -import jakarta.validation.Valid; import java.util.List; import java.util.UUID; @@ -137,17 +137,17 @@ public class NotificationTemplateController extends BaseController { SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @GetMapping("/templates") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - public PageData getNotificationTemplates(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public PageData getNotificationTemplates(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = "Case-insensitive 'substring' filter based on template's name and notification type") + @Parameter(description = "Case-insensitive 'substring' filter based on template's name and notification type") @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION) + @Parameter(description = SORT_PROPERTY_DESCRIPTION) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION) + @Parameter(description = SORT_ORDER_DESCRIPTION) @RequestParam(required = false) String sortOrder, - @ApiParam(value = "Comma-separated list of notification types to filter the templates") + @Parameter(description = "Comma-separated list of notification types to filter the templates") @RequestParam(required = false) NotificationType[] notificationTypes, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { // generic permission @@ -177,7 +177,7 @@ public class NotificationTemplateController extends BaseController { @GetMapping("/slack/conversations") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public List listSlackConversations(@RequestParam SlackConversationType type, - @ApiParam(value = "Slack bot token. If absent - system Slack settings will be used") + @Parameter(description = "Slack bot token. If absent - system Slack settings will be used") @RequestParam(required = false) String token, @AuthenticationPrincipal SecurityUser user) { // generic permission diff --git a/application/src/main/java/org/thingsboard/server/controller/OAuth2ConfigTemplateController.java b/application/src/main/java/org/thingsboard/server/controller/OAuth2ConfigTemplateController.java index f547a5f0ad..63258c5196 100644 --- a/application/src/main/java/org/thingsboard/server/controller/OAuth2ConfigTemplateController.java +++ b/application/src/main/java/org/thingsboard/server/controller/OAuth2ConfigTemplateController.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; @@ -30,6 +29,7 @@ import org.springframework.web.bind.annotation.RestController; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationTemplateId; import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationTemplate; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; @@ -63,7 +63,7 @@ public class OAuth2ConfigTemplateController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") @RequestMapping(value = "/{clientRegistrationTemplateId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteClientRegistrationTemplate(@ApiParam(value = "String representation of client registration template id to delete", example = "139b1f81-2f5d-11ec-9dbe-9b627e1a88f4") + public void deleteClientRegistrationTemplate(@Parameter(description = "String representation of client registration template id to delete", example = "139b1f81-2f5d-11ec-9dbe-9b627e1a88f4") @PathVariable(CLIENT_REGISTRATION_TEMPLATE_ID) String strClientRegistrationTemplateId) throws ThingsboardException { checkParameter(CLIENT_REGISTRATION_TEMPLATE_ID, strClientRegistrationTemplateId); accessControlService.checkPermission(getCurrentUser(), Resource.OAUTH2_CONFIGURATION_TEMPLATE, Operation.DELETE); diff --git a/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java b/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java index 519629fbc3..1688f08b52 100644 --- a/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java +++ b/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java @@ -15,8 +15,9 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -33,13 +34,13 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; import org.thingsboard.server.common.data.oauth2.OAuth2Info; import org.thingsboard.server.common.data.oauth2.PlatformType; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.oauth2.OAuth2Configuration; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; import org.thingsboard.server.utils.MiscUtils; -import jakarta.servlet.http.HttpServletRequest; import java.util.Enumeration; import java.util.List; @@ -61,13 +62,13 @@ public class OAuth2Controller extends BaseController { @RequestMapping(value = "/noauth/oauth2Clients", method = RequestMethod.POST) @ResponseBody public List getOAuth2Clients(HttpServletRequest request, - @ApiParam(value = "Mobile application package name, to find OAuth2 clients " + + @Parameter(description = "Mobile application package name, to find OAuth2 clients " + "where there is configured mobile application with such package name") @RequestParam(required = false) String pkgName, - @ApiParam(value = "Platform type to search OAuth2 clients for which " + + @Parameter(description = "Platform type to search OAuth2 clients for which " + "the usage with this platform type is allowed in the settings. " + "If platform type is not one of allowable values - it will just be ignored", - allowableValues = "WEB, ANDROID, IOS") + schema = @Schema(allowableValues = "WEB, ANDROID, IOS")) @RequestParam(required = false) String platform) throws ThingsboardException { if (log.isDebugEnabled()) { log.debug("Executing getOAuth2Clients: [{}][{}][{}]", request.getScheme(), request.getServerName(), request.getServerPort()); @@ -81,7 +82,8 @@ public class OAuth2Controller extends BaseController { if (StringUtils.isNotEmpty(platform)) { try { platformType = PlatformType.valueOf(platform); - } catch (Exception e) {} + } catch (Exception e) { + } } return oAuth2Service.getOAuth2Clients(MiscUtils.getScheme(request), MiscUtils.getDomainNameAndPort(request), pkgName, platformType); } diff --git a/application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java b/application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java index 9b923e01dc..2ee07ce196 100644 --- a/application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java +++ b/application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java @@ -15,8 +15,10 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.ByteArrayResource; @@ -42,6 +44,7 @@ import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.ota.TbOtaPackageService; import org.thingsboard.server.service.security.permission.Operation; @@ -52,16 +55,13 @@ import java.io.IOException; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_CHECKSUM_ALGORITHM_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_INFO_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -84,7 +84,7 @@ public class OtaPackageController extends BaseController { @PreAuthorize("hasAnyAuthority( 'TENANT_ADMIN')") @RequestMapping(value = "/otaPackage/{otaPackageId}/download", method = RequestMethod.GET) @ResponseBody - public ResponseEntity downloadOtaPackage(@ApiParam(value = OTA_PACKAGE_ID_PARAM_DESCRIPTION) + public ResponseEntity downloadOtaPackage(@Parameter(description = OTA_PACKAGE_ID_PARAM_DESCRIPTION) @PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException { checkParameter(OTA_PACKAGE_ID, strOtaPackageId); OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId)); @@ -106,11 +106,11 @@ public class OtaPackageController extends BaseController { @ApiOperation(value = "Get OTA Package Info (getOtaPackageInfoById)", notes = "Fetch the OTA Package Info object based on the provided OTA Package Id. " + OTA_PACKAGE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/otaPackage/info/{otaPackageId}", method = RequestMethod.GET) @ResponseBody - public OtaPackageInfo getOtaPackageInfoById(@ApiParam(value = OTA_PACKAGE_ID_PARAM_DESCRIPTION) + public OtaPackageInfo getOtaPackageInfoById(@Parameter(description = OTA_PACKAGE_ID_PARAM_DESCRIPTION) @PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException { checkParameter(OTA_PACKAGE_ID, strOtaPackageId); OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId)); @@ -120,11 +120,11 @@ public class OtaPackageController extends BaseController { @ApiOperation(value = "Get OTA Package (getOtaPackageById)", notes = "Fetch the OTA Package object based on the provided OTA Package Id. " + "The server checks that the OTA Package is owned by the same tenant. " + OTA_PACKAGE_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH, - produces = APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.GET) @ResponseBody - public OtaPackage getOtaPackageById(@ApiParam(value = OTA_PACKAGE_ID_PARAM_DESCRIPTION) + public OtaPackage getOtaPackageById(@Parameter(description = OTA_PACKAGE_ID_PARAM_DESCRIPTION) @PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException { checkParameter(OTA_PACKAGE_ID, strOtaPackageId); OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId)); @@ -137,12 +137,11 @@ public class OtaPackageController extends BaseController { "Specify existing OTA Package id to update the OTA Package Info. " + "Referencing non-existing OTA Package Id will cause 'Not Found' error. " + "\n\nOTA Package combination of the title with the version is unique in the scope of tenant. " + TENANT_AUTHORITY_PARAGRAPH, - produces = APPLICATION_JSON_VALUE, - consumes = APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/otaPackage", method = RequestMethod.POST) @ResponseBody - public OtaPackageInfo saveOtaPackageInfo(@ApiParam(value = "A JSON value representing the OTA Package.") + public OtaPackageInfo saveOtaPackageInfo(@Parameter(description = "A JSON value representing the OTA Package.") @RequestBody SaveOtaPackageInfoRequest otaPackageInfo) throws ThingsboardException { otaPackageInfo.setTenantId(getTenantId()); checkEntity(otaPackageInfo.getId(), otaPackageInfo, Resource.OTA_PACKAGE); @@ -152,18 +151,18 @@ public class OtaPackageController extends BaseController { @ApiOperation(value = "Save OTA Package data (saveOtaPackageData)", notes = "Update the OTA Package. Adds the date to the existing OTA Package Info" + TENANT_AUTHORITY_PARAGRAPH, - produces = APPLICATION_JSON_VALUE, - consumes = MULTIPART_FORM_DATA_VALUE) + responses = @ApiResponse(content = @Content(mediaType = APPLICATION_JSON_VALUE)), + requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(content = @Content(mediaType = MULTIPART_FORM_DATA_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.POST, consumes = MULTIPART_FORM_DATA_VALUE) @ResponseBody - public OtaPackageInfo saveOtaPackageData(@ApiParam(value = OTA_PACKAGE_ID_PARAM_DESCRIPTION) + public OtaPackageInfo saveOtaPackageData(@Parameter(description = OTA_PACKAGE_ID_PARAM_DESCRIPTION) @PathVariable(OTA_PACKAGE_ID) String strOtaPackageId, - @ApiParam(value = "OTA Package checksum. For example, '0xd87f7e0c'") + @Parameter(description = "OTA Package checksum. For example, '0xd87f7e0c'") @RequestParam(required = false) String checksum, - @ApiParam(value = "OTA Package checksum algorithm.", allowableValues = OTA_PACKAGE_CHECKSUM_ALGORITHM_ALLOWABLE_VALUES) + @Parameter(description = "OTA Package checksum algorithm.", schema = @Schema(allowableValues = {"MD5", "SHA256", "SHA384", "SHA512", "CRC32", "MURMUR3_32", "MURMUR3_128"})) @RequestParam(CHECKSUM_ALGORITHM) String checksumAlgorithmStr, - @ApiParam(value = "OTA Package data.") + @Parameter(description = "OTA Package data.") @RequestPart MultipartFile file) throws ThingsboardException, IOException { checkParameter(OTA_PACKAGE_ID, strOtaPackageId); checkParameter(CHECKSUM_ALGORITHM, checksumAlgorithmStr); @@ -178,19 +177,19 @@ public class OtaPackageController extends BaseController { @ApiOperation(value = "Get OTA Package Infos (getOtaPackages)", notes = "Returns a page of OTA Package Info objects owned by tenant. " + PAGE_DATA_PARAMETERS + OTA_PACKAGE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/otaPackages", method = RequestMethod.GET) @ResponseBody - public PageData getOtaPackages(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public PageData getOtaPackages(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = OTA_PACKAGE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "type", "title", "version", "tag", "url", "fileName", "dataSize", "checksum"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return checkNotNull(otaPackageService.findTenantOtaPackagesByTenantId(getTenantId(), pageLink)); @@ -199,23 +198,23 @@ public class OtaPackageController extends BaseController { @ApiOperation(value = "Get OTA Package Infos (getOtaPackages)", notes = "Returns a page of OTA Package Info objects owned by tenant. " + PAGE_DATA_PARAMETERS + OTA_PACKAGE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/otaPackages/{deviceProfileId}/{type}", method = RequestMethod.GET) @ResponseBody - public PageData getOtaPackages(@ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + public PageData getOtaPackages(@Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable("deviceProfileId") String strDeviceProfileId, - @ApiParam(value = "OTA Package type.", allowableValues = "FIRMWARE, SOFTWARE") + @Parameter(description = "OTA Package type.", schema = @Schema(allowableValues = "FIRMWARE, SOFTWARE")) @PathVariable("type") String strType, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = OTA_PACKAGE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "type", "title", "version", "tag", "url", "fileName", "dataSize", "checksum"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("deviceProfileId", strDeviceProfileId); checkParameter("type", strType); @@ -227,11 +226,11 @@ public class OtaPackageController extends BaseController { @ApiOperation(value = "Delete OTA Package (deleteOtaPackage)", notes = "Deletes the OTA Package. Referencing non-existing OTA Package Id will cause an error. " + "Can't delete the OTA Package if it is referenced by existing devices or device profile." + TENANT_AUTHORITY_PARAGRAPH, - produces = APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.DELETE) @ResponseBody - public void deleteOtaPackage(@ApiParam(value = OTA_PACKAGE_ID_PARAM_DESCRIPTION) + public void deleteOtaPackage(@Parameter(description = OTA_PACKAGE_ID_PARAM_DESCRIPTION) @PathVariable("otaPackageId") String strOtaPackageId) throws ThingsboardException { checkParameter(OTA_PACKAGE_ID, strOtaPackageId); OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId)); diff --git a/application/src/main/java/org/thingsboard/server/controller/QueueController.java b/application/src/main/java/org/thingsboard/server/controller/QueueController.java index 0e79ae7955..774c991f94 100644 --- a/application/src/main/java/org/thingsboard/server/controller/QueueController.java +++ b/application/src/main/java/org/thingsboard/server/controller/QueueController.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; @@ -32,6 +32,7 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.queue.Queue; import org.thingsboard.server.common.msg.queue.ServiceType; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.queue.TbQueueService; import org.thingsboard.server.service.security.permission.Operation; @@ -45,10 +46,7 @@ import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DE import static org.thingsboard.server.controller.ControllerConstants.QUEUE_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.QUEUE_NAME_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.QUEUE_QUEUE_TEXT_SEARCH_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.QUEUE_SERVICE_TYPE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.QUEUE_SORT_PROPERTY_ALLOWABLE_VALUES; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; @@ -69,17 +67,17 @@ public class QueueController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/queues", params = {"serviceType", "pageSize", "page"}, method = RequestMethod.GET) @ResponseBody - public PageData getTenantQueuesByServiceType(@ApiParam(value = QUEUE_SERVICE_TYPE_DESCRIPTION, allowableValues = QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES, required = true) + public PageData getTenantQueuesByServiceType(@Parameter(description = QUEUE_SERVICE_TYPE_DESCRIPTION, schema = @Schema(allowableValues = {"TB-RULE-ENGINE", "TB-CORE", "TB-TRANSPORT", "JS-EXECUTOR"}, required = true)) @RequestParam String serviceType, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = QUEUE_QUEUE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = QUEUE_QUEUE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = QUEUE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "topic"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("serviceType", serviceType); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -97,7 +95,7 @@ public class QueueController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/queues/{queueId}", method = RequestMethod.GET) @ResponseBody - public Queue getQueueById(@ApiParam(value = QUEUE_ID_PARAM_DESCRIPTION) + public Queue getQueueById(@Parameter(description = QUEUE_ID_PARAM_DESCRIPTION) @PathVariable("queueId") String queueIdStr) throws ThingsboardException { checkParameter("queueId", queueIdStr); QueueId queueId = new QueueId(UUID.fromString(queueIdStr)); @@ -110,7 +108,7 @@ public class QueueController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/queues/name/{queueName}", method = RequestMethod.GET) @ResponseBody - public Queue getQueueByName(@ApiParam(value = QUEUE_NAME_PARAM_DESCRIPTION) + public Queue getQueueByName(@Parameter(description = QUEUE_NAME_PARAM_DESCRIPTION) @PathVariable("queueName") String queueName) throws ThingsboardException { checkParameter("queueName", queueName); return checkNotNull(queueService.findQueueByTenantIdAndName(getTenantId(), queueName)); @@ -127,9 +125,9 @@ public class QueueController extends BaseController { @RequestMapping(value = "/queues", params = {"serviceType"}, method = RequestMethod.POST) @ResponseBody - public Queue saveQueue(@ApiParam(value = "A JSON value representing the queue.") + public Queue saveQueue(@Parameter(description = "A JSON value representing the queue.") @RequestBody Queue queue, - @ApiParam(value = QUEUE_SERVICE_TYPE_DESCRIPTION, allowableValues = QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES, required = true) + @Parameter(description = QUEUE_SERVICE_TYPE_DESCRIPTION, schema = @Schema(allowableValues = {"TB-RULE-ENGINE", "TB-CORE", "TB-TRANSPORT", "JS-EXECUTOR"}, required = true)) @RequestParam String serviceType) throws ThingsboardException { checkParameter("serviceType", serviceType); queue.setTenantId(getCurrentUser().getTenantId()); @@ -152,7 +150,7 @@ public class QueueController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") @RequestMapping(value = "/queues/{queueId}", method = RequestMethod.DELETE) @ResponseBody - public void deleteQueue(@ApiParam(value = QUEUE_ID_PARAM_DESCRIPTION) + public void deleteQueue(@Parameter(description = QUEUE_ID_PARAM_DESCRIPTION) @PathVariable("queueId") String queueIdStr) throws ThingsboardException { checkParameter("queueId", queueIdStr); QueueId queueId = new QueueId(toUUID(queueIdStr)); diff --git a/application/src/main/java/org/thingsboard/server/controller/RpcV1Controller.java b/application/src/main/java/org/thingsboard/server/controller/RpcV1Controller.java index 509e91e546..fd207dcc34 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RpcV1Controller.java +++ b/application/src/main/java/org/thingsboard/server/controller/RpcV1Controller.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -30,6 +29,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.request.async.DeferredResult; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.UUID; @@ -48,9 +48,9 @@ public class RpcV1Controller extends AbstractRpcController { @RequestMapping(value = "/oneway/{deviceId}", method = RequestMethod.POST) @ResponseBody public DeferredResult handleOneWayDeviceRPCRequest( - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable("deviceId") String deviceIdStr, - @ApiParam(value = "A JSON value representing the RPC request.") + @Parameter(description = "A JSON value representing the RPC request.") @RequestBody String requestBody) throws ThingsboardException { return handleDeviceRPCRequest(true, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.REQUEST_TIMEOUT, HttpStatus.CONFLICT); } @@ -60,9 +60,9 @@ public class RpcV1Controller extends AbstractRpcController { @RequestMapping(value = "/twoway/{deviceId}", method = RequestMethod.POST) @ResponseBody public DeferredResult handleTwoWayDeviceRPCRequest( - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable("deviceId") String deviceIdStr, - @ApiParam(value = "A JSON value representing the RPC request.") + @Parameter(description = "A JSON value representing the RPC request.") @RequestBody String requestBody) throws ThingsboardException { return handleDeviceRPCRequest(false, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.REQUEST_TIMEOUT, HttpStatus.CONFLICT); } diff --git a/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java b/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java index c611cfda54..eb7481c6e2 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java +++ b/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java @@ -16,10 +16,11 @@ package org.thingsboard.server.controller; import com.google.common.util.concurrent.FutureCallback; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import jakarta.annotation.Nullable; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -44,12 +45,12 @@ import org.thingsboard.server.common.data.rpc.Rpc; import org.thingsboard.server.common.data.rpc.RpcStatus; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.exception.ToErrorResponseEntity; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.rpc.RemoveRpcActorMsg; import org.thingsboard.server.service.security.permission.Operation; -import jakarta.annotation.Nullable; import java.util.UUID; import static org.thingsboard.server.common.data.DataConstants.RPC_DELETED; @@ -61,10 +62,7 @@ import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_ import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.RPC_ID; import static org.thingsboard.server.controller.ControllerConstants.RPC_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.RPC_SORT_PROPERTY_ALLOWABLE_VALUES; -import static org.thingsboard.server.controller.ControllerConstants.RPC_STATUS_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.RPC_TEXT_SEARCH_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -117,36 +115,36 @@ public class RpcV2Controller extends AbstractRpcController { @ApiOperation(value = "Send one-way RPC request", notes = ONE_WAY_RPC_REQUEST_DESCRIPTION) @ApiResponses(value = { - @ApiResponse(code = 200, message = "Persistent RPC request was saved to the database or lightweight RPC request was sent to the device."), - @ApiResponse(code = 400, message = "Invalid structure of the request."), - @ApiResponse(code = 401, message = "User is not authorized to send the RPC request. Most likely, User belongs to different Customer or Tenant."), - @ApiResponse(code = 504, message = "Timeout to process the RPC call. Most likely, device is offline."), + @ApiResponse(responseCode = "200", description = "Persistent RPC request was saved to the database or lightweight RPC request was sent to the device."), + @ApiResponse(responseCode = "400", description = "Invalid structure of the request."), + @ApiResponse(responseCode = "401", description = "User is not authorized to send the RPC request. Most likely, User belongs to different Customer or Tenant."), + @ApiResponse(responseCode = "504", description = "Timeout to process the RPC call. Most likely, device is offline."), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/oneway/{deviceId}", method = RequestMethod.POST) @ResponseBody public DeferredResult handleOneWayDeviceRPCRequest( - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable("deviceId") String deviceIdStr, - @ApiParam(value = "A JSON value representing the RPC request.") + @Parameter(description = "A JSON value representing the RPC request.") @RequestBody String requestBody) throws ThingsboardException { return handleDeviceRPCRequest(true, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.GATEWAY_TIMEOUT, HttpStatus.GATEWAY_TIMEOUT); } @ApiOperation(value = "Send two-way RPC request", notes = TWO_WAY_RPC_REQUEST_DESCRIPTION) @ApiResponses(value = { - @ApiResponse(code = 200, message = "Persistent RPC request was saved to the database or lightweight RPC response received."), - @ApiResponse(code = 400, message = "Invalid structure of the request."), - @ApiResponse(code = 401, message = "User is not authorized to send the RPC request. Most likely, User belongs to different Customer or Tenant."), - @ApiResponse(code = 504, message = "Timeout to process the RPC call. Most likely, device is offline."), + @ApiResponse(responseCode = "200", description = "Persistent RPC request was saved to the database or lightweight RPC response received."), + @ApiResponse(responseCode = "400", description = "Invalid structure of the request."), + @ApiResponse(responseCode = "401", description = "User is not authorized to send the RPC request. Most likely, User belongs to different Customer or Tenant."), + @ApiResponse(responseCode = "504", description = "Timeout to process the RPC call. Most likely, device is offline."), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/twoway/{deviceId}", method = RequestMethod.POST) @ResponseBody public DeferredResult handleTwoWayDeviceRPCRequest( - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String deviceIdStr, - @ApiParam(value = "A JSON value representing the RPC request.") + @Parameter(description = "A JSON value representing the RPC request.") @RequestBody String requestBody) throws ThingsboardException { return handleDeviceRPCRequest(false, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.GATEWAY_TIMEOUT, HttpStatus.GATEWAY_TIMEOUT); } @@ -156,7 +154,7 @@ public class RpcV2Controller extends AbstractRpcController { @RequestMapping(value = "/persistent/{rpcId}", method = RequestMethod.GET) @ResponseBody public Rpc getPersistedRpc( - @ApiParam(value = RPC_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = RPC_ID_PARAM_DESCRIPTION, required = true) @PathVariable(RPC_ID) String strRpc) throws ThingsboardException { checkParameter("RpcId", strRpc); RpcId rpcId = new RpcId(UUID.fromString(strRpc)); @@ -168,19 +166,19 @@ public class RpcV2Controller extends AbstractRpcController { @RequestMapping(value = "/persistent/device/{deviceId}", method = RequestMethod.GET) @ResponseBody public DeferredResult getPersistedRpcByDevice( - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(DEVICE_ID) String strDeviceId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = "Status of the RPC", allowableValues = RPC_STATUS_ALLOWABLE_VALUES) + @Parameter(description = "Status of the RPC", schema = @Schema(allowableValues = {"QUEUED", "SENT", "DELIVERED", "SUCCESSFUL", "TIMEOUT", "EXPIRED", "FAILED"})) @RequestParam(required = false) RpcStatus rpcStatus, - @ApiParam(value = RPC_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = RPC_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = RPC_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "expirationTime", "request", "response"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("DeviceId", strDeviceId); if (rpcStatus != null && rpcStatus.equals(RpcStatus.DELETED)) { @@ -223,7 +221,7 @@ public class RpcV2Controller extends AbstractRpcController { @RequestMapping(value = "/persistent/{rpcId}", method = RequestMethod.DELETE) @ResponseBody public void deleteRpc( - @ApiParam(value = RPC_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = RPC_ID_PARAM_DESCRIPTION, required = true) @PathVariable(RPC_ID) String strRpc) throws ThingsboardException { checkParameter("RpcId", strRpc); RpcId rpcId = new RpcId(UUID.fromString(strRpc)); diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java index 50abb3de1d..64606968b5 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -20,8 +20,10 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -66,6 +68,7 @@ import org.thingsboard.server.common.data.script.ScriptLanguage; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgMetaData; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.event.EventService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.rule.TbRuleChainService; @@ -93,12 +96,9 @@ import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PA import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_TEXT_SEARCH_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_TYPES_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_TYPE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.RULE_NODE_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -163,7 +163,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/{ruleChainId}", method = RequestMethod.GET) @ResponseBody public RuleChain getRuleChainById( - @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + @Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); @@ -177,7 +177,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/{ruleChainId}/output/labels", method = RequestMethod.GET) @ResponseBody public Set getRuleChainOutputLabels( - @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + @Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); @@ -192,7 +192,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/{ruleChainId}/output/labels/usage", method = RequestMethod.GET) @ResponseBody public List getRuleChainOutputLabelsUsage( - @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + @Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); @@ -206,7 +206,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/{ruleChainId}/metadata", method = RequestMethod.GET) @ResponseBody public RuleChainMetaData getRuleChainMetaData( - @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + @Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); @@ -226,7 +226,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain", method = RequestMethod.POST) @ResponseBody public RuleChain saveRuleChain( - @ApiParam(value = "A JSON value representing the rule chain.") + @Parameter(description = "A JSON value representing the rule chain.") @RequestBody RuleChain ruleChain) throws Exception { ruleChain.setTenantId(getCurrentUser().getTenantId()); checkEntity(ruleChain.getId(), ruleChain, Resource.RULE_CHAIN); @@ -240,7 +240,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/device/default", method = RequestMethod.POST) @ResponseBody public RuleChain saveRuleChain( - @ApiParam(value = "A JSON value representing the request.") + @Parameter(description = "A JSON value representing the request.") @RequestBody DefaultRuleChainCreateRequest request) throws Exception { checkNotNull(request); checkParameter(request.getName(), "name"); @@ -253,7 +253,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/{ruleChainId}/root", method = RequestMethod.POST) @ResponseBody public RuleChain setRootRuleChain( - @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + @Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); @@ -267,9 +267,9 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/metadata", method = RequestMethod.POST) @ResponseBody public RuleChainMetaData saveRuleChainMetaData( - @ApiParam(value = "A JSON value representing the rule chain metadata.") + @Parameter(description = "A JSON value representing the rule chain metadata.") @RequestBody RuleChainMetaData ruleChainMetaData, - @ApiParam(value = "Update related rule nodes.") + @Parameter(description = "Update related rule nodes.") @RequestParam(value = "updateRelated", required = false, defaultValue = "true") boolean updateRelated ) throws Exception { TenantId tenantId = getTenantId(); @@ -291,17 +291,17 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChains", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getRuleChains( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = RULE_CHAIN_TYPE_DESCRIPTION, allowableValues = RULE_CHAIN_TYPES_ALLOWABLE_VALUES) + @Parameter(description = RULE_CHAIN_TYPE_DESCRIPTION, schema = @Schema(allowableValues = {"CORE", "EDGE"})) @RequestParam(value = "type", required = false) String typeStr, - @ApiParam(value = RULE_CHAIN_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = RULE_CHAIN_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = RULE_CHAIN_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "root"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -319,7 +319,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/{ruleChainId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) public void deleteRuleChain( - @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + @Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); @@ -334,7 +334,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleNode/{ruleNodeId}/debugIn", method = RequestMethod.GET) @ResponseBody public JsonNode getLatestRuleNodeDebugInput( - @ApiParam(value = RULE_NODE_ID_PARAM_DESCRIPTION) + @Parameter(description = RULE_NODE_ID_PARAM_DESCRIPTION) @PathVariable(RULE_NODE_ID) String strRuleNodeId) throws ThingsboardException { checkParameter(RULE_NODE_ID, strRuleNodeId); RuleNodeId ruleNodeId = new RuleNodeId(toUUID(strRuleNodeId)); @@ -369,9 +369,9 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/testScript", method = RequestMethod.POST) @ResponseBody public JsonNode testScript( - @ApiParam(value = "Script language: JS or TBEL") + @Parameter(description = "Script language: JS or TBEL") @RequestParam(required = false) ScriptLanguage scriptLang, - @ApiParam(value = "Test JS request. See API call description above.") + @Parameter(description = "Test JS request. See API call description above.") @RequestBody JsonNode inputParams) throws ThingsboardException, JsonProcessingException { String script = inputParams.get("script").asText(); String scriptType = inputParams.get("scriptType").asText(); @@ -443,7 +443,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChains/export", params = {"limit"}, method = RequestMethod.GET) @ResponseBody public RuleChainData exportRuleChains( - @ApiParam(value = "A limit of rule chains to export.", required = true) + @Parameter(description = "A limit of rule chains to export.", required = true) @RequestParam("limit") int limit) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = new PageLink(limit); @@ -455,9 +455,9 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChains/import", method = RequestMethod.POST) @ResponseBody public List importRuleChains( - @ApiParam(value = "A JSON value representing the rule chains.") + @Parameter(description = "A JSON value representing the rule chains.") @RequestBody RuleChainData ruleChainData, - @ApiParam(value = "Enables overwrite for existing rule chains with the same name.") + @Parameter(description = "Enables overwrite for existing rule chains with the same name.") @RequestParam(required = false, defaultValue = "false") boolean overwrite) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); List importResults = ruleChainService.importTenantRuleChains(tenantId, ruleChainData, overwrite); @@ -507,7 +507,7 @@ public class RuleChainController extends BaseController { EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once rule chain will be delivered to edge service, it's going to start processing messages locally. " + "\n\nOnly rule chain with type 'EDGE' can be assigned to edge." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/ruleChain/{ruleChainId}", method = RequestMethod.POST) @ResponseBody @@ -530,7 +530,7 @@ public class RuleChainController extends BaseController { "Second, remote edge service will receive an 'unassign' command to remove rule chain " + EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once 'unassign' command will be delivered to edge service, it's going to remove rule chain locally." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/ruleChain/{ruleChainId}", method = RequestMethod.DELETE) @ResponseBody @@ -552,17 +552,17 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/edge/{edgeId}/ruleChains", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getEdgeRuleChains( - @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = RULE_CHAIN_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = RULE_CHAIN_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = RULE_CHAIN_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "root"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -578,7 +578,7 @@ public class RuleChainController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/ruleChain/{ruleChainId}/edgeTemplateRoot", method = RequestMethod.POST) @ResponseBody - public RuleChain setEdgeTemplateRootRuleChain(@ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + public RuleChain setEdgeTemplateRootRuleChain(@Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); @@ -592,7 +592,7 @@ public class RuleChainController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/ruleChain/{ruleChainId}/autoAssignToEdge", method = RequestMethod.POST) @ResponseBody - public RuleChain setAutoAssignToEdgeRuleChain(@ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + public RuleChain setAutoAssignToEdgeRuleChain(@Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); @@ -606,7 +606,7 @@ public class RuleChainController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/ruleChain/{ruleChainId}/autoAssignToEdge", method = RequestMethod.DELETE) @ResponseBody - public RuleChain unsetAutoAssignToEdgeRuleChain(@ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + public RuleChain unsetAutoAssignToEdgeRuleChain(@Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); diff --git a/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java b/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java index 724cb59b73..07d8fa04d3 100644 --- a/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java +++ b/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java @@ -17,6 +17,8 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -39,14 +41,12 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.UserPrincipal; import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService; -import springfox.documentation.annotations.ApiIgnore; -import jakarta.annotation.PostConstruct; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -@ApiIgnore +@Hidden @RestController @TbCoreComponent @RequestMapping("/api") diff --git a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java index d94dc31fa1..387d31d40d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java @@ -15,8 +15,10 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.ByteArrayResource; @@ -39,6 +41,7 @@ import org.thingsboard.server.common.data.lwm2m.LwM2mObject; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.resource.TbResourceService; import org.thingsboard.server.service.security.permission.Operation; @@ -48,16 +51,13 @@ import java.util.Base64; import java.util.List; import static org.thingsboard.server.controller.ControllerConstants.LWM2M_OBJECT_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.LWM2M_OBJECT_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_INFO_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_TEXT_SEARCH_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH; @@ -79,7 +79,7 @@ public class TbResourceController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/resource/{resourceId}/download", method = RequestMethod.GET) @ResponseBody - public ResponseEntity downloadResource(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) + public ResponseEntity downloadResource(@Parameter(description = RESOURCE_ID_PARAM_DESCRIPTION) @PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException { checkParameter(RESOURCE_ID, strResourceId); TbResourceId resourceId = new TbResourceId(toUUID(strResourceId)); @@ -97,11 +97,11 @@ public class TbResourceController extends BaseController { @ApiOperation(value = "Get Resource Info (getResourceInfoById)", notes = "Fetch the Resource Info object based on the provided Resource Id. " + RESOURCE_INFO_DESCRIPTION + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/resource/info/{resourceId}", method = RequestMethod.GET) @ResponseBody - public TbResourceInfo getResourceInfoById(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) + public TbResourceInfo getResourceInfoById(@Parameter(description = RESOURCE_ID_PARAM_DESCRIPTION) @PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException { checkParameter(RESOURCE_ID, strResourceId); TbResourceId resourceId = new TbResourceId(toUUID(strResourceId)); @@ -111,11 +111,11 @@ public class TbResourceController extends BaseController { @ApiOperation(value = "Get Resource (getResourceById)", notes = "Fetch the Resource object based on the provided Resource Id. " + RESOURCE_DESCRIPTION + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/resource/{resourceId}", method = RequestMethod.GET) @ResponseBody - public TbResource getResourceById(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) + public TbResource getResourceById(@Parameter(description = RESOURCE_ID_PARAM_DESCRIPTION) @PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException { checkParameter(RESOURCE_ID, strResourceId); TbResourceId resourceId = new TbResourceId(toUUID(strResourceId)); @@ -130,12 +130,11 @@ public class TbResourceController extends BaseController { "\n\nResource combination of the title with the key is unique in the scope of tenant. " + "Remove 'id', 'tenantId' from the request body example (below) to create new Resource entity." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json", - consumes = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/resource", method = RequestMethod.POST) @ResponseBody - public TbResource saveResource(@ApiParam(value = "A JSON value representing the Resource.") + public TbResource saveResource(@Parameter(description = "A JSON value representing the Resource.") @RequestBody TbResource resource) throws Exception { resource.setTenantId(getTenantId()); checkEntity(resource.getId(), resource, Resource.TB_RESOURCE); @@ -145,19 +144,19 @@ public class TbResourceController extends BaseController { @ApiOperation(value = "Get Resource Infos (getResources)", notes = "Returns a page of Resource Info objects owned by tenant or sysadmin. " + PAGE_DATA_PARAMETERS + RESOURCE_INFO_DESCRIPTION + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/resource", method = RequestMethod.GET) @ResponseBody - public PageData getResources(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public PageData getResources(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = RESOURCE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = RESOURCE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "title", "resourceType", "tenantId"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { @@ -170,19 +169,19 @@ public class TbResourceController extends BaseController { @ApiOperation(value = "Get LwM2M Objects (getLwm2mListObjectsPage)", notes = "Returns a page of LwM2M objects parsed from Resources with type 'LWM2M_MODEL' owned by tenant or sysadmin. " + PAGE_DATA_PARAMETERS + LWM2M_OBJECT_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/resource/lwm2m/page", method = RequestMethod.GET) @ResponseBody - public List getLwm2mListObjectsPage(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public List getLwm2mListObjectsPage(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = RESOURCE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = RESOURCE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = LWM2M_OBJECT_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"id", "name"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = new PageLink(pageSize, page, textSearch); return checkNotNull(resourceService.findLwM2mObjectPage(getTenantId(), sortProperty, sortOrder, pageLink)); @@ -191,15 +190,15 @@ public class TbResourceController extends BaseController { @ApiOperation(value = "Get LwM2M Objects (getLwm2mListObjects)", notes = "Returns a page of LwM2M objects parsed from Resources with type 'LWM2M_MODEL' owned by tenant or sysadmin. " + "You can specify parameters to filter the results. " + LWM2M_OBJECT_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/resource/lwm2m", method = RequestMethod.GET) @ResponseBody - public List getLwm2mListObjects(@ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES, required = true) + public List getLwm2mListObjects(@Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"}, required = true)) @RequestParam String sortOrder, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = LWM2M_OBJECT_SORT_PROPERTY_ALLOWABLE_VALUES, required = true) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"id", "name"}, required = true)) @RequestParam String sortProperty, - @ApiParam(value = "LwM2M Object ids.", required = true) + @Parameter(description = "LwM2M Object ids.", required = true) @RequestParam(required = false) String[] objectIds) throws ThingsboardException { return checkNotNull(resourceService.findLwM2mObject(getTenantId(), sortOrder, sortProperty, objectIds)); } @@ -209,7 +208,7 @@ public class TbResourceController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/resource/{resourceId}", method = RequestMethod.DELETE) @ResponseBody - public void deleteResource(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) + public void deleteResource(@Parameter(description = RESOURCE_ID_PARAM_DESCRIPTION) @PathVariable("resourceId") String strResourceId) throws ThingsboardException { checkParameter(RESOURCE_ID, strResourceId); TbResourceId resourceId = new TbResourceId(toUUID(strResourceId)); diff --git a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java index 262cd38629..1e72d70cbb 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java @@ -24,10 +24,14 @@ import com.google.common.util.concurrent.MoreExecutors; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import com.google.gson.JsonParser; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -46,6 +50,7 @@ import org.springframework.web.context.request.async.DeferredResult; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.StringUtils; @@ -74,7 +79,7 @@ import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; -import org.thingsboard.server.common.adaptor.JsonConverter; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.timeseries.TimeseriesService; import org.thingsboard.server.exception.InvalidParametersException; import org.thingsboard.server.exception.UncheckedApiException; @@ -85,9 +90,6 @@ import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.telemetry.AttributeData; import org.thingsboard.server.service.telemetry.TsData; -import jakarta.annotation.Nullable; -import jakarta.annotation.PostConstruct; -import jakarta.annotation.PreDestroy; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; @@ -100,8 +102,6 @@ import java.util.stream.Collectors; import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTES_JSON_REQUEST_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTES_KEYS_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES; -import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTES_SCOPE_ALLOWED_VALUES; import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTES_SCOPE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTE_DATA_EXAMPLE; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID; @@ -126,7 +126,6 @@ import static org.thingsboard.server.controller.ControllerConstants.SAVE_ENTITY_ import static org.thingsboard.server.controller.ControllerConstants.SAVE_ENTITY_TIMESERIES_STATUS_OK; import static org.thingsboard.server.controller.ControllerConstants.SAVE_ENTITY_TIMESERIES_STATUS_UNAUTHORIZED; import static org.thingsboard.server.controller.ControllerConstants.SAVE_TIMESERIES_REQUEST_PAYLOAD; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.STRICT_DATA_TYPES_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TELEMETRY_JSON_REQUEST_DESCRIPTION; @@ -176,13 +175,13 @@ public class TelemetryController extends BaseController { "\n * CLIENT_SCOPE - supported for devices;" + "\n * SHARED_SCOPE - supported for devices. " + "\n\n" + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/keys/attributes", method = RequestMethod.GET) @ResponseBody public DeferredResult getAttributeKeys( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr) throws ThingsboardException { return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, this::getAttributeKeysCallback); } @@ -192,16 +191,16 @@ public class TelemetryController extends BaseController { "\n * CLIENT_SCOPE - supported for devices;" + "\n * SHARED_SCOPE - supported for devices. " + "\n\n" + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/keys/attributes/{scope}", method = RequestMethod.GET) @ResponseBody public DeferredResult getAttributeKeysByScope( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, required = true, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES) @PathVariable("scope") String scope) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE", "CLIENT_SCOPE"})) @PathVariable("scope") String scope) throws ThingsboardException { return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, - (result, tenantId, entityId) -> getAttributeKeysCallback(result, tenantId, entityId, scope)); + (result, tenantId, entityId) -> getAttributeKeysCallback(result, tenantId, entityId, scope)); } @ApiOperation(value = "Get attributes (getAttributes)", @@ -211,17 +210,17 @@ public class TelemetryController extends BaseController { + ATTRIBUTE_DATA_EXAMPLE + MARKDOWN_CODE_BLOCK_END + "\n\n " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/values/attributes", method = RequestMethod.GET) @ResponseBody public DeferredResult getAttributes( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = ATTRIBUTES_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { - SecurityUser user = getCurrentUser(); + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = ATTRIBUTES_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { + SecurityUser user = getCurrentUser(); return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, - (result, tenantId, entityId) -> getAttributeValuesCallback(result, user, entityId, null, keysStr)); + (result, tenantId, entityId) -> getAttributeValuesCallback(result, user, entityId, null, keysStr)); } @@ -234,32 +233,32 @@ public class TelemetryController extends BaseController { + ATTRIBUTE_DATA_EXAMPLE + MARKDOWN_CODE_BLOCK_END + "\n\n " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/values/attributes/{scope}", method = RequestMethod.GET) @ResponseBody public DeferredResult getAttributesByScope( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES, required = true) @PathVariable("scope") String scope, - @ApiParam(value = ATTRIBUTES_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE", "CLIENT_SCOPE"}, required = true)) @PathVariable("scope") String scope, + @Parameter(description = ATTRIBUTES_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { SecurityUser user = getCurrentUser(); return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, - (result, tenantId, entityId) -> getAttributeValuesCallback(result, user, entityId, scope, keysStr)); + (result, tenantId, entityId) -> getAttributeValuesCallback(result, user, entityId, scope, keysStr)); } @ApiOperation(value = "Get time-series keys (getTimeseriesKeys)", notes = "Returns a set of unique time-series key names for the selected entity. " + "\n\n" + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/keys/timeseries", method = RequestMethod.GET) @ResponseBody public DeferredResult getTimeseriesKeys( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr) throws ThingsboardException { return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, - (result, tenantId, entityId) -> Futures.addCallback(tsService.findAllLatest(tenantId, entityId), getTsKeysToResponseCallback(result), MoreExecutors.directExecutor())); + (result, tenantId, entityId) -> Futures.addCallback(tsService.findAllLatest(tenantId, entityId), getTsKeysToResponseCallback(result), MoreExecutors.directExecutor())); } @ApiOperation(value = "Get latest time-series value (getLatestTimeseries)", @@ -274,15 +273,15 @@ public class TelemetryController extends BaseController { + LATEST_TS_STRICT_DATA_EXAMPLE + MARKDOWN_CODE_BLOCK_END + "\n\n " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/values/timeseries", method = RequestMethod.GET) @ResponseBody public DeferredResult getLatestTimeseries( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = TELEMETRY_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr, - @ApiParam(value = STRICT_DATA_TYPES_DESCRIPTION) + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = TELEMETRY_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr, + @Parameter(description = STRICT_DATA_TYPES_DESCRIPTION) @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes) throws ThingsboardException { SecurityUser user = getCurrentUser(); return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, @@ -298,30 +297,30 @@ public class TelemetryController extends BaseController { + TS_STRICT_DATA_EXAMPLE + MARKDOWN_CODE_BLOCK_END + "\n\n" + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/values/timeseries", method = RequestMethod.GET, params = {"keys", "startTs", "endTs"}) @ResponseBody public DeferredResult getTimeseries( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = TELEMETRY_KEYS_BASE_DESCRIPTION, required = true) @RequestParam(name = "keys") String keys, - @ApiParam(value = "A long value representing the start timestamp of the time range in milliseconds, UTC.") + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = TELEMETRY_KEYS_BASE_DESCRIPTION, required = true) @RequestParam(name = "keys") String keys, + @Parameter(description = "A long value representing the start timestamp of the time range in milliseconds, UTC.") @RequestParam(name = "startTs") Long startTs, - @ApiParam(value = "A long value representing the end timestamp of the time range in milliseconds, UTC.") + @Parameter(description = "A long value representing the end timestamp of the time range in milliseconds, UTC.") @RequestParam(name = "endTs") Long endTs, - @ApiParam(value = "A long value representing the aggregation interval range in milliseconds.") + @Parameter(description = "A long value representing the aggregation interval range in milliseconds.") @RequestParam(name = "interval", defaultValue = "0") Long interval, - @ApiParam(value = "An integer value that represents a max number of timeseries data points to fetch." + - " This parameter is used only in the case if 'agg' parameter is set to 'NONE'.", defaultValue = "100") + @Parameter(description = "An integer value that represents a max number of timeseries data points to fetch." + + " This parameter is used only in the case if 'agg' parameter is set to 'NONE'.", schema = @Schema(defaultValue = "100")) @RequestParam(name = "limit", defaultValue = "100") Integer limit, - @ApiParam(value = "A string value representing the aggregation function. " + + @Parameter(description = "A string value representing the aggregation function. " + "If the interval is not specified, 'agg' parameter will use 'NONE' value.", - allowableValues = "MIN, MAX, AVG, SUM, COUNT, NONE") + schema = @Schema(allowableValues = "MIN, MAX, AVG, SUM, COUNT, NONE")) @RequestParam(name = "agg", defaultValue = "NONE") String aggStr, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(name = "orderBy", defaultValue = "DESC") String orderBy, - @ApiParam(value = STRICT_DATA_TYPES_DESCRIPTION) + @Parameter(description = STRICT_DATA_TYPES_DESCRIPTION) @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes) throws ThingsboardException { return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, (result, tenantId, entityId) -> { @@ -338,23 +337,23 @@ public class TelemetryController extends BaseController { notes = "Creates or updates the device attributes based on device id and specified attribute scope. " + SAVE_ATTRIBUTES_REQUEST_PAYLOAD + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @ApiResponses(value = { - @ApiResponse(code = 200, message = SAVE_ATTIRIBUTES_STATUS_OK + + @ApiResponse(responseCode = "200", description = SAVE_ATTIRIBUTES_STATUS_OK + "Platform creates an audit log event about device attributes updates with action type 'ATTRIBUTES_UPDATED', " + "and also sends event msg to the rule engine with msg type 'ATTRIBUTES_UPDATED'."), - @ApiResponse(code = 400, message = SAVE_ATTIRIBUTES_STATUS_BAD_REQUEST), - @ApiResponse(code = 401, message = "User is not authorized to save device attributes for selected device. Most likely, User belongs to different Customer or Tenant."), - @ApiResponse(code = 500, message = "The exception was thrown during processing the request. " + + @ApiResponse(responseCode = "400", description = SAVE_ATTIRIBUTES_STATUS_BAD_REQUEST), + @ApiResponse(responseCode = "401", description = "User is not authorized to save device attributes for selected device. Most likely, User belongs to different Customer or Tenant."), + @ApiResponse(responseCode = "500", description = "The exception was thrown during processing the request. " + "Platform creates an audit log event about device attributes updates with action type 'ATTRIBUTES_UPDATED' that includes an error stacktrace."), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{deviceId}/{scope}", method = RequestMethod.POST) @ResponseBody public DeferredResult saveDeviceAttributes( - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("deviceId") String deviceIdStr, - @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES, required = true) @PathVariable("scope") String scope, - @ApiParam(value = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true) @RequestBody JsonNode request) throws ThingsboardException { + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("deviceId") String deviceIdStr, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE"}, required = true)) @PathVariable("scope") String scope, + @Parameter(description = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true) @RequestBody JsonNode request) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE, deviceIdStr); return saveAttributes(getTenantId(), entityId, scope, request); } @@ -364,21 +363,21 @@ public class TelemetryController extends BaseController { ENTITY_SAVE_ATTRIBUTE_SCOPES + SAVE_ATTRIBUTES_REQUEST_PAYLOAD + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @ApiResponses(value = { - @ApiResponse(code = 200, message = SAVE_ATTIRIBUTES_STATUS_OK + SAVE_ENTITY_ATTRIBUTES_STATUS_OK), - @ApiResponse(code = 400, message = SAVE_ATTIRIBUTES_STATUS_BAD_REQUEST), - @ApiResponse(code = 401, message = SAVE_ENTITY_ATTRIBUTES_STATUS_UNAUTHORIZED), - @ApiResponse(code = 500, message = SAVE_ENTITY_ATTRIBUTES_STATUS_INTERNAL_SERVER_ERROR), + @ApiResponse(responseCode = "200", description = SAVE_ATTIRIBUTES_STATUS_OK + SAVE_ENTITY_ATTRIBUTES_STATUS_OK), + @ApiResponse(responseCode = "400", description = SAVE_ATTIRIBUTES_STATUS_BAD_REQUEST), + @ApiResponse(responseCode = "401", description = SAVE_ENTITY_ATTRIBUTES_STATUS_UNAUTHORIZED), + @ApiResponse(responseCode = "500", description = SAVE_ENTITY_ATTRIBUTES_STATUS_INTERNAL_SERVER_ERROR), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/{scope}", method = RequestMethod.POST) @ResponseBody public DeferredResult saveEntityAttributesV1( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES) @PathVariable("scope") String scope, - @ApiParam(value = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true) @RequestBody JsonNode request) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE"})) @PathVariable("scope")String scope, + @Parameter(description = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true)@RequestBody JsonNode request) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return saveAttributes(getTenantId(), entityId, scope, request); } @@ -388,21 +387,21 @@ public class TelemetryController extends BaseController { ENTITY_SAVE_ATTRIBUTE_SCOPES + SAVE_ATTRIBUTES_REQUEST_PAYLOAD + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @ApiResponses(value = { - @ApiResponse(code = 200, message = SAVE_ATTIRIBUTES_STATUS_OK + SAVE_ENTITY_ATTRIBUTES_STATUS_OK), - @ApiResponse(code = 400, message = SAVE_ATTIRIBUTES_STATUS_BAD_REQUEST), - @ApiResponse(code = 401, message = SAVE_ENTITY_ATTRIBUTES_STATUS_UNAUTHORIZED), - @ApiResponse(code = 500, message = SAVE_ENTITY_ATTRIBUTES_STATUS_INTERNAL_SERVER_ERROR), + @ApiResponse(responseCode = "200", description = SAVE_ATTIRIBUTES_STATUS_OK + SAVE_ENTITY_ATTRIBUTES_STATUS_OK), + @ApiResponse(responseCode = "400", description = SAVE_ATTIRIBUTES_STATUS_BAD_REQUEST), + @ApiResponse(responseCode = "401", description = SAVE_ENTITY_ATTRIBUTES_STATUS_UNAUTHORIZED), + @ApiResponse(responseCode = "500", description = SAVE_ENTITY_ATTRIBUTES_STATUS_INTERNAL_SERVER_ERROR), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/attributes/{scope}", method = RequestMethod.POST) @ResponseBody public DeferredResult saveEntityAttributesV2( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES, required = true) @PathVariable("scope") String scope, - @ApiParam(value = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true) @RequestBody JsonNode request) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE"}, required = true)) @PathVariable("scope")String scope, + @Parameter(description = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true)@RequestBody JsonNode request) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return saveAttributes(getTenantId(), entityId, scope, request); } @@ -413,21 +412,21 @@ public class TelemetryController extends BaseController { SAVE_TIMESERIES_REQUEST_PAYLOAD + "\n\n The scope parameter is not used in the API call implementation but should be specified whatever value because it is used as a path variable. " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @ApiResponses(value = { - @ApiResponse(code = 200, message = SAVE_ENTITY_TIMESERIES_STATUS_OK), - @ApiResponse(code = 400, message = INVALID_STRUCTURE_OF_THE_REQUEST), - @ApiResponse(code = 401, message = SAVE_ENTITY_TIMESERIES_STATUS_UNAUTHORIZED), - @ApiResponse(code = 500, message = SAVE_ENTITY_TIMESERIES_STATUS_INTERNAL_SERVER_ERROR), + @ApiResponse(responseCode = "200", description = SAVE_ENTITY_TIMESERIES_STATUS_OK), + @ApiResponse(responseCode = "400", description = INVALID_STRUCTURE_OF_THE_REQUEST), + @ApiResponse(responseCode = "401", description = SAVE_ENTITY_TIMESERIES_STATUS_UNAUTHORIZED), + @ApiResponse(responseCode = "500", description = SAVE_ENTITY_TIMESERIES_STATUS_INTERNAL_SERVER_ERROR), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/timeseries/{scope}", method = RequestMethod.POST) @ResponseBody public DeferredResult saveEntityTelemetry( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = TELEMETRY_SCOPE_DESCRIPTION, required = true, allowableValues = "ANY") @PathVariable("scope") String scope, - @ApiParam(value = TELEMETRY_JSON_REQUEST_DESCRIPTION, required = true) @RequestBody String requestBody) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = TELEMETRY_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = "ANY")) @PathVariable("scope")String scope, + @Parameter(description = TELEMETRY_JSON_REQUEST_DESCRIPTION, required = true)@RequestBody String requestBody) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return saveTelemetry(getTenantId(), entityId, requestBody, 0L); } @@ -438,22 +437,22 @@ public class TelemetryController extends BaseController { "\n\n The scope parameter is not used in the API call implementation but should be specified whatever value because it is used as a path variable. " + "\n\nThe ttl parameter takes affect only in case of Cassandra DB." + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @ApiResponses(value = { - @ApiResponse(code = 200, message = SAVE_ENTITY_TIMESERIES_STATUS_OK), - @ApiResponse(code = 400, message = INVALID_STRUCTURE_OF_THE_REQUEST), - @ApiResponse(code = 401, message = SAVE_ENTITY_TIMESERIES_STATUS_UNAUTHORIZED), - @ApiResponse(code = 500, message = SAVE_ENTITY_TIMESERIES_STATUS_INTERNAL_SERVER_ERROR), + @ApiResponse(responseCode = "200", description = SAVE_ENTITY_TIMESERIES_STATUS_OK), + @ApiResponse(responseCode = "400", description = INVALID_STRUCTURE_OF_THE_REQUEST), + @ApiResponse(responseCode = "401", description = SAVE_ENTITY_TIMESERIES_STATUS_UNAUTHORIZED), + @ApiResponse(responseCode = "500", description = SAVE_ENTITY_TIMESERIES_STATUS_INTERNAL_SERVER_ERROR), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/timeseries/{scope}/{ttl}", method = RequestMethod.POST) @ResponseBody public DeferredResult saveEntityTelemetryWithTTL( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = TELEMETRY_SCOPE_DESCRIPTION, required = true, allowableValues = "ANY") @PathVariable("scope") String scope, - @ApiParam(value = "A long value representing TTL (Time to Live) parameter.", required = true) @PathVariable("ttl") Long ttl, - @ApiParam(value = TELEMETRY_JSON_REQUEST_DESCRIPTION, required = true) @RequestBody String requestBody) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = TELEMETRY_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = "ANY")) @PathVariable("scope")String scope, + @Parameter(description = "A long value representing TTL (Time to Live) parameter.", required = true)@PathVariable("ttl")Long ttl, + @Parameter(description = TELEMETRY_JSON_REQUEST_DESCRIPTION, required = true)@RequestBody String requestBody) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return saveTelemetry(getTenantId(), entityId, requestBody, ttl); } @@ -464,29 +463,29 @@ public class TelemetryController extends BaseController { " Use 'startTs' and 'endTs' to specify time-range instead. " + " Use 'rewriteLatestIfDeleted' to rewrite latest value (stored in separate table for performance) after deletion of the time range. " + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @ApiResponses(value = { - @ApiResponse(code = 200, message = "Timeseries for the selected keys in the request was removed. " + + @ApiResponse(responseCode = "200", description = "Timeseries for the selected keys in the request was removed. " + "Platform creates an audit log event about entity timeseries removal with action type 'TIMESERIES_DELETED'."), - @ApiResponse(code = 400, message = "Platform returns a bad request in case if keys list is empty or start and end timestamp values is empty when deleteAllDataForKeys is set to false."), - @ApiResponse(code = 401, message = "User is not authorized to delete entity timeseries for selected entity. Most likely, User belongs to different Customer or Tenant."), - @ApiResponse(code = 500, message = "The exception was thrown during processing the request. " + + @ApiResponse(responseCode = "400", description = "Platform returns a bad request in case if keys list is empty or start and end timestamp values is empty when deleteAllDataForKeys is set to false."), + @ApiResponse(responseCode = "401", description = "User is not authorized to delete entity timeseries for selected entity. Most likely, User belongs to different Customer or Tenant."), + @ApiResponse(responseCode = "500", description = "The exception was thrown during processing the request. " + "Platform creates an audit log event about entity timeseries removal with action type 'TIMESERIES_DELETED' that includes an error stacktrace."), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/timeseries/delete", method = RequestMethod.DELETE) @ResponseBody public DeferredResult deleteEntityTimeseries( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = TELEMETRY_KEYS_DESCRIPTION, required = true) @RequestParam(name = "keys") String keysStr, - @ApiParam(value = "A boolean value to specify if should be deleted all data for selected keys or only data that are in the selected time range.") + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = TELEMETRY_KEYS_DESCRIPTION, required = true) @RequestParam(name = "keys") String keysStr, + @Parameter(description = "A boolean value to specify if should be deleted all data for selected keys or only data that are in the selected time range.") @RequestParam(name = "deleteAllDataForKeys", defaultValue = "false") boolean deleteAllDataForKeys, - @ApiParam(value = "A long value representing the start timestamp of removal time range in milliseconds.") + @Parameter(description = "A long value representing the start timestamp of removal time range in milliseconds.") @RequestParam(name = "startTs", required = false) Long startTs, - @ApiParam(value = "A long value representing the end timestamp of removal time range in milliseconds.") + @Parameter(description = "A long value representing the end timestamp of removal time range in milliseconds.") @RequestParam(name = "endTs", required = false) Long endTs, - @ApiParam(value = "If the parameter is set to true, the latest telemetry will be rewritten in case that current latest value was removed, otherwise, in case that parameter is set to false the new latest value will not set.") + @Parameter(description = "If the parameter is set to true, the latest telemetry will be rewritten in case that current latest value was removed, otherwise, in case that parameter is set to false the new latest value will not set.") @RequestParam(name = "rewriteLatestIfDeleted", defaultValue = "false") boolean rewriteLatestIfDeleted) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return deleteTimeseries(entityId, keysStr, deleteAllDataForKeys, startTs, endTs, rewriteLatestIfDeleted); @@ -538,22 +537,22 @@ public class TelemetryController extends BaseController { @ApiOperation(value = "Delete device attributes (deleteDeviceAttributes)", notes = "Delete device attributes using provided Device Id, scope and a list of keys. " + "Referencing a non-existing Device Id will cause an error" + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @ApiResponses(value = { - @ApiResponse(code = 200, message = "Device attributes was removed for the selected keys in the request. " + + @ApiResponse(responseCode = "200", description = "Device attributes was removed for the selected keys in the request. " + "Platform creates an audit log event about device attributes removal with action type 'ATTRIBUTES_DELETED'."), - @ApiResponse(code = 400, message = "Platform returns a bad request in case if keys or scope are not specified."), - @ApiResponse(code = 401, message = "User is not authorized to delete device attributes for selected entity. Most likely, User belongs to different Customer or Tenant."), - @ApiResponse(code = 500, message = "The exception was thrown during processing the request. " + + @ApiResponse(responseCode = "400", description = "Platform returns a bad request in case if keys or scope are not specified."), + @ApiResponse(responseCode = "401", description = "User is not authorized to delete device attributes for selected entity. Most likely, User belongs to different Customer or Tenant."), + @ApiResponse(responseCode = "500", description = "The exception was thrown during processing the request. " + "Platform creates an audit log event about device attributes removal with action type 'ATTRIBUTES_DELETED' that includes an error stacktrace."), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{deviceId}/{scope}", method = RequestMethod.DELETE) @ResponseBody public DeferredResult deleteDeviceAttributes( - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(DEVICE_ID) String deviceIdStr, - @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES, required = true) @PathVariable("scope") String scope, - @ApiParam(value = ATTRIBUTES_KEYS_DESCRIPTION, required = true) @RequestParam(name = "keys") String keysStr) throws ThingsboardException { + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(DEVICE_ID) String deviceIdStr, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE", "CLIENT_SCOPE"}, required = true)) @PathVariable("scope")String scope, + @Parameter(description = ATTRIBUTES_KEYS_DESCRIPTION, required = true)@RequestParam(name = "keys")String keysStr) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE, deviceIdStr); return deleteAttributes(entityId, scope, keysStr); } @@ -561,23 +560,23 @@ public class TelemetryController extends BaseController { @ApiOperation(value = "Delete entity attributes (deleteEntityAttributes)", notes = "Delete entity attributes using provided Entity Id, scope and a list of keys. " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @ApiResponses(value = { - @ApiResponse(code = 200, message = "Entity attributes was removed for the selected keys in the request. " + + @ApiResponse(responseCode = "200", description = "Entity attributes was removed for the selected keys in the request. " + "Platform creates an audit log event about entity attributes removal with action type 'ATTRIBUTES_DELETED'."), - @ApiResponse(code = 400, message = "Platform returns a bad request in case if keys or scope are not specified."), - @ApiResponse(code = 401, message = "User is not authorized to delete entity attributes for selected entity. Most likely, User belongs to different Customer or Tenant."), - @ApiResponse(code = 500, message = "The exception was thrown during processing the request. " + + @ApiResponse(responseCode = "400", description = "Platform returns a bad request in case if keys or scope are not specified."), + @ApiResponse(responseCode = "401", description = "User is not authorized to delete entity attributes for selected entity. Most likely, User belongs to different Customer or Tenant."), + @ApiResponse(responseCode = "500", description = "The exception was thrown during processing the request. " + "Platform creates an audit log event about entity attributes removal with action type 'ATTRIBUTES_DELETED' that includes an error stacktrace."), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/{scope}", method = RequestMethod.DELETE) @ResponseBody public DeferredResult deleteEntityAttributes( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, required = true, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES) @PathVariable("scope") String scope, - @ApiParam(value = ATTRIBUTES_KEYS_DESCRIPTION, required = true) @RequestParam(name = "keys") String keysStr) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE", "CLIENT_SCOPE"})) @PathVariable("scope")String scope, + @Parameter(description = ATTRIBUTES_KEYS_DESCRIPTION, required = true)@RequestParam(name = "keys")String keysStr) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return deleteAttributes(entityId, scope, keysStr); } diff --git a/application/src/main/java/org/thingsboard/server/controller/TenantController.java b/application/src/main/java/org/thingsboard/server/controller/TenantController.java index 6574969e15..6fb58207bf 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TenantController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TenantController.java @@ -16,8 +16,8 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.node.ObjectNode; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -36,6 +36,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.tenant.TbTenantService; @@ -46,15 +47,12 @@ import static org.thingsboard.server.controller.ControllerConstants.HOME_DASHBOA import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH; import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID; import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.TENANT_INFO_SORT_PROPERTY_ALLOWABLE_VALUES; -import static org.thingsboard.server.controller.ControllerConstants.TENANT_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.TENANT_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK; @@ -76,7 +74,7 @@ public class TenantController extends BaseController { @RequestMapping(value = "/tenant/{tenantId}", method = RequestMethod.GET) @ResponseBody public Tenant getTenantById( - @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION) + @Parameter(description = TENANT_ID_PARAM_DESCRIPTION) @PathVariable(TENANT_ID) String strTenantId) throws ThingsboardException { checkParameter(TENANT_ID, strTenantId); TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId)); @@ -94,7 +92,7 @@ public class TenantController extends BaseController { @RequestMapping(value = "/tenant/info/{tenantId}", method = RequestMethod.GET) @ResponseBody public TenantInfo getTenantInfoById( - @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION) + @Parameter(description = TENANT_ID_PARAM_DESCRIPTION) @PathVariable(TENANT_ID) String strTenantId) throws ThingsboardException { checkParameter(TENANT_ID, strTenantId); TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId)); @@ -112,7 +110,7 @@ public class TenantController extends BaseController { @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/tenant", method = RequestMethod.POST) @ResponseBody - public Tenant saveTenant(@ApiParam(value = "A JSON value representing the tenant.") + public Tenant saveTenant(@Parameter(description = "A JSON value representing the tenant.") @RequestBody Tenant tenant) throws Exception { checkEntity(tenant.getId(), tenant, Resource.TENANT); return tbTenantService.save(tenant); @@ -123,7 +121,7 @@ public class TenantController extends BaseController { @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/tenant/{tenantId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteTenant(@ApiParam(value = TENANT_ID_PARAM_DESCRIPTION) + public void deleteTenant(@Parameter(description = TENANT_ID_PARAM_DESCRIPTION) @PathVariable(TENANT_ID) String strTenantId) throws Exception { checkParameter(TENANT_ID, strTenantId); TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId)); @@ -136,15 +134,15 @@ public class TenantController extends BaseController { @RequestMapping(value = "/tenants", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenants( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = TENANT_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = TENANT_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = TENANT_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "title", "email", "country", "state", "city", "address", "address2", "zip", "phone", "email"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return checkNotNull(tenantService.findTenants(pageLink)); @@ -156,15 +154,15 @@ public class TenantController extends BaseController { @RequestMapping(value = "/tenantInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantInfos( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = TENANT_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = TENANT_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = TENANT_INFO_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "tenantProfileName", "title", "email", "country", "state", "city", "address", "address2", "zip", "phone", "email"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder ) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); diff --git a/application/src/main/java/org/thingsboard/server/controller/TenantProfileController.java b/application/src/main/java/org/thingsboard/server/controller/TenantProfileController.java index a7fe973ec0..8f667ec184 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TenantProfileController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TenantProfileController.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.tenant.profile.TbTenantProfileService; import org.thingsboard.server.service.security.permission.Operation; @@ -50,13 +51,10 @@ import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_COD import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; import static org.thingsboard.server.controller.ControllerConstants.TENANT_PROFILE_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.TENANT_PROFILE_INFO_SORT_PROPERTY_ALLOWABLE_VALUES; -import static org.thingsboard.server.controller.ControllerConstants.TENANT_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.TENANT_PROFILE_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK; @@ -77,7 +75,7 @@ public class TenantProfileController extends BaseController { @RequestMapping(value = "/tenantProfile/{tenantProfileId}", method = RequestMethod.GET) @ResponseBody public TenantProfile getTenantProfileById( - @ApiParam(value = TENANT_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = TENANT_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable("tenantProfileId") String strTenantProfileId) throws ThingsboardException { checkParameter("tenantProfileId", strTenantProfileId); TenantProfileId tenantProfileId = new TenantProfileId(toUUID(strTenantProfileId)); @@ -90,7 +88,7 @@ public class TenantProfileController extends BaseController { @RequestMapping(value = "/tenantProfileInfo/{tenantProfileId}", method = RequestMethod.GET) @ResponseBody public EntityInfo getTenantProfileInfoById( - @ApiParam(value = TENANT_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = TENANT_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable("tenantProfileId") String strTenantProfileId) throws ThingsboardException { checkParameter("tenantProfileId", strTenantProfileId); TenantProfileId tenantProfileId = new TenantProfileId(toUUID(strTenantProfileId)); @@ -162,7 +160,7 @@ public class TenantProfileController extends BaseController { @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/tenantProfile", method = RequestMethod.POST) @ResponseBody - public TenantProfile saveTenantProfile(@ApiParam(value = "A JSON value representing the tenant profile.") + public TenantProfile saveTenantProfile(@Parameter(description = "A JSON value representing the tenant profile.") @RequestBody TenantProfile tenantProfile) throws ThingsboardException { TenantProfile oldProfile; if (tenantProfile.getId() == null) { @@ -180,7 +178,7 @@ public class TenantProfileController extends BaseController { @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/tenantProfile/{tenantProfileId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteTenantProfile(@ApiParam(value = TENANT_PROFILE_ID_PARAM_DESCRIPTION) + public void deleteTenantProfile(@Parameter(description = TENANT_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable("tenantProfileId") String strTenantProfileId) throws ThingsboardException { checkParameter("tenantProfileId", strTenantProfileId); TenantProfileId tenantProfileId = new TenantProfileId(toUUID(strTenantProfileId)); @@ -194,7 +192,7 @@ public class TenantProfileController extends BaseController { @RequestMapping(value = "/tenantProfile/{tenantProfileId}/default", method = RequestMethod.POST) @ResponseBody public TenantProfile setDefaultTenantProfile( - @ApiParam(value = TENANT_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = TENANT_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable("tenantProfileId") String strTenantProfileId) throws ThingsboardException { checkParameter("tenantProfileId", strTenantProfileId); TenantProfileId tenantProfileId = new TenantProfileId(toUUID(strTenantProfileId)); @@ -208,15 +206,15 @@ public class TenantProfileController extends BaseController { @RequestMapping(value = "/tenantProfiles", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantProfiles( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = TENANT_PROFILE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = TENANT_PROFILE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = TENANT_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "description", "isDefault"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return checkNotNull(tenantProfileService.findTenantProfiles(getTenantId(), pageLink)); @@ -228,15 +226,15 @@ public class TenantProfileController extends BaseController { @RequestMapping(value = "/tenantProfileInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantProfileInfos( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = TENANT_PROFILE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = TENANT_PROFILE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = TENANT_PROFILE_INFO_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"id", "name"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return checkNotNull(tenantProfileService.findTenantProfileInfos(getTenantId(), pageLink)); diff --git a/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthConfigController.java b/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthConfigController.java index a809f5280c..f674ed0ca8 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthConfigController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthConfigController.java @@ -15,8 +15,9 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; import lombok.Data; import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; @@ -34,12 +35,12 @@ import org.thingsboard.server.common.data.security.model.mfa.account.AccountTwoF import org.thingsboard.server.common.data.security.model.mfa.account.TwoFaAccountConfig; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderConfig; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderType; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.auth.mfa.TwoFactorAuthService; import org.thingsboard.server.service.security.auth.mfa.config.TwoFaConfigManager; import org.thingsboard.server.service.security.model.SecurityUser; -import jakarta.validation.Valid; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -99,7 +100,7 @@ public class TwoFactorAuthConfigController extends BaseController { ControllerConstants.AVAILABLE_FOR_ANY_AUTHORIZED_USER) @PostMapping("/account/config/generate") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - public TwoFaAccountConfig generateTwoFaAccountConfig(@ApiParam(value = "2FA provider type to generate new account config for", defaultValue = "TOTP", required = true) + public TwoFaAccountConfig generateTwoFaAccountConfig(@Parameter(description = "2FA provider type to generate new account config for", schema = @Schema(defaultValue = "TOTP", required = true)) @RequestParam TwoFaProviderType providerType) throws Exception { SecurityUser user = getCurrentUser(); return twoFactorAuthService.generateNewAccountConfig(user, providerType); @@ -258,7 +259,7 @@ public class TwoFactorAuthConfigController extends BaseController { ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @PostMapping("/settings") @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") - public PlatformTwoFaSettings savePlatformTwoFaSettings(@ApiParam(value = "Settings value", required = true) + public PlatformTwoFaSettings savePlatformTwoFaSettings(@Parameter(description = "Settings value", required = true) @RequestBody PlatformTwoFaSettings twoFaSettings) throws ThingsboardException { return twoFaConfigManager.savePlatformTwoFaSettings(getTenantId(), twoFaSettings); } diff --git a/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthController.java b/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthController.java index ee1db6868a..1478e21c76 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthController.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; +import jakarta.servlet.http.HttpServletRequest; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.security.model.mfa.PlatformTwoFaSettin import org.thingsboard.server.common.data.security.model.mfa.account.EmailTwoFaAccountConfig; import org.thingsboard.server.common.data.security.model.mfa.account.SmsTwoFaAccountConfig; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderType; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.auth.mfa.TwoFactorAuthService; @@ -44,7 +45,6 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.token.JwtTokenFactory; import org.thingsboard.server.service.security.system.SystemSecurityService; -import jakarta.servlet.http.HttpServletRequest; import java.util.Collections; import java.util.List; import java.util.Optional; diff --git a/application/src/main/java/org/thingsboard/server/controller/UiSettingsController.java b/application/src/main/java/org/thingsboard/server/controller/UiSettingsController.java index a40d3b85af..11bd0e8364 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UiSettingsController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UiSettingsController.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.RequestMapping; @@ -23,6 +22,7 @@ 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.exception.ThingsboardException; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; @RestController diff --git a/application/src/main/java/org/thingsboard/server/controller/UserController.java b/application/src/main/java/org/thingsboard/server/controller/UserController.java index 5bf6a86307..b05d5feb83 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UserController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UserController.java @@ -17,8 +17,9 @@ package org.thingsboard.server.controller; 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.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -64,6 +65,7 @@ import org.thingsboard.server.common.data.settings.UserDashboardAction; import org.thingsboard.server.common.data.settings.UserDashboardsInfo; import org.thingsboard.server.common.data.settings.UserSettings; import org.thingsboard.server.common.data.settings.UserSettingsType; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.user.TbUserService; @@ -75,7 +77,6 @@ import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; import org.thingsboard.server.service.security.system.SystemSecurityService; -import jakarta.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -92,7 +93,6 @@ import static org.thingsboard.server.controller.ControllerConstants.HOME_DASHBOA import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; @@ -102,7 +102,6 @@ import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID; import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH; import static org.thingsboard.server.controller.ControllerConstants.USER_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.USER_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.USER_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK; @@ -141,7 +140,7 @@ public class UserController extends BaseController { @RequestMapping(value = "/user/{userId}", method = RequestMethod.GET) @ResponseBody public User getUserById( - @ApiParam(value = USER_ID_PARAM_DESCRIPTION) + @Parameter(description = USER_ID_PARAM_DESCRIPTION) @PathVariable(USER_ID) String strUserId) throws ThingsboardException { checkParameter(USER_ID, strUserId); UserId userId = new UserId(toUUID(strUserId)); @@ -177,7 +176,7 @@ public class UserController extends BaseController { @RequestMapping(value = "/user/{userId}/token", method = RequestMethod.GET) @ResponseBody public JwtPair getUserToken( - @ApiParam(value = USER_ID_PARAM_DESCRIPTION) + @Parameter(description = USER_ID_PARAM_DESCRIPTION) @PathVariable(USER_ID) String strUserId) throws ThingsboardException { checkParameter(USER_ID, strUserId); if (!userTokenAccessEnabled) { @@ -205,9 +204,9 @@ public class UserController extends BaseController { @RequestMapping(value = "/user", method = RequestMethod.POST) @ResponseBody public User saveUser( - @ApiParam(value = "A JSON value representing the User.", required = true) + @Parameter(description = "A JSON value representing the User.", required = true) @RequestBody User user, - @ApiParam(value = "Send activation email (or use activation link)", defaultValue = "true") + @Parameter(description = "Send activation email (or use activation link)" , schema = @Schema(defaultValue = "true")) @RequestParam(required = false, defaultValue = "true") boolean sendActivationMail, HttpServletRequest request) throws ThingsboardException { if (!Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { user.setTenantId(getCurrentUser().getTenantId()); @@ -222,7 +221,7 @@ public class UserController extends BaseController { @RequestMapping(value = "/user/sendActivationMail", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) public void sendActivationEmail( - @ApiParam(value = "Email of the user", required = true) + @Parameter(description = "Email of the user", required = true) @RequestParam(value = "email") String email, HttpServletRequest request) throws ThingsboardException { User user = checkNotNull(userService.findUserByEmail(getCurrentUser().getTenantId(), email)); @@ -248,7 +247,7 @@ public class UserController extends BaseController { @RequestMapping(value = "/user/{userId}/activationLink", method = RequestMethod.GET, produces = "text/plain") @ResponseBody public String getActivationLink( - @ApiParam(value = USER_ID_PARAM_DESCRIPTION) + @Parameter(description = USER_ID_PARAM_DESCRIPTION) @PathVariable(USER_ID) String strUserId, HttpServletRequest request) throws ThingsboardException { checkParameter(USER_ID, strUserId); @@ -273,7 +272,7 @@ public class UserController extends BaseController { @RequestMapping(value = "/user/{userId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) public void deleteUser( - @ApiParam(value = USER_ID_PARAM_DESCRIPTION) + @Parameter(description = USER_ID_PARAM_DESCRIPTION) @PathVariable(USER_ID) String strUserId) throws ThingsboardException { checkParameter(USER_ID, strUserId); UserId userId = new UserId(toUUID(strUserId)); @@ -291,15 +290,15 @@ public class UserController extends BaseController { @RequestMapping(value = "/users", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getUsers( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = USER_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = USER_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = USER_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "firstName", "lastName", "email"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); SecurityUser currentUser = getCurrentUser(); @@ -317,15 +316,15 @@ public class UserController extends BaseController { @RequestMapping(value = "/users/info", method = RequestMethod.GET) @ResponseBody public PageData findUsersByQuery( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = USER_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = USER_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = USER_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "firstName", "lastName", "email"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { SecurityUser securityUser = getCurrentUser(); @@ -354,17 +353,17 @@ public class UserController extends BaseController { @RequestMapping(value = "/tenant/{tenantId}/users", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantAdmins( - @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = TENANT_ID_PARAM_DESCRIPTION, required = true) @PathVariable(TENANT_ID) String strTenantId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = USER_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = USER_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = USER_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "firstName", "lastName", "email"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("tenantId", strTenantId); TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId)); @@ -378,17 +377,17 @@ public class UserController extends BaseController { @RequestMapping(value = "/customer/{customerId}/users", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerUsers( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) @PathVariable(CUSTOMER_ID) String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = USER_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = USER_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = USER_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "firstName", "lastName", "email"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("customerId", strCustomerId); CustomerId customerId = new CustomerId(toUUID(strCustomerId)); @@ -404,9 +403,9 @@ public class UserController extends BaseController { @RequestMapping(value = "/user/{userId}/userCredentialsEnabled", method = RequestMethod.POST) @ResponseBody public void setUserCredentialsEnabled( - @ApiParam(value = USER_ID_PARAM_DESCRIPTION) + @Parameter(description = USER_ID_PARAM_DESCRIPTION) @PathVariable(USER_ID) String strUserId, - @ApiParam(value = "Enable (\"true\") or disable (\"false\") the credentials.", defaultValue = "true") + @Parameter(description = "Enable (\"true\") or disable (\"false\") the credentials." , schema = @Schema(defaultValue = "true")) @RequestParam(required = false, defaultValue = "true") boolean userCredentialsEnabled) throws ThingsboardException { checkParameter(USER_ID, strUserId); UserId userId = new UserId(toUUID(strUserId)); @@ -427,17 +426,17 @@ public class UserController extends BaseController { @RequestMapping(value = "/users/assign/{alarmId}", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getUsersForAssign( - @ApiParam(value = ALARM_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ALARM_ID_PARAM_DESCRIPTION, required = true) @PathVariable("alarmId") String strAlarmId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = USER_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = USER_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = USER_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "firstName", "lastName", "email"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { try { checkParameter("alarmId", strAlarmId); @@ -508,7 +507,7 @@ public class UserController extends BaseController { "Example: to delete B and C element in { \"A\": {\"B\": 5}, \"C\": 15} send A.B,C in jsonPaths request parameter") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/user/settings/{paths}", method = RequestMethod.DELETE) - public void deleteUserSettings(@ApiParam(value = PATHS) + public void deleteUserSettings(@Parameter(description = PATHS) @PathVariable(PATHS) String paths) throws ThingsboardException { checkParameter(USER_ID, paths); @@ -522,7 +521,7 @@ public class UserController extends BaseController { "{A:5, B:{C:10, D:30}}. The same could be achieved by putting {B.D:30}") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @PutMapping(value = "/user/settings/{type}") - public void putUserSettings(@ApiParam(value = "Settings type, case insensitive, one of: \"general\", \"quick_links\", \"doc_links\" or \"dashboards\".") + public void putUserSettings(@Parameter(description = "Settings type, case insensitive, one of: \"general\", \"quick_links\", \"doc_links\" or \"dashboards\".") @PathVariable("type") String strType, @RequestBody JsonNode settings) throws ThingsboardException { SecurityUser currentUser = getCurrentUser(); UserSettingsType type = checkEnumParameter("Settings type", strType, UserSettingsType::valueOf); @@ -534,7 +533,7 @@ public class UserController extends BaseController { notes = "Fetch the User settings based on authorized user. ") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @GetMapping(value = "/user/settings/{type}") - public JsonNode getUserSettings(@ApiParam(value = "Settings type, case insensitive, one of: \"general\", \"quick_links\", \"doc_links\" or \"dashboards\".") + public JsonNode getUserSettings(@Parameter(description = "Settings type, case insensitive, one of: \"general\", \"quick_links\", \"doc_links\" or \"dashboards\".") @PathVariable("type") String strType) throws ThingsboardException { SecurityUser currentUser = getCurrentUser(); UserSettingsType type = checkEnumParameter("Settings type", strType, UserSettingsType::valueOf); @@ -548,9 +547,9 @@ public class UserController extends BaseController { "Example: to delete B and C element in { \"A\": {\"B\": 5}, \"C\": 15} send A.B,C in jsonPaths request parameter") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/user/settings/{type}/{paths}", method = RequestMethod.DELETE) - public void deleteUserSettings(@ApiParam(value = PATHS) + public void deleteUserSettings(@Parameter(description = PATHS) @PathVariable(PATHS) String paths, - @ApiParam(value = "Settings type, case insensitive, one of: \"general\", \"quick_links\", \"doc_links\" or \"dashboards\".") + @Parameter(description = "Settings type, case insensitive, one of: \"general\", \"quick_links\", \"doc_links\" or \"dashboards\".") @PathVariable("type") String strType) throws ThingsboardException { checkParameter(USER_ID, paths); UserSettingsType type = checkEnumParameter("Settings type", strType, UserSettingsType::valueOf); @@ -574,9 +573,9 @@ public class UserController extends BaseController { @RequestMapping(value = "/user/dashboards/{dashboardId}/{action}", method = RequestMethod.GET) @ResponseBody public UserDashboardsInfo reportUserDashboardAction( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DashboardController.DASHBOARD_ID) String strDashboardId, - @ApiParam(value = "Dashboard action, one of: \"visit\", \"star\" or \"unstar\".") + @Parameter(description = "Dashboard action, one of: \"visit\", \"star\" or \"unstar\".") @PathVariable("action") String strAction) throws ThingsboardException { checkParameter(DashboardController.DASHBOARD_ID, strDashboardId); checkParameter("action", strAction); diff --git a/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java b/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java index d1ecd0441a..9f71890e70 100644 --- a/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; @@ -37,6 +36,7 @@ import org.thingsboard.server.common.data.widget.WidgetType; import org.thingsboard.server.common.data.widget.WidgetTypeDetails; import org.thingsboard.server.common.data.widget.WidgetTypeInfo; import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.permission.Operation; @@ -67,7 +67,7 @@ public class WidgetTypeController extends AutoCommitController { @RequestMapping(value = "/widgetType/{widgetTypeId}", method = RequestMethod.GET) @ResponseBody public WidgetTypeDetails getWidgetTypeById( - @ApiParam(value = WIDGET_TYPE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = WIDGET_TYPE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("widgetTypeId") String strWidgetTypeId) throws ThingsboardException { checkParameter("widgetTypeId", strWidgetTypeId); WidgetTypeId widgetTypeId = new WidgetTypeId(toUUID(strWidgetTypeId)); @@ -88,7 +88,7 @@ public class WidgetTypeController extends AutoCommitController { @RequestMapping(value = "/widgetType", method = RequestMethod.POST) @ResponseBody public WidgetTypeDetails saveWidgetType( - @ApiParam(value = "A JSON value representing the Widget Type Details.", required = true) + @Parameter(description = "A JSON value representing the Widget Type Details.", required = true) @RequestBody WidgetTypeDetails widgetTypeDetails) throws Exception { var currentUser = getCurrentUser(); if (Authority.SYS_ADMIN.equals(currentUser.getAuthority())) { @@ -119,7 +119,7 @@ public class WidgetTypeController extends AutoCommitController { @RequestMapping(value = "/widgetType/{widgetTypeId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) public void deleteWidgetType( - @ApiParam(value = WIDGET_TYPE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = WIDGET_TYPE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("widgetTypeId") String strWidgetTypeId) throws Exception { checkParameter("widgetTypeId", strWidgetTypeId); var currentUser = getCurrentUser(); @@ -143,9 +143,9 @@ public class WidgetTypeController extends AutoCommitController { @RequestMapping(value = "/widgetTypes", params = {"isSystem", "bundleAlias"}, method = RequestMethod.GET) @ResponseBody public List getBundleWidgetTypes( - @ApiParam(value = "System or Tenant", required = true) + @Parameter(description = "System or Tenant", required = true) @RequestParam boolean isSystem, - @ApiParam(value = "Widget Bundle alias", required = true) + @Parameter(description = "Widget Bundle alias", required = true) @RequestParam String bundleAlias) throws ThingsboardException { TenantId tenantId; if (isSystem) { @@ -162,9 +162,9 @@ public class WidgetTypeController extends AutoCommitController { @RequestMapping(value = "/widgetTypesDetails", params = {"isSystem", "bundleAlias"}, method = RequestMethod.GET) @ResponseBody public List getBundleWidgetTypesDetails( - @ApiParam(value = "System or Tenant", required = true) + @Parameter(description = "System or Tenant", required = true) @RequestParam boolean isSystem, - @ApiParam(value = "Widget Bundle alias", required = true) + @Parameter(description = "Widget Bundle alias", required = true) @RequestParam String bundleAlias) throws ThingsboardException { TenantId tenantId; if (isSystem) { @@ -181,9 +181,9 @@ public class WidgetTypeController extends AutoCommitController { @RequestMapping(value = "/widgetTypesInfos", params = {"isSystem", "bundleAlias"}, method = RequestMethod.GET) @ResponseBody public List getBundleWidgetTypesInfos( - @ApiParam(value = "System or Tenant", required = true) + @Parameter(description = "System or Tenant", required = true) @RequestParam boolean isSystem, - @ApiParam(value = "Widget Bundle alias", required = true) + @Parameter(description = "Widget Bundle alias", required = true) @RequestParam String bundleAlias) throws ThingsboardException { TenantId tenantId; if (isSystem) { @@ -200,11 +200,11 @@ public class WidgetTypeController extends AutoCommitController { @RequestMapping(value = "/widgetType", params = {"isSystem", "bundleAlias", "alias"}, method = RequestMethod.GET) @ResponseBody public WidgetType getWidgetType( - @ApiParam(value = "System or Tenant", required = true) + @Parameter(description = "System or Tenant", required = true) @RequestParam boolean isSystem, - @ApiParam(value = "Widget Bundle alias", required = true) + @Parameter(description = "Widget Bundle alias", required = true) @RequestParam String bundleAlias, - @ApiParam(value = "Widget Type alias", required = true) + @Parameter(description = "Widget Type alias", required = true) @RequestParam String alias) throws ThingsboardException { TenantId tenantId; if (isSystem) { diff --git a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java index 737e6d54d5..9e36015ee1 100644 --- a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java +++ b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; @@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.widgets.bundle.TbWidgetsBundleService; import org.thingsboard.server.service.security.permission.Operation; @@ -46,13 +47,11 @@ import static org.thingsboard.server.controller.ControllerConstants.AVAILABLE_FO import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH; import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK; import static org.thingsboard.server.controller.ControllerConstants.WIDGET_BUNDLE_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.WIDGET_BUNDLE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.WIDGET_BUNDLE_TEXT_SEARCH_DESCRIPTION; @RestController @@ -71,7 +70,7 @@ public class WidgetsBundleController extends BaseController { @RequestMapping(value = "/widgetsBundle/{widgetsBundleId}", method = RequestMethod.GET) @ResponseBody public WidgetsBundle getWidgetsBundleById( - @ApiParam(value = WIDGET_BUNDLE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = WIDGET_BUNDLE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("widgetsBundleId") String strWidgetsBundleId) throws ThingsboardException { checkParameter("widgetsBundleId", strWidgetsBundleId); WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId)); @@ -92,7 +91,7 @@ public class WidgetsBundleController extends BaseController { @RequestMapping(value = "/widgetsBundle", method = RequestMethod.POST) @ResponseBody public WidgetsBundle saveWidgetsBundle( - @ApiParam(value = "A JSON value representing the Widget Bundle.", required = true) + @Parameter(description = "A JSON value representing the Widget Bundle.", required = true) @RequestBody WidgetsBundle widgetsBundle) throws Exception { var currentUser = getCurrentUser(); if (Authority.SYS_ADMIN.equals(currentUser.getAuthority())) { @@ -112,7 +111,7 @@ public class WidgetsBundleController extends BaseController { @RequestMapping(value = "/widgetsBundle/{widgetsBundleId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) public void deleteWidgetsBundle( - @ApiParam(value = WIDGET_BUNDLE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = WIDGET_BUNDLE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("widgetsBundleId") String strWidgetsBundleId) throws ThingsboardException { checkParameter("widgetsBundleId", strWidgetsBundleId); WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId)); @@ -127,15 +126,15 @@ public class WidgetsBundleController extends BaseController { @RequestMapping(value = "/widgetsBundles", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getWidgetsBundles( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = WIDGET_BUNDLE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = WIDGET_BUNDLE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = WIDGET_BUNDLE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "title", "tenantId"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { diff --git a/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java b/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java index 73d763af34..c436461c65 100644 --- a/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java +++ b/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java @@ -15,6 +15,10 @@ */ package org.thingsboard.server.controller.plugin; +import jakarta.websocket.RemoteEndpoint; +import jakarta.websocket.SendHandler; +import jakarta.websocket.SendResult; +import jakarta.websocket.Session; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.BeanCreationNotAllowedException; import org.springframework.beans.factory.annotation.Autowired; @@ -47,10 +51,6 @@ import org.thingsboard.server.service.ws.WebSocketService; import org.thingsboard.server.service.ws.WebSocketSessionRef; import org.thingsboard.server.service.ws.WebSocketSessionType; -import jakarta.websocket.RemoteEndpoint; -import jakarta.websocket.SendHandler; -import jakarta.websocket.SendResult; -import jakarta.websocket.Session; import java.io.IOException; import java.net.URI; import java.security.InvalidParameterException; diff --git a/application/src/main/java/org/thingsboard/server/exception/ThingsboardCredentialsExpiredResponse.java b/application/src/main/java/org/thingsboard/server/exception/ThingsboardCredentialsExpiredResponse.java index 46e7205824..a055d4c94a 100644 --- a/application/src/main/java/org/thingsboard/server/exception/ThingsboardCredentialsExpiredResponse.java +++ b/application/src/main/java/org/thingsboard/server/exception/ThingsboardCredentialsExpiredResponse.java @@ -15,12 +15,11 @@ */ package org.thingsboard.server.exception; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.springframework.http.HttpStatus; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; -@ApiModel +@Schema public class ThingsboardCredentialsExpiredResponse extends ThingsboardErrorResponse { private final String resetToken; @@ -34,7 +33,7 @@ public class ThingsboardCredentialsExpiredResponse extends ThingsboardErrorRespo return new ThingsboardCredentialsExpiredResponse(message, resetToken); } - @ApiModelProperty(position = 5, value = "Password reset token", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Password reset token", accessMode = Schema.AccessMode.READ_ONLY) public String getResetToken() { return resetToken; } diff --git a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java index 73cc5b0902..e1a76bbcac 100644 --- a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java +++ b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java @@ -15,14 +15,13 @@ */ package org.thingsboard.server.exception; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.springframework.http.HttpStatus; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import java.util.Date; -@ApiModel +@Schema public class ThingsboardErrorResponse { // HTTP Response Status Code private final HttpStatus status; @@ -46,17 +45,17 @@ public class ThingsboardErrorResponse { return new ThingsboardErrorResponse(message, errorCode, status); } - @ApiModelProperty(position = 1, value = "HTTP Response Status Code", example = "401", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "HTTP Response Status Code", example = "401", accessMode = Schema.AccessMode.READ_ONLY) public Integer getStatus() { return status.value(); } - @ApiModelProperty(position = 2, value = "Error message", example = "Authentication failed", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Error message", example = "Authentication failed", accessMode = Schema.AccessMode.READ_ONLY) public String getMessage() { return message; } - @ApiModelProperty(position = 3, value = "Platform error code:" + + @Schema(description = "Platform error code:" + "\n* `2` - General error (HTTP: 500 - Internal Server Error)" + "\n\n* `10` - Authentication failed (HTTP: 401 - Unauthorized)" + "\n\n* `11` - JWT token expired (HTTP: 401 - Unauthorized)" + @@ -68,13 +67,13 @@ public class ThingsboardErrorResponse { "\n\n* `33` - Too many requests (HTTP: 429 - Too Many Requests)" + "\n\n* `34` - Too many updates (Too many updates over Websocket session)" + "\n\n* `40` - Subscription violation (HTTP: 403 - Forbidden)", - example = "10", dataType = "integer", - accessMode = ApiModelProperty.AccessMode.READ_ONLY) + example = "10", type = "integer", + accessMode = Schema.AccessMode.READ_ONLY) public ThingsboardErrorCode getErrorCode() { return errorCode; } - @ApiModelProperty(position = 4, value = "Timestamp", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp", accessMode = Schema.AccessMode.READ_ONLY) public Date getTimestamp() { return timestamp; } diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginRequest.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginRequest.java index 78cf6b1f98..6065466a62 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginRequest.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginRequest.java @@ -17,10 +17,9 @@ package org.thingsboard.server.service.security.auth.rest; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; -@ApiModel +@Schema public class LoginRequest { private String username; @@ -33,12 +32,12 @@ public class LoginRequest { this.password = password; } - @ApiModelProperty(position = 1, required = true, value = "User email", example = "tenant@thingsboard.org") + @Schema(required = true, description = "User email", example = "tenant@thingsboard.org") public String getUsername() { return username; } - @ApiModelProperty(position = 2, required = true, value = "User password", example = "tenant") + @Schema(required = true, description = "User password", example = "tenant") public String getPassword() { return password; } diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginResponse.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginResponse.java index 8fdd443fe8..91113a4caa 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginResponse.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginResponse.java @@ -15,19 +15,18 @@ */ package org.thingsboard.server.service.security.auth.rest; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class LoginResponse { - @ApiModelProperty(position = 1, required = true, value = "JWT token", + @Schema(required = true, description = "JWT token", example = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZW5hbnRAdGhpbmdzYm9hcmQub3JnIi...") private String token; - @ApiModelProperty(position = 2, required = true, value = "Refresh token", + @Schema(required = true, description = "Refresh token", example = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZW5hbnRAdGhpbmdzYm9hcmQub3JnIi...") private String refreshToken; diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/ActivateUserRequest.java b/application/src/main/java/org/thingsboard/server/service/security/model/ActivateUserRequest.java index aff95ea246..a3f6057d61 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/ActivateUserRequest.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/ActivateUserRequest.java @@ -15,16 +15,15 @@ */ package org.thingsboard.server.service.security.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class ActivateUserRequest { - @ApiModelProperty(position = 1, value = "The activate token to verify", example = "AAB254FF67D..") + @Schema(description = "The activate token to verify", example = "AAB254FF67D..") private String activateToken; - @ApiModelProperty(position = 2, value = "The new password to set", example = "secret") + @Schema(description = "The new password to set", example = "secret") private String password; } diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/ChangePasswordRequest.java b/application/src/main/java/org/thingsboard/server/service/security/model/ChangePasswordRequest.java index 4b21acef5e..0596f8f43a 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/ChangePasswordRequest.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/ChangePasswordRequest.java @@ -15,17 +15,16 @@ */ package org.thingsboard.server.service.security.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class ChangePasswordRequest { - @ApiModelProperty(position = 1, value = "The old password", example = "OldPassword") + @Schema(description = "The old password", example = "OldPassword") private String currentPassword; - @ApiModelProperty(position = 1, value = "The new password", example = "NewPassword") + @Schema(description = "The new password", example = "NewPassword") private String newPassword; } diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordEmailRequest.java b/application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordEmailRequest.java index 93f9541986..fb4832a264 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordEmailRequest.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordEmailRequest.java @@ -15,14 +15,13 @@ */ package org.thingsboard.server.service.security.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class ResetPasswordEmailRequest { - @ApiModelProperty(position = 1, value = "The email of the user", example = "user@example.com") + @Schema(description = "The email of the user", example = "user@example.com") private String email; } diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordRequest.java b/application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordRequest.java index 3869da9b02..6afeff730b 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordRequest.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordRequest.java @@ -15,16 +15,15 @@ */ package org.thingsboard.server.service.security.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class ResetPasswordRequest { - @ApiModelProperty(position = 1, value = "The reset token to verify", example = "AAB254FF67D..") + @Schema(description = "The reset token to verify", example = "AAB254FF67D..") private String resetToken; - @ApiModelProperty(position = 2, value = "The new password to set", example = "secret") + @Schema(description = "The new password to set", example = "secret") private String password; } diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/AttributeData.java b/application/src/main/java/org/thingsboard/server/service/telemetry/AttributeData.java index b7c7b281ca..58a56e05c1 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/AttributeData.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/AttributeData.java @@ -15,10 +15,9 @@ */ package org.thingsboard.server.service.telemetry; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; -@ApiModel +@Schema public class AttributeData implements Comparable{ private final long lastUpdateTs; @@ -32,17 +31,17 @@ public class AttributeData implements Comparable{ this.value = value; } - @ApiModelProperty(position = 1, value = "Timestamp last updated attribute, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp last updated attribute, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) public long getLastUpdateTs() { return lastUpdateTs; } - @ApiModelProperty(position = 2, value = "String representing attribute key", example = "active", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "String representing attribute key", example = "active", accessMode = Schema.AccessMode.READ_ONLY) public String getKey() { return key; } - @ApiModelProperty(position = 3, value = "Object representing value of attribute key", example = "false", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Object representing value of attribute key", example = "false", accessMode = Schema.AccessMode.READ_ONLY) public Object getValue() { return value; } diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/TsData.java b/application/src/main/java/org/thingsboard/server/service/telemetry/TsData.java index d0af1080d3..d0f07ac094 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/TsData.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/TsData.java @@ -15,10 +15,9 @@ */ package org.thingsboard.server.service.telemetry; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; -@ApiModel +@Schema public class TsData implements Comparable{ private final long ts; @@ -30,12 +29,12 @@ public class TsData implements Comparable{ this.value = value; } - @ApiModelProperty(position = 1, value = "Timestamp last updated timeseries, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp last updated timeseries, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) public long getTs() { return ts; } - @ApiModelProperty(position = 2, value = "Object representing value of timeseries key", example = "20", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Object representing value of timeseries key", example = "20", accessMode = Schema.AccessMode.READ_ONLY) public Object getValue() { return value; } diff --git a/application/src/main/java/org/thingsboard/server/springfox/SpringfoxHandlerProviderBeanPostProcessor.java b/application/src/main/java/org/thingsboard/server/springfox/SpringfoxHandlerProviderBeanPostProcessor.java deleted file mode 100644 index 6a222870b0..0000000000 --- a/application/src/main/java/org/thingsboard/server/springfox/SpringfoxHandlerProviderBeanPostProcessor.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * 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.springfox; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.stereotype.Component; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; -import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider; - -import java.lang.reflect.Field; -import java.util.List; -import java.util.stream.Collectors; - -@Component -//TODO: remove after fixing issue https://github.com/springfox/springfox/issues/3462 or after migration from springfox to springdoc -public class SpringfoxHandlerProviderBeanPostProcessor implements BeanPostProcessor { - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof WebMvcRequestHandlerProvider) { - customizeSpringfoxHandlerMappings(getHandlerMappings(bean)); - } - return bean; - } - - private void customizeSpringfoxHandlerMappings(List mappings) { - List copy = mappings.stream() - .filter(mapping -> mapping.getPatternParser() == null) - .collect(Collectors.toList()); - mappings.clear(); - mappings.addAll(copy); - } - - @SuppressWarnings("unchecked") - private List getHandlerMappings(Object bean) { - try { - Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings"); - field.setAccessible(true); - return (List) field.get(bean); - } catch (IllegalArgumentException | IllegalAccessException e) { - throw new IllegalStateException(e); - } - } -} diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 6e68e1066f..7473121866 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -988,10 +988,12 @@ edges: state: persistToTelemetry: "${EDGES_PERSIST_STATE_TO_TELEMETRY:false}" +springdoc: + api-docs.enabled: "${SWAGGER_ENABLED:true}" + default-produces-media-type: "${SWAGGER_DEFAULT_PRODUCES_MEDIA_TYPE:application/json}" + swagger: - enabled: "${SWAGGER_ENABLED:true}" - api_path_regex: "${SWAGGER_API_PATH_REGEX:/api/.*}" - security_path_regex: "${SWAGGER_SECURITY_PATH_REGEX:/api/.*}" + api_path: "${SWAGGER_API_PATH:/api/**}" non_security_path_regex: "${SWAGGER_NON_SECURITY_PATH_REGEX:/api/(?:noauth|v1)/.*}" title: "${SWAGGER_TITLE:ThingsBoard REST API}" description: "${SWAGGER_DESCRIPTION: ThingsBoard open-source IoT platform REST API documentation.}" diff --git a/common/data/pom.xml b/common/data/pom.xml index cf528b9bbd..9aa6aed2c0 100644 --- a/common/data/pom.xml +++ b/common/data/pom.xml @@ -105,8 +105,8 @@ commons-codec - io.swagger - swagger-annotations + io.swagger.core.v3 + swagger-annotations-jakarta com.google.protobuf diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/AdminSettings.java b/common/data/src/main/java/org/thingsboard/server/common/data/AdminSettings.java index c1f296c26c..a70d235bd5 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/AdminSettings.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/AdminSettings.java @@ -16,14 +16,13 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.id.AdminSettingsId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema public class AdminSettings extends BaseData implements HasTenantId { private static final long serialVersionUID = -7670322981725511892L; @@ -50,19 +49,19 @@ public class AdminSettings extends BaseData implements HasTenan this.jsonValue = adminSettings.getJsonValue(); } - @ApiModelProperty(position = 1, value = "The Id of the Administration Settings, auto-generated, UUID") + @Schema(description = "The Id of the Administration Settings, auto-generated, UUID") @Override public AdminSettingsId getId() { return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the settings creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the settings creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) public TenantId getTenantId() { return tenantId; } @@ -71,7 +70,7 @@ public class AdminSettings extends BaseData implements HasTenan this.tenantId = tenantId; } - @ApiModelProperty(position = 4, value = "The Administration Settings key, (e.g. 'general' or 'mail')", example = "mail") + @Schema(description = "The Administration Settings key, (e.g. 'general' or 'mail')", example = "mail") public String getKey() { return key; } @@ -80,7 +79,7 @@ public class AdminSettings extends BaseData implements HasTenan this.key = key; } - @ApiModelProperty(position = 5, value = "JSON representation of the Administration Settings value") + @Schema(description = "JSON representation of the Administration Settings value") public JsonNode getJsonValue() { return jsonValue; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Customer.java b/common/data/src/main/java/org/thingsboard/server/common/data/Customer.java index 636ab0de38..6f9d6e4360 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Customer.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Customer.java @@ -19,7 +19,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty.Access; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -35,9 +36,9 @@ public class Customer extends ContactBased implements HasTenantId, E @NoXss @Length(fieldName = "title") - @ApiModelProperty(position = 3, value = "Title of the customer", example = "Company A") + @Schema(description = "Title of the customer", example = "Company A") private String title; - @ApiModelProperty(position = 5, required = true, value = "JSON object with Tenant Id") + @Schema(required = true, description = "JSON object with Tenant Id") private TenantId tenantId; @Getter @Setter @@ -74,7 +75,7 @@ public class Customer extends ContactBased implements HasTenantId, E this.title = title; } - @ApiModelProperty(position = 1, value = "JSON object with the customer Id. " + + @Schema(description = "JSON object with the customer Id. " + "Specify this field to update the customer. " + "Referencing non-existing customer Id will cause error. " + "Omit this field to create new customer." ) @@ -83,61 +84,61 @@ public class Customer extends ContactBased implements HasTenantId, E return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the customer creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the customer creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 6, required = true, value = "Country", example = "US") + @Schema(required = true, description = "Country", example = "US") @Override public String getCountry() { return super.getCountry(); } - @ApiModelProperty(position = 7, required = true, value = "State", example = "NY") + @Schema(required = true, description = "State", example = "NY") @Override public String getState() { return super.getState(); } - @ApiModelProperty(position = 8, required = true, value = "City", example = "New York") + @Schema(required = true, description = "City", example = "New York") @Override public String getCity() { return super.getCity(); } - @ApiModelProperty(position = 9, required = true, value = "Address Line 1", example = "42 Broadway Suite 12-400") + @Schema(required = true, description = "Address Line 1", example = "42 Broadway Suite 12-400") @Override public String getAddress() { return super.getAddress(); } - @ApiModelProperty(position = 10, required = true, value = "Address Line 2", example = "") + @Schema(required = true, description = "Address Line 2", example = "") @Override public String getAddress2() { return super.getAddress2(); } - @ApiModelProperty(position = 11, required = true, value = "Zip code", example = "10004") + @Schema(required = true, description = "Zip code", example = "10004") @Override public String getZip() { return super.getZip(); } - @ApiModelProperty(position = 12, required = true, value = "Phone number", example = "+1(415)777-7777") + @Schema(required = true, description = "Phone number", example = "+1(415)777-7777") @Override public String getPhone() { return super.getPhone(); } - @ApiModelProperty(position = 13, required = true, value = "Email", example = "example@company.com") + @Schema(required = true, description = "Email", example = "example@company.com") @Override public String getEmail() { return super.getEmail(); } - @ApiModelProperty(position = 14, value = "Additional parameters of the device", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Additional parameters of the device",implementation = com.fasterxml.jackson.databind.JsonNode.class) @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); @@ -159,7 +160,7 @@ public class Customer extends ContactBased implements HasTenantId, E @Override @JsonProperty(access = Access.READ_ONLY) - @ApiModelProperty(position = 4, value = "Name of the customer. Read-only, duplicated from title for backward compatibility", example = "Company A", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Name of the customer. Read-only, duplicated from title for backward compatibility", example = "Company A", accessMode = Schema.AccessMode.READ_ONLY) public String getName() { return title; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java b/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java index 10496aaaa2..f0e09a1128 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.collect.Streams; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -59,10 +59,10 @@ public class Dashboard extends DashboardInfo implements ExportableEntity implements HasName, HasTenantId, HasTitle { private TenantId tenantId; @@ -61,7 +60,7 @@ public class DashboardInfo extends BaseData implements HasName, Has this.mobileOrder = dashboardInfo.getMobileOrder(); } - @ApiModelProperty(position = 1, value = "JSON object with the dashboard Id. " + + @Schema(description = "JSON object with the dashboard Id. " + "Specify existing dashboard Id to update the dashboard. " + "Referencing non-existing dashboard id will cause error. " + "Omit this field to create new dashboard.") @@ -70,13 +69,13 @@ public class DashboardInfo extends BaseData implements HasName, Has return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the dashboard creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the dashboard creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Tenant Id of the dashboard can't be changed.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id. Tenant Id of the dashboard can't be changed.", accessMode = Schema.AccessMode.READ_ONLY) public TenantId getTenantId() { return tenantId; } @@ -85,7 +84,7 @@ public class DashboardInfo extends BaseData implements HasName, Has this.tenantId = tenantId; } - @ApiModelProperty(position = 4, value = "Title of the dashboard.") + @Schema(description = "Title of the dashboard.") public String getTitle() { return title; } @@ -94,7 +93,7 @@ public class DashboardInfo extends BaseData implements HasName, Has this.title = title; } - @ApiModelProperty(position = 8, value = "Thumbnail picture for rendering of the dashboards in a grid view on mobile devices.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Thumbnail picture for rendering of the dashboards in a grid view on mobile devices.", accessMode = Schema.AccessMode.READ_ONLY) public String getImage() { return image; } @@ -103,7 +102,7 @@ public class DashboardInfo extends BaseData implements HasName, Has this.image = image; } - @ApiModelProperty(position = 5, value = "List of assigned customers with their info.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "List of assigned customers with their info.", accessMode = Schema.AccessMode.READ_ONLY) public Set getAssignedCustomers() { return assignedCustomers; } @@ -112,7 +111,7 @@ public class DashboardInfo extends BaseData implements HasName, Has this.assignedCustomers = assignedCustomers; } - @ApiModelProperty(position = 6, value = "Hide dashboard from mobile devices. Useful if the dashboard is not designed for small screens.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Hide dashboard from mobile devices. Useful if the dashboard is not designed for small screens.", accessMode = Schema.AccessMode.READ_ONLY) public boolean isMobileHide() { return mobileHide; } @@ -121,7 +120,7 @@ public class DashboardInfo extends BaseData implements HasName, Has this.mobileHide = mobileHide; } - @ApiModelProperty(position = 7, value = "Order on mobile devices. Useful to adjust sorting of the dashboards for mobile applications", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Order on mobile devices. Useful to adjust sorting of the dashboards for mobile applications", accessMode = Schema.AccessMode.READ_ONLY) public Integer getMobileOrder() { return mobileOrder; } @@ -179,7 +178,7 @@ public class DashboardInfo extends BaseData implements HasName, Has } } - @ApiModelProperty(position = 4, value = "Same as title of the dashboard. Read-only field. Update the 'title' to change the 'name' of the dashboard.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Same as title of the dashboard. Read-only field. Update the 'title' to change the 'name' of the dashboard.", accessMode = Schema.AccessMode.READ_ONLY) @Override @JsonProperty(access = JsonProperty.Access.READ_ONLY) public String getName() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Device.java b/common/data/src/main/java/org/thingsboard/server/common/data/Device.java index 45e4244bcb..c8cb6384e2 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Device.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Device.java @@ -18,8 +18,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -37,7 +36,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.Optional; -@ApiModel +@Schema @EqualsAndHashCode(callSuper = true) @Slf4j public class Device extends BaseDataWithAdditionalInfo implements HasLabel, HasTenantId, HasCustomerId, HasOtaPackage, ExportableEntity { @@ -103,7 +102,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL return this; } - @ApiModelProperty(position = 1, value = "JSON object with the Device Id. " + + @Schema(description = "JSON object with the Device Id. " + "Specify this field to update the Device. " + "Referencing non-existing Device Id will cause error. " + "Omit this field to create new Device." ) @@ -112,13 +111,13 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the device creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the device creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Use 'assignDeviceToTenant' to change the Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id. Use 'assignDeviceToTenant' to change the Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) public TenantId getTenantId() { return tenantId; } @@ -127,7 +126,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL this.tenantId = tenantId; } - @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignDeviceToCustomer' to change the Customer Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Customer Id. Use 'assignDeviceToCustomer' to change the Customer Id.", accessMode = Schema.AccessMode.READ_ONLY) public CustomerId getCustomerId() { return customerId; } @@ -136,7 +135,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL this.customerId = customerId; } - @ApiModelProperty(position = 5, required = true, value = "Unique Device Name in scope of Tenant", example = "A4B72CCDFF33") + @Schema(required = true, description = "Unique Device Name in scope of Tenant", example = "A4B72CCDFF33") @Override public String getName() { return name; @@ -146,7 +145,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL this.name = name; } - @ApiModelProperty(position = 6, required = true, value = "Device Profile Name", example = "Temperature Sensor") + @Schema(required = true, description = "Device Profile Name", example = "Temperature Sensor") public String getType() { return type; } @@ -155,7 +154,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL this.type = type; } - @ApiModelProperty(position = 7, required = true, value = "Label that may be used in widgets", example = "Room 234 Sensor") + @Schema(required = true, description = "Label that may be used in widgets", example = "Room 234 Sensor") public String getLabel() { return label; } @@ -164,7 +163,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL this.label = label; } - @ApiModelProperty(position = 8, required = true, value = "JSON object with Device Profile Id.") + @Schema(required = true, description = "JSON object with Device Profile Id.") public DeviceProfileId getDeviceProfileId() { return deviceProfileId; } @@ -173,7 +172,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL this.deviceProfileId = deviceProfileId; } - @ApiModelProperty(position = 9, value = "JSON object with content specific to type of transport in the device profile.") + @Schema(description = "JSON object with content specific to type of transport in the device profile.") public DeviceData getDeviceData() { if (deviceData != null) { return deviceData; @@ -201,7 +200,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL } } - @ApiModelProperty(position = 10, value = "JSON object with Ota Package Id.") + @Schema(description = "JSON object with Ota Package Id.") public OtaPackageId getFirmwareId() { return firmwareId; } @@ -210,7 +209,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL this.firmwareId = firmwareId; } - @ApiModelProperty(position = 11, value = "JSON object with Ota Package Id.") + @Schema(description = "JSON object with Ota Package Id.") public OtaPackageId getSoftwareId() { return softwareId; } @@ -219,7 +218,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL this.softwareId = softwareId; } - @ApiModelProperty(position = 12, value = "Additional parameters of the device", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Additional parameters of the device",implementation = com.fasterxml.jackson.databind.JsonNode.class) @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java index 3204cc217a..80cc3a1d24 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java @@ -15,26 +15,25 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.DeviceId; -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) public class DeviceInfo extends Device { private static final long serialVersionUID = -3004579925090663691L; - @ApiModelProperty(position = 13, value = "Title of the Customer that owns the device.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Title of the Customer that owns the device.", accessMode = Schema.AccessMode.READ_ONLY) private String customerTitle; - @ApiModelProperty(position = 14, value = "Indicates special 'Public' Customer that is auto-generated to use the devices on public dashboards.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Indicates special 'Public' Customer that is auto-generated to use the devices on public dashboards.", accessMode = Schema.AccessMode.READ_ONLY) private boolean customerIsPublic; - @ApiModelProperty(position = 15, value = "Name of the corresponding Device Profile.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Name of the corresponding Device Profile.", accessMode = Schema.AccessMode.READ_ONLY) private String deviceProfileName; - @ApiModelProperty(position = 16, value = "Device active flag.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Device active flag.", accessMode = Schema.AccessMode.READ_ONLY) private boolean active; public DeviceInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java index 2be110b258..090bafdb69 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java @@ -17,8 +17,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonProcessingException; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -36,7 +35,7 @@ import jakarta.validation.Valid; import java.io.ByteArrayInputStream; import java.io.IOException; -@ApiModel +@Schema @Data @ToString(exclude = {"image", "profileDataBytes"}) @EqualsAndHashCode(callSuper = true) @@ -45,34 +44,34 @@ public class DeviceProfile extends BaseData implements HasName, private static final long serialVersionUID = 6998485460273302018L; - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id that owns the profile.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id that owns the profile.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "name") - @ApiModelProperty(position = 4, value = "Unique Device Profile Name in scope of Tenant.", example = "Moisture Sensor") + @Schema(description = "Unique Device Profile Name in scope of Tenant.", example = "Moisture Sensor") private String name; @NoXss - @ApiModelProperty(position = 11, value = "Device Profile description. ") + @Schema(description = "Device Profile description. ") private String description; @Length(fieldName = "image", max = 1000000) - @ApiModelProperty(position = 12, value = "Either URL or Base64 data of the icon. Used in the mobile application to visualize set of device profiles in the grid view. ") + @Schema(description = "Either URL or Base64 data of the icon. Used in the mobile application to visualize set of device profiles in the grid view. ") private String image; private boolean isDefault; - @ApiModelProperty(position = 16, value = "Type of the profile. Always 'DEFAULT' for now. Reserved for future use.") + @Schema(description = "Type of the profile. Always 'DEFAULT' for now. Reserved for future use.") private DeviceProfileType type; - @ApiModelProperty(position = 14, value = "Type of the transport used to connect the device. Default transport supports HTTP, CoAP and MQTT.") + @Schema(description = "Type of the transport used to connect the device. Default transport supports HTTP, CoAP and MQTT.") private DeviceTransportType transportType; - @ApiModelProperty(position = 15, value = "Provisioning strategy.") + @Schema(description = "Provisioning strategy.") private DeviceProfileProvisionType provisionType; - @ApiModelProperty(position = 7, value = "Reference to the rule chain. " + + @Schema(description = "Reference to the rule chain. " + "If present, the specified rule chain will be used to process all messages related to device, including telemetry, attribute updates, etc. " + "Otherwise, the root rule chain will be used to process those messages.") private RuleChainId defaultRuleChainId; - @ApiModelProperty(position = 6, value = "Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to device details.") + @Schema(description = "Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to device details.") private DashboardId defaultDashboardId; @NoXss - @ApiModelProperty(position = 8, value = "Rule engine queue name. " + + @Schema(description = "Rule engine queue name. " + "If present, the specified queue will be used to store all unprocessed messages related to device, including telemetry, attribute updates, etc. " + "Otherwise, the 'Main' queue will be used to store those messages.") private String defaultQueueName; @@ -81,15 +80,15 @@ public class DeviceProfile extends BaseData implements HasName, @JsonIgnore private byte[] profileDataBytes; @NoXss - @ApiModelProperty(position = 13, value = "Unique provisioning key used by 'Device Provisioning' feature.") + @Schema(description = "Unique provisioning key used by 'Device Provisioning' feature.") private String provisionDeviceKey; - @ApiModelProperty(position = 9, value = "Reference to the firmware OTA package. If present, the specified package will be used as default device firmware. ") + @Schema(description = "Reference to the firmware OTA package. If present, the specified package will be used as default device firmware. ") private OtaPackageId firmwareId; - @ApiModelProperty(position = 10, value = "Reference to the software OTA package. If present, the specified package will be used as default device software. ") + @Schema(description = "Reference to the software OTA package. If present, the specified package will be used as default device software. ") private OtaPackageId softwareId; - @ApiModelProperty(position = 17, value = "Reference to the edge rule chain. " + + @Schema(description = "Reference to the edge rule chain. " + "If present, the specified edge rule chain will be used on the edge to process all messages related to device, including telemetry, attribute updates, etc. " + "Otherwise, the edge root rule chain will be used to process those messages.") private RuleChainId defaultEdgeRuleChainId; @@ -122,7 +121,7 @@ public class DeviceProfile extends BaseData implements HasName, this.externalId = deviceProfile.getExternalId(); } - @ApiModelProperty(position = 1, value = "JSON object with the device profile Id. " + + @Schema(description = "JSON object with the device profile Id. " + "Specify this field to update the device profile. " + "Referencing non-existing device profile Id will cause error. " + "Omit this field to create new device profile.") @@ -131,18 +130,18 @@ public class DeviceProfile extends BaseData implements HasName, return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the profile creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the profile creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 5, value = "Used to mark the default profile. Default profile is used when the device profile is not specified during device creation.") + @Schema(description = "Used to mark the default profile. Default profile is used when the device profile is not specified during device creation.") public boolean isDefault() { return isDefault; } - @ApiModelProperty(position = 16, value = "Complex JSON object that includes addition device profile configuration (transport, alarm rules, etc).") + @Schema(description = "Complex JSON object that includes addition device profile configuration (transport, alarm rules, etc).") public DeviceProfileData getProfileData() { if (profileData != null) { return profileData; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileInfo.java index 295b9f6b99..93b094f901 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileInfo.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.ToString; import lombok.Value; @@ -33,16 +33,16 @@ import java.util.UUID; @ToString(callSuper = true, exclude = "image") public class DeviceProfileInfo extends EntityInfo { - @ApiModelProperty(position = 3, value = "Either URL or Base64 data of the icon. Used in the mobile application to visualize set of device profiles in the grid view. ") + @Schema(description = "Either URL or Base64 data of the icon. Used in the mobile application to visualize set of device profiles in the grid view. ") private final String image; - @ApiModelProperty(position = 4, value = "Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to device details.") + @Schema(description = "Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to device details.") private final DashboardId defaultDashboardId; - @ApiModelProperty(position = 5, value = "Type of the profile. Always 'DEFAULT' for now. Reserved for future use.") + @Schema(description = "Type of the profile. Always 'DEFAULT' for now. Reserved for future use.") private final DeviceProfileType type; - @ApiModelProperty(position = 6, value = "Type of the transport used to connect the device. Default transport supports HTTP, CoAP and MQTT.") + @Schema(description = "Type of the transport used to connect the device. Default transport supports HTTP, CoAP and MQTT.") private final DeviceTransportType transportType; - @ApiModelProperty(position = 7, value = "Tenant id.") + @Schema(description = "Tenant id.") private final TenantId tenantId; @JsonCreator diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityInfo.java index 6a86a65d1f..d3109c68d6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityInfo.java @@ -17,8 +17,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityIdFactory; @@ -26,13 +25,13 @@ import org.thingsboard.server.common.data.id.HasId; import java.util.UUID; -@ApiModel +@Schema @Data public class EntityInfo implements HasId, HasName { - @ApiModelProperty(position = 1, value = "JSON object with the entity Id. ") + @Schema(description = "JSON object with the entity Id. ") private final EntityId id; - @ApiModelProperty(position = 2, value = "Entity Name") + @Schema(description = "Entity Name") private final String name; @JsonCreator diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java index c0e44baeb3..72c7346c9e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java @@ -16,7 +16,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -40,23 +40,23 @@ public class EntityView extends BaseDataWithAdditionalInfo private static final long serialVersionUID = 5582010124562018986L; - @ApiModelProperty(position = 7, required = true, value = "JSON object with the referenced Entity Id (Device or Asset).") + @Schema(required = true, description = "JSON object with the referenced Entity Id (Device or Asset).") private EntityId entityId; private TenantId tenantId; private CustomerId customerId; @NoXss @Length(fieldName = "name") - @ApiModelProperty(position = 5, required = true, value = "Entity View name", example = "A4B72CCDFF33") + @Schema(required = true, description = "Entity View name", example = "A4B72CCDFF33") private String name; @NoXss @Length(fieldName = "type") - @ApiModelProperty(position = 6, required = true, value = "Device Profile Name", example = "Temperature Sensor") + @Schema(required = true, description = "Device Profile Name", example = "Temperature Sensor") private String type; - @ApiModelProperty(position = 8, required = true, value = "Set of telemetry and attribute keys to expose via Entity View.") + @Schema(required = true, description = "Set of telemetry and attribute keys to expose via Entity View.") private TelemetryEntityView keys; - @ApiModelProperty(position = 9, value = "Represents the start time of the interval that is used to limit access to target device telemetry. Customer will not be able to see entity telemetry that is outside the specified interval;") + @Schema(description = "Represents the start time of the interval that is used to limit access to target device telemetry. Customer will not be able to see entity telemetry that is outside the specified interval;") private long startTimeMs; - @ApiModelProperty(position = 10, value = "Represents the end time of the interval that is used to limit access to target device telemetry. Customer will not be able to see entity telemetry that is outside the specified interval;") + @Schema(description = "Represents the end time of the interval that is used to limit access to target device telemetry. Customer will not be able to see entity telemetry that is outside the specified interval;") private long endTimeMs; private EntityViewId externalId; @@ -82,7 +82,7 @@ public class EntityView extends BaseDataWithAdditionalInfo this.externalId = entityView.getExternalId(); } - @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignEntityViewToCustomer' to change the Customer Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Customer Id. Use 'assignEntityViewToCustomer' to change the Customer Id.", accessMode = Schema.AccessMode.READ_ONLY) @Override public CustomerId getCustomerId() { return customerId; @@ -93,13 +93,13 @@ public class EntityView extends BaseDataWithAdditionalInfo return name; } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) @Override public TenantId getTenantId() { return tenantId; } - @ApiModelProperty(position = 1, value = "JSON object with the Entity View Id. " + + @Schema(description = "JSON object with the Entity View Id. " + "Specify this field to update the Entity View. " + "Referencing non-existing Entity View Id will cause error. " + "Omit this field to create new Entity View." ) @@ -108,13 +108,13 @@ public class EntityView extends BaseDataWithAdditionalInfo return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the Entity View creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the Entity View creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 11, value = "Additional parameters of the device", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Additional parameters of the device",implementation = com.fasterxml.jackson.databind.JsonNode.class) @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityViewInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityViewInfo.java index 069ea3ae5d..ca3d26087f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityViewInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityViewInfo.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.EntityViewId; @@ -24,9 +24,9 @@ import org.thingsboard.server.common.data.id.EntityViewId; @EqualsAndHashCode(callSuper = true) public class EntityViewInfo extends EntityView { - @ApiModelProperty(position = 12, value = "Title of the Customer that owns the entity view.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Title of the Customer that owns the entity view.", accessMode = Schema.AccessMode.READ_ONLY) private String customerTitle; - @ApiModelProperty(position = 13, value = "Indicates special 'Public' Customer that is auto-generated to use the entity view on public dashboards.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Indicates special 'Public' Customer that is auto-generated to use the entity view on public dashboards.", accessMode = Schema.AccessMode.READ_ONLY) private boolean customerIsPublic; public EntityViewInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java index 11491db4f9..d20438a5b3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EventId; @@ -27,18 +26,18 @@ import org.thingsboard.server.common.data.id.TenantId; * @author Andrew Shvayka */ @Data -@ApiModel +@Schema public class EventInfo extends BaseData { - @ApiModelProperty(position = 1, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; - @ApiModelProperty(position = 2, value = "Event type", example = "STATS") + @Schema(description = "Event type", example = "STATS") private String type; - @ApiModelProperty(position = 3, value = "string", example = "784f394c-42b6-435a-983c-b7beff2784f9") + @Schema(description = "string", example = "784f394c-42b6-435a-983c-b7beff2784f9") private String uid; - @ApiModelProperty(position = 4, value = "JSON object with Entity Id for which event is created.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Entity Id for which event is created.", accessMode = Schema.AccessMode.READ_ONLY) private EntityId entityId; - @ApiModelProperty(position = 5, value = "Event body.", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Event body.",implementation = com.fasterxml.jackson.databind.JsonNode.class) private transient JsonNode body; public EventInfo() { @@ -53,7 +52,7 @@ public class EventInfo extends BaseData { super(event); } - @ApiModelProperty(position = 6, value = "Timestamp of the event creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the event creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/ExportableEntity.java b/common/data/src/main/java/org/thingsboard/server/common/data/ExportableEntity.java index 4677cff29b..a2b21d2a86 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/ExportableEntity.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ExportableEntity.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; @@ -24,7 +24,7 @@ public interface ExportableEntity extends HasId, HasName void setId(I id); - @ApiModelProperty(position = 100, value = "JSON object with External Id from the VCS", accessMode = ApiModelProperty.AccessMode.READ_ONLY, hidden = true) + @Schema(description = "JSON object with External Id from the VCS", accessMode = Schema.AccessMode.READ_ONLY, hidden = true) I getExternalId(); void setExternalId(I externalId); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java b/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java index 6dfbfaa4ed..8971eb9f78 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java @@ -15,17 +15,16 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class HomeDashboard extends Dashboard { public static final String HIDE_DASHBOARD_TOOLBAR_DESCRIPTION = "Hide dashboard toolbar flag. Useful for rendering dashboards on mobile."; - @ApiModelProperty(position = 10, value = HIDE_DASHBOARD_TOOLBAR_DESCRIPTION) + @Schema(description = HIDE_DASHBOARD_TOOLBAR_DESCRIPTION) private boolean hideDashboardToolbar; public HomeDashboard(Dashboard dashboard, boolean hideDashboardToolbar) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboardInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboardInfo.java index ae694fd61a..173b88259c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboardInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboardInfo.java @@ -15,18 +15,17 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import org.thingsboard.server.common.data.id.DashboardId; -@ApiModel +@Schema @Data @AllArgsConstructor public class HomeDashboardInfo { - @ApiModelProperty(position = 1, value = "JSON object with the dashboard Id.") + @Schema(description = "JSON object with the dashboard Id.") private DashboardId dashboardId; - @ApiModelProperty(position = 1, value = HomeDashboard.HIDE_DASHBOARD_TOOLBAR_DESCRIPTION) + @Schema(description = HomeDashboard.HIDE_DASHBOARD_TOOLBAR_DESCRIPTION) private boolean hideDashboardToolbar; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java b/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java index d3aaddf3af..d7f4f20e02 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java @@ -15,22 +15,21 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.OtaPackageId; import java.nio.ByteBuffer; -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) public class OtaPackage extends OtaPackageInfo { private static final long serialVersionUID = 3091601761339422546L; - @ApiModelProperty(position = 16, value = "OTA Package data.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package data.", accessMode = Schema.AccessMode.READ_ONLY) private transient ByteBuffer data; public OtaPackage() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java index ab84724117..aa43567adc 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java @@ -17,8 +17,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; @@ -30,7 +29,7 @@ import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @Slf4j @Data @EqualsAndHashCode(callSuper = true) @@ -38,44 +37,44 @@ public class OtaPackageInfo extends BaseDataWithAdditionalInfo imp private static final long serialVersionUID = 3168391583570815419L; - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Tenant Id of the ota package can't be changed.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id. Tenant Id of the ota package can't be changed.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; - @ApiModelProperty(position = 4, value = "JSON object with Device Profile Id. Device Profile Id of the ota package can't be changed.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Device Profile Id. Device Profile Id of the ota package can't be changed.", accessMode = Schema.AccessMode.READ_ONLY) private DeviceProfileId deviceProfileId; - @ApiModelProperty(position = 5, value = "OTA Package type.", example = "FIRMWARE", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package type.", example = "FIRMWARE", accessMode = Schema.AccessMode.READ_ONLY) private OtaPackageType type; @Length(fieldName = "title") @NoXss - @ApiModelProperty(position = 6, value = "OTA Package title.", example = "fw", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package title.", example = "fw", accessMode = Schema.AccessMode.READ_ONLY) private String title; @Length(fieldName = "version") @NoXss - @ApiModelProperty(position = 7, value = "OTA Package version.", example = "1.0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package version.", example = "1.0", accessMode = Schema.AccessMode.READ_ONLY) private String version; @Length(fieldName = "tag") @NoXss - @ApiModelProperty(position = 8, value = "OTA Package tag.", example = "fw_1.0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package tag.", example = "fw_1.0", accessMode = Schema.AccessMode.READ_ONLY) private String tag; @Length(fieldName = "url") @NoXss - @ApiModelProperty(position = 9, value = "OTA Package url.", example = "http://thingsboard.org/fw/1", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package url.", example = "http://thingsboard.org/fw/1", accessMode = Schema.AccessMode.READ_ONLY) private String url; - @ApiModelProperty(position = 10, value = "Indicates OTA Package 'has data'. Field is returned from DB ('true' if data exists or url is set). If OTA Package 'has data' is 'false' we can not assign the OTA Package to the Device or Device Profile.", example = "true", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Indicates OTA Package 'has data'. Field is returned from DB ('true' if data exists or url is set). If OTA Package 'has data' is 'false' we can not assign the OTA Package to the Device or Device Profile.", example = "true", accessMode = Schema.AccessMode.READ_ONLY) private boolean hasData; @Length(fieldName = "file name") @NoXss - @ApiModelProperty(position = 11, value = "OTA Package file name.", example = "fw_1.0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package file name.", example = "fw_1.0", accessMode = Schema.AccessMode.READ_ONLY) private String fileName; @NoXss @Length(fieldName = "contentType") - @ApiModelProperty(position = 12, value = "OTA Package content type.", example = "APPLICATION_OCTET_STREAM", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package content type.", example = "APPLICATION_OCTET_STREAM", accessMode = Schema.AccessMode.READ_ONLY) private String contentType; - @ApiModelProperty(position = 13, value = "OTA Package checksum algorithm.", example = "CRC32", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package checksum algorithm.", example = "CRC32", accessMode = Schema.AccessMode.READ_ONLY) private ChecksumAlgorithm checksumAlgorithm; @Length(fieldName = "checksum", max = 1020) - @ApiModelProperty(position = 14, value = "OTA Package checksum.", example = "0xd87f7e0c", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package checksum.", example = "0xd87f7e0c", accessMode = Schema.AccessMode.READ_ONLY) private String checksum; - @ApiModelProperty(position = 15, value = "OTA Package data size.", example = "8", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package data size.", example = "8", accessMode = Schema.AccessMode.READ_ONLY) private Long dataSize; public OtaPackageInfo() { @@ -103,7 +102,7 @@ public class OtaPackageInfo extends BaseDataWithAdditionalInfo imp this.dataSize = otaPackageInfo.getDataSize(); } - @ApiModelProperty(position = 1, value = "JSON object with the ota package Id. " + + @Schema(description = "JSON object with the ota package Id. " + "Specify existing ota package Id to update the ota package. " + "Referencing non-existing ota package id will cause error. " + "Omit this field to create new ota package.") @@ -112,7 +111,7 @@ public class OtaPackageInfo extends BaseDataWithAdditionalInfo imp return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the ota package creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the ota package creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); @@ -129,7 +128,7 @@ public class OtaPackageInfo extends BaseDataWithAdditionalInfo imp return StringUtils.isNotEmpty(url); } - @ApiModelProperty(position = 17, value = "OTA Package description.", example = "Description for the OTA Package fw_1.0") + @Schema(description = "OTA Package description.", example = "Description for the OTA Package fw_1.0") @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/SaveDeviceWithCredentialsRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/SaveDeviceWithCredentialsRequest.java index f8c74a5155..7714be385b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/SaveDeviceWithCredentialsRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/SaveDeviceWithCredentialsRequest.java @@ -15,18 +15,17 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.security.DeviceCredentials; -@ApiModel +@Schema @Data public class SaveDeviceWithCredentialsRequest { - @ApiModelProperty(position = 1, value = "The JSON with device entity.", required = true) + @Schema(description = "The JSON with device entity.", required = true) private final Device device; - @ApiModelProperty(position = 2, value = "The JSON with credentials entity.", required = true) + @Schema(description = "The JSON with credentials entity.", required = true) private final DeviceCredentials credentials; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/SaveOtaPackageInfoRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/SaveOtaPackageInfoRequest.java index 8a54de65fa..4c85c44d94 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/SaveOtaPackageInfoRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/SaveOtaPackageInfoRequest.java @@ -15,18 +15,17 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) @NoArgsConstructor public class SaveOtaPackageInfoRequest extends OtaPackageInfo { - @ApiModelProperty(position = 16, value = "Indicates OTA Package uses url. Should be 'true' if uses url or 'false' if will be used data.", example = "true", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Indicates OTA Package uses url. Should be 'true' if uses url or 'false' if will be used data.", example = "true", accessMode = Schema.AccessMode.READ_ONLY) boolean usesUrl; public SaveOtaPackageInfoRequest(OtaPackageInfo otaPackageInfo, boolean usesUrl) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/ShortCustomerInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/ShortCustomerInfo.java index 237a4d9a22..180180f569 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/ShortCustomerInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ShortCustomerInfo.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; @@ -27,20 +26,20 @@ import org.thingsboard.server.common.data.validation.NoXss; * Created by igor on 2/27/18. */ -@ApiModel +@Schema @AllArgsConstructor public class ShortCustomerInfo { - @ApiModelProperty(position = 1, value = "JSON object with the customer Id.") + @Schema(description = "JSON object with the customer Id.") @Getter @Setter private CustomerId customerId; - @ApiModelProperty(position = 2, value = "Title of the customer.") + @Schema(description = "Title of the customer.") @Getter @Setter @NoXss private String title; - @ApiModelProperty(position = 3, value = "Indicates special 'Public' customer used to embed dashboards on public websites.") + @Schema(description = "Indicates special 'Public' customer used to embed dashboards on public websites.") @Getter @Setter private boolean isPublic; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/SystemInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/SystemInfo.java index ea46c91239..93ff39ef7a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/SystemInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/SystemInfo.java @@ -15,15 +15,15 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.List; @Data public class SystemInfo { - @ApiModelProperty(position = 1, value = "Is monolith.") + @Schema(description = "Is monolith.") private boolean isMonolith; - @ApiModelProperty(position = 2, value = "System data.") + @Schema(description = "System data.") private List systemData; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/SystemInfoData.java b/common/data/src/main/java/org/thingsboard/server/common/data/SystemInfoData.java index 5ae53565cf..1db6a5002a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/SystemInfoData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/SystemInfoData.java @@ -15,26 +15,26 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Data public class SystemInfoData { - @ApiModelProperty(position = 1, value = "Service Id.") + @Schema(description = "Service Id.") private String serviceId; - @ApiModelProperty(position = 2, value = "Service type.") + @Schema(description = "Service type.") private String serviceType; - @ApiModelProperty(position = 3, value = "CPU usage, in percent.") + @Schema(description = "CPU usage, in percent.") private Long cpuUsage; - @ApiModelProperty(position = 4, value = "Total CPU usage.") + @Schema(description = "Total CPU usage.") private Long cpuCount; - @ApiModelProperty(position = 5, value = "Memory usage, in percent.") + @Schema(description = "Memory usage, in percent.") private Long memoryUsage; - @ApiModelProperty(position = 6, value = "Total memory in bytes.") + @Schema(description = "Total memory in bytes.") private Long totalMemory; - @ApiModelProperty(position = 7, value = "Disk usage, in percent.") + @Schema(description = "Disk usage, in percent.") private Long discUsage; - @ApiModelProperty(position = 8, value = "Total disc space in bytes.") + @Schema(description = "Total disc space in bytes.") private Long totalDiscSpace; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java b/common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java index 91bb7ba383..c6aa878948 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; @@ -32,10 +32,10 @@ public class TbResource extends TbResourceInfo { @NoXss @Length(fieldName = "file name") - @ApiModelProperty(position = 8, value = "Resource file name.", example = "19.xml", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Resource file name.", example = "19.xml", accessMode = Schema.AccessMode.READ_ONLY) private String fileName; - @ApiModelProperty(position = 9, value = "Resource data.", example = "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCEtLQpGSUxFIElORk9STUFUSU9OCgpPTUEgUGVybWFuZW50IERvY3VtZW50CiAgIEZpbGU6IE9NQS1TVVAtTHdNMk1fQmluYXJ5QXBwRGF0YUNvbnRhaW5lci1WMV8wXzEtMjAxOTAyMjEtQQogICBUeXBlOiB4bWwKClB1YmxpYyBSZWFjaGFibGUgSW5mb3JtYXRpb24KICAgUGF0aDogaHR0cDovL3d3dy5vcGVubW9iaWxlYWxsaWFuY2Uub3JnL3RlY2gvcHJvZmlsZXMKICAgTmFtZTogTHdNMk1fQmluYXJ5QXBwRGF0YUNvbnRhaW5lci12MV8wXzEueG1sCgpOT1JNQVRJVkUgSU5GT1JNQVRJT04KCiAgSW5mb3JtYXRpb24gYWJvdXQgdGhpcyBmaWxlIGNhbiBiZSBmb3VuZCBpbiB0aGUgbGF0ZXN0IHJldmlzaW9uIG9mCgogIE9NQS1UUy1MV00yTV9CaW5hcnlBcHBEYXRhQ29udGFpbmVyLVYxXzBfMQoKICBUaGlzIGlzIGF2YWlsYWJsZSBhdCBodHRwOi8vd3d3Lm9wZW5tb2JpbGVhbGxpYW5jZS5vcmcvCgogIFNlbmQgY29tbWVudHMgdG8gaHR0cHM6Ly9naXRodWIuY29tL09wZW5Nb2JpbGVBbGxpYW5jZS9PTUFfTHdNMk1fZm9yX0RldmVsb3BlcnMvaXNzdWVzCgpDSEFOR0UgSElTVE9SWQoKMTUwNjIwMTggU3RhdHVzIGNoYW5nZWQgdG8gQXBwcm92ZWQgYnkgRE0sIERvYyBSZWYgIyBPTUEtRE0mU0UtMjAxOC0wMDYxLUlOUF9MV00yTV9BUFBEQVRBX1YxXzBfRVJQX2Zvcl9maW5hbF9BcHByb3ZhbAoyMTAyMjAxOSBTdGF0dXMgY2hhbmdlZCB0byBBcHByb3ZlZCBieSBJUFNPLCBEb2MgUmVmICMgT01BLUlQU08tMjAxOS0wMDI1LUlOUF9Md00yTV9PYmplY3RfQXBwX0RhdGFfQ29udGFpbmVyXzFfMF8xX2Zvcl9GaW5hbF9BcHByb3ZhbAoKTEVHQUwgRElTQ0xBSU1FUgoKQ29weXJpZ2h0IDIwMTkgT3BlbiBNb2JpbGUgQWxsaWFuY2UuCgpSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCmFyZSBtZXQ6CgoxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodApub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCjIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Cm5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0cwpjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQKZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgoKVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwoiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVApMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUwpGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQpDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULApJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLApCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7CkxPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIKQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCkxJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOCkFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRQpQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KClRoZSBhYm92ZSBsaWNlbnNlIGlzIHVzZWQgYXMgYSBsaWNlbnNlIHVuZGVyIGNvcHlyaWdodCBvbmx5LiBQbGVhc2UKcmVmZXJlbmNlIHRoZSBPTUEgSVBSIFBvbGljeSBmb3IgcGF0ZW50IGxpY2Vuc2luZyB0ZXJtczoKaHR0cHM6Ly93d3cub21hc3BlY3dvcmtzLm9yZy9hYm91dC9pbnRlbGxlY3R1YWwtcHJvcGVydHktcmlnaHRzLwoKLS0+CjxMV00yTSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbj0iaHR0cDovL29wZW5tb2JpbGVhbGxpYW5jZS5vcmcvdGVjaC9wcm9maWxlcy9MV00yTS54c2QiPgoJPE9iamVjdCBPYmplY3RUeXBlPSJNT0RlZmluaXRpb24iPgoJCTxOYW1lPkJpbmFyeUFwcERhdGFDb250YWluZXI8L05hbWU+CgkJPERlc2NyaXB0aW9uMT48IVtDREFUQVtUaGlzIEx3TTJNIE9iamVjdHMgcHJvdmlkZXMgdGhlIGFwcGxpY2F0aW9uIHNlcnZpY2UgZGF0YSByZWxhdGVkIHRvIGEgTHdNMk0gU2VydmVyLCBlZy4gV2F0ZXIgbWV0ZXIgZGF0YS4gClRoZXJlIGFyZSBzZXZlcmFsIG1ldGhvZHMgdG8gY3JlYXRlIGluc3RhbmNlIHRvIGluZGljYXRlIHRoZSBtZXNzYWdlIGRpcmVjdGlvbiBiYXNlZCBvbiB0aGUgbmVnb3RpYXRpb24gYmV0d2VlbiBBcHBsaWNhdGlvbiBhbmQgTHdNMk0uIFRoZSBDbGllbnQgYW5kIFNlcnZlciBzaG91bGQgbmVnb3RpYXRlIHRoZSBpbnN0YW5jZShzKSB1c2VkIHRvIGV4Y2hhbmdlIHRoZSBkYXRhLiBGb3IgZXhhbXBsZToKIC0gVXNpbmcgYSBzaW5nbGUgaW5zdGFuY2UgZm9yIGJvdGggZGlyZWN0aW9ucyBjb21tdW5pY2F0aW9uLCBmcm9tIENsaWVudCB0byBTZXJ2ZXIgYW5kIGZyb20gU2VydmVyIHRvIENsaWVudC4KIC0gVXNpbmcgYW4gaW5zdGFuY2UgZm9yIGNvbW11bmljYXRpb24gZnJvbSBDbGllbnQgdG8gU2VydmVyIGFuZCBhbm90aGVyIG9uZSBmb3IgY29tbXVuaWNhdGlvbiBmcm9tIFNlcnZlciB0byBDbGllbnQKIC0gVXNpbmcgc2V2ZXJhbCBpbnN0YW5jZXMKXV0+PC9EZXNjcmlwdGlvbjE+CgkJPE9iamVjdElEPjE5PC9PYmplY3RJRD4KCQk8T2JqZWN0VVJOPnVybjpvbWE6bHdtMm06b21hOjE5PC9PYmplY3RVUk4+CgkJPExXTTJNVmVyc2lvbj4xLjA8L0xXTTJNVmVyc2lvbj4KCQk8T2JqZWN0VmVyc2lvbj4xLjA8L09iamVjdFZlcnNpb24+CgkJPE11bHRpcGxlSW5zdGFuY2VzPk11bHRpcGxlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQk8TWFuZGF0b3J5Pk9wdGlvbmFsPC9NYW5kYXRvcnk+CgkJPFJlc291cmNlcz4KCQkJPEl0ZW0gSUQ9IjAiPjxOYW1lPkRhdGE8L05hbWU+CgkJCQk8T3BlcmF0aW9ucz5SVzwvT3BlcmF0aW9ucz4KCQkJCTxNdWx0aXBsZUluc3RhbmNlcz5NdWx0aXBsZTwvTXVsdGlwbGVJbnN0YW5jZXM+CgkJCQk8TWFuZGF0b3J5Pk1hbmRhdG9yeTwvTWFuZGF0b3J5PgoJCQkJPFR5cGU+T3BhcXVlPC9UeXBlPgoJCQkJPFJhbmdlRW51bWVyYXRpb24gLz4KCQkJCTxVbml0cyAvPgoJCQkJPERlc2NyaXB0aW9uPjwhW0NEQVRBW0luZGljYXRlcyB0aGUgYXBwbGljYXRpb24gZGF0YSBjb250ZW50Ll1dPjwvRGVzY3JpcHRpb24+CgkJCTwvSXRlbT4KCQkJPEl0ZW0gSUQ9IjEiPjxOYW1lPkRhdGEgUHJpb3JpdHk8L05hbWU+CgkJCQk8T3BlcmF0aW9ucz5SVzwvT3BlcmF0aW9ucz4KCQkJCTxNdWx0aXBsZUluc3RhbmNlcz5TaW5nbGU8L011bHRpcGxlSW5zdGFuY2VzPgoJCQkJPE1hbmRhdG9yeT5PcHRpb25hbDwvTWFuZGF0b3J5PgoJCQkJPFR5cGU+SW50ZWdlcjwvVHlwZT4KCQkJCTxSYW5nZUVudW1lcmF0aW9uPjEgYnl0ZXM8L1JhbmdlRW51bWVyYXRpb24+CgkJCQk8VW5pdHMgLz4KCQkJCTxEZXNjcmlwdGlvbj48IVtDREFUQVtJbmRpY2F0ZXMgdGhlIEFwcGxpY2F0aW9uIGRhdGEgcHJpb3JpdHk6CjA6SW1tZWRpYXRlCjE6QmVzdEVmZm9ydAoyOkxhdGVzdAozLTEwMDogUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UuCjEwMS0yNTQ6IFByb3ByaWV0YXJ5IG1vZGUuXV0+PC9EZXNjcmlwdGlvbj4KCQkJPC9JdGVtPgoJCQk8SXRlbSBJRD0iMiI+PE5hbWU+RGF0YSBDcmVhdGlvbiBUaW1lPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPlRpbWU8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbiAvPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBEYXRhIGluc3RhbmNlIGNyZWF0aW9uIHRpbWVzdGFtcC5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+CgkJCTxJdGVtIElEPSIzIj48TmFtZT5EYXRhIERlc2NyaXB0aW9uPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPlN0cmluZzwvVHlwZT4KCQkJCTxSYW5nZUVudW1lcmF0aW9uPjMyIGJ5dGVzPC9SYW5nZUVudW1lcmF0aW9uPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBkYXRhIGRlc2NyaXB0aW9uLgplLmcuICJtZXRlciByZWFkaW5nIi5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+CgkJCTxJdGVtIElEPSI0Ij48TmFtZT5EYXRhIEZvcm1hdDwvTmFtZT4KCQkJCTxPcGVyYXRpb25zPlJXPC9PcGVyYXRpb25zPgoJCQkJPE11bHRpcGxlSW5zdGFuY2VzPlNpbmdsZTwvTXVsdGlwbGVJbnN0YW5jZXM+CgkJCQk8TWFuZGF0b3J5Pk9wdGlvbmFsPC9NYW5kYXRvcnk+CgkJCQk8VHlwZT5TdHJpbmc8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbj4zMiBieXRlczwvUmFuZ2VFbnVtZXJhdGlvbj4KCQkJCTxVbml0cyAvPgoJCQkJPERlc2NyaXB0aW9uPjwhW0NEQVRBW0luZGljYXRlcyB0aGUgZm9ybWF0IG9mIHRoZSBBcHBsaWNhdGlvbiBEYXRhLgplLmcuIFlHLU1ldGVyLVdhdGVyLVJlYWRpbmcKVVRGOC1zdHJpbmcKXV0+PC9EZXNjcmlwdGlvbj4KCQkJPC9JdGVtPgoJCQk8SXRlbSBJRD0iNSI+PE5hbWU+QXBwIElEPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPkludGVnZXI8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbj4yIGJ5dGVzPC9SYW5nZUVudW1lcmF0aW9uPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBkZXN0aW5hdGlvbiBBcHBsaWNhdGlvbiBJRC5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+PC9SZXNvdXJjZXM+CgkJPERlc2NyaXB0aW9uMj48IVtDREFUQVtdXT48L0Rlc2NyaXB0aW9uMj4KCTwvT2JqZWN0Pgo8L0xXTTJNPgo=", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Resource data.", example = "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCEtLQpGSUxFIElORk9STUFUSU9OCgpPTUEgUGVybWFuZW50IERvY3VtZW50CiAgIEZpbGU6IE9NQS1TVVAtTHdNMk1fQmluYXJ5QXBwRGF0YUNvbnRhaW5lci1WMV8wXzEtMjAxOTAyMjEtQQogICBUeXBlOiB4bWwKClB1YmxpYyBSZWFjaGFibGUgSW5mb3JtYXRpb24KICAgUGF0aDogaHR0cDovL3d3dy5vcGVubW9iaWxlYWxsaWFuY2Uub3JnL3RlY2gvcHJvZmlsZXMKICAgTmFtZTogTHdNMk1fQmluYXJ5QXBwRGF0YUNvbnRhaW5lci12MV8wXzEueG1sCgpOT1JNQVRJVkUgSU5GT1JNQVRJT04KCiAgSW5mb3JtYXRpb24gYWJvdXQgdGhpcyBmaWxlIGNhbiBiZSBmb3VuZCBpbiB0aGUgbGF0ZXN0IHJldmlzaW9uIG9mCgogIE9NQS1UUy1MV00yTV9CaW5hcnlBcHBEYXRhQ29udGFpbmVyLVYxXzBfMQoKICBUaGlzIGlzIGF2YWlsYWJsZSBhdCBodHRwOi8vd3d3Lm9wZW5tb2JpbGVhbGxpYW5jZS5vcmcvCgogIFNlbmQgY29tbWVudHMgdG8gaHR0cHM6Ly9naXRodWIuY29tL09wZW5Nb2JpbGVBbGxpYW5jZS9PTUFfTHdNMk1fZm9yX0RldmVsb3BlcnMvaXNzdWVzCgpDSEFOR0UgSElTVE9SWQoKMTUwNjIwMTggU3RhdHVzIGNoYW5nZWQgdG8gQXBwcm92ZWQgYnkgRE0sIERvYyBSZWYgIyBPTUEtRE0mU0UtMjAxOC0wMDYxLUlOUF9MV00yTV9BUFBEQVRBX1YxXzBfRVJQX2Zvcl9maW5hbF9BcHByb3ZhbAoyMTAyMjAxOSBTdGF0dXMgY2hhbmdlZCB0byBBcHByb3ZlZCBieSBJUFNPLCBEb2MgUmVmICMgT01BLUlQU08tMjAxOS0wMDI1LUlOUF9Md00yTV9PYmplY3RfQXBwX0RhdGFfQ29udGFpbmVyXzFfMF8xX2Zvcl9GaW5hbF9BcHByb3ZhbAoKTEVHQUwgRElTQ0xBSU1FUgoKQ29weXJpZ2h0IDIwMTkgT3BlbiBNb2JpbGUgQWxsaWFuY2UuCgpSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCmFyZSBtZXQ6CgoxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodApub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCjIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Cm5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0cwpjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQKZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgoKVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwoiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVApMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUwpGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQpDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULApJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLApCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7CkxPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIKQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCkxJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOCkFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRQpQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KClRoZSBhYm92ZSBsaWNlbnNlIGlzIHVzZWQgYXMgYSBsaWNlbnNlIHVuZGVyIGNvcHlyaWdodCBvbmx5LiBQbGVhc2UKcmVmZXJlbmNlIHRoZSBPTUEgSVBSIFBvbGljeSBmb3IgcGF0ZW50IGxpY2Vuc2luZyB0ZXJtczoKaHR0cHM6Ly93d3cub21hc3BlY3dvcmtzLm9yZy9hYm91dC9pbnRlbGxlY3R1YWwtcHJvcGVydHktcmlnaHRzLwoKLS0+CjxMV00yTSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbj0iaHR0cDovL29wZW5tb2JpbGVhbGxpYW5jZS5vcmcvdGVjaC9wcm9maWxlcy9MV00yTS54c2QiPgoJPE9iamVjdCBPYmplY3RUeXBlPSJNT0RlZmluaXRpb24iPgoJCTxOYW1lPkJpbmFyeUFwcERhdGFDb250YWluZXI8L05hbWU+CgkJPERlc2NyaXB0aW9uMT48IVtDREFUQVtUaGlzIEx3TTJNIE9iamVjdHMgcHJvdmlkZXMgdGhlIGFwcGxpY2F0aW9uIHNlcnZpY2UgZGF0YSByZWxhdGVkIHRvIGEgTHdNMk0gU2VydmVyLCBlZy4gV2F0ZXIgbWV0ZXIgZGF0YS4gClRoZXJlIGFyZSBzZXZlcmFsIG1ldGhvZHMgdG8gY3JlYXRlIGluc3RhbmNlIHRvIGluZGljYXRlIHRoZSBtZXNzYWdlIGRpcmVjdGlvbiBiYXNlZCBvbiB0aGUgbmVnb3RpYXRpb24gYmV0d2VlbiBBcHBsaWNhdGlvbiBhbmQgTHdNMk0uIFRoZSBDbGllbnQgYW5kIFNlcnZlciBzaG91bGQgbmVnb3RpYXRlIHRoZSBpbnN0YW5jZShzKSB1c2VkIHRvIGV4Y2hhbmdlIHRoZSBkYXRhLiBGb3IgZXhhbXBsZToKIC0gVXNpbmcgYSBzaW5nbGUgaW5zdGFuY2UgZm9yIGJvdGggZGlyZWN0aW9ucyBjb21tdW5pY2F0aW9uLCBmcm9tIENsaWVudCB0byBTZXJ2ZXIgYW5kIGZyb20gU2VydmVyIHRvIENsaWVudC4KIC0gVXNpbmcgYW4gaW5zdGFuY2UgZm9yIGNvbW11bmljYXRpb24gZnJvbSBDbGllbnQgdG8gU2VydmVyIGFuZCBhbm90aGVyIG9uZSBmb3IgY29tbXVuaWNhdGlvbiBmcm9tIFNlcnZlciB0byBDbGllbnQKIC0gVXNpbmcgc2V2ZXJhbCBpbnN0YW5jZXMKXV0+PC9EZXNjcmlwdGlvbjE+CgkJPE9iamVjdElEPjE5PC9PYmplY3RJRD4KCQk8T2JqZWN0VVJOPnVybjpvbWE6bHdtMm06b21hOjE5PC9PYmplY3RVUk4+CgkJPExXTTJNVmVyc2lvbj4xLjA8L0xXTTJNVmVyc2lvbj4KCQk8T2JqZWN0VmVyc2lvbj4xLjA8L09iamVjdFZlcnNpb24+CgkJPE11bHRpcGxlSW5zdGFuY2VzPk11bHRpcGxlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQk8TWFuZGF0b3J5Pk9wdGlvbmFsPC9NYW5kYXRvcnk+CgkJPFJlc291cmNlcz4KCQkJPEl0ZW0gSUQ9IjAiPjxOYW1lPkRhdGE8L05hbWU+CgkJCQk8T3BlcmF0aW9ucz5SVzwvT3BlcmF0aW9ucz4KCQkJCTxNdWx0aXBsZUluc3RhbmNlcz5NdWx0aXBsZTwvTXVsdGlwbGVJbnN0YW5jZXM+CgkJCQk8TWFuZGF0b3J5Pk1hbmRhdG9yeTwvTWFuZGF0b3J5PgoJCQkJPFR5cGU+T3BhcXVlPC9UeXBlPgoJCQkJPFJhbmdlRW51bWVyYXRpb24gLz4KCQkJCTxVbml0cyAvPgoJCQkJPERlc2NyaXB0aW9uPjwhW0NEQVRBW0luZGljYXRlcyB0aGUgYXBwbGljYXRpb24gZGF0YSBjb250ZW50Ll1dPjwvRGVzY3JpcHRpb24+CgkJCTwvSXRlbT4KCQkJPEl0ZW0gSUQ9IjEiPjxOYW1lPkRhdGEgUHJpb3JpdHk8L05hbWU+CgkJCQk8T3BlcmF0aW9ucz5SVzwvT3BlcmF0aW9ucz4KCQkJCTxNdWx0aXBsZUluc3RhbmNlcz5TaW5nbGU8L011bHRpcGxlSW5zdGFuY2VzPgoJCQkJPE1hbmRhdG9yeT5PcHRpb25hbDwvTWFuZGF0b3J5PgoJCQkJPFR5cGU+SW50ZWdlcjwvVHlwZT4KCQkJCTxSYW5nZUVudW1lcmF0aW9uPjEgYnl0ZXM8L1JhbmdlRW51bWVyYXRpb24+CgkJCQk8VW5pdHMgLz4KCQkJCTxEZXNjcmlwdGlvbj48IVtDREFUQVtJbmRpY2F0ZXMgdGhlIEFwcGxpY2F0aW9uIGRhdGEgcHJpb3JpdHk6CjA6SW1tZWRpYXRlCjE6QmVzdEVmZm9ydAoyOkxhdGVzdAozLTEwMDogUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UuCjEwMS0yNTQ6IFByb3ByaWV0YXJ5IG1vZGUuXV0+PC9EZXNjcmlwdGlvbj4KCQkJPC9JdGVtPgoJCQk8SXRlbSBJRD0iMiI+PE5hbWU+RGF0YSBDcmVhdGlvbiBUaW1lPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPlRpbWU8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbiAvPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBEYXRhIGluc3RhbmNlIGNyZWF0aW9uIHRpbWVzdGFtcC5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+CgkJCTxJdGVtIElEPSIzIj48TmFtZT5EYXRhIERlc2NyaXB0aW9uPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPlN0cmluZzwvVHlwZT4KCQkJCTxSYW5nZUVudW1lcmF0aW9uPjMyIGJ5dGVzPC9SYW5nZUVudW1lcmF0aW9uPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBkYXRhIGRlc2NyaXB0aW9uLgplLmcuICJtZXRlciByZWFkaW5nIi5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+CgkJCTxJdGVtIElEPSI0Ij48TmFtZT5EYXRhIEZvcm1hdDwvTmFtZT4KCQkJCTxPcGVyYXRpb25zPlJXPC9PcGVyYXRpb25zPgoJCQkJPE11bHRpcGxlSW5zdGFuY2VzPlNpbmdsZTwvTXVsdGlwbGVJbnN0YW5jZXM+CgkJCQk8TWFuZGF0b3J5Pk9wdGlvbmFsPC9NYW5kYXRvcnk+CgkJCQk8VHlwZT5TdHJpbmc8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbj4zMiBieXRlczwvUmFuZ2VFbnVtZXJhdGlvbj4KCQkJCTxVbml0cyAvPgoJCQkJPERlc2NyaXB0aW9uPjwhW0NEQVRBW0luZGljYXRlcyB0aGUgZm9ybWF0IG9mIHRoZSBBcHBsaWNhdGlvbiBEYXRhLgplLmcuIFlHLU1ldGVyLVdhdGVyLVJlYWRpbmcKVVRGOC1zdHJpbmcKXV0+PC9EZXNjcmlwdGlvbj4KCQkJPC9JdGVtPgoJCQk8SXRlbSBJRD0iNSI+PE5hbWU+QXBwIElEPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPkludGVnZXI8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbj4yIGJ5dGVzPC9SYW5nZUVudW1lcmF0aW9uPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBkZXN0aW5hdGlvbiBBcHBsaWNhdGlvbiBJRC5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+PC9SZXNvdXJjZXM+CgkJPERlc2NyaXB0aW9uMj48IVtDREFUQVtdXT48L0Rlc2NyaXB0aW9uMj4KCTwvT2JqZWN0Pgo8L0xXTTJNPgo=", accessMode = Schema.AccessMode.READ_ONLY) private String data; public TbResource() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java index 331958ac58..f3e8f1bf8f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; @@ -26,7 +25,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @Slf4j @Data @EqualsAndHashCode(callSuper = true) @@ -34,19 +33,19 @@ public class TbResourceInfo extends BaseData implements HasName, H private static final long serialVersionUID = 7282664529021651736L; - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Tenant Id of the resource can't be changed.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id. Tenant Id of the resource can't be changed.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "title") - @ApiModelProperty(position = 4, value = "Resource title.", example = "BinaryAppDataContainer id=19 v1.0") + @Schema(description = "Resource title.", example = "BinaryAppDataContainer id=19 v1.0") private String title; - @ApiModelProperty(position = 5, value = "Resource type.", example = "LWM2M_MODEL", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Resource type.", example = "LWM2M_MODEL", accessMode = Schema.AccessMode.READ_ONLY) private ResourceType resourceType; @NoXss @Length(fieldName = "resourceKey") - @ApiModelProperty(position = 6, value = "Resource key.", example = "19_1.0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Resource key.", example = "19_1.0", accessMode = Schema.AccessMode.READ_ONLY) private String resourceKey; - @ApiModelProperty(position = 7, value = "Resource search text.", example = "19_1.0:binaryappdatacontainer", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Resource search text.", example = "19_1.0:binaryappdatacontainer", accessMode = Schema.AccessMode.READ_ONLY) private String searchText; public TbResourceInfo() { @@ -66,7 +65,7 @@ public class TbResourceInfo extends BaseData implements HasName, H this.searchText = resourceInfo.getSearchText(); } - @ApiModelProperty(position = 1, value = "JSON object with the Resource Id. " + + @Schema(description = "JSON object with the Resource Id. " + "Specify this field to update the Resource. " + "Referencing non-existing Resource Id will cause error. " + "Omit this field to create new Resource." ) @@ -75,7 +74,7 @@ public class TbResourceInfo extends BaseData implements HasName, H return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the resource creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the resource creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java b/common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java index 89cd9ec467..d01cc3aa41 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java @@ -18,15 +18,14 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @EqualsAndHashCode(callSuper = true) public class Tenant extends ContactBased implements HasTenantId, HasTitle { @@ -34,14 +33,14 @@ public class Tenant extends ContactBased implements HasTenantId, HasTi @Length(fieldName = "title") @NoXss - @ApiModelProperty(position = 3, value = "Title of the tenant", example = "Company A") + @Schema(description = "Title of the tenant", example = "Company A") private String title; @NoXss @Length(fieldName = "region") - @ApiModelProperty(position = 5, value = "Geo region of the tenant", example = "North America") + @Schema(description = "Geo region of the tenant", example = "North America") private String region; - @ApiModelProperty(position = 6, required = true, value = "JSON object with Tenant Profile Id") + @Schema(required = true, description = "JSON object with Tenant Profile Id") private TenantProfileId tenantProfileId; public Tenant() { @@ -74,7 +73,7 @@ public class Tenant extends ContactBased implements HasTenantId, HasTi } @Override - @ApiModelProperty(position = 4, value = "Name of the tenant. Read-only, duplicated from title for backward compatibility", example = "Company A", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Name of the tenant. Read-only, duplicated from title for backward compatibility", example = "Company A", accessMode = Schema.AccessMode.READ_ONLY) @JsonProperty(access = JsonProperty.Access.READ_ONLY) public String getName() { return title; @@ -96,7 +95,7 @@ public class Tenant extends ContactBased implements HasTenantId, HasTi this.tenantProfileId = tenantProfileId; } - @ApiModelProperty(position = 1, value = "JSON object with the tenant Id. " + + @Schema(description = "JSON object with the tenant Id. " + "Specify this field to update the tenant. " + "Referencing non-existing tenant Id will cause error. " + "Omit this field to create new tenant." ) @@ -105,61 +104,61 @@ public class Tenant extends ContactBased implements HasTenantId, HasTi return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the tenant creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the tenant creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 7, required = true, value = "Country", example = "US") + @Schema(required = true, description = "Country", example = "US") @Override public String getCountry() { return super.getCountry(); } - @ApiModelProperty(position = 8, required = true, value = "State", example = "NY") + @Schema(required = true, description = "State", example = "NY") @Override public String getState() { return super.getState(); } - @ApiModelProperty(position = 9, required = true, value = "City", example = "New York") + @Schema(required = true, description = "City", example = "New York") @Override public String getCity() { return super.getCity(); } - @ApiModelProperty(position = 10, required = true, value = "Address Line 1", example = "42 Broadway Suite 12-400") + @Schema(required = true, description = "Address Line 1", example = "42 Broadway Suite 12-400") @Override public String getAddress() { return super.getAddress(); } - @ApiModelProperty(position = 11, required = true, value = "Address Line 2", example = "") + @Schema(required = true, description = "Address Line 2", example = "") @Override public String getAddress2() { return super.getAddress2(); } - @ApiModelProperty(position = 12, required = true, value = "Zip code", example = "10004") + @Schema(required = true, description = "Zip code", example = "10004") @Override public String getZip() { return super.getZip(); } - @ApiModelProperty(position = 13, required = true, value = "Phone number", example = "+1(415)777-7777") + @Schema(required = true, description = "Phone number", example = "+1(415)777-7777") @Override public String getPhone() { return super.getPhone(); } - @ApiModelProperty(position = 14, required = true, value = "Email", example = "example@company.com") + @Schema(required = true, description = "Email", example = "example@company.com") @Override public String getEmail() { return super.getEmail(); } - @ApiModelProperty(position = 15, value = "Additional parameters of the device", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Additional parameters of the device",implementation = com.fasterxml.jackson.databind.JsonNode.class) @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java index e98e14d2d0..fd7ca7fc7f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java @@ -15,15 +15,14 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.TenantId; -@ApiModel +@Schema @Data public class TenantInfo extends Tenant { - @ApiModelProperty(position = 15, value = "Tenant Profile name", example = "Default") + @Schema(description = "Tenant Profile name", example = "Default") private String tenantProfileName; public TenantInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java index 5ce6c00fb8..d4b5f51e77 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java @@ -18,8 +18,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -34,7 +33,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.Optional; -@ApiModel +@Schema @Data @ToString(exclude = {"profileDataBytes"}) @EqualsAndHashCode(callSuper = true) @@ -47,17 +46,17 @@ public class TenantProfile extends BaseData implements HasName @NoXss @Length(fieldName = "name") - @ApiModelProperty(position = 3, value = "Name of the tenant profile", example = "High Priority Tenants") + @Schema(description = "Name of the tenant profile", example = "High Priority Tenants") private String name; @NoXss - @ApiModelProperty(position = 4, value = "Description of the tenant profile", example = "Any text") + @Schema(description = "Description of the tenant profile", example = "Any text") private String description; - @ApiModelProperty(position = 5, value = "Default Tenant profile to be used.", example = "true") + @Schema(description = "Default Tenant profile to be used.", example = "true") private boolean isDefault; - @ApiModelProperty(position = 6, value = "If enabled, will push all messages related to this tenant and processed by the rule engine into separate queue. " + + @Schema(description = "If enabled, will push all messages related to this tenant and processed by the rule engine into separate queue. " + "Useful for complex microservices deployments, to isolate processing of the data for specific tenants", example = "true") private boolean isolatedTbRuleEngine; - @ApiModelProperty(position = 7, value = "Complex JSON object that contains profile settings: queue configs, max devices, max assets, rate limits, etc.") + @Schema(description = "Complex JSON object that contains profile settings: queue configs, max devices, max assets, rate limits, etc.") private transient TenantProfileData profileData; @JsonIgnore private byte[] profileDataBytes; @@ -79,7 +78,7 @@ public class TenantProfile extends BaseData implements HasName this.setProfileData(tenantProfile.getProfileData()); } - @ApiModelProperty(position = 1, value = "JSON object with the tenant profile Id. " + + @Schema(description = "JSON object with the tenant profile Id. " + "Specify this field to update the tenant profile. " + "Referencing non-existing tenant profile Id will cause error. " + "Omit this field to create new tenant profile.") @@ -88,7 +87,7 @@ public class TenantProfile extends BaseData implements HasName return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the tenant profile creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the tenant profile creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/UpdateMessage.java b/common/data/src/main/java/org/thingsboard/server/common/data/UpdateMessage.java index 43210de9d0..522ef80c53 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/UpdateMessage.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/UpdateMessage.java @@ -15,27 +15,26 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serializable; -@ApiModel +@Schema @Data public class UpdateMessage implements Serializable { - @ApiModelProperty(position = 1, value = "'True' if new platform update is available.") + @Schema(description = "'True' if new platform update is available.") private final boolean updateAvailable; - @ApiModelProperty(position = 2, value = "Current ThingsBoard version.") + @Schema(description = "Current ThingsBoard version.") private final String currentVersion; - @ApiModelProperty(position = 3, value = "Latest ThingsBoard version.") + @Schema(description = "Latest ThingsBoard version.") private final String latestVersion; - @ApiModelProperty(position = 4, value = "Upgrade instructions URL.") + @Schema(description = "Upgrade instructions URL.") private final String upgradeInstructionsUrl; - @ApiModelProperty(position = 5, value = "Current ThingsBoard version release notes URL.") + @Schema(description = "Current ThingsBoard version release notes URL.") private final String currentVersionReleaseNotesUrl; - @ApiModelProperty(position = 6, value = "Latest ThingsBoard version release notes URL.") + @Schema(description = "Latest ThingsBoard version release notes URL.") private final String latestVersionReleaseNotesUrl; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/User.java b/common/data/src/main/java/org/thingsboard/server/common/data/User.java index b3d9268c6b..15bc41f22c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/User.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/User.java @@ -18,8 +18,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; @@ -32,7 +31,7 @@ import org.thingsboard.server.common.data.validation.NoXss; import static org.apache.commons.lang3.StringUtils.isNotEmpty; -@ApiModel +@Schema @EqualsAndHashCode(callSuper = true) public class User extends BaseDataWithAdditionalInfo implements HasName, HasTenantId, HasCustomerId, NotificationRecipient { @@ -71,7 +70,7 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, } - @ApiModelProperty(position = 1, value = "JSON object with the User Id. " + + @Schema(description = "JSON object with the User Id. " + "Specify this field to update the device. " + "Referencing non-existing User Id will cause error. " + "Omit this field to create new customer.") @@ -80,13 +79,13 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the user creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the user creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with the Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with the Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) public TenantId getTenantId() { return tenantId; } @@ -95,7 +94,7 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, this.tenantId = tenantId; } - @ApiModelProperty(position = 4, value = "JSON object with the Customer Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with the Customer Id.", accessMode = Schema.AccessMode.READ_ONLY) public CustomerId getCustomerId() { return customerId; } @@ -104,7 +103,7 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, this.customerId = customerId; } - @ApiModelProperty(position = 5, required = true, value = "Email of the user", example = "user@example.com") + @Schema(required = true, description = "Email of the user", example = "user@example.com") public String getEmail() { return email; } @@ -113,14 +112,14 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, this.email = email; } - @ApiModelProperty(position = 6, accessMode = ApiModelProperty.AccessMode.READ_ONLY, value = "Duplicates the email of the user, readonly", example = "user@example.com") + @Schema(accessMode = Schema.AccessMode.READ_ONLY, description = "Duplicates the email of the user, readonly", example = "user@example.com") @Override @JsonProperty(access = JsonProperty.Access.READ_ONLY) public String getName() { return email; } - @ApiModelProperty(position = 7, required = true, value = "Authority", example = "SYS_ADMIN, TENANT_ADMIN or CUSTOMER_USER") + @Schema(required = true, description = "Authority", example = "SYS_ADMIN, TENANT_ADMIN or CUSTOMER_USER") public Authority getAuthority() { return authority; } @@ -129,7 +128,7 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, this.authority = authority; } - @ApiModelProperty(position = 8, required = true, value = "First name of the user", example = "John") + @Schema(required = true, description = "First name of the user", example = "John") public String getFirstName() { return firstName; } @@ -138,7 +137,7 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, this.firstName = firstName; } - @ApiModelProperty(position = 9, required = true, value = "Last name of the user", example = "Doe") + @Schema(required = true, description = "Last name of the user", example = "Doe") public String getLastName() { return lastName; } @@ -147,7 +146,7 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, this.lastName = lastName; } - @ApiModelProperty(position = 10, required = true, value = "Phone number of the user", example = "38012345123") + @Schema(required = true, description = "Phone number of the user", example = "38012345123") public String getPhone() { return phone; } @@ -156,7 +155,7 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, this.phone = phone; } - @ApiModelProperty(position = 11, value = "Additional parameters of the user", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Additional parameters of the user", implementation = com.fasterxml.jackson.databind.JsonNode.class) @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/UserEmailInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/UserEmailInfo.java index f1eb95c805..644144efa5 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/UserEmailInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/UserEmailInfo.java @@ -15,25 +15,24 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.UserId; -@ApiModel +@Schema @Data @AllArgsConstructor public class UserEmailInfo implements HasId { - @ApiModelProperty(position = 1, value = "User id") + @Schema(description = "User id") private UserId id; - @ApiModelProperty(position = 2, value = "User email", example = "john@gmail.com") + @Schema(description = "User email", example = "john@gmail.com") private String email; - @ApiModelProperty(position = 3, value = "User first name", example = "John") + @Schema(description = "User first name", example = "John") private String firstName; - @ApiModelProperty(position = 4, value = "User last name", example = "Brown") + @Schema(description = "User last name", example = "Brown") private String lastName; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java index 34fec2cd82..222570e914 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java @@ -18,8 +18,7 @@ package org.thingsboard.server.common.data.alarm; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -41,7 +40,7 @@ import java.util.List; /** * Created by ashvayka on 11.05.17. */ -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) @Builder @@ -49,45 +48,45 @@ import java.util.List; @JsonIgnoreProperties(ignoreUnknown = true) public class Alarm extends BaseData implements HasName, HasTenantId, HasCustomerId { - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; - @ApiModelProperty(position = 4, value = "JSON object with Customer Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Customer Id", accessMode = Schema.AccessMode.READ_ONLY) private CustomerId customerId; @NoXss - @ApiModelProperty(position = 6, required = true, value = "representing type of the Alarm", example = "High Temperature Alarm") + @Schema(required = true, description = "representing type of the Alarm", example = "High Temperature Alarm") @Length(fieldName = "type") private String type; - @ApiModelProperty(position = 7, required = true, value = "JSON object with alarm originator id") + @Schema(required = true, description = "JSON object with alarm originator id") private EntityId originator; - @ApiModelProperty(position = 8, required = true, value = "Alarm severity", example = "CRITICAL") + @Schema(required = true, description = "Alarm severity", example = "CRITICAL") private AlarmSeverity severity; - @ApiModelProperty(position = 9, required = true, value = "Acknowledged", example = "true") + @Schema(required = true, description = "Acknowledged", example = "true") private boolean acknowledged; - @ApiModelProperty(position = 10, required = true, value = "Cleared", example = "false") + @Schema(required = true, description = "Cleared", example = "false") private boolean cleared; - @ApiModelProperty(position = 11, value = "Alarm assignee user id") + @Schema(description = "Alarm assignee user id") private UserId assigneeId; - @ApiModelProperty(position = 12, value = "Timestamp of the alarm start time, in milliseconds", example = "1634058704565") + @Schema(description = "Timestamp of the alarm start time, in milliseconds", example = "1634058704565") private long startTs; - @ApiModelProperty(position = 13, value = "Timestamp of the alarm end time(last time update), in milliseconds", example = "1634111163522") + @Schema(description = "Timestamp of the alarm end time(last time update), in milliseconds", example = "1634111163522") private long endTs; - @ApiModelProperty(position = 14, value = "Timestamp of the alarm acknowledgement, in milliseconds", example = "1634115221948") + @Schema(description = "Timestamp of the alarm acknowledgement, in milliseconds", example = "1634115221948") private long ackTs; - @ApiModelProperty(position = 15, value = "Timestamp of the alarm clearing, in milliseconds", example = "1634114528465") + @Schema(description = "Timestamp of the alarm clearing, in milliseconds", example = "1634114528465") private long clearTs; - @ApiModelProperty(position = 16, value = "Timestamp of the alarm assignment, in milliseconds", example = "1634115928465") + @Schema(description = "Timestamp of the alarm assignment, in milliseconds", example = "1634115928465") private long assignTs; - @ApiModelProperty(position = 17, value = "JSON object with alarm details") + @Schema(description = "JSON object with alarm details") private transient JsonNode details; - @ApiModelProperty(position = 18, value = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") private boolean propagate; - @ApiModelProperty(position = 19, value = "Propagation flag to specify if alarm should be propagated to the owner (tenant or customer) of alarm originator", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to the owner (tenant or customer) of alarm originator", example = "true") private boolean propagateToOwner; - @ApiModelProperty(position = 20, value = "Propagation flag to specify if alarm should be propagated to the tenant entity", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to the tenant entity", example = "true") private boolean propagateToTenant; - @ApiModelProperty(position = 21, value = "JSON array of relation types that should be used for propagation. " + + @Schema(description = "JSON array of relation types that should be used for propagation. " + "By default, 'propagateRelationTypes' array is empty which means that the alarm will be propagated based on any relation type to parent entities. " + "This parameter should be used only in case when 'propagate' parameter is set to true, otherwise, 'propagateRelationTypes' array will be ignored.") private List propagateRelationTypes; @@ -125,12 +124,12 @@ public class Alarm extends BaseData implements HasName, HasTenantId, Ha @Override @JsonProperty(access = JsonProperty.Access.READ_ONLY) - @ApiModelProperty(position = 5, required = true, value = "representing type of the Alarm", example = "High Temperature Alarm") + @Schema(required = true, description = "representing type of the Alarm", example = "High Temperature Alarm") public String getName() { return type; } - @ApiModelProperty(position = 1, value = "JSON object with the alarm Id. " + + @Schema(description = "JSON object with the alarm Id. " + "Specify this field to update the alarm. " + "Referencing non-existing alarm Id will cause error. " + "Omit this field to create new alarm.") @@ -140,14 +139,14 @@ public class Alarm extends BaseData implements HasName, HasTenantId, Ha } - @ApiModelProperty(position = 2, value = "Timestamp of the alarm creation, in milliseconds", example = "1634058704567", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the alarm creation, in milliseconds", example = "1634058704567", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } @JsonProperty(access = JsonProperty.Access.READ_ONLY) - @ApiModelProperty(position = 22, required = true, value = "status of the Alarm", example = "ACTIVE_UNACK", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "status of the Alarm", example = "ACTIVE_UNACK", accessMode = Schema.AccessMode.READ_ONLY) public AlarmStatus getStatus() { return toStatus(cleared, acknowledged); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java index 982e0f94d1..0ed046311f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java @@ -17,8 +17,7 @@ package org.thingsboard.server.common.data.alarm; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -30,23 +29,23 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @Data @Builder @AllArgsConstructor public class AlarmComment extends BaseData implements HasName { - @ApiModelProperty(position = 3, value = "JSON object with Alarm id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Alarm id.", accessMode = Schema.AccessMode.READ_ONLY) private EntityId alarmId; - @ApiModelProperty(position = 4, value = "JSON object with User id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with User id.", accessMode = Schema.AccessMode.READ_ONLY) private UserId userId; - @ApiModelProperty(position = 5, value = "Defines origination of comment. System type means comment was created by TB. OTHER type means comment was created by user.", example = "SYSTEM/OTHER", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Defines origination of comment. System type means comment was created by TB. OTHER type means comment was created by user.", example = "SYSTEM/OTHER", accessMode = Schema.AccessMode.READ_ONLY) private AlarmCommentType type; - @ApiModelProperty(position = 6, value = "JSON object with text of comment.", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "JSON object with text of comment.",implementation = com.fasterxml.jackson.databind.JsonNode.class) @NoXss @Length(fieldName = "comment", max = 10000) private transient JsonNode comment; - @ApiModelProperty(position = 1, value = "JSON object with the alarm comment Id. " + + @Schema(description = "JSON object with the alarm comment Id. " + "Specify this field to update the alarm comment. " + "Referencing non-existing alarm Id will cause error. " + "Omit this field to create new alarm." ) @@ -55,7 +54,7 @@ public class AlarmComment extends BaseData implements HasName { return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the alarm comment creation, in milliseconds", example = "1634058704567", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the alarm comment creation, in milliseconds", example = "1634058704567", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); @@ -71,7 +70,7 @@ public class AlarmComment extends BaseData implements HasName { @Override @JsonProperty(access = JsonProperty.Access.READ_ONLY) - @ApiModelProperty(position = 5, required = true, value = "representing comment text", example = "Please take a look") + @Schema(required = true, description = "representing comment text", example = "Please take a look") public String getName() { return comment.toString(); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCommentInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCommentInfo.java index e84cb78697..b68f771621 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCommentInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCommentInfo.java @@ -15,24 +15,23 @@ */ package org.thingsboard.server.common.data.alarm; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) public class AlarmCommentInfo extends AlarmComment { private static final long serialVersionUID = 2807343093519543377L; - @ApiModelProperty(position = 19, value = "User first name", example = "John") + @Schema(description = "User first name", example = "John") private String firstName; - @ApiModelProperty(position = 19, value = "User last name", example = "Brown") + @Schema(description = "User last name", example = "Brown") private String lastName; - @ApiModelProperty(position = 19, value = "User email address", example = "johnBrown@gmail.com") + @Schema(description = "User email address", example = "johnBrown@gmail.com") private String email; public AlarmCommentInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCreateOrUpdateActiveRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCreateOrUpdateActiveRequest.java index 1c71e66b87..ea4649bcd6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCreateOrUpdateActiveRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCreateOrUpdateActiveRequest.java @@ -16,7 +16,7 @@ package org.thingsboard.server.common.data.alarm; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Data; import org.thingsboard.server.common.data.id.AlarmId; @@ -35,29 +35,29 @@ import jakarta.validation.constraints.NotNull; public class AlarmCreateOrUpdateActiveRequest implements AlarmModificationRequest { @NotNull - @ApiModelProperty(position = 1, value = "JSON object with Tenant Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; - @ApiModelProperty(position = 2, value = "JSON object with Customer Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Customer Id", accessMode = Schema.AccessMode.READ_ONLY) private CustomerId customerId; @NotNull - @ApiModelProperty(position = 3, required = true, value = "representing type of the Alarm", example = "High Temperature Alarm") + @Schema(required = true, description = "representing type of the Alarm", example = "High Temperature Alarm") @Length(fieldName = "type") private String type; @NotNull - @ApiModelProperty(position = 4, required = true, value = "JSON object with alarm originator id") + @Schema(required = true, description = "JSON object with alarm originator id") private EntityId originator; @NotNull - @ApiModelProperty(position = 5, required = true, value = "Alarm severity", example = "CRITICAL") + @Schema(required = true, description = "Alarm severity", example = "CRITICAL") private AlarmSeverity severity; - @ApiModelProperty(position = 6, value = "Timestamp of the alarm start time, in milliseconds", example = "1634058704565") + @Schema(description = "Timestamp of the alarm start time, in milliseconds", example = "1634058704565") private long startTs; - @ApiModelProperty(position = 7, value = "Timestamp of the alarm end time(last time update), in milliseconds", example = "1634111163522") + @Schema(description = "Timestamp of the alarm end time(last time update), in milliseconds", example = "1634111163522") private long endTs; @NoXss - @ApiModelProperty(position = 8, value = "JSON object with alarm details") + @Schema(description = "JSON object with alarm details") private JsonNode details; @Valid - @ApiModelProperty(position = 9, value = "JSON object with propagation details") + @Schema(description = "JSON object with propagation details") private AlarmPropagationInfo propagation; private UserId userId; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmInfo.java index 9086c4aa7b..61e53044ad 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmInfo.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.alarm; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -24,24 +23,24 @@ import lombok.ToString; @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -@ApiModel +@Schema public class AlarmInfo extends Alarm { private static final long serialVersionUID = 2807343093519543363L; @Getter @Setter - @ApiModelProperty(position = 19, value = "Alarm originator name", example = "Thermostat") + @Schema(description = "Alarm originator name", example = "Thermostat") private String originatorName; @Getter @Setter - @ApiModelProperty(position = 20, value = "Alarm originator label", example = "Thermostat label") + @Schema(description = "Alarm originator label", example = "Thermostat label") private String originatorLabel; @Getter @Setter - @ApiModelProperty(position = 21, value = "Alarm assignee") + @Schema(description = "Alarm assignee") private AlarmAssignee assignee; public AlarmInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmPropagationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmPropagationInfo.java index 8ba744a85e..49ad2c4ded 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmPropagationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmPropagationInfo.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.alarm; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Data; import org.thingsboard.server.common.data.validation.NoXss; @@ -29,14 +29,14 @@ public class AlarmPropagationInfo { public static AlarmPropagationInfo EMPTY = new AlarmPropagationInfo(false, false, false, Collections.emptyList()); - @ApiModelProperty(position = 1, value = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") private boolean propagate; - @ApiModelProperty(position = 2, value = "Propagation flag to specify if alarm should be propagated to the owner (tenant or customer) of alarm originator", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to the owner (tenant or customer) of alarm originator", example = "true") private boolean propagateToOwner; - @ApiModelProperty(position = 3, value = "Propagation flag to specify if alarm should be propagated to the tenant entity", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to the tenant entity", example = "true") private boolean propagateToTenant; @NoXss - @ApiModelProperty(position = 4, value = "JSON array of relation types that should be used for propagation. " + + @Schema(description = "JSON array of relation types that should be used for propagation. " + "By default, 'propagateRelationTypes' array is empty which means that the alarm will be propagated based on any relation type to parent entities. " + "This parameter should be used only in case when 'propagate' parameter is set to true, otherwise, 'propagateRelationTypes' array will be ignored.") private List propagateRelationTypes; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmUpdateRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmUpdateRequest.java index e97b40e1f1..06bacb50fc 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmUpdateRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmUpdateRequest.java @@ -16,7 +16,7 @@ package org.thingsboard.server.common.data.alarm; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Data; import org.thingsboard.server.common.data.id.AlarmId; @@ -32,26 +32,26 @@ import jakarta.validation.constraints.NotNull; public class AlarmUpdateRequest implements AlarmModificationRequest { @NotNull - @ApiModelProperty(position = 1, value = "JSON object with Tenant Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; @NotNull - @ApiModelProperty(position = 2, value = "JSON object with the alarm Id. " + + @Schema(description = "JSON object with the alarm Id. " + "Specify this field to update the alarm. " + "Referencing non-existing alarm Id will cause error. " + "Omit this field to create new alarm.") private AlarmId alarmId; @NotNull - @ApiModelProperty(position = 3, required = true, value = "Alarm severity", example = "CRITICAL") + @Schema(required = true, description = "Alarm severity", example = "CRITICAL") private AlarmSeverity severity; - @ApiModelProperty(position = 4, value = "Timestamp of the alarm start time, in milliseconds", example = "1634058704565") + @Schema(description = "Timestamp of the alarm start time, in milliseconds", example = "1634058704565") private long startTs; - @ApiModelProperty(position = 5, value = "Timestamp of the alarm end time(last time update), in milliseconds", example = "1634111163522") + @Schema(description = "Timestamp of the alarm end time(last time update), in milliseconds", example = "1634111163522") private long endTs; @NoXss - @ApiModelProperty(position = 6, value = "JSON object with alarm details") + @Schema(description = "JSON object with alarm details") private JsonNode details; @Valid - @ApiModelProperty(position = 7, value = "JSON object with propagation details") + @Schema(description = "JSON object with propagation details") private AlarmPropagationInfo propagation; private UserId userId; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java b/common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java index bbb56305db..49bcc15875 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data.asset; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -35,7 +34,7 @@ import org.thingsboard.server.common.data.validation.NoXss; import java.util.Optional; -@ApiModel +@Schema @EqualsAndHashCode(callSuper = true) public class Asset extends BaseDataWithAdditionalInfo implements HasLabel, HasTenantId, HasCustomerId, ExportableEntity { @@ -88,7 +87,7 @@ public class Asset extends BaseDataWithAdditionalInfo implements HasLab this.externalId = asset.getExternalId(); } - @ApiModelProperty(position = 1, value = "JSON object with the asset Id. " + + @Schema(description = "JSON object with the asset Id. " + "Specify this field to update the asset. " + "Referencing non-existing asset Id will cause error. " + "Omit this field to create new asset.") @@ -97,13 +96,13 @@ public class Asset extends BaseDataWithAdditionalInfo implements HasLab return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the asset creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the asset creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) public TenantId getTenantId() { return tenantId; } @@ -112,7 +111,7 @@ public class Asset extends BaseDataWithAdditionalInfo implements HasLab this.tenantId = tenantId; } - @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignAssetToCustomer' to change the Customer Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Customer Id. Use 'assignAssetToCustomer' to change the Customer Id.", accessMode = Schema.AccessMode.READ_ONLY) public CustomerId getCustomerId() { return customerId; } @@ -121,7 +120,7 @@ public class Asset extends BaseDataWithAdditionalInfo implements HasLab this.customerId = customerId; } - @ApiModelProperty(position = 5, required = true, value = "Unique Asset Name in scope of Tenant", example = "Empire State Building") + @Schema(required = true, description = "Unique Asset Name in scope of Tenant", example = "Empire State Building") @Override public String getName() { return name; @@ -131,7 +130,7 @@ public class Asset extends BaseDataWithAdditionalInfo implements HasLab this.name = name; } - @ApiModelProperty(position = 6, required = true, value = "Asset type", example = "Building") + @Schema(required = true, description = "Asset type", example = "Building") public String getType() { return type; } @@ -140,7 +139,7 @@ public class Asset extends BaseDataWithAdditionalInfo implements HasLab this.type = type; } - @ApiModelProperty(position = 7, required = true, value = "Label that may be used in widgets", example = "NY Building") + @Schema(required = true, description = "Label that may be used in widgets", example = "NY Building") public String getLabel() { return label; } @@ -149,7 +148,7 @@ public class Asset extends BaseDataWithAdditionalInfo implements HasLab this.label = label; } - @ApiModelProperty(position = 8, required = true, value = "JSON object with Asset Profile Id.") + @Schema(required = true, description = "JSON object with Asset Profile Id.") public AssetProfileId getAssetProfileId() { return assetProfileId; } @@ -158,7 +157,7 @@ public class Asset extends BaseDataWithAdditionalInfo implements HasLab this.assetProfileId = assetProfileId; } - @ApiModelProperty(position = 9, value = "Additional parameters of the asset", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Additional parameters of the asset",implementation = com.fasterxml.jackson.databind.JsonNode.class) @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetInfo.java index b2d1fa95a2..08c084fde6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetInfo.java @@ -15,25 +15,24 @@ */ package org.thingsboard.server.common.data.asset; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.AssetId; -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) public class AssetInfo extends Asset { private static final long serialVersionUID = -4094528227011066194L; - @ApiModelProperty(position = 10, value = "Title of the Customer that owns the asset.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Title of the Customer that owns the asset.", accessMode = Schema.AccessMode.READ_ONLY) private String customerTitle; - @ApiModelProperty(position = 11, value = "Indicates special 'Public' Customer that is auto-generated to use the assets on public dashboards.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Indicates special 'Public' Customer that is auto-generated to use the assets on public dashboards.", accessMode = Schema.AccessMode.READ_ONLY) private boolean customerIsPublic; - @ApiModelProperty(position = 12, value = "Name of the corresponding Asset Profile.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Name of the corresponding Asset Profile.", accessMode = Schema.AccessMode.READ_ONLY) private String assetProfileName; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetProfile.java index 5456ba36ce..f8acb0ef08 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetProfile.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetProfile.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.asset; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -34,7 +33,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @Data @ToString(exclude = {"image"}) @EqualsAndHashCode(callSuper = true) @@ -43,33 +42,33 @@ public class AssetProfile extends BaseData implements HasName, H private static final long serialVersionUID = 6998485460273302018L; - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id that owns the profile.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id that owns the profile.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "name") - @ApiModelProperty(position = 4, value = "Unique Asset Profile Name in scope of Tenant.", example = "Building") + @Schema(description = "Unique Asset Profile Name in scope of Tenant.", example = "Building") private String name; @NoXss - @ApiModelProperty(position = 11, value = "Asset Profile description. ") + @Schema(description = "Asset Profile description. ") private String description; @Length(fieldName = "image", max = 1000000) - @ApiModelProperty(position = 12, value = "Either URL or Base64 data of the icon. Used in the mobile application to visualize set of asset profiles in the grid view. ") + @Schema(description = "Either URL or Base64 data of the icon. Used in the mobile application to visualize set of asset profiles in the grid view. ") private String image; private boolean isDefault; - @ApiModelProperty(position = 7, value = "Reference to the rule chain. " + + @Schema(description = "Reference to the rule chain. " + "If present, the specified rule chain will be used to process all messages related to asset, including asset updates, telemetry, attribute updates, etc. " + "Otherwise, the root rule chain will be used to process those messages.") private RuleChainId defaultRuleChainId; - @ApiModelProperty(position = 6, value = "Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to asset details.") + @Schema(description = "Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to asset details.") private DashboardId defaultDashboardId; @NoXss - @ApiModelProperty(position = 8, value = "Rule engine queue name. " + + @Schema(description = "Rule engine queue name. " + "If present, the specified queue will be used to store all unprocessed messages related to asset, including asset updates, telemetry, attribute updates, etc. " + "Otherwise, the 'Main' queue will be used to store those messages.") private String defaultQueueName; - @ApiModelProperty(position = 13, value = "Reference to the edge rule chain. " + + @Schema(description = "Reference to the edge rule chain. " + "If present, the specified edge rule chain will be used on the edge to process all messages related to asset, including asset updates, telemetry, attribute updates, etc. " + "Otherwise, the edge root rule chain will be used to process those messages.") private RuleChainId defaultEdgeRuleChainId; @@ -98,7 +97,7 @@ public class AssetProfile extends BaseData implements HasName, H this.externalId = assetProfile.getExternalId(); } - @ApiModelProperty(position = 1, value = "JSON object with the asset profile Id. " + + @Schema(description = "JSON object with the asset profile Id. " + "Specify this field to update the asset profile. " + "Referencing non-existing asset profile Id will cause error. " + "Omit this field to create new asset profile.") @@ -107,13 +106,13 @@ public class AssetProfile extends BaseData implements HasName, H return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the profile creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the profile creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 5, value = "Used to mark the default profile. Default profile is used when the asset profile is not specified during asset creation.") + @Schema(description = "Used to mark the default profile. Default profile is used when the asset profile is not specified during asset creation.") public boolean isDefault(){ return isDefault; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetProfileInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetProfileInfo.java index e590c4c094..dc1adb1b63 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetProfileInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetProfileInfo.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.asset; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.ToString; import lombok.Value; @@ -35,12 +35,12 @@ import java.util.UUID; @ToString(callSuper = true, exclude = "image") public class AssetProfileInfo extends EntityInfo { - @ApiModelProperty(position = 3, value = "Either URL or Base64 data of the icon. Used in the mobile application to visualize set of asset profiles in the grid view. ") + @Schema(description = "Either URL or Base64 data of the icon. Used in the mobile application to visualize set of asset profiles in the grid view. ") private final String image; - @ApiModelProperty(position = 4, value = "Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to asset details.") + @Schema(description = "Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to asset details.") private final DashboardId defaultDashboardId; - @ApiModelProperty(position = 5, value = "Tenant id.") + @Schema(description = "Tenant id.") private final TenantId tenantId; @JsonCreator diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetSearchQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetSearchQuery.java index aeb693b02c..c8a7be5df5 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetSearchQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetSearchQuery.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.asset; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.relation.EntityRelation; @@ -32,11 +32,11 @@ import java.util.List; @Data public class AssetSearchQuery { - @ApiModelProperty(position = 3, value = "Main search parameters.") + @Schema(description = "Main search parameters.") private RelationsSearchParameters parameters; - @ApiModelProperty(position = 1, value = "Type of the relation between root entity and asset (e.g. 'Contains' or 'Manages').") + @Schema(description = "Type of the relation between root entity and asset (e.g. 'Contains' or 'Manages').") private String relationType; - @ApiModelProperty(position = 2, value = "Array of asset types to filter the related entities (e.g. 'Building', 'Vehicle').") + @Schema(description = "Array of asset types to filter the related entities (e.g. 'Building', 'Vehicle').") private List assetTypes; public EntityRelationsQuery toEntitySearchQuery() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/audit/AuditLog.java b/common/data/src/main/java/org/thingsboard/server/common/data/audit/AuditLog.java index 5b6b68e622..5e95a54bb1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/audit/AuditLog.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/audit/AuditLog.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data.audit; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseData; @@ -28,31 +27,31 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @EqualsAndHashCode(callSuper = true) @Data public class AuditLog extends BaseData { - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; - @ApiModelProperty(position = 4, value = "JSON object with Customer Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Customer Id", accessMode = Schema.AccessMode.READ_ONLY) private CustomerId customerId; - @ApiModelProperty(position = 5, value = "JSON object with Entity id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Entity id", accessMode = Schema.AccessMode.READ_ONLY) private EntityId entityId; @NoXss - @ApiModelProperty(position = 6, value = "Name of the logged entity", example = "Thermometer", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Name of the logged entity", example = "Thermometer", accessMode = Schema.AccessMode.READ_ONLY) private String entityName; - @ApiModelProperty(position = 7, value = "JSON object with User id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with User id.", accessMode = Schema.AccessMode.READ_ONLY) private UserId userId; - @ApiModelProperty(position = 8, value = "Unique user name(email) of the user that performed some action on logged entity", example = "tenant@thingsboard.org", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Unique user name(email) of the user that performed some action on logged entity", example = "tenant@thingsboard.org", accessMode = Schema.AccessMode.READ_ONLY) private String userName; - @ApiModelProperty(position = 9, value = "String represented Action type", example = "ADDED", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "String represented Action type", example = "ADDED", accessMode = Schema.AccessMode.READ_ONLY) private ActionType actionType; - @ApiModelProperty(position = 10, value = "JsonNode represented action data", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JsonNode represented action data", accessMode = Schema.AccessMode.READ_ONLY) private JsonNode actionData; - @ApiModelProperty(position = 11, value = "String represented Action status", example = "SUCCESS", allowableValues = "SUCCESS,FAILURE", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "String represented Action status", example = "SUCCESS", allowableValues = "SUCCESS,FAILURE", accessMode = Schema.AccessMode.READ_ONLY) private ActionStatus actionStatus; - @ApiModelProperty(position = 12, value = "Failure action details info. An empty string in case of action status type 'SUCCESS', otherwise includes stack trace of the caused exception.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Failure action details info. An empty string in case of action status type 'SUCCESS', otherwise includes stack trace of the caused exception.", accessMode = Schema.AccessMode.READ_ONLY) private String actionFailureDetails; public AuditLog() { @@ -77,13 +76,13 @@ public class AuditLog extends BaseData { this.actionFailureDetails = auditLog.getActionFailureDetails(); } - @ApiModelProperty(position = 2, value = "Timestamp of the auditLog creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the auditLog creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 1, value = "JSON object with the auditLog Id") + @Schema(description = "JSON object with the auditLog Id") @Override public AuditLogId getId() { return super.getId(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/DeviceSearchQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/DeviceSearchQuery.java index dbde84abbe..f3157c1571 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/DeviceSearchQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/DeviceSearchQuery.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.device; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.relation.EntityRelation; @@ -27,15 +26,15 @@ import org.thingsboard.server.common.data.relation.RelationsSearchParameters; import java.util.Collections; import java.util.List; -@ApiModel +@Schema @Data public class DeviceSearchQuery { - @ApiModelProperty(position = 3, value = "Main search parameters.") + @Schema(description = "Main search parameters.") private RelationsSearchParameters parameters; - @ApiModelProperty(position = 1, value = "Type of the relation between root entity and device (e.g. 'Contains' or 'Manages').") + @Schema(description = "Type of the relation between root entity and device (e.g. 'Contains' or 'Manages').") private String relationType; - @ApiModelProperty(position = 2, value = "Array of device types to filter the related entities (e.g. 'Temperature Sensor', 'Smoke Sensor').") + @Schema(description = "Array of device types to filter the related entities (e.g. 'Temperature Sensor', 'Smoke Sensor').") private List deviceTypes; public EntityRelationsQuery toEntitySearchQuery() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DefaultDeviceConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DefaultDeviceConfiguration.java index 9e7c85e6f4..a5dd1919e1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DefaultDeviceConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DefaultDeviceConfiguration.java @@ -15,11 +15,11 @@ */ package org.thingsboard.server.common.data.device.data; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.DeviceProfileType; -@ApiModel +@Schema @Data public class DefaultDeviceConfiguration implements DeviceConfiguration { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceConfiguration.java index 79793b0fd7..aa1cb8dff8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceConfiguration.java @@ -19,12 +19,12 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.DeviceProfileType; import java.io.Serializable; -@ApiModel +@Schema @JsonIgnoreProperties(ignoreUnknown = true) @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceData.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceData.java index 5ec461c271..b362231691 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceData.java @@ -15,21 +15,20 @@ */ package org.thingsboard.server.common.data.device.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serializable; -@ApiModel +@Schema @Data public class DeviceData implements Serializable { private static final long serialVersionUID = -3771567735290681274L; - @ApiModelProperty(position = 1, value = "Device configuration for device profile type. DEFAULT is only supported value for now") + @Schema(description = "Device configuration for device profile type. DEFAULT is only supported value for now") private DeviceConfiguration configuration; - @ApiModelProperty(position = 2, value = "Device transport configuration used to connect the device") + @Schema(description = "Device transport configuration used to connect the device") private DeviceTransportConfiguration transportConfiguration; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceTransportConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceTransportConfiguration.java index c5f385df4a..ace00a129f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceTransportConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceTransportConfiguration.java @@ -19,12 +19,12 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.DeviceTransportType; import java.io.Serializable; -@ApiModel +@Schema @JsonIgnoreProperties(ignoreUnknown = true) @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmCondition.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmCondition.java index a8b83a1cf6..3cb3ff99f1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmCondition.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmCondition.java @@ -16,23 +16,22 @@ package org.thingsboard.server.common.data.device.profile; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import jakarta.validation.Valid; import java.io.Serializable; import java.util.List; -@ApiModel +@Schema @Data @JsonIgnoreProperties(ignoreUnknown = true) public class AlarmCondition implements Serializable { @Valid - @ApiModelProperty(position = 1, value = "JSON array of alarm condition filters") + @Schema(description = "JSON array of alarm condition filters") private List condition; - @ApiModelProperty(position = 2, value = "JSON object representing alarm condition type") + @Schema(description = "JSON object representing alarm condition type") private AlarmConditionSpec spec; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilter.java index 7a44d707f9..39360cdb3e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilter.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.device.profile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.query.EntityKeyValueType; import org.thingsboard.server.common.data.query.KeyFilterPredicate; @@ -25,20 +24,20 @@ import org.thingsboard.server.common.data.validation.NoXss; import jakarta.validation.Valid; import java.io.Serializable; -@ApiModel +@Schema @Data public class AlarmConditionFilter implements Serializable { @Valid - @ApiModelProperty(position = 1, value = "JSON object for specifying alarm condition by specific key") + @Schema(description = "JSON object for specifying alarm condition by specific key") private AlarmConditionFilterKey key; - @ApiModelProperty(position = 2, value = "String representation of the type of the value", example = "NUMERIC") + @Schema(description = "String representation of the type of the value", example = "NUMERIC") private EntityKeyValueType valueType; @NoXss - @ApiModelProperty(position = 3, value = "Value used in Constant comparison. For other types, such as TIME_SERIES or ATTRIBUTE, the predicate condition is used") + @Schema(description = "Value used in Constant comparison. For other types, such as TIME_SERIES or ATTRIBUTE, the predicate condition is used") private Object value; @Valid - @ApiModelProperty(position = 4, value = "JSON object representing filter condition") + @Schema(description = "JSON object representing filter condition") private KeyFilterPredicate predicate; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilterKey.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilterKey.java index 58dcedc993..a4782fdbff 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilterKey.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilterKey.java @@ -15,21 +15,20 @@ */ package org.thingsboard.server.common.data.device.profile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.validation.NoXss; import java.io.Serializable; -@ApiModel +@Schema @Data public class AlarmConditionFilterKey implements Serializable { - @ApiModelProperty(position = 1, value = "The key type", example = "TIME_SERIES") + @Schema(description = "The key type", example = "TIME_SERIES") private final AlarmConditionKeyType type; @NoXss - @ApiModelProperty(position = 2, value = "String value representing the key", example = "temp") + @Schema(description = "String value representing the key", example = "temp") private final String key; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmRule.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmRule.java index 0f23ae5624..83615dfd4f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmRule.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmRule.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.device.profile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.validation.NoXss; @@ -24,20 +23,20 @@ import org.thingsboard.server.common.data.validation.NoXss; import jakarta.validation.Valid; import java.io.Serializable; -@ApiModel +@Schema @Data public class AlarmRule implements Serializable { @Valid - @ApiModelProperty(position = 1, value = "JSON object representing the alarm rule condition") + @Schema(description = "JSON object representing the alarm rule condition") private AlarmCondition condition; - @ApiModelProperty(position = 2, value = "JSON object representing time interval during which the rule is active") + @Schema(description = "JSON object representing time interval during which the rule is active") private AlarmSchedule schedule; // Advanced @NoXss - @ApiModelProperty(position = 3, value = "String value representing the additional details for an alarm rule") + @Schema(description = "String value representing the additional details for an alarm rule") private String alarmDetails; - @ApiModelProperty(position = 4, value = "JSON object with the dashboard Id representing the reference to alarm details dashboard used by mobile application") + @Schema(description = "JSON object with the dashboard Id representing the reference to alarm details dashboard used by mobile application") private DashboardId dashboardId; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileAlarm.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileAlarm.java index 96f365a152..395149c52b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileAlarm.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileAlarm.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.device.profile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.validation.Length; @@ -27,34 +26,34 @@ import java.io.Serializable; import java.util.List; import java.util.TreeMap; -@ApiModel +@Schema @Data public class DeviceProfileAlarm implements Serializable { - @ApiModelProperty(position = 1, value = "String value representing the alarm rule id", example = "highTemperatureAlarmID") + @Schema(description = "String value representing the alarm rule id", example = "highTemperatureAlarmID") private String id; @Length(fieldName = "alarm type") @NoXss - @ApiModelProperty(position = 2, value = "String value representing type of the alarm", example = "High Temperature Alarm") + @Schema(description = "String value representing type of the alarm", example = "High Temperature Alarm") private String alarmType; @Valid - @ApiModelProperty(position = 3, value = "Complex JSON object representing create alarm rules. The unique create alarm rule can be created for each alarm severity type. " + + @Schema(description = "Complex JSON object representing create alarm rules. The unique create alarm rule can be created for each alarm severity type. " + "There can be 5 create alarm rules configured per a single alarm type. See method implementation notes and AlarmRule model for more details") private TreeMap createRules; @Valid - @ApiModelProperty(position = 4, value = "JSON object representing clear alarm rule") + @Schema(description = "JSON object representing clear alarm rule") private AlarmRule clearRule; // Hidden in advanced settings - @ApiModelProperty(position = 5, value = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") private boolean propagate; - @ApiModelProperty(position = 6, value = "Propagation flag to specify if alarm should be propagated to the owner (tenant or customer) of alarm originator", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to the owner (tenant or customer) of alarm originator", example = "true") private boolean propagateToOwner; - @ApiModelProperty(position = 7, value = "Propagation flag to specify if alarm should be propagated to the tenant entity", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to the tenant entity", example = "true") private boolean propagateToTenant; - @ApiModelProperty(position = 8, value = "JSON array of relation types that should be used for propagation. " + + @Schema(description = "JSON array of relation types that should be used for propagation. " + "By default, 'propagateRelationTypes' array is empty which means that the alarm will be propagated based on any relation type to parent entities. " + "This parameter should be used only in case when 'propagate' parameter is set to true, otherwise, 'propagateRelationTypes' array will be ignored.") private List propagateRelationTypes; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java index f6b2de915b..e2e7a646ea 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java @@ -15,27 +15,26 @@ */ package org.thingsboard.server.common.data.device.profile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import jakarta.validation.Valid; import java.io.Serializable; import java.util.List; -@ApiModel +@Schema @Data public class DeviceProfileData implements Serializable { - @ApiModelProperty(position = 1, value = "JSON object of device profile configuration") + @Schema(description = "JSON object of device profile configuration") private DeviceProfileConfiguration configuration; @Valid - @ApiModelProperty(position = 2, value = "JSON object of device profile transport configuration") + @Schema(description = "JSON object of device profile transport configuration") private DeviceProfileTransportConfiguration transportConfiguration; - @ApiModelProperty(position = 3, value = "JSON object of provisioning strategy type per device profile") + @Schema(description = "JSON object of provisioning strategy type per device profile") private DeviceProfileProvisionConfiguration provisionConfiguration; @Valid - @ApiModelProperty(position = 4, value = "JSON array of alarm rules configuration per device profile") + @Schema(description = "JSON array of alarm rules configuration per device profile") private List alarms; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java index 4405115905..b59c5fadea 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java @@ -15,56 +15,55 @@ */ package org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serializable; -@ApiModel +@Schema @Data public class LwM2MServerSecurityConfig implements Serializable { - @ApiModelProperty(position = 1, value = "Server short Id. Used as link to associate server Object Instance. This identifier uniquely identifies each LwM2M Server configured for the LwM2M Client. " + + @Schema(description = "Server short Id. Used as link to associate server Object Instance. This identifier uniquely identifies each LwM2M Server configured for the LwM2M Client. " + "This Resource MUST be set when the Bootstrap-Server Resource has a value of 'false'. " + - "The values ID:0 and ID:65535 values MUST NOT be used for identifying the LwM2M Server.", example = "123", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + "The values ID:0 and ID:65535 values MUST NOT be used for identifying the LwM2M Server.", example = "123", accessMode = Schema.AccessMode.READ_ONLY) protected Integer shortServerId = 123; /** Security -> ObjectId = 0 'LWM2M Security' */ - @ApiModelProperty(position = 2, value = "Is Bootstrap Server or Lwm2m Server. " + + @Schema(description = "Is Bootstrap Server or Lwm2m Server. " + "The LwM2M Client MAY be configured to use one or more LwM2M Server Account(s). " + "The LwM2M Client MUST have at most one LwM2M Bootstrap-Server Account. " + - "(*) The LwM2M client MUST have at least one LwM2M server account after completing the boot sequence specified.", example = "true or false", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + "(*) The LwM2M client MUST have at least one LwM2M server account after completing the boot sequence specified.", example = "true or false", accessMode = Schema.AccessMode.READ_ONLY) protected boolean bootstrapServerIs = false; - @ApiModelProperty(position = 3, value = "Host for 'No Security' mode", example = "0.0.0.0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Host for 'No Security' mode", example = "0.0.0.0", accessMode = Schema.AccessMode.READ_ONLY) protected String host; - @ApiModelProperty(position = 4, value = "Port for Lwm2m Server: 'No Security' mode: Lwm2m Server or Bootstrap Server", example = "'5685' or '5687'", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Port for Lwm2m Server: 'No Security' mode: Lwm2m Server or Bootstrap Server", example = "'5685' or '5687'", accessMode = Schema.AccessMode.READ_ONLY) protected Integer port; - @ApiModelProperty(position = 7, value = "Client Hold Off Time. The number of seconds to wait before initiating a Client Initiated Bootstrap once the LwM2M Client has determined it should initiate this bootstrap mode. (This information is relevant for use with a Bootstrap-Server only.)", example = "1", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Client Hold Off Time. The number of seconds to wait before initiating a Client Initiated Bootstrap once the LwM2M Client has determined it should initiate this bootstrap mode. (This information is relevant for use with a Bootstrap-Server only.)", example = "1", accessMode = Schema.AccessMode.READ_ONLY) protected Integer clientHoldOffTime = 1; - @ApiModelProperty(position = 8, value = "Server Public Key for 'Security' mode (DTLS): RPK or X509. Format: base64 encoded", example = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAZ0pSaGKHk/GrDaUDnQZpeEdGwX7m3Ws+U/kiVat\n" + - "+44sgk3c8g0LotfMpLlZJPhPwJ6ipXV+O1r7IZUjBs3LNA==", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Server Public Key for 'Security' mode (DTLS): RPK or X509. Format: base64 encoded", example = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAZ0pSaGKHk/GrDaUDnQZpeEdGwX7m3Ws+U/kiVat\n" + + "+44sgk3c8g0LotfMpLlZJPhPwJ6ipXV+O1r7IZUjBs3LNA==", accessMode = Schema.AccessMode.READ_ONLY) protected String serverPublicKey; - @ApiModelProperty(position = 9, value = "Server Public Key for 'Security' mode (DTLS): X509. Format: base64 encoded", example = "MMIICODCCAd6gAwIBAgIUI88U1zowOdrxDK/dOV+36gJxI2MwCgYIKoZIzj0EAwIwejELMAkGA1UEBhMCVUs\n" + + @Schema(description = "Server Public Key for 'Security' mode (DTLS): X509. Format: base64 encoded", example = "MMIICODCCAd6gAwIBAgIUI88U1zowOdrxDK/dOV+36gJxI2MwCgYIKoZIzj0EAwIwejELMAkGA1UEBhMCVUs\n" + "xEjAQBgNVBAgTCUt5aXYgY2l0eTENMAsGA1UEBxMES3lpdjEUMBIGA1UEChMLVGhpbmdzYm9hcmQxFzAVBgNVBAsMDkRFVkVMT1BFUl9URVNUMRkwFwYDVQQDDBBpbnRlcm1lZGlhdGVfY2EwMB4XDTIyMDEwOTEzMDMwMFoXDTI3MDEwODEzMDMwMFowFDESMBAGA1UEAxM\n" + "JbG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUO3vBo/JTv0eooY7XHiKAIVDoWKFqtrU7C6q8AIKqpLcqhCdW+haFeBOH3PjY6EwaWkY04Bir4oanU0s7tz2uKOBpzCBpDAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/\n" + "BAIwADAdBgNVHQ4EFgQUEjc3Q4a0TxzP/3x3EV4fHxYUg0YwHwYDVR0jBBgwFoAUuSquGycMU6Q0SYNcbtSkSD3TfH0wLwYDVR0RBCgwJoIVbG9jYWxob3N0LmxvY2FsZG9tYWlugglsb2NhbGhvc3SCAiAtMAoGCCqGSM49BAMCA0gAMEUCIQD7dbZObyUaoDiNbX+9fUNp\n" + - "AWrD7N7XuJUwZ9FcN75R3gIgb2RNjDkHoyUyF1YajwkBk+7XmIXNClmizNJigj908mw=", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + "AWrD7N7XuJUwZ9FcN75R3gIgb2RNjDkHoyUyF1YajwkBk+7XmIXNClmizNJigj908mw=", accessMode = Schema.AccessMode.READ_ONLY) protected String serverCertificate; - @ApiModelProperty(position = 10, value = "Bootstrap Server Account Timeout (If the value is set to 0, or if this resource is not instantiated, the Bootstrap-Server Account lifetime is infinite.)", example = "0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Bootstrap Server Account Timeout (If the value is set to 0, or if this resource is not instantiated, the Bootstrap-Server Account lifetime is infinite.)", example = "0", accessMode = Schema.AccessMode.READ_ONLY) Integer bootstrapServerAccountTimeout = 0; /** Config -> ObjectId = 1 'LwM2M Server' */ - @ApiModelProperty(position = 11, value = "Specify the lifetime of the registration in seconds.", example = "300", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Specify the lifetime of the registration in seconds.", example = "300", accessMode = Schema.AccessMode.READ_ONLY) private Integer lifetime = 300; - @ApiModelProperty(position = 12, value = "The default value the LwM2M Client should use for the Minimum Period of an Observation in the absence of this parameter being included in an Observation. " + - "If this Resource doesn’t exist, the default value is 0.", example = "1", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "The default value the LwM2M Client should use for the Minimum Period of an Observation in the absence of this parameter being included in an Observation. " + + "If this Resource doesn’t exist, the default value is 0.", example = "1", accessMode = Schema.AccessMode.READ_ONLY) private Integer defaultMinPeriod = 1; /** ResourceID=6 'Notification Storing When Disabled or Offline' */ - @ApiModelProperty(position = 13, value = "If true, the LwM2M Client stores “Notify” operations to the LwM2M Server while the LwM2M Server account is disabled or the LwM2M Client is offline. After the LwM2M Server account is enabled or the LwM2M Client is online, the LwM2M Client reports the stored “Notify” operations to the Server. " + + @Schema(description = "If true, the LwM2M Client stores “Notify” operations to the LwM2M Server while the LwM2M Server account is disabled or the LwM2M Client is offline. After the LwM2M Server account is enabled or the LwM2M Client is online, the LwM2M Client reports the stored “Notify” operations to the Server. " + "If false, the LwM2M Client discards all the “Notify” operations or temporarily disables the Observe function while the LwM2M Server is disabled or the LwM2M Client is offline. " + - "The default value is true.", example = "true", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + "The default value is true.", example = "true", accessMode = Schema.AccessMode.READ_ONLY) private boolean notifIfDisabled = true; - @ApiModelProperty(position = 14, value = "This Resource defines the transport binding configured for the LwM2M Client. " + - "If the LwM2M Client supports the binding specified in this Resource, the LwM2M Client MUST use that transport for the Current Binding Mode.", example = "U", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "This Resource defines the transport binding configured for the LwM2M Client. " + + "If the LwM2M Client supports the binding specified in this Resource, the LwM2M Client MUST use that transport for the Current Binding Mode.", example = "U", accessMode = Schema.AccessMode.READ_ONLY) private String binding = "U"; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java index ce622322d9..ea3e5a8dce 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java @@ -15,15 +15,14 @@ */ package org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class LwM2MServerSecurityConfigDefault extends LwM2MServerSecurityConfig { - @ApiModelProperty(position = 5, value = "Host for 'Security' mode (DTLS)", example = "0.0.0.0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Host for 'Security' mode (DTLS)", example = "0.0.0.0", accessMode = Schema.AccessMode.READ_ONLY) protected String securityHost; - @ApiModelProperty(position = 6, value = "Port for 'Security' mode (DTLS): Lwm2m Server or Bootstrap Server", example = "5686 or 5688", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Port for 'Security' mode (DTLS): Lwm2m Server or Bootstrap Server", example = "5686 or 5688", accessMode = Schema.AccessMode.READ_ONLY) protected Integer securityPort; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/Edge.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/Edge.java index 6d1d9390ba..169f4007f0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edge/Edge.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/Edge.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.edge; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.Setter; import lombok.ToString; @@ -31,7 +30,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @EqualsAndHashCode(callSuper = true) @ToString @Setter @@ -89,7 +88,7 @@ public class Edge extends BaseDataWithAdditionalInfo implements HasLabel this.secret = edge.getSecret(); } - @ApiModelProperty(position = 1, value = "JSON object with the Edge Id. " + + @Schema(description = "JSON object with the Edge Id. " + "Specify this field to update the Edge. " + "Referencing non-existing Edge Id will cause error. " + "Omit this field to create new Edge." ) @@ -98,51 +97,51 @@ public class Edge extends BaseDataWithAdditionalInfo implements HasLabel return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the edge creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the edge creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Use 'assignDeviceToTenant' to change the Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id. Use 'assignDeviceToTenant' to change the Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) @Override public TenantId getTenantId() { return this.tenantId; } - @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignEdgeToCustomer' to change the Customer Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Customer Id. Use 'assignEdgeToCustomer' to change the Customer Id.", accessMode = Schema.AccessMode.READ_ONLY) @Override public CustomerId getCustomerId() { return this.customerId; } - @ApiModelProperty(position = 5, value = "JSON object with Root Rule Chain Id. Use 'setEdgeRootRuleChain' to change the Root Rule Chain Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Root Rule Chain Id. Use 'setEdgeRootRuleChain' to change the Root Rule Chain Id.", accessMode = Schema.AccessMode.READ_ONLY) public RuleChainId getRootRuleChainId() { return this.rootRuleChainId; } - @ApiModelProperty(position = 6, required = true, value = "Unique Edge Name in scope of Tenant", example = "Silo_A_Edge") + @Schema(required = true, description = "Unique Edge Name in scope of Tenant", example = "Silo_A_Edge") @Override public String getName() { return this.name; } - @ApiModelProperty(position = 7, required = true, value = "Edge type", example = "Silos") + @Schema(required = true, description = "Edge type", example = "Silos") public String getType() { return this.type; } - @ApiModelProperty(position = 8, value = "Label that may be used in widgets", example = "Silo Edge on far field") + @Schema(description = "Label that may be used in widgets", example = "Silo Edge on far field") public String getLabel() { return this.label; } - @ApiModelProperty(position = 9, required = true, value = "Edge routing key ('username') to authorize on cloud") + @Schema(required = true, description = "Edge routing key ('username') to authorize on cloud") public String getRoutingKey() { return this.routingKey; } - @ApiModelProperty(position = 10, required = true, value = "Edge secret ('password') to authorize on cloud") + @Schema(required = true, description = "Edge secret ('password') to authorize on cloud") public String getSecret() { return this.secret; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInstallInstructions.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInstallInstructions.java index acfc458906..92a893c973 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInstallInstructions.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInstallInstructions.java @@ -15,18 +15,17 @@ */ package org.thingsboard.server.common.data.edge; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@ApiModel +@Schema @Data @AllArgsConstructor @NoArgsConstructor public class EdgeInstallInstructions { - @ApiModelProperty(position = 1, value = "Markdown with docker install instructions") + @Schema(description = "Markdown with docker install instructions") private String dockerInstallInstructions; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeSearchQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeSearchQuery.java index cf029ba793..575e4cbba0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeSearchQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeSearchQuery.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.edge; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.relation.EntityRelation; @@ -29,11 +29,11 @@ import java.util.List; @Data public class EdgeSearchQuery { - @ApiModelProperty(position = 3, value = "Main search parameters.") + @Schema(description = "Main search parameters.") private RelationsSearchParameters parameters; - @ApiModelProperty(position = 1, value = "Type of the relation between root entity and edge (e.g. 'Contains' or 'Manages').") + @Schema(description = "Type of the relation between root entity and edge (e.g. 'Contains' or 'Manages').") private String relationType; - @ApiModelProperty(position = 2, value = "Array of edge types to filter the related entities (e.g. 'Silos', 'Stores').") + @Schema(description = "Array of edge types to filter the related entities (e.g. 'Silos', 'Stores').") private List edgeTypes; public EntityRelationsQuery toEntitySearchQuery() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/entityview/EntityViewSearchQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/entityview/EntityViewSearchQuery.java index c840d828fa..de77d3bb76 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/entityview/EntityViewSearchQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/entityview/EntityViewSearchQuery.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.entityview; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.relation.EntityRelation; @@ -27,15 +26,15 @@ import org.thingsboard.server.common.data.relation.RelationsSearchParameters; import java.util.Collections; import java.util.List; -@ApiModel +@Schema @Data public class EntityViewSearchQuery { - @ApiModelProperty(position = 3, value = "Main search parameters.") + @Schema(description = "Main search parameters.") private RelationsSearchParameters parameters; - @ApiModelProperty(position = 1, value = "Type of the relation between root entity and device (e.g. 'Contains' or 'Manages').") + @Schema(description = "Type of the relation between root entity and device (e.g. 'Contains' or 'Manages').") private String relationType; - @ApiModelProperty(position = 2, value = "Array of entity view types to filter the related entities (e.g. 'Temperature Sensor', 'Smoke Sensor').") + @Schema(description = "Array of entity view types to filter the related entities (e.g. 'Temperature Sensor', 'Smoke Sensor').") private List entityViewTypes; public EntityRelationsQuery toEntitySearchQuery() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugEventFilter.java index c6773838a7..14507abae7 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugEventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugEventFilter.java @@ -15,20 +15,19 @@ */ package org.thingsboard.server.common.data.event; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.StringUtils; @Data -@ApiModel +@Schema public abstract class DebugEventFilter implements EventFilter { - @ApiModelProperty(position = 1, value = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") + @Schema(description = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") protected String server; - @ApiModelProperty(position = 10, value = "Boolean value to filter the errors", allowableValues = "false, true") + @Schema(description = "Boolean value to filter the errors", allowableValues = "false, true") protected boolean isError; - @ApiModelProperty(position = 11, value = "The case insensitive 'contains' filter based on error message", example = "not present in the DB") + @Schema(description = "The case insensitive 'contains' filter based on error message", example = "not present in the DB") protected String errorStr; public void setIsError(boolean isError) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEventFilter.java index e20cd0dfa9..951965ee72 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEventFilter.java @@ -15,20 +15,19 @@ */ package org.thingsboard.server.common.data.event; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.StringUtils; @Data -@ApiModel +@Schema public class ErrorEventFilter implements EventFilter { - @ApiModelProperty(position = 1, value = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") + @Schema(description = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") protected String server; - @ApiModelProperty(position = 2, value = "String value representing the method name when the error happened", example = "onClusterEventMsg") + @Schema(description = "String value representing the method name when the error happened", example = "onClusterEventMsg") protected String method; - @ApiModelProperty(position = 3, value = "The case insensitive 'contains' filter based on error message", example = "not present in the DB") + @Schema(description = "The case insensitive 'contains' filter based on error message", example = "not present in the DB") protected String errorStr; @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/EventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/EventFilter.java index 7a520e212f..af4a283ef7 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/EventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/EventFilter.java @@ -17,10 +17,9 @@ package org.thingsboard.server.common.data.event; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; -@ApiModel +@Schema @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, @@ -34,7 +33,7 @@ import io.swagger.annotations.ApiModelProperty; }) public interface EventFilter { - @ApiModelProperty(position = 1, required = true, value = "String value representing the event type", example = "STATS") + @Schema(required = true, description = "String value representing the event type", example = "STATS") EventType getEventType(); boolean isNotEmpty(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/LifeCycleEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/LifeCycleEventFilter.java index 659a16a135..3d193a5064 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/LifeCycleEventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/LifeCycleEventFilter.java @@ -15,22 +15,21 @@ */ package org.thingsboard.server.common.data.event; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.StringUtils; @Data -@ApiModel +@Schema public class LifeCycleEventFilter implements EventFilter { - @ApiModelProperty(position = 1, value = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") + @Schema(description = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") protected String server; - @ApiModelProperty(position = 2, value = "String value representing the lifecycle event type", example = "STARTED") + @Schema(description = "String value representing the lifecycle event type", example = "STARTED") protected String event; - @ApiModelProperty(position = 3, value = "String value representing status of the lifecycle event", allowableValues = "Success, Failure") + @Schema(description = "String value representing status of the lifecycle event", allowableValues = "Success, Failure") protected String status; - @ApiModelProperty(position = 4, value = "The case insensitive 'contains' filter based on error message", example = "not present in the DB") + @Schema(description = "The case insensitive 'contains' filter based on error message", example = "not present in the DB") protected String errorStr; @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEventFilter.java index 29e31cf0c8..7f00c26579 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEventFilter.java @@ -15,18 +15,17 @@ */ package org.thingsboard.server.common.data.event; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.StringUtils; @Data @EqualsAndHashCode(callSuper = true) -@ApiModel +@Schema public class RuleChainDebugEventFilter extends DebugEventFilter { - @ApiModelProperty(position = 2, value = "String value representing the message") + @Schema(description = "String value representing the message") protected String message; @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEventFilter.java index 589a70106e..b9cdfe8d37 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEventFilter.java @@ -15,32 +15,31 @@ */ package org.thingsboard.server.common.data.event; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.StringUtils; @Data @EqualsAndHashCode(callSuper = true) -@ApiModel +@Schema public class RuleNodeDebugEventFilter extends DebugEventFilter { - @ApiModelProperty(position = 2, value = "String value representing msg direction type (incoming to entity or outcoming from entity)", allowableValues = "IN, OUT") + @Schema(description = "String value representing msg direction type (incoming to entity or outcoming from entity)", allowableValues = "IN, OUT") protected String msgDirectionType; - @ApiModelProperty(position = 3, value = "String value representing the entity id in the event body (originator of the message)", example = "de9d54a0-2b7a-11ec-a3cc-23386423d98f") + @Schema(description = "String value representing the entity id in the event body (originator of the message)", example = "de9d54a0-2b7a-11ec-a3cc-23386423d98f") protected String entityId; - @ApiModelProperty(position = 4, value = "String value representing the entity type", allowableValues = "DEVICE") + @Schema(description = "String value representing the entity type", allowableValues = "DEVICE") protected String entityType; - @ApiModelProperty(position = 5, value = "String value representing the message id in the rule engine", example = "de9d54a0-2b7a-11ec-a3cc-23386423d98f") + @Schema(description = "String value representing the message id in the rule engine", example = "de9d54a0-2b7a-11ec-a3cc-23386423d98f") protected String msgId; - @ApiModelProperty(position = 6, value = "String value representing the message type", example = "POST_TELEMETRY_REQUEST") + @Schema(description = "String value representing the message type", example = "POST_TELEMETRY_REQUEST") protected String msgType; - @ApiModelProperty(position = 7, value = "String value representing the type of message routing", example = "Success") + @Schema(description = "String value representing the type of message routing", example = "Success") protected String relationType; - @ApiModelProperty(position = 8, value = "The case insensitive 'contains' filter based on data (key and value) for the message.", example = "humidity") + @Schema(description = "The case insensitive 'contains' filter based on data (key and value) for the message.", example = "humidity") protected String dataSearch; - @ApiModelProperty(position = 9, value = "The case insensitive 'contains' filter based on metadata (key and value) for the message.", example = "deviceName") + @Schema(description = "The case insensitive 'contains' filter based on metadata (key and value) for the message.", example = "deviceName") protected String metadataSearch; @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEventFilter.java index 15ac1c9c90..24485dd297 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEventFilter.java @@ -15,24 +15,23 @@ */ package org.thingsboard.server.common.data.event; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.StringUtils; @Data -@ApiModel +@Schema public class StatisticsEventFilter implements EventFilter { - @ApiModelProperty(position = 1, value = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") + @Schema(description = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") protected String server; - @ApiModelProperty(position = 2, value = "The minimum number of successfully processed messages", example = "25") + @Schema(description = "The minimum number of successfully processed messages", example = "25") protected Integer minMessagesProcessed; - @ApiModelProperty(position = 3, value = "The maximum number of successfully processed messages", example = "250") + @Schema(description = "The maximum number of successfully processed messages", example = "250") protected Integer maxMessagesProcessed; - @ApiModelProperty(position = 4, value = "The minimum number of errors occurred during messages processing", example = "30") + @Schema(description = "The minimum number of errors occurred during messages processing", example = "30") protected Integer minErrorsOccurred; - @ApiModelProperty(position = 5, value = "The maximum number of errors occurred during messages processing", example = "300") + @Schema(description = "The maximum number of errors occurred during messages processing", example = "300") protected Integer maxErrorsOccurred; @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/AlarmCommentId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/AlarmCommentId.java index 1cccaa4147..fdd8902127 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/AlarmCommentId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/AlarmCommentId.java @@ -17,11 +17,11 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import java.util.UUID; -@ApiModel +@Schema public class AlarmCommentId extends UUIDBased { private static final long serialVersionUID = 1L; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/AlarmId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/AlarmId.java index 74e61ce9f3..be60f8f329 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/AlarmId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/AlarmId.java @@ -17,13 +17,12 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; -@ApiModel +@Schema public class AlarmId extends UUIDBased implements EntityId { private static final long serialVersionUID = 1L; @@ -37,7 +36,7 @@ public class AlarmId extends UUIDBased implements EntityId { return new AlarmId(UUID.fromString(alarmId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "ALARM", allowableValues = "ALARM") + @Schema(required = true, description = "string", example = "ALARM", allowableValues = "ALARM") @Override public EntityType getEntityType() { return EntityType.ALARM; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/ApiUsageStateId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/ApiUsageStateId.java index 50e24a0f22..0cdf879eac 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/ApiUsageStateId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/ApiUsageStateId.java @@ -17,13 +17,12 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; -@ApiModel +@Schema public class ApiUsageStateId extends UUIDBased implements EntityId { @JsonCreator @@ -35,7 +34,7 @@ public class ApiUsageStateId extends UUIDBased implements EntityId { return new ApiUsageStateId(UUID.fromString(userId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "API_USAGE_STATE", allowableValues = "API_USAGE_STATE") + @Schema(required = true, description = "string", example = "API_USAGE_STATE", allowableValues = "API_USAGE_STATE") @Override public EntityType getEntityType() { return EntityType.API_USAGE_STATE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/AssetId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/AssetId.java index 593c305a07..01fdc7680b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/AssetId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/AssetId.java @@ -17,13 +17,12 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; -@ApiModel +@Schema public class AssetId extends UUIDBased implements EntityId { private static final long serialVersionUID = 1L; @@ -37,7 +36,7 @@ public class AssetId extends UUIDBased implements EntityId { return new AssetId(UUID.fromString(assetId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "ASSET", allowableValues = "ASSET") + @Schema(required = true, description = "string", example = "ASSET", allowableValues = "ASSET") @Override public EntityType getEntityType() { return EntityType.ASSET; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/AssetProfileId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/AssetProfileId.java index 5de08e53e5..7fbf28c4d3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/AssetProfileId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/AssetProfileId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -35,7 +35,7 @@ public class AssetProfileId extends UUIDBased implements EntityId { return new AssetProfileId(UUID.fromString(assetProfileId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "ASSET_PROFILE", allowableValues = "ASSET_PROFILE") + @Schema(required = true, description = "string", example = "ASSET_PROFILE", allowableValues = "ASSET_PROFILE") @Override public EntityType getEntityType() { return EntityType.ASSET_PROFILE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/CustomerId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/CustomerId.java index beaa331ecf..dccd89b73b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/CustomerId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/CustomerId.java @@ -17,13 +17,12 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; -@ApiModel +@Schema public final class CustomerId extends UUIDBased implements EntityId { private static final long serialVersionUID = 1L; @@ -33,7 +32,7 @@ public final class CustomerId extends UUIDBased implements EntityId { super(id); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "CUSTOMER", allowableValues = "CUSTOMER") + @Schema(required = true, description = "string", example = "CUSTOMER", allowableValues = "CUSTOMER") @Override public EntityType getEntityType() { return EntityType.CUSTOMER; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/DashboardId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/DashboardId.java index 740a801651..3af27d5457 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/DashboardId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/DashboardId.java @@ -17,13 +17,12 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; -@ApiModel +@Schema public class DashboardId extends UUIDBased implements EntityId { @JsonCreator @@ -35,7 +34,7 @@ public class DashboardId extends UUIDBased implements EntityId { return new DashboardId(UUID.fromString(dashboardId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "DASHBOARD", allowableValues = "DASHBOARD") + @Schema(required = true, description = "string", example = "DASHBOARD", allowableValues = "DASHBOARD") @Override public EntityType getEntityType() { return EntityType.DASHBOARD; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/DeviceId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/DeviceId.java index e39c5805ce..25c1fb6be4 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/DeviceId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/DeviceId.java @@ -17,13 +17,12 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; -@ApiModel +@Schema public class DeviceId extends UUIDBased implements EntityId { private static final long serialVersionUID = 1L; @@ -38,7 +37,7 @@ public class DeviceId extends UUIDBased implements EntityId { } @Override - @ApiModelProperty(position = 2, required = true, value = "string", example = "DEVICE", allowableValues = "DEVICE") + @Schema(required = true, description = "string", example = "DEVICE", allowableValues = "DEVICE") public EntityType getEntityType() { return EntityType.DEVICE; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/DeviceProfileId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/DeviceProfileId.java index 26bc6d2b96..25c22ce8c1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/DeviceProfileId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/DeviceProfileId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -35,7 +35,7 @@ public class DeviceProfileId extends UUIDBased implements EntityId { return new DeviceProfileId(UUID.fromString(deviceProfileId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "DEVICE_PROFILE", allowableValues = "DEVICE_PROFILE") + @Schema(required = true, description = "string", example = "DEVICE_PROFILE", allowableValues = "DEVICE_PROFILE") @Override public EntityType getEntityType() { return EntityType.DEVICE_PROFILE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/EdgeId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/EdgeId.java index fb96f15740..b5a6632b44 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/EdgeId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/EdgeId.java @@ -18,7 +18,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ConcurrentReferenceHashMap.ReferenceType; import org.thingsboard.server.common.data.EntityType; @@ -41,7 +41,7 @@ public class EdgeId extends UUIDBased implements EntityId { return new EdgeId(UUID.fromString(edgeId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "EDGE", allowableValues = "EDGE") + @Schema(required = true, description = "string", example = "EDGE", allowableValues = "EDGE") @Override public EntityType getEntityType() { return EntityType.EDGE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityId.java index 3f112e92ed..a6addb1d11 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityId.java @@ -18,8 +18,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.io.Serializable; @@ -31,15 +30,15 @@ import java.util.UUID; @JsonDeserialize(using = EntityIdDeserializer.class) @JsonSerialize(using = EntityIdSerializer.class) -@ApiModel +@Schema public interface EntityId extends HasUUID, Serializable { //NOSONAR, the constant is closely related to EntityId UUID NULL_UUID = UUID.fromString("13814000-1dd2-11b2-8080-808080808080"); - @ApiModelProperty(position = 1, required = true, value = "ID of the entity, time-based UUID v1", example = "784f394c-42b6-435a-983c-b7beff2784f9") + @Schema(required = true, description = "ID of the entity, time-based UUID v1", example = "784f394c-42b6-435a-983c-b7beff2784f9") UUID getId(); - @ApiModelProperty(position = 2, required = true, example = "DEVICE") + @Schema(required = true, example = "DEVICE") EntityType getEntityType(); @JsonIgnore diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityViewId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityViewId.java index 9cf7e83fa3..0a57acb813 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityViewId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityViewId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -38,7 +38,7 @@ public class EntityViewId extends UUIDBased implements EntityId { return new EntityViewId(UUID.fromString(entityViewID)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "ENTITY_VIEW", allowableValues = "ENTITY_VIEW") + @Schema(required = true, description = "string", example = "ENTITY_VIEW", allowableValues = "ENTITY_VIEW") @Override public EntityType getEntityType() { return EntityType.ENTITY_VIEW; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/OtaPackageId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/OtaPackageId.java index 8977da637b..2799ecfdab 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/OtaPackageId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/OtaPackageId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -35,7 +35,7 @@ public class OtaPackageId extends UUIDBased implements EntityId { return new OtaPackageId(UUID.fromString(firmwareId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "OTA_PACKAGE", allowableValues = "OTA_PACKAGE") + @Schema(required = true, description = "string", example = "OTA_PACKAGE", allowableValues = "OTA_PACKAGE") @Override public EntityType getEntityType() { return EntityType.OTA_PACKAGE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/RpcId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/RpcId.java index 7a3045c8a8..4f640303b9 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/RpcId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/RpcId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -31,7 +31,7 @@ public final class RpcId extends UUIDBased implements EntityId { super(id); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "RPC", allowableValues = "RPC") + @Schema(required = true, description = "string", example = "RPC", allowableValues = "RPC") @Override public EntityType getEntityType() { return EntityType.RPC; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleChainId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleChainId.java index cb3e2ca334..a4e4b9019c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleChainId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleChainId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -29,7 +29,7 @@ public class RuleChainId extends UUIDBased implements EntityId { super(id); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "RULE_CHAIN", allowableValues = "RULE_CHAIN") + @Schema(required = true, description = "string", example = "RULE_CHAIN", allowableValues = "RULE_CHAIN") @Override public EntityType getEntityType() { return EntityType.RULE_CHAIN; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleNodeId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleNodeId.java index db410dfea2..a4fc103ada 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleNodeId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleNodeId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -29,7 +29,7 @@ public class RuleNodeId extends UUIDBased implements EntityId { super(id); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "RULE_NODE", allowableValues = "RULE_NODE") + @Schema(required = true, description = "string", example = "RULE_NODE", allowableValues = "RULE_NODE") @Override public EntityType getEntityType() { return EntityType.RULE_NODE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/TbResourceId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/TbResourceId.java index e2716b0f43..eb1ce5cd13 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/TbResourceId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/TbResourceId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -31,7 +31,7 @@ public class TbResourceId extends UUIDBased implements EntityId { super(id); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "TB_RESOURCE", allowableValues = "TB_RESOURCE") + @Schema(required = true, description = "string", example = "TB_RESOURCE", allowableValues = "TB_RESOURCE") @Override public EntityType getEntityType() { return EntityType.TB_RESOURCE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/TenantId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/TenantId.java index 6f5fb09927..9a4264ca60 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/TenantId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/TenantId.java @@ -18,7 +18,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ConcurrentReferenceHashMap.ReferenceType; import org.thingsboard.server.common.data.EntityType; @@ -50,7 +50,7 @@ public final class TenantId extends UUIDBased implements EntityId { return this.equals(SYS_TENANT_ID); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "TENANT", allowableValues = "TENANT") + @Schema(required = true, description = "string", example = "TENANT", allowableValues = "TENANT") @Override public EntityType getEntityType() { return EntityType.TENANT; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/TenantProfileId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/TenantProfileId.java index f1e67a9435..e73d94df9f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/TenantProfileId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/TenantProfileId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -35,7 +35,7 @@ public class TenantProfileId extends UUIDBased implements EntityId { return new TenantProfileId(UUID.fromString(tenantProfileId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "TENANT_PROFILE", allowableValues = "TENANT_PROFILE") + @Schema(required = true, description = "string", example = "TENANT_PROFILE", allowableValues = "TENANT_PROFILE") @Override public EntityType getEntityType() { return EntityType.TENANT_PROFILE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/UUIDBased.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/UUIDBased.java index b234ee5961..5b52bd0af9 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/UUIDBased.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/UUIDBased.java @@ -15,13 +15,12 @@ */ package org.thingsboard.server.common.data.id; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; import java.util.UUID; -@ApiModel +@Schema public abstract class UUIDBased implements HasUUID, Serializable { private static final long serialVersionUID = 1L; @@ -37,7 +36,7 @@ public abstract class UUIDBased implements HasUUID, Serializable { this.id = id; } - @ApiModelProperty(position = 1, required = true, value = "string", example = "784f394c-42b6-435a-983c-b7beff2784f9") + @Schema(required = true, description = "string", example = "784f394c-42b6-435a-983c-b7beff2784f9") public UUID getId() { return id; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/UserId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/UserId.java index 999e762a12..4053ada987 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/UserId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/UserId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -33,7 +33,7 @@ public class UserId extends UUIDBased implements EntityId { return new UserId(UUID.fromString(userId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "USER", allowableValues = "USER") + @Schema(required = true, description = "string", example = "USER", allowableValues = "USER") @Override public EntityType getEntityType() { return EntityType.USER; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetTypeId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetTypeId.java index ff5fe2b62f..3dfef42d57 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetTypeId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetTypeId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -31,7 +31,7 @@ public final class WidgetTypeId extends UUIDBased implements EntityId { super(id); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "WIDGET_TYPE", allowableValues = "WIDGET_TYPE") + @Schema(required = true, description = "string", example = "WIDGET_TYPE", allowableValues = "WIDGET_TYPE") @Override public EntityType getEntityType() { return EntityType.WIDGET_TYPE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetsBundleId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetsBundleId.java index b6e6d2cc00..46509c1fe4 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetsBundleId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetsBundleId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -31,7 +31,7 @@ public final class WidgetsBundleId extends UUIDBased implements EntityId { super(id); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "WIDGETS_BUNDLE", allowableValues = "WIDGETS_BUNDLE") + @Schema(required = true, description = "string", example = "WIDGETS_BUNDLE", allowableValues = "WIDGETS_BUNDLE") @Override public EntityType getEntityType() { return EntityType.WIDGETS_BUNDLE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mInstance.java b/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mInstance.java index 382dca5415..7614501c56 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mInstance.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mInstance.java @@ -15,16 +15,15 @@ */ package org.thingsboard.server.common.data.lwm2m; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class LwM2mInstance { - @ApiModelProperty(position = 1, value = "LwM2M Instance id.", example = "0") + @Schema(description = "LwM2M Instance id.", example = "0") int id; - @ApiModelProperty(position = 2, value = "LwM2M Resource observe.") + @Schema(description = "LwM2M Resource observe.") LwM2mResourceObserve[] resources; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mObject.java b/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mObject.java index 18de593227..44165bccd1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mObject.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mObject.java @@ -15,23 +15,22 @@ */ package org.thingsboard.server.common.data.lwm2m; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class LwM2mObject { - @ApiModelProperty(position = 1, value = "LwM2M Object id.", example = "19") + @Schema(description = "LwM2M Object id.", example = "19") int id; - @ApiModelProperty(position = 2, value = "LwM2M Object key id.", example = "19_1.0") + @Schema(description = "LwM2M Object key id.", example = "19_1.0") String keyId; - @ApiModelProperty(position = 3, value = "LwM2M Object name.", example = "BinaryAppDataContainer") + @Schema(description = "LwM2M Object name.", example = "BinaryAppDataContainer") String name; - @ApiModelProperty(position = 4, value = "LwM2M Object multiple.", example = "true") + @Schema(description = "LwM2M Object multiple.", example = "true") boolean multiple; - @ApiModelProperty(position = 5, value = "LwM2M Object mandatory.", example = "false") + @Schema(description = "LwM2M Object mandatory.", example = "false") boolean mandatory; - @ApiModelProperty(position = 6, value = "LwM2M Object instances.") + @Schema(description = "LwM2M Object instances.") LwM2mInstance [] instances; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mResourceObserve.java b/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mResourceObserve.java index a40f422ad0..611d3ca66a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mResourceObserve.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mResourceObserve.java @@ -15,28 +15,27 @@ */ package org.thingsboard.server.common.data.lwm2m; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import java.util.stream.Stream; -@ApiModel +@Schema @Data @AllArgsConstructor public class LwM2mResourceObserve { - @ApiModelProperty(position = 1, value = "LwM2M Resource Observe id.", example = "0") + @Schema(description = "LwM2M Resource Observe id.", example = "0") int id; - @ApiModelProperty(position = 2, value = "LwM2M Resource Observe name.", example = "Data") + @Schema(description = "LwM2M Resource Observe name.", example = "Data") String name; - @ApiModelProperty(position = 3, value = "LwM2M Resource Observe observe.", example = "false") + @Schema(description = "LwM2M Resource Observe observe.", example = "false") boolean observe; - @ApiModelProperty(position = 4, value = "LwM2M Resource Observe attribute.", example = "false") + @Schema(description = "LwM2M Resource Observe attribute.", example = "false") boolean attribute; - @ApiModelProperty(position = 5, value = "LwM2M Resource Observe telemetry.", example = "false") + @Schema(description = "LwM2M Resource Observe telemetry.", example = "false") boolean telemetry; - @ApiModelProperty(position = 6, value = "LwM2M Resource Observe key name.", example = "data") + @Schema(description = "LwM2M Resource Observe key name.", example = "data") String keyName; public LwM2mResourceObserve(int id, String name, boolean observe, boolean attribute, boolean telemetry) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2BasicMapperConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2BasicMapperConfig.java index ba86a5781c..96ab5ccbed 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2BasicMapperConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2BasicMapperConfig.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.oauth2; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; @@ -27,31 +26,31 @@ import org.thingsboard.server.common.data.validation.Length; @EqualsAndHashCode @Data @ToString -@ApiModel +@Schema public class OAuth2BasicMapperConfig { @Length(fieldName = "emailAttributeKey", max = 31) - @ApiModelProperty(value = "Email attribute key of OAuth2 principal attributes. " + + @Schema(description = "Email attribute key of OAuth2 principal attributes. " + "Must be specified for BASIC mapper type and cannot be specified for GITHUB type") private final String emailAttributeKey; @Length(fieldName = "firstNameAttributeKey", max = 31) - @ApiModelProperty(value = "First name attribute key") + @Schema(description = "First name attribute key") private final String firstNameAttributeKey; @Length(fieldName = "lastNameAttributeKey", max = 31) - @ApiModelProperty(value = "Last name attribute key") + @Schema(description = "Last name attribute key") private final String lastNameAttributeKey; - @ApiModelProperty(value = "Tenant naming strategy. For DOMAIN type, domain for tenant name will be taken from the email (substring before '@')", required = true) + @Schema(description = "Tenant naming strategy. For DOMAIN type, domain for tenant name will be taken from the email (substring before '@')", required = true) private final TenantNameStrategyType tenantNameStrategy; @Length(fieldName = "tenantNamePattern") - @ApiModelProperty(value = "Tenant name pattern for CUSTOM naming strategy. " + + @Schema(description = "Tenant name pattern for CUSTOM naming strategy. " + "OAuth2 attributes in the pattern can be used by enclosing attribute key in '%{' and '}'", example = "%{email}") private final String tenantNamePattern; @Length(fieldName = "customerNamePattern") - @ApiModelProperty(value = "Customer name pattern. When creating a user on the first OAuth2 log in, if specified, " + + @Schema(description = "Customer name pattern. When creating a user on the first OAuth2 log in, if specified, " + "customer name will be used to create or find existing customer in the platform and assign customerId to the user") private final String customerNamePattern; @Length(fieldName = "defaultDashboardName") - @ApiModelProperty(value = "Name of the tenant's dashboard to set as default dashboard for newly created user") + @Schema(description = "Name of the tenant's dashboard to set as default dashboard for newly created user") private final String defaultDashboardName; - @ApiModelProperty(value = "Whether default dashboard should be open in full screen") + @Schema(description = "Whether default dashboard should be open in full screen") private final boolean alwaysFullScreen; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientInfo.java index c7770cca0f..be8d2c9d54 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientInfo.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.oauth2; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -26,14 +25,14 @@ import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor -@ApiModel +@Schema public class OAuth2ClientInfo { - @ApiModelProperty(value = "OAuth2 client name", example = "GitHub") + @Schema(description = "OAuth2 client name", example = "GitHub") private String name; - @ApiModelProperty(value = "Name of the icon, displayed on OAuth2 log in button", example = "github-logo") + @Schema(description = "Name of the icon, displayed on OAuth2 log in button", example = "github-logo") private String icon; - @ApiModelProperty(value = "URI for OAuth2 log in. On HTTP GET request to this URI, it redirects to the OAuth2 provider page", + @Schema(description = "URI for OAuth2 log in. On HTTP GET request to this URI, it redirects to the OAuth2 provider page", example = "/oauth2/authorization/8352f191-2b4d-11ec-9ed1-cbf57c026ecc") private String url; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientRegistrationTemplate.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientRegistrationTemplate.java index 57945bf93e..cf56547e4d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientRegistrationTemplate.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientRegistrationTemplate.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.oauth2; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -33,45 +32,45 @@ import java.util.List; @Data @ToString @NoArgsConstructor -@ApiModel +@Schema public class OAuth2ClientRegistrationTemplate extends BaseDataWithAdditionalInfo implements HasName { @Length(fieldName = "providerId") - @ApiModelProperty(value = "OAuth2 provider identifier (e.g. its name)", required = true) + @Schema(description = "OAuth2 provider identifier (e.g. its name)", required = true) private String providerId; @Valid - @ApiModelProperty(value = "Default config for mapping OAuth2 log in response to platform entities") + @Schema(description = "Default config for mapping OAuth2 log in response to platform entities") private OAuth2MapperConfig mapperConfig; @Length(fieldName = "authorizationUri") - @ApiModelProperty(value = "Default authorization URI of the OAuth2 provider") + @Schema(description = "Default authorization URI of the OAuth2 provider") private String authorizationUri; @Length(fieldName = "accessTokenUri") - @ApiModelProperty(value = "Default access token URI of the OAuth2 provider") + @Schema(description = "Default access token URI of the OAuth2 provider") private String accessTokenUri; - @ApiModelProperty(value = "Default OAuth scopes that will be requested from OAuth2 platform") + @Schema(description = "Default OAuth scopes that will be requested from OAuth2 platform") private List scope; @Length(fieldName = "userInfoUri") - @ApiModelProperty(value = "Default user info URI of the OAuth2 provider") + @Schema(description = "Default user info URI of the OAuth2 provider") private String userInfoUri; @Length(fieldName = "userNameAttributeName") - @ApiModelProperty(value = "Default name of the username attribute in OAuth2 provider log in response") + @Schema(description = "Default name of the username attribute in OAuth2 provider log in response") private String userNameAttributeName; @Length(fieldName = "jwkSetUri") - @ApiModelProperty(value = "Default JSON Web Key URI of the OAuth2 provider") + @Schema(description = "Default JSON Web Key URI of the OAuth2 provider") private String jwkSetUri; @Length(fieldName = "clientAuthenticationMethod") - @ApiModelProperty(value = "Default client authentication method to use: 'BASIC' or 'POST'") + @Schema(description = "Default client authentication method to use: 'BASIC' or 'POST'") private String clientAuthenticationMethod; - @ApiModelProperty(value = "Comment for OAuth2 provider") + @Schema(description = "Comment for OAuth2 provider") private String comment; @Length(fieldName = "loginButtonIcon") - @ApiModelProperty(value = "Default log in button icon for OAuth2 provider") + @Schema(description = "Default log in button icon for OAuth2 provider") private String loginButtonIcon; @Length(fieldName = "loginButtonLabel") - @ApiModelProperty(value = "Default OAuth2 provider label") + @Schema(description = "Default OAuth2 provider label") private String loginButtonLabel; @Length(fieldName = "helpLink") - @ApiModelProperty(value = "Help link for OAuth2 provider") + @Schema(description = "Help link for OAuth2 provider") private String helpLink; public OAuth2ClientRegistrationTemplate(OAuth2ClientRegistrationTemplate clientRegistrationTemplate) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2DomainInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2DomainInfo.java index 06a175b441..71108ef137 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2DomainInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2DomainInfo.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.oauth2; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -30,10 +29,10 @@ import lombok.ToString; @NoArgsConstructor @AllArgsConstructor @Builder -@ApiModel +@Schema public class OAuth2DomainInfo { - @ApiModelProperty(value = "Domain scheme. Mixed scheme means than both HTTP and HTTPS are going to be used", required = true) + @Schema(description = "Domain scheme. Mixed scheme means than both HTTP and HTTPS are going to be used", required = true) private SchemeType scheme; - @ApiModelProperty(value = "Domain name. Cannot be empty", required = true) + @Schema(description = "Domain name. Cannot be empty", required = true) private String name; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2Info.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2Info.java index 30531c3241..5c292ef23e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2Info.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2Info.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.oauth2; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -32,10 +31,10 @@ import java.util.List; @Builder(toBuilder = true) @NoArgsConstructor @AllArgsConstructor -@ApiModel +@Schema public class OAuth2Info { - @ApiModelProperty("Whether OAuth2 settings are enabled or not") + @Schema(description = "Whether OAuth2 settings are enabled or not") private boolean enabled; - @ApiModelProperty(value = "List of configured OAuth2 clients. Cannot contain null values", required = true) + @Schema(description = "List of configured OAuth2 clients. Cannot contain null values", required = true) private List oauth2ParamsInfos; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MapperConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MapperConfig.java index 89c8bcaa07..0896734d84 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MapperConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MapperConfig.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.oauth2; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; @@ -28,16 +28,16 @@ import jakarta.validation.Valid; @Data @ToString public class OAuth2MapperConfig { - @ApiModelProperty(value = "Whether user should be created if not yet present on the platform after successful authentication") + @Schema(description = "Whether user should be created if not yet present on the platform after successful authentication") private boolean allowUserCreation; - @ApiModelProperty(value = "Whether user credentials should be activated when user is created after successful authentication") + @Schema(description = "Whether user credentials should be activated when user is created after successful authentication") private boolean activateUser; - @ApiModelProperty(value = "Type of OAuth2 mapper. Depending on this param, different mapper config fields must be specified", required = true) + @Schema(description = "Type of OAuth2 mapper. Depending on this param, different mapper config fields must be specified", required = true) private MapperType type; @Valid - @ApiModelProperty(value = "Mapper config for BASIC and GITHUB mapper types") + @Schema(description = "Mapper config for BASIC and GITHUB mapper types") private OAuth2BasicMapperConfig basic; @Valid - @ApiModelProperty(value = "Mapper config for CUSTOM mapper type") + @Schema(description = "Mapper config for CUSTOM mapper type") private OAuth2CustomMapperConfig custom; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MobileInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MobileInfo.java index 2f6717adfc..f8999fa44b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MobileInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MobileInfo.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.oauth2; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -30,10 +29,10 @@ import lombok.ToString; @NoArgsConstructor @AllArgsConstructor @Builder -@ApiModel +@Schema public class OAuth2MobileInfo { - @ApiModelProperty(value = "Application package name. Cannot be empty", required = true) + @Schema(description = "Application package name. Cannot be empty", required = true) private String pkgName; - @ApiModelProperty(value = "Application secret. The length must be at least 16 characters", required = true) + @Schema(description = "Application secret. The length must be at least 16 characters", required = true) private String appSecret; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ParamsInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ParamsInfo.java index 8dcb827d71..9e34a5e598 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ParamsInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ParamsInfo.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.oauth2; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -32,16 +31,16 @@ import java.util.List; @Builder(toBuilder = true) @NoArgsConstructor @AllArgsConstructor -@ApiModel +@Schema public class OAuth2ParamsInfo { - @ApiModelProperty(value = "List of configured domains where OAuth2 platform will redirect a user after successful " + + @Schema(description = "List of configured domains where OAuth2 platform will redirect a user after successful " + "authentication. Cannot be empty. There have to be only one domain with specific name with scheme type 'MIXED'. " + "Configured domains with the same name must have different scheme types", required = true) private List domainInfos; - @ApiModelProperty(value = "Mobile applications settings. Application package name must be unique within the list", required = true) + @Schema(description = "Mobile applications settings. Application package name must be unique within the list", required = true) private List mobileInfos; - @ApiModelProperty(value = "List of OAuth2 provider settings. Cannot be empty", required = true) + @Schema(description = "List of OAuth2 provider settings. Cannot be empty", required = true) private List clientRegistrations; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2RegistrationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2RegistrationInfo.java index e212585efb..3ccbb72bdb 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2RegistrationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2RegistrationInfo.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data.oauth2; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -33,34 +32,34 @@ import java.util.List; @NoArgsConstructor @AllArgsConstructor @Builder -@ApiModel +@Schema public class OAuth2RegistrationInfo { - @ApiModelProperty(value = "Config for mapping OAuth2 log in response to platform entities", required = true) + @Schema(description = "Config for mapping OAuth2 log in response to platform entities", required = true) private OAuth2MapperConfig mapperConfig; - @ApiModelProperty(value = "OAuth2 client ID. Cannot be empty", required = true) + @Schema(description = "OAuth2 client ID. Cannot be empty", required = true) private String clientId; - @ApiModelProperty(value = "OAuth2 client secret. Cannot be empty", required = true) + @Schema(description = "OAuth2 client secret. Cannot be empty", required = true) private String clientSecret; - @ApiModelProperty(value = "Authorization URI of the OAuth2 provider. Cannot be empty", required = true) + @Schema(description = "Authorization URI of the OAuth2 provider. Cannot be empty", required = true) private String authorizationUri; - @ApiModelProperty(value = "Access token URI of the OAuth2 provider. Cannot be empty", required = true) + @Schema(description = "Access token URI of the OAuth2 provider. Cannot be empty", required = true) private String accessTokenUri; - @ApiModelProperty(value = "OAuth scopes that will be requested from OAuth2 platform. Cannot be empty", required = true) + @Schema(description = "OAuth scopes that will be requested from OAuth2 platform. Cannot be empty", required = true) private List scope; - @ApiModelProperty(value = "User info URI of the OAuth2 provider") + @Schema(description = "User info URI of the OAuth2 provider") private String userInfoUri; - @ApiModelProperty(value = "Name of the username attribute in OAuth2 provider response. Cannot be empty") + @Schema(description = "Name of the username attribute in OAuth2 provider response. Cannot be empty") private String userNameAttributeName; - @ApiModelProperty(value = "JSON Web Key URI of the OAuth2 provider") + @Schema(description = "JSON Web Key URI of the OAuth2 provider") private String jwkSetUri; - @ApiModelProperty(value = "Client authentication method to use: 'BASIC' or 'POST'. Cannot be empty", required = true) + @Schema(description = "Client authentication method to use: 'BASIC' or 'POST'. Cannot be empty", required = true) private String clientAuthenticationMethod; - @ApiModelProperty(value = "OAuth2 provider label. Cannot be empty", required = true) + @Schema(description = "OAuth2 provider label. Cannot be empty", required = true) private String loginButtonLabel; - @ApiModelProperty(value = "Log in button icon for OAuth2 provider") + @Schema(description = "Log in button icon for OAuth2 provider") private String loginButtonIcon; - @ApiModelProperty(value = "List of platforms for which usage of the OAuth2 client is allowed (empty for all allowed)") + @Schema(description = "List of platforms for which usage of the OAuth2 client is allowed (empty for all allowed)") private List platforms; - @ApiModelProperty(value = "Additional info of OAuth2 client (e.g. providerName)", required = true) + @Schema(description = "Additional info of OAuth2 client (e.g. providerName)", required = true) private JsonNode additionalInfo; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/objects/AttributesEntityView.java b/common/data/src/main/java/org/thingsboard/server/common/data/objects/AttributesEntityView.java index 44f9ab0a2f..b2e71bf947 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/objects/AttributesEntityView.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/objects/AttributesEntityView.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.objects; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.NoArgsConstructor; @@ -28,15 +27,15 @@ import java.util.List; * Created by Victor Basanets on 9/05/2017. */ @Data -@ApiModel +@Schema @NoArgsConstructor public class AttributesEntityView implements Serializable { - @ApiModelProperty(position = 1, required = true, value = "List of client-side attribute keys to expose", example = "currentConfiguration") + @Schema(required = true, description = "List of client-side attribute keys to expose", example = "currentConfiguration") private List cs = new ArrayList<>(); - @ApiModelProperty(position = 3, required = true, value = "List of server-side attribute keys to expose", example = "model") + @Schema(required = true, description = "List of server-side attribute keys to expose", example = "model") private List ss = new ArrayList<>(); - @ApiModelProperty(position = 2, required = true, value = "List of shared attribute keys to expose", example = "targetConfiguration") + @Schema(required = true, description = "List of shared attribute keys to expose", example = "targetConfiguration") private List sh = new ArrayList<>(); public AttributesEntityView(List cs, diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/objects/TelemetryEntityView.java b/common/data/src/main/java/org/thingsboard/server/common/data/objects/TelemetryEntityView.java index 2dd115138e..ad538128b7 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/objects/TelemetryEntityView.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/objects/TelemetryEntityView.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.objects; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.NoArgsConstructor; @@ -27,14 +26,14 @@ import java.util.List; /** * Created by Victor Basanets on 9/05/2017. */ -@ApiModel +@Schema @Data @NoArgsConstructor public class TelemetryEntityView implements Serializable { - @ApiModelProperty(position = 1, required = true, value = "List of time-series data keys to expose", example = "temperature, humidity") + @Schema(required = true, description = "List of time-series data keys to expose", example = "temperature, humidity") private List timeseries; - @ApiModelProperty(position = 2, required = true, value = "JSON object with attributes to expose") + @Schema(required = true, description = "JSON object with attributes to expose") private AttributesEntityView attributes; public TelemetryEntityView(List timeseries, AttributesEntityView attributes) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageData.java b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageData.java index 2ae94a0064..4f510ebb2b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageData.java @@ -17,15 +17,14 @@ package org.thingsboard.server.common.data.page; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import java.util.Collections; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; -@ApiModel +@Schema public class PageData { private final List data; @@ -48,22 +47,22 @@ public class PageData { this.hasNext = hasNext; } - @ApiModelProperty(position = 1, value = "Array of the entities", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Array of the entities", accessMode = Schema.AccessMode.READ_ONLY) public List getData() { return data; } - @ApiModelProperty(position = 2, value = "Total number of available pages. Calculated based on the 'pageSize' request parameter and total number of entities that match search criteria", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Total number of available pages. Calculated based on the 'pageSize' request parameter and total number of entities that match search criteria", accessMode = Schema.AccessMode.READ_ONLY) public int getTotalPages() { return totalPages; } - @ApiModelProperty(position = 3, value = "Total number of elements in all available pages", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Total number of elements in all available pages", accessMode = Schema.AccessMode.READ_ONLY) public long getTotalElements() { return totalElements; } - @ApiModelProperty(position = 4, value = "'false' value indicates the end of the result set", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "'false' value indicates the end of the result set", accessMode = Schema.AccessMode.READ_ONLY) @JsonProperty("hasNext") public boolean hasNext() { return hasNext; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java index 1c186f2697..3387f85e6f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data.plugin; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -29,27 +28,27 @@ import org.thingsboard.server.common.data.validation.Length; /** * @author Andrew Shvayka */ -@ApiModel +@Schema @ToString public class ComponentDescriptor extends BaseData { private static final long serialVersionUID = 1L; - @ApiModelProperty(position = 3, value = "Type of the Rule Node", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Type of the Rule Node", accessMode = Schema.AccessMode.READ_ONLY) @Getter @Setter private ComponentType type; - @ApiModelProperty(position = 4, value = "Scope of the Rule Node. Always set to 'TENANT', since no rule chains on the 'SYSTEM' level yet.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, allowableValues = "TENANT", example = "TENANT") + @Schema(description = "Scope of the Rule Node. Always set to 'TENANT', since no rule chains on the 'SYSTEM' level yet.", accessMode = Schema.AccessMode.READ_ONLY, allowableValues = "TENANT", example = "TENANT") @Getter @Setter private ComponentScope scope; - @ApiModelProperty(position = 5, value = "Clustering mode of the RuleNode. This mode represents the ability to start Rule Node in multiple microservices.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, allowableValues = "USER_PREFERENCE, ENABLED, SINGLETON", example = "ENABLED") + @Schema(description = "Clustering mode of the RuleNode. This mode represents the ability to start Rule Node in multiple microservices.", accessMode = Schema.AccessMode.READ_ONLY, allowableValues = "USER_PREFERENCE, ENABLED, SINGLETON", example = "ENABLED") @Getter @Setter private ComponentClusteringMode clusteringMode; @Length(fieldName = "name") - @ApiModelProperty(position = 6, value = "Name of the Rule Node. Taken from the @RuleNode annotation.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "Custom Rule Node") + @Schema(description = "Name of the Rule Node. Taken from the @RuleNode annotation.", accessMode = Schema.AccessMode.READ_ONLY, example = "Custom Rule Node") @Getter @Setter private String name; - @ApiModelProperty(position = 7, value = "Full name of the Java class that implements the Rule Engine Node interface.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "com.mycompany.CustomRuleNode") + @Schema(description = "Full name of the Java class that implements the Rule Engine Node interface.", accessMode = Schema.AccessMode.READ_ONLY, example = "com.mycompany.CustomRuleNode") @Getter @Setter private String clazz; - @ApiModelProperty(position = 8, value = "Complex JSON object that represents the Rule Node configuration.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Complex JSON object that represents the Rule Node configuration.", accessMode = Schema.AccessMode.READ_ONLY) @Getter @Setter private transient JsonNode configurationDescriptor; @Length(fieldName = "actions") - @ApiModelProperty(position = 9, value = "Rule Node Actions. Deprecated. Always null.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Rule Node Actions. Deprecated. Always null.", accessMode = Schema.AccessMode.READ_ONLY) @Getter @Setter private String actions; public ComponentDescriptor() { @@ -70,7 +69,7 @@ public class ComponentDescriptor extends BaseData { this.actions = plugin.getActions(); } - @ApiModelProperty(position = 1, value = "JSON object with the descriptor Id. " + + @Schema(description = "JSON object with the descriptor Id. " + "Specify existing descriptor id to update the descriptor. " + "Referencing non-existing descriptor Id will cause error. " + "Omit this field to create new descriptor." ) @@ -79,7 +78,7 @@ public class ComponentDescriptor extends BaseData { return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the descriptor creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the descriptor creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityCountQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityCountQuery.java index 2665abe7e9..e85cbc2fb8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityCountQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityCountQuery.java @@ -15,14 +15,14 @@ */ package org.thingsboard.server.common.data.query; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.ToString; import java.util.Collections; import java.util.List; -@ApiModel +@Schema @ToString public class EntityCountQuery { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityKey.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityKey.java index f5362dd824..76d90087fe 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityKey.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityKey.java @@ -15,12 +15,12 @@ */ package org.thingsboard.server.common.data.query; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serializable; -@ApiModel +@Schema @Data public class EntityKey implements Serializable { private static final long serialVersionUID = -6421575477523085543L; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilter.java index ad5d42e31d..c8999cce2b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilter.java @@ -15,12 +15,12 @@ */ package org.thingsboard.server.common.data.query; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serializable; -@ApiModel +@Schema @Data public class KeyFilter implements Serializable { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelation.java b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelation.java index fa2d52f3f4..ecde8d82dc 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelation.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelation.java @@ -17,8 +17,7 @@ package org.thingsboard.server.common.data.relation; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.BaseDataWithAdditionalInfo; import org.thingsboard.server.common.data.id.EntityId; @@ -27,7 +26,7 @@ import org.thingsboard.server.common.data.validation.Length; import java.io.Serializable; @Slf4j -@ApiModel +@Schema public class EntityRelation implements Serializable { private static final long serialVersionUID = 2807343040519543363L; @@ -73,7 +72,7 @@ public class EntityRelation implements Serializable { this.additionalInfo = entityRelation.getAdditionalInfo(); } - @ApiModelProperty(position = 1, value = "JSON object with [from] Entity Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with [from] Entity Id.", accessMode = Schema.AccessMode.READ_ONLY) public EntityId getFrom() { return from; } @@ -82,7 +81,7 @@ public class EntityRelation implements Serializable { this.from = from; } - @ApiModelProperty(position = 2, value = "JSON object with [to] Entity Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with [to] Entity Id.", accessMode = Schema.AccessMode.READ_ONLY) public EntityId getTo() { return to; } @@ -91,7 +90,7 @@ public class EntityRelation implements Serializable { this.to = to; } - @ApiModelProperty(position = 3, value = "String value of relation type.", example = "Contains") + @Schema(description = "String value of relation type.", example = "Contains") public String getType() { return type; } @@ -100,7 +99,7 @@ public class EntityRelation implements Serializable { this.type = type; } - @ApiModelProperty(position = 4, value = "Represents the type group of the relation.", example = "COMMON") + @Schema(description = "Represents the type group of the relation.", example = "COMMON") public RelationTypeGroup getTypeGroup() { return typeGroup; } @@ -109,7 +108,7 @@ public class EntityRelation implements Serializable { this.typeGroup = typeGroup; } - @ApiModelProperty(position = 5, value = "Additional parameters of the relation", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Additional parameters of the relation",implementation = com.fasterxml.jackson.databind.JsonNode.class) public JsonNode getAdditionalInfo() { return BaseDataWithAdditionalInfo.getJson(() -> additionalInfo, () -> additionalInfoBytes); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationInfo.java index 44acbb6a5f..364d40b062 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationInfo.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.relation; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; public class EntityRelationInfo extends EntityRelation { @@ -32,7 +32,7 @@ public class EntityRelationInfo extends EntityRelation { super(entityRelation); } - @ApiModelProperty(position = 6, value = "Name of the entity for [from] direction.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "A4B72CCDFF33") + @Schema(description = "Name of the entity for [from] direction.", accessMode = Schema.AccessMode.READ_ONLY, example = "A4B72CCDFF33") public String getFromName() { return fromName; } @@ -41,7 +41,7 @@ public class EntityRelationInfo extends EntityRelation { this.fromName = fromName; } - @ApiModelProperty(position = 7, value = "Name of the entity for [to] direction.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "A4B72CCDFF35") + @Schema(description = "Name of the entity for [to] direction.", accessMode = Schema.AccessMode.READ_ONLY, example = "A4B72CCDFF35") public String getToName() { return toName; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationsQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationsQuery.java index b3f052d59e..cefd2fa4f4 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationsQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationsQuery.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.relation; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.List; @@ -25,12 +24,12 @@ import java.util.List; * Created by ashvayka on 02.05.17. */ @Data -@ApiModel +@Schema public class EntityRelationsQuery { - @ApiModelProperty(position = 2, value = "Main search parameters.") + @Schema(description = "Main search parameters.") private RelationsSearchParameters parameters; - @ApiModelProperty(position = 1, value = "Main filters.") + @Schema(description = "Main filters.") private List filters; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationEntityTypeFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationEntityTypeFilter.java index 80ff4fe874..b8e5e94a19 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationEntityTypeFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationEntityTypeFilter.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.relation; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import org.thingsboard.server.common.data.EntityType; @@ -28,12 +27,12 @@ import java.util.List; */ @Data @AllArgsConstructor -@ApiModel +@Schema public class RelationEntityTypeFilter { - @ApiModelProperty(position = 1, value = "Type of the relation between root entity and other entity (e.g. 'Contains' or 'Manages').", example = "Contains") + @Schema(description = "Type of the relation between root entity and other entity (e.g. 'Contains' or 'Manages').", example = "Contains") private String relationType; - @ApiModelProperty(position = 2, value = "Array of entity types to filter the related entities (e.g. 'DEVICE', 'ASSET').") + @Schema(description = "Array of entity types to filter the related entities (e.g. 'DEVICE', 'ASSET').") private List entityTypes; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java b/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java index 23a3a6407c..cfc338ff55 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data.relation; import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import org.thingsboard.server.common.data.EntityType; @@ -29,22 +28,22 @@ import java.util.UUID; /** * Created by ashvayka on 03.05.17. */ -@ApiModel +@Schema @Data @AllArgsConstructor public class RelationsSearchParameters { - @ApiModelProperty(position = 1, value = "Root entity id to start search from.", example = "784f394c-42b6-435a-983c-b7beff2784f9") + @Schema(description = "Root entity id to start search from.", example = "784f394c-42b6-435a-983c-b7beff2784f9") private UUID rootId; - @ApiModelProperty(position = 2, value = "Type of the root entity.") + @Schema(description = "Type of the root entity.") private EntityType rootType; - @ApiModelProperty(position = 3, value = "Type of the root entity.") + @Schema(description = "Type of the root entity.") private EntitySearchDirection direction; - @ApiModelProperty(position = 4, value = "Type of the relation.") + @Schema(description = "Type of the relation.") private RelationTypeGroup relationTypeGroup; - @ApiModelProperty(position = 5, value = "Maximum level of the search depth.") + @Schema(description = "Maximum level of the search depth.") private int maxLevel = 1; - @ApiModelProperty(position = 6, value = "Fetch entities that match the last level of search. Useful to find Devices that are strictly 'maxLevel' relations away from the root entity.") + @Schema(description = "Fetch entities that match the last level of search. Useful to find Devices that are strictly 'maxLevel' relations away from the root entity.") private boolean fetchLastLevelOnly; public RelationsSearchParameters(EntityId entityId, EntitySearchDirection direction, int maxLevel, boolean fetchLastLevelOnly) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rpc/Rpc.java b/common/data/src/main/java/org/thingsboard/server/common/data/rpc/Rpc.java index 154a725761..d764a1fe0b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rpc/Rpc.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rpc/Rpc.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data.rpc; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseData; @@ -26,24 +25,24 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.RpcId; import org.thingsboard.server.common.data.id.TenantId; -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) public class Rpc extends BaseData implements HasTenantId { - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; - @ApiModelProperty(position = 4, value = "JSON object with Device Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Device Id.", accessMode = Schema.AccessMode.READ_ONLY) private DeviceId deviceId; - @ApiModelProperty(position = 5, value = "Expiration time of the request.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Expiration time of the request.", accessMode = Schema.AccessMode.READ_ONLY) private long expirationTime; - @ApiModelProperty(position = 6, value = "The request body that will be used to send message to device.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "The request body that will be used to send message to device.", accessMode = Schema.AccessMode.READ_ONLY) private JsonNode request; - @ApiModelProperty(position = 7, value = "The response from the device.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "The response from the device.", accessMode = Schema.AccessMode.READ_ONLY) private JsonNode response; - @ApiModelProperty(position = 8, value = "The current status of the RPC call.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "The current status of the RPC call.", accessMode = Schema.AccessMode.READ_ONLY) private RpcStatus status; - @ApiModelProperty(position = 9, value = "Additional info used in the rule engine to process the updates to the RPC state.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Additional info used in the rule engine to process the updates to the RPC state.", accessMode = Schema.AccessMode.READ_ONLY) private JsonNode additionalInfo; public Rpc() { @@ -65,13 +64,13 @@ public class Rpc extends BaseData implements HasTenantId { this.additionalInfo = rpc.getAdditionalInfo(); } - @ApiModelProperty(position = 1, value = "JSON object with the rpc Id. Referencing non-existing rpc Id will cause error.") + @Schema(description = "JSON object with the rpc Id. Referencing non-existing rpc Id will cause error.") @Override public RpcId getId() { return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the rpc creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the rpc creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/DefaultRuleChainCreateRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/DefaultRuleChainCreateRequest.java index 0df8b4e03a..3ab6912824 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/DefaultRuleChainCreateRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/DefaultRuleChainCreateRequest.java @@ -15,21 +15,20 @@ */ package org.thingsboard.server.common.data.rule; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.io.Serializable; -@ApiModel +@Schema @Data @Slf4j public class DefaultRuleChainCreateRequest implements Serializable { private static final long serialVersionUID = 5600333716030561537L; - @ApiModelProperty(position = 1, required = true, value = "Name of the new rule chain", example = "Root Rule Chain") + @Schema(required = true, description = "Name of the new rule chain", example = "Root Rule Chain") private String name; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/NodeConnectionInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/NodeConnectionInfo.java index 4bccbf6366..febf3e29f0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/NodeConnectionInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/NodeConnectionInfo.java @@ -15,20 +15,19 @@ */ package org.thingsboard.server.common.data.rule; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; /** * Created by ashvayka on 21.03.18. */ -@ApiModel +@Schema @Data public class NodeConnectionInfo { - @ApiModelProperty(position = 1, required = true, value = "Index of rule node in the 'nodes' array of the RuleChainMetaData. Indicates the 'from' part of the connection.") + @Schema(required = true, description = "Index of rule node in the 'nodes' array of the RuleChainMetaData. Indicates the 'from' part of the connection.") private int fromIndex; - @ApiModelProperty(position = 2, required = true, value = "Index of rule node in the 'nodes' array of the RuleChainMetaData. Indicates the 'to' part of the connection.") + @Schema(required = true, description = "Index of rule node in the 'nodes' array of the RuleChainMetaData. Indicates the 'to' part of the connection.") private int toIndex; - @ApiModelProperty(position = 3, required = true, value = "Type of the relation. Typically indicated the result of processing by the 'from' rule node. For example, 'Success' or 'Failure'") + @Schema(required = true, description = "Type of the relation. Typically indicated the result of processing by the 'from' rule node. For example, 'Success' or 'Failure'") private String type; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java index edb70cefda..9d4099755e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java @@ -17,8 +17,7 @@ package org.thingsboard.server.common.data.rule; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; @@ -32,7 +31,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) @Slf4j @@ -40,21 +39,21 @@ public class RuleChain extends BaseDataWithAdditionalInfo implement private static final long serialVersionUID = -5656679015121935465L; - @ApiModelProperty(position = 3, required = true, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "name") - @ApiModelProperty(position = 4, required = true, value = "Rule Chain name", example = "Humidity data processing") + @Schema(required = true, description = "Rule Chain name", example = "Humidity data processing") private String name; - @ApiModelProperty(position = 5, value = "Rule Chain type. 'EDGE' rule chains are processing messages on the edge devices only.", example = "A4B72CCDFF33") + @Schema(description = "Rule Chain type. 'EDGE' rule chains are processing messages on the edge devices only.", example = "A4B72CCDFF33") private RuleChainType type; - @ApiModelProperty(position = 6, value = "JSON object with Rule Chain Id. Pointer to the first rule node that should receive all messages pushed to this rule chain.") + @Schema(description = "JSON object with Rule Chain Id. Pointer to the first rule node that should receive all messages pushed to this rule chain.") private RuleNodeId firstRuleNodeId; - @ApiModelProperty(position = 7, value = "Indicates root rule chain. The root rule chain process messages from all devices and entities by default. User may configure default rule chain per device profile.") + @Schema(description = "Indicates root rule chain. The root rule chain process messages from all devices and entities by default. User may configure default rule chain per device profile.") private boolean root; - @ApiModelProperty(position = 8, value = "Reserved for future usage.") + @Schema(description = "Reserved for future usage.") private boolean debugMode; - @ApiModelProperty(position = 9, value = "Reserved for future usage. The actual list of rule nodes and their relations is stored in the database separately.") + @Schema(description = "Reserved for future usage. The actual list of rule nodes and their relations is stored in the database separately.") private transient JsonNode configuration; private RuleChainId externalId; @@ -86,7 +85,7 @@ public class RuleChain extends BaseDataWithAdditionalInfo implement return name; } - @ApiModelProperty(position = 1, value = "JSON object with the Rule Chain Id. " + + @Schema(description = "JSON object with the Rule Chain Id. " + "Specify this field to update the Rule Chain. " + "Referencing non-existing Rule Chain Id will cause error. " + "Omit this field to create new rule chain." ) @@ -95,7 +94,7 @@ public class RuleChain extends BaseDataWithAdditionalInfo implement return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the rule chain creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the rule chain creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainConnectionInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainConnectionInfo.java index edd22564f1..87a7dde0ca 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainConnectionInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainConnectionInfo.java @@ -16,23 +16,22 @@ package org.thingsboard.server.common.data.rule; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.RuleChainId; /** * Created by ashvayka on 21.03.18. */ -@ApiModel +@Schema @Data public class RuleChainConnectionInfo { - @ApiModelProperty(position = 1, required = true, value = "Index of rule node in the 'nodes' array of the RuleChainMetaData. Indicates the 'from' part of the connection.") + @Schema(required = true, description = "Index of rule node in the 'nodes' array of the RuleChainMetaData. Indicates the 'from' part of the connection.") private int fromIndex; - @ApiModelProperty(position = 2, required = true, value = "JSON object with the Rule Chain Id.") + @Schema(required = true, description = "JSON object with the Rule Chain Id.") private RuleChainId targetRuleChainId; - @ApiModelProperty(position = 3, required = true, value = "JSON object with the additional information about the connection.") + @Schema(required = true, description = "JSON object with the additional information about the connection.") private JsonNode additionalInfo; - @ApiModelProperty(position = 4, required = true, value = "Type of the relation. Typically indicated the result of processing by the 'from' rule node. For example, 'Success' or 'Failure'") + @Schema(required = true, description = "Type of the relation. Typically indicated the result of processing by the 'from' rule node. For example, 'Success' or 'Failure'") private String type; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainData.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainData.java index ee53811ce1..74aaaa2c12 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainData.java @@ -15,18 +15,17 @@ */ package org.thingsboard.server.common.data.rule; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.List; -@ApiModel +@Schema @Data public class RuleChainData { - @ApiModelProperty(position = 1, required = true, value = "List of the Rule Chain objects.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "List of the Rule Chain objects.", accessMode = Schema.AccessMode.READ_ONLY) List ruleChains; - @ApiModelProperty(position = 2, required = true, value = "List of the Rule Chain metadata objects.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "List of the Rule Chain metadata objects.", accessMode = Schema.AccessMode.READ_ONLY) List metadata; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainMetaData.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainMetaData.java index 6ebdeed1dc..79d2f75254 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainMetaData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainMetaData.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.rule; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.RuleChainId; @@ -26,23 +25,23 @@ import java.util.List; /** * Created by igor on 3/13/18. */ -@ApiModel +@Schema @Data public class RuleChainMetaData { - @ApiModelProperty(position = 1, required = true, value = "JSON object with Rule Chain Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "JSON object with Rule Chain Id.", accessMode = Schema.AccessMode.READ_ONLY) private RuleChainId ruleChainId; - @ApiModelProperty(position = 2, required = true, value = "Index of the first rule node in the 'nodes' list") + @Schema(required = true, description = "Index of the first rule node in the 'nodes' list") private Integer firstNodeIndex; - @ApiModelProperty(position = 3, required = true, value = "List of rule node JSON objects") + @Schema(required = true, description = "List of rule node JSON objects") private List nodes; - @ApiModelProperty(position = 4, required = true, value = "List of JSON objects that represent connections between rule nodes") + @Schema(required = true, description = "List of JSON objects that represent connections between rule nodes") private List connections; - @ApiModelProperty(position = 5, required = true, value = "List of JSON objects that represent connections between rule nodes and other rule chains.") + @Schema(required = true, description = "List of JSON objects that represent connections between rule nodes and other rule chains.") private List ruleChainConnections; public void addConnectionInfo(int fromIndex, int toIndex, String type) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainOutputLabelsUsage.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainOutputLabelsUsage.java index 7a2b2c5b8d..f148aaa9f4 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainOutputLabelsUsage.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainOutputLabelsUsage.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.rule; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.id.RuleChainId; @@ -24,21 +23,21 @@ import org.thingsboard.server.common.data.id.RuleNodeId; import java.util.Set; -@ApiModel +@Schema @Data @Slf4j public class RuleChainOutputLabelsUsage { - @ApiModelProperty(position = 1, required = true, value = "Rule Chain Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "Rule Chain Id", accessMode = Schema.AccessMode.READ_ONLY) private RuleChainId ruleChainId; - @ApiModelProperty(position = 2, required = true, value = "Rule Node Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "Rule Node Id", accessMode = Schema.AccessMode.READ_ONLY) private RuleNodeId ruleNodeId; - @ApiModelProperty(position = 3, required = true, value = "Rule Chain Name", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "Rule Chain Name", accessMode = Schema.AccessMode.READ_ONLY) private String ruleChainName; - @ApiModelProperty(position = 4, required = true, value = "Rule Node Name", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "Rule Node Name", accessMode = Schema.AccessMode.READ_ONLY) private String ruleNodeName; - @ApiModelProperty(position = 5, required = true, value = "Output labels", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "Output labels", accessMode = Schema.AccessMode.READ_ONLY) private Set labels; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java index 16a127e48a..1926bb8c3c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java @@ -17,8 +17,7 @@ package org.thingsboard.server.common.data.rule; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; @@ -29,7 +28,7 @@ import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) @Slf4j @@ -37,20 +36,20 @@ public class RuleNode extends BaseDataWithAdditionalInfo implements private static final long serialVersionUID = -5656679015121235465L; - @ApiModelProperty(position = 3, value = "JSON object with the Rule Chain Id. ", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with the Rule Chain Id. ", accessMode = Schema.AccessMode.READ_ONLY) private RuleChainId ruleChainId; @Length(fieldName = "type") - @ApiModelProperty(position = 4, value = "Full Java Class Name of the rule node implementation. ", example = "com.mycompany.iot.rule.engine.ProcessingNode") + @Schema(description = "Full Java Class Name of the rule node implementation. ", example = "com.mycompany.iot.rule.engine.ProcessingNode") private String type; @NoXss @Length(fieldName = "name") - @ApiModelProperty(position = 5, value = "User defined name of the rule node. Used on UI and for logging. ", example = "Process sensor reading") + @Schema(description = "User defined name of the rule node. Used on UI and for logging. ", example = "Process sensor reading") private String name; - @ApiModelProperty(position = 6, value = "Enable/disable debug. ", example = "false") + @Schema(description = "Enable/disable debug. ", example = "false") private boolean debugMode; - @ApiModelProperty(position = 7, value = "Enable/disable singleton mode. ", example = "false") + @Schema(description = "Enable/disable singleton mode. ", example = "false") private boolean singletonMode; - @ApiModelProperty(position = 8, value = "JSON with the rule node configuration. Structure depends on the rule node implementation.", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "JSON with the rule node configuration. Structure depends on the rule node implementation.",implementation = com.fasterxml.jackson.databind.JsonNode.class) private transient JsonNode configuration; @JsonIgnore private byte[] configurationBytes; @@ -89,7 +88,7 @@ public class RuleNode extends BaseDataWithAdditionalInfo implements setJson(data, json -> this.configuration = json, bytes -> this.configurationBytes = bytes); } - @ApiModelProperty(position = 1, value = "JSON object with the Rule Node Id. " + + @Schema(description = "JSON object with the Rule Node Id. " + "Specify this field to update the Rule Node. " + "Referencing non-existing Rule Node Id will cause error. " + "Omit this field to create new rule node." ) @@ -98,13 +97,13 @@ public class RuleNode extends BaseDataWithAdditionalInfo implements return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the rule node creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the rule node creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 8, value = "Additional parameters of the rule node. Contains 'layoutX' and 'layoutY' properties for visualization.", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Additional parameters of the rule node. Contains 'layoutX' and 'layoutY' properties for visualization.",implementation = com.fasterxml.jackson.databind.JsonNode.class) @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentials.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentials.java index e12aa43cbc..cdd5950fbb 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentials.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentials.java @@ -15,14 +15,13 @@ */ package org.thingsboard.server.common.data.security; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.id.DeviceCredentialsId; import org.thingsboard.server.common.data.id.DeviceId; -@ApiModel +@Schema @EqualsAndHashCode(callSuper = true) public class DeviceCredentials extends BaseData implements DeviceCredentialsFilter { @@ -48,7 +47,7 @@ public class DeviceCredentials extends BaseData implements this.credentialsValue = deviceCredentials.getCredentialsValue(); } - @ApiModelProperty(position = 1, required = true, accessMode = ApiModelProperty.AccessMode.READ_ONLY, value = "The Id is automatically generated during device creation. " + + @Schema(required = true, accessMode = Schema.AccessMode.READ_ONLY, description = "The Id is automatically generated during device creation. " + "Use 'getDeviceCredentialsByDeviceId' to obtain the id based on device id. " + "Use 'updateDeviceCredentials' to update device credentials. ", example = "784f394c-42b6-435a-983c-b7beff2784f9") @Override @@ -56,13 +55,13 @@ public class DeviceCredentials extends BaseData implements return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the device credentials creation, in milliseconds", example = "1609459200000") + @Schema(description = "Timestamp of the device credentials creation, in milliseconds", example = "1609459200000") @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, required = true, value = "JSON object with the device Id.") + @Schema(required = true, description = "JSON object with the device Id.") public DeviceId getDeviceId() { return deviceId; } @@ -71,7 +70,7 @@ public class DeviceCredentials extends BaseData implements this.deviceId = deviceId; } - @ApiModelProperty(position = 4, value = "Type of the credentials", allowableValues="ACCESS_TOKEN, X509_CERTIFICATE, MQTT_BASIC, LWM2M_CREDENTIALS") + @Schema(description = "Type of the credentials", allowableValues ="ACCESS_TOKEN, X509_CERTIFICATE, MQTT_BASIC, LWM2M_CREDENTIALS") @Override public DeviceCredentialsType getCredentialsType() { return credentialsType; @@ -81,7 +80,7 @@ public class DeviceCredentials extends BaseData implements this.credentialsType = credentialsType; } - @ApiModelProperty(position = 5, required = true, value = "Unique Credentials Id per platform instance. " + + @Schema(required = true, description = "Unique Credentials Id per platform instance. " + "Used to lookup credentials from the database. " + "By default, new access token for your device. " + "Depends on the type of the credentials." @@ -95,7 +94,7 @@ public class DeviceCredentials extends BaseData implements this.credentialsId = credentialsId; } - @ApiModelProperty(position = 6, value = "Value of the credentials. " + + @Schema(description = "Value of the credentials. " + "Null in case of ACCESS_TOKEN credentials type. Base64 value in case of X509_CERTIFICATE. " + "Complex object in case of MQTT_BASIC and LWM2M_CREDENTIALS", example = "Null in case of ACCESS_TOKEN. See model definition.") public String getCredentialsValue() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/JwtPair.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/JwtPair.java index 62f15499e3..af2962f314 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/JwtPair.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/JwtPair.java @@ -15,20 +15,19 @@ */ package org.thingsboard.server.common.data.security.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.security.Authority; -@ApiModel(value = "JWT Pair") +@Schema(description = "JWT Pair") @Data @NoArgsConstructor public class JwtPair { - @ApiModelProperty(position = 1, value = "The JWT Access Token. Used to perform API calls.", example = "AAB254FF67D..") + @Schema(description = "The JWT Access Token. Used to perform API calls.", example = "AAB254FF67D..") private String token; - @ApiModelProperty(position = 1, value = "The JWT Refresh Token. Used to get new JWT Access Token if old one has expired.", example = "AAB254FF67D..") + @Schema(description = "The JWT Refresh Token. Used to get new JWT Access Token if old one has expired.", example = "AAB254FF67D..") private String refreshToken; private Authority scope; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/JwtSettings.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/JwtSettings.java index 33bbca468b..53c0096a22 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/JwtSettings.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/JwtSettings.java @@ -15,13 +15,12 @@ */ package org.thingsboard.server.common.data.security.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@ApiModel(value = "JWT Settings") +@Schema(description = "JWT Settings") @AllArgsConstructor @NoArgsConstructor @Data @@ -30,26 +29,26 @@ public class JwtSettings { /** * {@link JwtToken} will expire after this time. */ - @ApiModelProperty(position = 1, value = "The JWT will expire after seconds.", example = "9000") + @Schema(description = "The JWT will expire after seconds.", example = "9000") private Integer tokenExpirationTime; /** * {@link JwtToken} can be refreshed during this timeframe. */ - @ApiModelProperty(position = 2, value = "The JWT can be refreshed during seconds.", example = "604800") + @Schema(description = "The JWT can be refreshed during seconds.", example = "604800") private Integer refreshTokenExpTime; /** * Token issuer. */ - @ApiModelProperty(position = 3, value = "The JWT issuer.", example = "thingsboard.io") + @Schema(description = "The JWT issuer.", example = "thingsboard.io") private String tokenIssuer; /** * Key is used to sign {@link JwtToken}. * Base64 encoded */ - @ApiModelProperty(position = 4, value = "The JWT key is used to sing token. Base64 encoded.", example = "cTU4WnNqemI2aU5wbWVjdm1vYXRzanhjNHRUcXliMjE=") + @Schema(description = "The JWT key is used to sing token. Base64 encoded.", example = "cTU4WnNqemI2aU5wbWVjdm1vYXRzanhjNHRUcXliMjE=") private String tokenSigningKey; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/SecuritySettings.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/SecuritySettings.java index 4c19b1fa5d..bdfbf975ad 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/SecuritySettings.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/SecuritySettings.java @@ -15,22 +15,21 @@ */ package org.thingsboard.server.common.data.security.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serializable; -@ApiModel +@Schema @Data public class SecuritySettings implements Serializable { private static final long serialVersionUID = -1307613974597312465L; - @ApiModelProperty(position = 1, value = "The user password policy object." ) + @Schema(description = "The user password policy object." ) private UserPasswordPolicy passwordPolicy; - @ApiModelProperty(position = 2, value = "Maximum number of failed login attempts allowed before user account is locked." ) + @Schema(description = "Maximum number of failed login attempts allowed before user account is locked." ) private Integer maxFailedLoginAttempts; - @ApiModelProperty(position = 3, value = "Email to use for notifications about locked users." ) + @Schema(description = "Email to use for notifications about locked users." ) private String userLockoutNotificationEmail; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/UserPasswordPolicy.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/UserPasswordPolicy.java index 881af89e27..d94183ba02 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/UserPasswordPolicy.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/UserPasswordPolicy.java @@ -15,32 +15,31 @@ */ package org.thingsboard.server.common.data.security.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serializable; -@ApiModel +@Schema @Data public class UserPasswordPolicy implements Serializable { - @ApiModelProperty(position = 1, value = "Minimum number of symbols in the password." ) + @Schema(description = "Minimum number of symbols in the password." ) private Integer minimumLength; - @ApiModelProperty(position = 1, value = "Minimum number of uppercase letters in the password." ) + @Schema(description = "Minimum number of uppercase letters in the password." ) private Integer minimumUppercaseLetters; - @ApiModelProperty(position = 1, value = "Minimum number of lowercase letters in the password." ) + @Schema(description = "Minimum number of lowercase letters in the password." ) private Integer minimumLowercaseLetters; - @ApiModelProperty(position = 1, value = "Minimum number of digits in the password." ) + @Schema(description = "Minimum number of digits in the password." ) private Integer minimumDigits; - @ApiModelProperty(position = 1, value = "Minimum number of special in the password." ) + @Schema(description = "Minimum number of special in the password." ) private Integer minimumSpecialCharacters; - @ApiModelProperty(position = 1, value = "Allow whitespaces") + @Schema(description = "Allow whitespaces") private Boolean allowWhitespaces = true; - @ApiModelProperty(position = 1, value = "Password expiration period (days). Force expiration of the password." ) + @Schema(description = "Password expiration period (days). Force expiration of the password." ) private Integer passwordExpirationPeriodDays; - @ApiModelProperty(position = 1, value = "Password reuse frequency (days). Disallow to use the same password for the defined number of days" ) + @Schema(description = "Password reuse frequency (days). Disallow to use the same password for the defined number of days" ) private Integer passwordReuseFrequencyDays; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/settings/AbstractUserDashboardInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/settings/AbstractUserDashboardInfo.java index ce214cb603..21ab795f1d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/settings/AbstractUserDashboardInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/settings/AbstractUserDashboardInfo.java @@ -15,23 +15,22 @@ */ package org.thingsboard.server.common.data.settings; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.HasTitle; import java.io.Serializable; import java.util.UUID; -@ApiModel +@Schema @Data public abstract class AbstractUserDashboardInfo implements HasTitle, Serializable { private static final long serialVersionUID = -6461562426034242608L; - @ApiModelProperty(position = 1, value = "JSON object with Dashboard id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Dashboard id.", accessMode = Schema.AccessMode.READ_ONLY) private UUID id; - @ApiModelProperty(position = 2, value = "Title of the dashboard.") + @Schema(description = "Title of the dashboard.") private String title; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/settings/LastVisitedDashboardInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/settings/LastVisitedDashboardInfo.java index e49910eb43..0085f059f0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/settings/LastVisitedDashboardInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/settings/LastVisitedDashboardInfo.java @@ -15,23 +15,22 @@ */ package org.thingsboard.server.common.data.settings; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import java.io.Serializable; @EqualsAndHashCode(callSuper = true) -@ApiModel +@Schema @Data public class LastVisitedDashboardInfo extends AbstractUserDashboardInfo implements Serializable { private static final long serialVersionUID = -6461562426034242608L; - @ApiModelProperty(position = 3, value = "Starred flag") + @Schema(description = "Starred flag") private boolean starred; - @ApiModelProperty(position = 4, value = "Last visit timestamp") + @Schema(description = "Last visit timestamp") private long lastVisited; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/settings/StarredDashboardInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/settings/StarredDashboardInfo.java index e71404c392..6fba8798e8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/settings/StarredDashboardInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/settings/StarredDashboardInfo.java @@ -15,20 +15,19 @@ */ package org.thingsboard.server.common.data.settings; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import java.io.Serializable; @EqualsAndHashCode(callSuper = true) -@ApiModel +@Schema @Data public class StarredDashboardInfo extends AbstractUserDashboardInfo implements Serializable { private static final long serialVersionUID = -7830828696329673361L; - @ApiModelProperty(position = 4, value = "Starred timestamp") + @Schema(description = "Starred timestamp") private long starredAt; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/settings/UserDashboardsInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/settings/UserDashboardsInfo.java index ef0b01889c..61056a3ae0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/settings/UserDashboardsInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/settings/UserDashboardsInfo.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.settings; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; @@ -25,7 +24,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -@ApiModel +@Schema @Data @AllArgsConstructor public class UserDashboardsInfo implements Serializable { @@ -33,10 +32,10 @@ public class UserDashboardsInfo implements Serializable { private static final long serialVersionUID = 2628320657987010348L; public static final UserDashboardsInfo EMPTY = new UserDashboardsInfo(Collections.emptyList(), Collections.emptyList()); - @ApiModelProperty(position = 1, value = "List of last visited dashboards.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "List of last visited dashboards.", accessMode = Schema.AccessMode.READ_ONLY) private List last; - @ApiModelProperty(position = 2, value = "List of starred dashboards.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "List of starred dashboards.", accessMode = Schema.AccessMode.READ_ONLY) private List starred; public UserDashboardsInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/settings/UserSettings.java b/common/data/src/main/java/org/thingsboard/server/common/data/settings/UserSettings.java index cf48d9c215..34e80ae1d5 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/settings/UserSettings.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/settings/UserSettings.java @@ -17,8 +17,7 @@ package org.thingsboard.server.common.data.settings; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.validation.Length; @@ -29,21 +28,21 @@ import java.io.Serializable; import static org.thingsboard.server.common.data.BaseDataWithAdditionalInfo.getJson; import static org.thingsboard.server.common.data.BaseDataWithAdditionalInfo.setJson; -@ApiModel +@Schema @Data public class UserSettings implements Serializable { private static final long serialVersionUID = 2628320657987010348L; - @ApiModelProperty(position = 1, value = "JSON object with User id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with User id.", accessMode = Schema.AccessMode.READ_ONLY) private UserId userId; - @ApiModelProperty(position = 2, value = "Type of the settings.") + @Schema(description = "Type of the settings.") @NoXss @Length(fieldName = "type", max = 50) private UserSettingsType type; - @ApiModelProperty(position = 3, value = "JSON object with user settings.", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "JSON object with user settings.",implementation = com.fasterxml.jackson.databind.JsonNode.class) @NoXss @Length(fieldName = "settings", max = 100000) private transient JsonNode settings; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/AwsSnsSmsProviderConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/AwsSnsSmsProviderConfiguration.java index c153c7a0a0..7c76f01807 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/AwsSnsSmsProviderConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/AwsSnsSmsProviderConfiguration.java @@ -15,19 +15,18 @@ */ package org.thingsboard.server.common.data.sms.config; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class AwsSnsSmsProviderConfiguration implements SmsProviderConfiguration { - @ApiModelProperty(position = 1, value = "The AWS SNS Access Key ID.") + @Schema(description = "The AWS SNS Access Key ID.") private String accessKeyId; - @ApiModelProperty(position = 2, value = "The AWS SNS Access Key.") + @Schema(description = "The AWS SNS Access Key.") private String secretAccessKey; - @ApiModelProperty(position = 3, value = "The AWS region.") + @Schema(description = "The AWS region.") private String region; @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/SmppSmsProviderConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/SmppSmsProviderConfiguration.java index fddb4016b1..ba1f4461d4 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/SmppSmsProviderConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/SmppSmsProviderConfiguration.java @@ -15,34 +15,34 @@ */ package org.thingsboard.server.common.data.sms.config; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Data public class SmppSmsProviderConfiguration implements SmsProviderConfiguration { - @ApiModelProperty(value = "SMPP version", allowableValues = "3.3, 3.4", required = true) + @Schema(description = "SMPP version", allowableValues = "3.3, 3.4", required = true) private String protocolVersion; - @ApiModelProperty(value = "SMPP host", required = true) + @Schema(description = "SMPP host", required = true) private String host; - @ApiModelProperty(value = "SMPP port", required = true) + @Schema(description = "SMPP port", required = true) private Integer port; - @ApiModelProperty(value = "System ID", required = true) + @Schema(description = "System ID", required = true) private String systemId; - @ApiModelProperty(value = "Password", required = true) + @Schema(description = "Password", required = true) private String password; - @ApiModelProperty(value = "System type", required = false) + @Schema(description = "System type", required = false) private String systemType; - @ApiModelProperty(value = "TX - Transmitter, RX - Receiver, TRX - Transciever. By default TX is used", required = false) + @Schema(description = "TX - Transmitter, RX - Receiver, TRX - Transciever. By default TX is used", required = false) private SmppBindType bindType; - @ApiModelProperty(value = "Service type", required = false) + @Schema(description = "Service type", required = false) private String serviceType; - @ApiModelProperty(value = "Source address", required = false) + @Schema(description = "Source address", required = false) private String sourceAddress; - @ApiModelProperty(value = "Source TON (Type of Number). Needed is source address is set. 5 by default.\n" + + @Schema(description = "Source TON (Type of Number). Needed is source address is set. 5 by default.\n" + "0 - Unknown\n" + "1 - International\n" + "2 - National\n" + @@ -51,7 +51,7 @@ public class SmppSmsProviderConfiguration implements SmsProviderConfiguration { "5 - Alphanumeric\n" + "6 - Abbreviated", required = false) private Byte sourceTon; - @ApiModelProperty(value = "Source NPI (Numbering Plan Identification). Needed is source address is set. 0 by default.\n" + + @Schema(description = "Source NPI (Numbering Plan Identification). Needed is source address is set. 0 by default.\n" + "0 - Unknown\n" + "1 - ISDN/telephone numbering plan (E163/E164)\n" + "3 - Data numbering plan (X.121)\n" + @@ -64,7 +64,7 @@ public class SmppSmsProviderConfiguration implements SmsProviderConfiguration { "18 - WAP Client Id (to be defined by WAP Forum)", required = false) private Byte sourceNpi; - @ApiModelProperty(value = "Destination TON (Type of Number). 5 by default.\n" + + @Schema(description = "Destination TON (Type of Number). 5 by default.\n" + "0 - Unknown\n" + "1 - International\n" + "2 - National\n" + @@ -73,7 +73,7 @@ public class SmppSmsProviderConfiguration implements SmsProviderConfiguration { "5 - Alphanumeric\n" + "6 - Abbreviated", required = false) private Byte destinationTon; - @ApiModelProperty(value = "Destination NPI (Numbering Plan Identification). 0 by default.\n" + + @Schema(description = "Destination NPI (Numbering Plan Identification). 0 by default.\n" + "0 - Unknown\n" + "1 - ISDN/telephone numbering plan (E163/E164)\n" + "3 - Data numbering plan (X.121)\n" + @@ -86,11 +86,11 @@ public class SmppSmsProviderConfiguration implements SmsProviderConfiguration { "18 - WAP Client Id (to be defined by WAP Forum)", required = false) private Byte destinationNpi; - @ApiModelProperty(value = "Address range", required = false) + @Schema(description = "Address range", required = false) private String addressRange; - @ApiModelProperty(allowableValues = "0-10,13-14", - value = "0 - SMSC Default Alphabet (ASCII for short and long code and to GSM for toll-free, used as default)\n" + + @Schema(allowableValues = "0-10,13-14", + description = "0 - SMSC Default Alphabet (ASCII for short and long code and to GSM for toll-free, used as default)\n" + "1 - IA5 (ASCII for short and long code, Latin 9 for toll-free (ISO-8859-9))\n" + "2 - Octet Unspecified (8-bit binary)\n" + "3 - Latin 1 (ISO-8859-1)\n" + diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/TestSmsRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/TestSmsRequest.java index 9a7e5fbfbf..5f792fc869 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/TestSmsRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/TestSmsRequest.java @@ -15,19 +15,18 @@ */ package org.thingsboard.server.common.data.sms.config; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class TestSmsRequest { - @ApiModelProperty(position = 1, value = "The SMS provider configuration") + @Schema(description = "The SMS provider configuration") private SmsProviderConfiguration providerConfiguration; - @ApiModelProperty(position = 2, value = "The phone number or other identifier to specify as a recipient of the SMS.") + @Schema(description = "The phone number or other identifier to specify as a recipient of the SMS.") private String numberTo; - @ApiModelProperty(position = 3, value = "The test message") + @Schema(description = "The test message") private String message; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/TwilioSmsProviderConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/TwilioSmsProviderConfiguration.java index 55cce68703..f9a5fb5c77 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/TwilioSmsProviderConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/TwilioSmsProviderConfiguration.java @@ -15,19 +15,18 @@ */ package org.thingsboard.server.common.data.sms.config; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class TwilioSmsProviderConfiguration implements SmsProviderConfiguration { - @ApiModelProperty(position = 1, value = "Twilio account Sid.") + @Schema(description = "Twilio account Sid.") private String accountSid; - @ApiModelProperty(position = 2, value = "Twilio account Token.") + @Schema(description = "Twilio account Token.") private String accountToken; - @ApiModelProperty(position = 3, value = "The number/id of a sender.") + @Schema(description = "The number/id of a sender.") private String numberFrom; @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/TenantProfileData.java b/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/TenantProfileData.java index 1def815cff..67427ac29d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/TenantProfileData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/TenantProfileData.java @@ -15,20 +15,19 @@ */ package org.thingsboard.server.common.data.tenant.profile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.List; -@ApiModel +@Schema @Data public class TenantProfileData { - @ApiModelProperty(position = 1, value = "Complex JSON object that contains profile settings: max devices, max assets, rate limits, etc.") + @Schema(description = "Complex JSON object that contains profile settings: max devices, max assets, rate limits, etc.") private TenantProfileConfiguration configuration; - @ApiModelProperty(position = 2, value = "JSON array of queue configuration per tenant profile") + @Schema(description = "JSON array of queue configuration per tenant profile") private List queueConfiguration; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/BaseWidgetType.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/BaseWidgetType.java index a7e9fee82a..7580bca240 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/BaseWidgetType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/BaseWidgetType.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.widget; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.HasName; @@ -30,19 +30,19 @@ public class BaseWidgetType extends BaseData implements HasName, H private static final long serialVersionUID = 8388684344603660756L; - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "bundleAlias") - @ApiModelProperty(position = 4, value = "Reference to widget bundle", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Reference to widget bundle", accessMode = Schema.AccessMode.READ_ONLY) private String bundleAlias; @NoXss @Length(fieldName = "alias") - @ApiModelProperty(position = 5, value = "Unique alias that is used in dashboards as a reference widget type", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Unique alias that is used in dashboards as a reference widget type", accessMode = Schema.AccessMode.READ_ONLY) private String alias; @NoXss @Length(fieldName = "name") - @ApiModelProperty(position = 6, value = "Widget name used in search and UI", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Widget name used in search and UI", accessMode = Schema.AccessMode.READ_ONLY) private String name; public BaseWidgetType() { @@ -61,7 +61,7 @@ public class BaseWidgetType extends BaseData implements HasName, H this.name = widgetType.getName(); } - @ApiModelProperty(position = 1, value = "JSON object with the Widget Type Id. " + + @Schema(description = "JSON object with the Widget Type Id. " + "Specify this field to update the Widget Type. " + "Referencing non-existing Widget Type Id will cause error. " + "Omit this field to create new Widget Type." ) @@ -70,7 +70,7 @@ public class BaseWidgetType extends BaseData implements HasName, H return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the Widget Type creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the Widget Type creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java index f726cfb71a..de6421c24c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java @@ -16,14 +16,14 @@ package org.thingsboard.server.common.data.widget; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.WidgetTypeId; @Data public class WidgetType extends BaseWidgetType { - @ApiModelProperty(position = 7, value = "Complex JSON object that describes the widget type", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Complex JSON object that describes the widget type", accessMode = Schema.AccessMode.READ_ONLY) private transient JsonNode descriptor; public WidgetType() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java index e6faece85d..0e06012c70 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java @@ -16,7 +16,7 @@ package org.thingsboard.server.common.data.widget; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.validation.Length; @@ -27,11 +27,11 @@ import org.thingsboard.server.common.data.validation.NoXss; public class WidgetTypeDetails extends WidgetType { @Length(fieldName = "image", max = 1000000) - @ApiModelProperty(position = 8, value = "Base64 encoded thumbnail", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Base64 encoded thumbnail", accessMode = Schema.AccessMode.READ_ONLY) private String image; @NoXss @Length(fieldName = "description") - @ApiModelProperty(position = 9, value = "Description of the widget", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Description of the widget", accessMode = Schema.AccessMode.READ_ONLY) private String description; public WidgetTypeDetails() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java index f5c4abd66d..0ba8761af6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.widget; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.validation.NoXss; @@ -23,13 +23,13 @@ import org.thingsboard.server.common.data.validation.NoXss; @Data public class WidgetTypeInfo extends BaseWidgetType { - @ApiModelProperty(position = 7, value = "Base64 encoded widget thumbnail", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Base64 encoded widget thumbnail", accessMode = Schema.AccessMode.READ_ONLY) private String image; @NoXss - @ApiModelProperty(position = 7, value = "Description of the widget type", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Description of the widget type", accessMode = Schema.AccessMode.READ_ONLY) private String description; @NoXss - @ApiModelProperty(position = 8, value = "Type of the widget (timeseries, latest, control, alarm or static)", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Type of the widget (timeseries, latest, control, alarm or static)", accessMode = Schema.AccessMode.READ_ONLY) private String widgetType; public WidgetTypeInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java index 0ceef991ad..c93d08612f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data.widget; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -32,7 +31,7 @@ import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @EqualsAndHashCode(callSuper = true) public class WidgetsBundle extends BaseData implements HasName, HasTenantId, ExportableEntity, HasTitle { @@ -40,34 +39,34 @@ public class WidgetsBundle extends BaseData implements HasName, @Getter @Setter - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "alias") @Getter @Setter - @ApiModelProperty(position = 4, value = "Unique alias that is used in widget types as a reference widget bundle", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Unique alias that is used in widget types as a reference widget bundle", accessMode = Schema.AccessMode.READ_ONLY) private String alias; @NoXss @Length(fieldName = "title") @Getter @Setter - @ApiModelProperty(position = 5, value = "Title used in search and UI", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Title used in search and UI", accessMode = Schema.AccessMode.READ_ONLY) private String title; @Length(fieldName = "image", max = 1000000) @Getter @Setter - @ApiModelProperty(position = 6, value = "Base64 encoded thumbnail", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Base64 encoded thumbnail", accessMode = Schema.AccessMode.READ_ONLY) private String image; @NoXss @Length(fieldName = "description") @Getter @Setter - @ApiModelProperty(position = 7, value = "Description", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Description", accessMode = Schema.AccessMode.READ_ONLY) private String description; @Getter @@ -92,7 +91,7 @@ public class WidgetsBundle extends BaseData implements HasName, this.externalId = widgetsBundle.getExternalId(); } - @ApiModelProperty(position = 1, value = "JSON object with the Widget Bundle Id. " + + @Schema(description = "JSON object with the Widget Bundle Id. " + "Specify this field to update the Widget Bundle. " + "Referencing non-existing Widget Bundle Id will cause error. " + "Omit this field to create new Widget Bundle." ) @@ -101,13 +100,13 @@ public class WidgetsBundle extends BaseData implements HasName, return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the Widget Bundle creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the Widget Bundle creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "Same as title of the Widget Bundle. Read-only field. Update the 'title' to change the 'name' of the Widget Bundle.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Same as title of the Widget Bundle. Read-only field. Update the 'title' to change the 'name' of the Widget Bundle.", accessMode = Schema.AccessMode.READ_ONLY) @Override @JsonProperty(access = JsonProperty.Access.READ_ONLY) public String getName() { diff --git a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java index cf0b25ec90..a5e4f2af54 100644 --- a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java +++ b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java @@ -17,8 +17,11 @@ package org.thingsboard.server.transport.http; import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -127,22 +130,22 @@ public class DeviceApiController implements TbTransportService { @Autowired private HttpTransportContext transportContext; - @ApiOperation(value = "Get attributes (getDeviceAttributes)", - notes = "Returns all attributes that belong to device. " + @Operation(summary = "Get attributes (getDeviceAttributes)", + description = "Returns all attributes that belong to device. " + "Use optional 'clientKeys' and/or 'sharedKeys' parameter to return specific attributes. " + "\n Example of the result: " + MARKDOWN_CODE_BLOCK_START + ATTRIBUTE_PAYLOAD_EXAMPLE + MARKDOWN_CODE_BLOCK_END + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) - @RequestMapping(value = "/{deviceToken}/attributes", method = RequestMethod.GET, produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) + @RequestMapping(value = "/{deviceToken}/attributes", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public DeferredResult getDeviceAttributes( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, - @ApiParam(value = "Comma separated key names for attribute with client scope", required = true, defaultValue = "state") + @Parameter(description = "Comma separated key names for attribute with client scope", required = true , schema = @Schema(defaultValue = "state")) @RequestParam(value = "clientKeys", required = false, defaultValue = "") String clientKeys, - @ApiParam(value = "Comma separated key names for attribute with shared scope", required = true, defaultValue = "configuration") + @Parameter(description = "Comma separated key names for attribute with shared scope", required = true , schema = @Schema(defaultValue = "configuration")) @RequestParam(value = "sharedKeys", required = false, defaultValue = "") String sharedKeys) { DeferredResult responseWriter = new DeferredResult<>(); transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), @@ -165,19 +168,19 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - @ApiOperation(value = "Post attributes (postDeviceAttributes)", - notes = "Post client attribute updates on behalf of device. " + @Operation(summary = "Post attributes (postDeviceAttributes)", + description = "Post client attribute updates on behalf of device. " + "\n Example of the request: " + MARKDOWN_CODE_BLOCK_START + ATTRIBUTE_PAYLOAD_EXAMPLE + MARKDOWN_CODE_BLOCK_END + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @RequestMapping(value = "/{deviceToken}/attributes", method = RequestMethod.POST) public DeferredResult postDeviceAttributes( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, - @ApiParam(value = "JSON with attribute key-value pairs. See API call description for example.") + @Parameter(description = "JSON with attribute key-value pairs. See API call description for example.") @RequestBody String json) { DeferredResult responseWriter = new DeferredResult<>(); transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), @@ -189,15 +192,15 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - @ApiOperation(value = "Post time-series data (postTelemetry)", - notes = "Post time-series data on behalf of device. " + @Operation(summary = "Post time-series data (postTelemetry)", + description = "Post time-series data on behalf of device. " + "\n Example of the request: " + TS_PAYLOAD + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @RequestMapping(value = "/{deviceToken}/telemetry", method = RequestMethod.POST) public DeferredResult postTelemetry( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, @RequestBody String json, HttpServletRequest request) { DeferredResult responseWriter = new DeferredResult(); @@ -210,8 +213,8 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - @ApiOperation(value = "Save claiming information (claimDevice)", - notes = "Saves the information required for user to claim the device. " + + @Operation(summary = "Save claiming information (claimDevice)", + description = "Saves the information required for user to claim the device. " + "See more info about claiming in the corresponding 'Claiming devices' platform documentation." + "\n Example of the request payload: " + MARKDOWN_CODE_BLOCK_START @@ -220,10 +223,10 @@ public class DeviceApiController implements TbTransportService { + "Note: both 'secretKey' and 'durationMs' is optional parameters. " + "In case the secretKey is not specified, the empty string as a default value is used. In case the durationMs is not specified, the system parameter device.claim.duration is used.\n\n" + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @RequestMapping(value = "/{deviceToken}/claim", method = RequestMethod.POST) public DeferredResult claimDevice( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, @RequestBody(required = false) String json) { DeferredResult responseWriter = new DeferredResult<>(); @@ -237,17 +240,17 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - @ApiOperation(value = "Subscribe to RPC commands (subscribeToCommands) (Deprecated)", - notes = "Subscribes to RPC commands using http long polling. " + + @Operation(summary = "Subscribe to RPC commands (subscribeToCommands) (Deprecated)", + description = "Subscribes to RPC commands using http long polling. " + "Deprecated, since long polling is resource and network consuming. " + "Consider using MQTT or CoAP protocol for light-weight real-time updates. \n\n" + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) - @RequestMapping(value = "/{deviceToken}/rpc", method = RequestMethod.GET, produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) + @RequestMapping(value = "/{deviceToken}/rpc", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public DeferredResult subscribeToCommands( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, - @ApiParam(value = "Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side.") + @Parameter(description = "Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side.") @RequestParam(value = "timeout", required = false, defaultValue = "0") long timeout) { DeferredResult responseWriter = new DeferredResult<>(); transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), @@ -263,17 +266,17 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - @ApiOperation(value = "Reply to RPC commands (replyToCommand)", - notes = "Replies to server originated RPC command identified by 'requestId' parameter. The response is arbitrary JSON.\n\n" + + @Operation(summary = "Reply to RPC commands (replyToCommand)", + description = "Replies to server originated RPC command identified by 'requestId' parameter. The response is arbitrary JSON.\n\n" + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @RequestMapping(value = "/{deviceToken}/rpc/{requestId}", method = RequestMethod.POST) public DeferredResult replyToCommand( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, - @ApiParam(value = "RPC request id from the incoming RPC request", required = true, defaultValue = "123") + @Parameter(description = "RPC request id from the incoming RPC request", required = true , schema = @Schema(defaultValue = "123")) @PathVariable("requestId") Integer requestId, - @ApiParam(value = "Reply to the RPC request, JSON. For example: {\"status\":\"success\"}", required = true) + @Parameter(description = "Reply to the RPC request, JSON. For example: {\"status\":\"success\"}", required = true) @RequestBody String json) { DeferredResult responseWriter = new DeferredResult(); transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), @@ -284,8 +287,8 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - @ApiOperation(value = "Send the RPC command (postRpcRequest)", - notes = "Send the RPC request to server. The request payload is a JSON document that contains 'method' and 'params'. For example:" + + @Operation(summary = "Send the RPC command (postRpcRequest)", + description = "Send the RPC request to server. The request payload is a JSON document that contains 'method' and 'params'. For example:" + MARKDOWN_CODE_BLOCK_START + "{\"method\": \"sumOnServer\", \"params\":{\"a\":2, \"b\":2}}" + MARKDOWN_CODE_BLOCK_END + @@ -294,12 +297,12 @@ public class DeviceApiController implements TbTransportService { "{\"result\": 4}" + MARKDOWN_CODE_BLOCK_END + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @RequestMapping(value = "/{deviceToken}/rpc", method = RequestMethod.POST) public DeferredResult postRpcRequest( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, - @ApiParam(value = "The RPC request JSON", required = true) + @Parameter(description = "The RPC request JSON", required = true) @RequestBody String json) { DeferredResult responseWriter = new DeferredResult(); transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), @@ -317,17 +320,17 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - @ApiOperation(value = "Subscribe to attribute updates (subscribeToAttributes) (Deprecated)", - notes = "Subscribes to client and shared scope attribute updates using http long polling. " + + @Operation(summary = "Subscribe to attribute updates (subscribeToAttributes) (Deprecated)", + description = "Subscribes to client and shared scope attribute updates using http long polling. " + "Deprecated, since long polling is resource and network consuming. " + "Consider using MQTT or CoAP protocol for light-weight real-time updates. \n\n" + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) - @RequestMapping(value = "/{deviceToken}/attributes/updates", method = RequestMethod.GET, produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) + @RequestMapping(value = "/{deviceToken}/attributes/updates", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public DeferredResult subscribeToAttributes( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, - @ApiParam(value = "Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side.") + @Parameter(description = "Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side.") @RequestParam(value = "timeout", required = false, defaultValue = "0") long timeout) { DeferredResult responseWriter = new DeferredResult<>(); transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), @@ -343,8 +346,8 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - @ApiOperation(value = "Get Device Firmware (getFirmware)", - notes = "Downloads the current firmware package." + + @Operation(summary = "Get Device Firmware (getFirmware)", + description = "Downloads the current firmware package." + "When the platform initiates firmware update, " + "it informs the device by updating the 'fw_title', 'fw_version', 'fw_checksum' and 'fw_checksum_algorithm' shared attributes." + "The 'fw_title' and 'fw_version' parameters must be supplied in this request to double-check " + @@ -354,24 +357,24 @@ public class DeviceApiController implements TbTransportService { "For example, device may request first 16 KB of firmware using 'chunk'=0 and 'size'=16384. " + "Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. \n\n" + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @RequestMapping(value = "/{deviceToken}/firmware", method = RequestMethod.GET) public DeferredResult getFirmware( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, - @ApiParam(value = "Title of the firmware, corresponds to the value of 'fw_title' attribute.", required = true) + @Parameter(description = "Title of the firmware, corresponds to the value of 'fw_title' attribute.", required = true) @RequestParam(value = "title") String title, - @ApiParam(value = "Version of the firmware, corresponds to the value of 'fw_version' attribute.", required = true) + @Parameter(description = "Version of the firmware, corresponds to the value of 'fw_version' attribute.", required = true) @RequestParam(value = "version") String version, - @ApiParam(value = "Size of the chunk. Optional. Omit to download the entire file without chunks.") + @Parameter(description = "Size of the chunk. Optional. Omit to download the entire file without chunks.") @RequestParam(value = "size", required = false, defaultValue = "0") int size, - @ApiParam(value = "Index of the chunk. Optional. Omit to download the entire file without chunks.") + @Parameter(description = "Index of the chunk. Optional. Omit to download the entire file without chunks.") @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) { return getOtaPackageCallback(deviceToken, title, version, size, chunk, OtaPackageType.FIRMWARE); } - @ApiOperation(value = "Get Device Software (getSoftware)", - notes = "Downloads the current software package." + + @Operation(summary = "Get Device Software (getSoftware)", + description = "Downloads the current software package." + "When the platform initiates software update, " + "it informs the device by updating the 'sw_title', 'sw_version', 'sw_checksum' and 'sw_checksum_algorithm' shared attributes." + "The 'sw_title' and 'sw_version' parameters must be supplied in this request to double-check " + @@ -381,24 +384,24 @@ public class DeviceApiController implements TbTransportService { "For example, device may request first 16 KB of software using 'chunk'=0 and 'size'=16384. " + "Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. \n\n" + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @RequestMapping(value = "/{deviceToken}/software", method = RequestMethod.GET) public DeferredResult getSoftware( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, - @ApiParam(value = "Title of the software, corresponds to the value of 'sw_title' attribute.", required = true) + @Parameter(description = "Title of the software, corresponds to the value of 'sw_title' attribute.", required = true) @RequestParam(value = "title") String title, - @ApiParam(value = "Version of the software, corresponds to the value of 'sw_version' attribute.", required = true) + @Parameter(description = "Version of the software, corresponds to the value of 'sw_version' attribute.", required = true) @RequestParam(value = "version") String version, - @ApiParam(value = "Size of the chunk. Optional. Omit to download the entire file without using chunks.") + @Parameter(description = "Size of the chunk. Optional. Omit to download the entire file without using chunks.") @RequestParam(value = "size", required = false, defaultValue = "0") int size, - @ApiParam(value = "Index of the chunk. Optional. Omit to download the entire file without using chunks.") + @Parameter(description = "Index of the chunk. Optional. Omit to download the entire file without using chunks.") @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) { return getOtaPackageCallback(deviceToken, title, version, size, chunk, OtaPackageType.SOFTWARE); } - @ApiOperation(value = "Provision new device (provisionDevice)", - notes = "Exchange the provision request to the device credentials. " + + @Operation(summary = "Provision new device (provisionDevice)", + description = "Exchange the provision request to the device credentials. " + "See more info about provisioning in the corresponding 'Device provisioning' platform documentation." + "Requires valid JSON request with the following format: " + MARKDOWN_CODE_BLOCK_START + @@ -417,10 +420,10 @@ public class DeviceApiController implements TbTransportService { " \"status\":\"SUCCESS\"\n" + "}" + MARKDOWN_CODE_BLOCK_END , - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @RequestMapping(value = "/provision", method = RequestMethod.POST) public DeferredResult provisionDevice( - @ApiParam(value = "JSON with provision request. See API call description for example.") + @Parameter(description = "JSON with provision request. See API call description for example.") @RequestBody String json) { DeferredResult responseWriter = new DeferredResult<>(); transportContext.getTransportService().process(JsonConverter.convertToProvisionRequestMsg(json), diff --git a/pom.xml b/pom.xml index b5475cc655..9d0fc4fe15 100755 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ 3.11.14 31.1-jre 2.6.1 - 3.4 + 3.12.0 1.15 2.11.0 1.2 @@ -92,8 +92,8 @@ 4.8.0 3.0.0-M9 3.0.2 - 3.0.4 - 1.6.3 + 2.1.0 + 2.2.9 0.7 1.18.2 1.69 @@ -135,7 +135,7 @@ 1.5.2 5.9.3 2.6.0 - 5.13.1 + 5.15.0 1.3.0 1.2.7 @@ -143,7 +143,7 @@ 3.23.1 5.2.0 1.3 - 1.17.3 + 1.18.3 1.12 3.0.0 6.1.0.202203080745-r @@ -1768,13 +1768,13 @@ ${curator.version} - org.thingsboard - springfox-boot-starter - ${springfox-swagger.version} + org.springdoc + springdoc-openapi-starter-webmvc-ui + ${springdoc-swagger.version} - io.swagger - swagger-annotations + io.swagger.core.v3 + swagger-annotations-jakarta ${swagger-annotations.version} @@ -2010,6 +2010,16 @@ mockserver-netty ${mock-server.version} test + + + io.swagger.parser.v3 + swagger-parser-v2-converter + + + io.swagger.parser.v3 + swagger-parser + + org.mock-server