diff --git a/application/pom.xml b/application/pom.xml
index e66a5abaf3..51c267306d 100644
--- a/application/pom.xml
+++ b/application/pom.xml
@@ -507,6 +507,82 @@
+
+
+ openapi-spec
+
+ true
+ none
+ none
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ org.thingsboard.server.ThingsboardServerApplication
+ 9001
+
+
+
+ build-info
+ build-info
+
+ false
+
+
+
+ openapi-start
+ start
+
+ false
+ true
+ -Xmx1024m
+
+ --spring.config.name=thingsboard
+ --spring.profiles.active=openapi
+
+ 180
+ 2000
+
+
+
+ openapi-stop
+ stop
+
+ false
+
+
+
+
+
+ org.springdoc
+ springdoc-openapi-maven-plugin
+ 1.4
+
+
+ generate-openapi-spec
+ generate
+
+
+
+ http://localhost:8080/v3/api-docs/thingsboard
+ openapi.json
+ ${project.build.directory}
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ true
+
+
+
+
+
+
jenkins
diff --git a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
index 20782cf071..6eec556b93 100644
--- a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
+++ b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
@@ -31,6 +31,7 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.thingsboard.common.util.JacksonUtil;
+import org.thingsboard.common.util.SsrfProtectionValidator;
import org.thingsboard.rule.engine.api.DeviceStateManager;
import org.thingsboard.rule.engine.api.JobManager;
import org.thingsboard.rule.engine.api.MailService;
@@ -144,6 +145,7 @@ import org.thingsboard.server.utils.DebugModeRateLimitsConfig;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -614,9 +616,17 @@ public class ActorSystemContext {
@Getter
private boolean localCacheType;
+ @Value("${actors.rule.external.ssrf_protection_enabled:false}")
+ private boolean ssrfProtectionEnabled;
+
+ @Value("${actors.rule.external.ssrf_additional_blocked_hosts:}")
+ private List ssrfAdditionalBlockedHosts;
+
@PostConstruct
public void init() {
this.localCacheType = "caffeine".equals(cacheType);
+ SsrfProtectionValidator.setEnabled(ssrfProtectionEnabled);
+ SsrfProtectionValidator.setAdditionalBlockedHosts(ssrfAdditionalBlockedHosts);
}
@Value("${actors.tenant.create_components_on_init:true}")
diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
index afe52bf942..f93bb34af8 100644
--- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
+++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
@@ -184,11 +184,24 @@ public class DefaultTbContext implements TbContext {
if (!msg.isValid()) {
return;
}
+ RuleChainId selfRuleChainId = nodeCtx.getSelf().getRuleChainId();
+ RuleNodeId selfId = nodeCtx.getSelf().getId();
+ if (msg.isAlreadyInStack(selfRuleChainId, selfId)) {
+ log.warn("[{}] Detected rule chain processing loop for rule node [{}] in rule chain [{}]. " +
+ "The message will be failed to prevent infinite loop. " +
+ "Please check the rule chain configuration for circular references.",
+ nodeCtx.getTenantId(), selfId, selfRuleChainId);
+ tellFailure(msg, new RuntimeException(
+ "Detected rule chain processing loop for rule node [" + selfId + "] " +
+ "in rule chain [" + selfRuleChainId + "]. " +
+ "Please check the rule chain configuration for circular references."));
+ return;
+ }
TbMsg tbMsg = msg.copy()
.ruleChainId(ruleChainId)
.resetRuleNodeId()
.build();
- tbMsg.pushToStack(nodeCtx.getSelf().getRuleChainId(), nodeCtx.getSelf().getId());
+ tbMsg.pushToStack(selfRuleChainId, selfId);
TopicPartitionInfo tpi = resolvePartition(msg);
doEnqueue(tpi, tbMsg, new SimpleTbQueueCallback(md -> ack(msg), t -> tellFailure(msg, t)));
}
diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java
index 3eecae7f7a..cc74d248d2 100644
--- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java
+++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java
@@ -137,7 +137,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor**
-
+
Example: **ApiKey tb_5te51SkLRYpjGrujUGwqkjFvooWBlQpVe2An2Dr3w13wjfxDW**
-
+
**NOTE**: Use only ONE authentication method at a time. If both are authorized, JWT auth takes the priority.
""");
@@ -213,11 +219,12 @@ public class SwaggerConfiguration {
private void addLoginOperation(OpenAPI openAPI) {
var operation = new Operation();
operation.summary("Login method to get user JWT token data");
+ operation.operationId("login");
operation.description("""
Login method used to authenticate user and get JWT token data.
-
+
Value of the response **token** field can be used as **X-Authorization** header value:
-
+
`X-Authorization: Bearer $JWT_TOKEN_VALUE`.""");
var requestBody = new RequestBody().description("Login request")
@@ -235,11 +242,12 @@ public class SwaggerConfiguration {
private void addRefreshTokenOperation(OpenAPI openAPI) {
var operation = new Operation();
operation.summary("Refresh user JWT token data");
+ operation.operationId("refreshToken");
operation.description("""
Method to refresh JWT token. Provide a valid refresh token to get a new JWT token.
-
+
The response contains a new token that can be used for authorization.
-
+
`X-Authorization: Bearer $JWT_TOKEN_VALUE`""");
var requestBody = new RequestBody().description("Refresh token request")
@@ -260,7 +268,6 @@ public class SwaggerConfiguration {
return GroupedOpenApi.builder()
.group(groupName)
.pathsToMatch(apiPath)
- .addRouterOperationCustomizer(routerOperationCustomizer(localSpringDocParameterNameDiscoverer))
.addOperationCustomizer(operationCustomizer())
.addOpenApiCustomizer(customOpenApiCustomizer())
.build();
@@ -270,9 +277,21 @@ public class SwaggerConfiguration {
@Lazy(false)
ModelConverter mapAwareConverter() {
return (type, context, chain) -> {
+ JavaType javaType = Json.mapper().constructType(type.getType());
+ if (javaType != null) {
+ Class> cls = javaType.getRawClass();
+ Schema> atomicSchema = switch (cls.getName()) {
+ case "java.util.concurrent.atomic.AtomicInteger" -> new IntegerSchema().format("int32");
+ case "java.util.concurrent.atomic.AtomicLong" -> new IntegerSchema().format("int64");
+ case "com.google.common.util.concurrent.AtomicDouble" -> new IntegerSchema().format("double");
+ default -> null;
+ };
+ if (atomicSchema != null) {
+ return atomicSchema;
+ }
+ }
if (chain.hasNext()) {
Schema schema = chain.next().resolve(type, context, chain);
- JavaType javaType = Json.mapper().constructType(type.getType());
if (javaType != null) {
Class> cls = javaType.getRawClass();
if (Map.class.isAssignableFrom(cls)) {
@@ -292,45 +311,18 @@ public class SwaggerConfiguration {
}
private void addDefaultSchemas(OpenAPI openAPI) {
- var jsonNodeSchema = ModelConverters.getInstance().readAllAsResolvedSchema(new AnnotatedType().type(JsonNode.class)).schema;
- jsonNodeSchema.setType("any");
- //noinspection unchecked
- jsonNodeSchema.setExamples(List.of(JacksonUtil.newObjectNode()));
- jsonNodeSchema.setDescription("A value representing the any type (object or primitive)");
+ Schema> errorCodeSchema = new Schema<>()
+ .type("integer")
+ .description("Platform error code")
+ ._enum(Arrays.stream(ThingsboardErrorCode.values())
+ .map(ThingsboardErrorCode::getErrorCode)
+ .collect(Collectors.toList()));
openAPI.getComponents()
- .addSchemas("JsonNode", jsonNodeSchema)
.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);
- }
-
- private RouterOperationCustomizer routerOperationCustomizer(SpringDocParameterNameDiscoverer localSpringDocParameterNameDiscoverer) {
- return (routerOperation, handlerMethod) -> {
- String[] pNames = localSpringDocParameterNameDiscoverer.getParameterNames(handlerMethod.getMethod());
- String[] reflectionParametersNames = Arrays.stream(handlerMethod.getMethod().getParameters()).map(java.lang.reflect.Parameter::getName).toArray(String[]::new);
- if (pNames == null || Arrays.stream(pNames).anyMatch(Objects::isNull)) {
- pNames = reflectionParametersNames;
- }
- MethodParameter[] parameters = handlerMethod.getMethodParameters();
- List requestParams = new ArrayList<>();
- for (var i = 0; i < parameters.length; i++) {
- var methodParameter = parameters[i];
- RequestParam requestParam = methodParameter.getParameterAnnotation(RequestParam.class);
- if (requestParam != null) {
- String pName = StringUtils.isNotBlank(requestParam.value()) ? requestParam.value() :
- pNames[i];
- if (StringUtils.isNotBlank(pName)) {
- requestParams.add(pName);
- }
- }
- }
- if (!requestParams.isEmpty()) {
- var path = routerOperation.getPath() + "{?" + String.join(",", requestParams) + "}";
- routerOperation.setPath(path);
- }
- return routerOperation;
- };
+ .addSchemas("ThingsboardCredentialsExpiredResponse", ModelConverters.getInstance().readAllAsResolvedSchema(new AnnotatedType().type(ThingsboardCredentialsExpiredResponse.class)).schema)
+ .addSchemas("ThingsboardErrorCode", errorCodeSchema);
}
private OperationCustomizer operationCustomizer() {
@@ -370,17 +362,58 @@ public class SwaggerConfiguration {
});
sortedPaths.setExtensions(paths.getExtensions());
openAPI.setPaths(sortedPaths);
+
+ if (openAPI.getComponents() != null && openAPI.getComponents().getSchemas() != null) {
+ Map schemas = openAPI.getComponents().getSchemas();
+
+ // Fix all schemas: if they have additionalProperties but no type, set type to object
+ schemas.forEach((schemaName, schema) -> {
+ if (schema.getAdditionalProperties() != null && schema.getType() == null) {
+ schema.setType("object");
+ log.debug("Added type 'object' to schema: {}", schemaName);
+ }
+ });
+
+ // Fix polymorphic properties: replace inline oneOf with base type $ref
+ schemas.values().forEach(schema -> {
+ replaceInlineOneOfProperties(schema, schemas);
+ if (schema.getAllOf() != null) {
+ List allOf = schema.getAllOf();
+ for (Schema allOfElement : allOf) {
+ replaceInlineOneOfProperties(allOfElement, schemas);
+ }
+ }
+ });
+
+ // Fix polymorphic request/response bodies: replace inline oneOf with base type $ref
+ paths.values().stream()
+ .flatMap(pathItem -> pathItem.readOperationsMap().values().stream())
+ .forEach(operation -> {
+ // Request bodies
+ if (operation.getRequestBody() != null && operation.getRequestBody().getContent() != null) {
+ replaceInlineOneOfInContent(operation.getRequestBody().getContent(), schemas);
+ }
+ // Response bodies
+ if (operation.getResponses() != null) {
+ operation.getResponses().values().stream()
+ .filter(response -> response.getContent() != null)
+ .forEach(response -> replaceInlineOneOfInContent(response.getContent(), schemas));
+ }
+ });
+ }
+
+ // Set JsonNode schema last so model scanning cannot overwrite it
+ openAPI.getComponents().addSchemas("JsonNode", new Schema<>()
+ .description("A value representing the any type (object or primitive)")
+ .example(JacksonUtil.newObjectNode()));
+
var sortedSchemas = new TreeMap<>(openAPI.getComponents().getSchemas());
openAPI.getComponents().setSchemas(new LinkedHashMap<>(sortedSchemas));
};
}
private SecurityRequirement createSecurityRequirement(String schemeName) {
- return new SecurityRequirement().addList(schemeName, Arrays.asList(
- Authority.SYS_ADMIN.name(),
- Authority.TENANT_ADMIN.name(),
- Authority.CUSTOMER_USER.name()
- ));
+ return new SecurityRequirement().addList(schemeName, List.of());
}
private Tag extractTagFromPath(Map.Entry entry) {
@@ -388,6 +421,102 @@ public class SwaggerConfiguration {
return tagName != null ? tagFromTagItem(tagName) : null;
}
+ private String findBaseTypeForOneOf(Map schemas, List oneOfSchemas) {
+ if (oneOfSchemas.isEmpty()) {
+ return null;
+ }
+
+ for (Schema oneOfSchema : oneOfSchemas) {
+ String ref = oneOfSchema.get$ref();
+ if (ref == null) {
+ continue;
+ }
+ String refName = ref.substring(ref.lastIndexOf('/') + 1);
+
+ // Check if this entry is itself a base type with discriminator
+ Schema> candidate = schemas.get(refName);
+ if (candidate != null && candidate.getDiscriminator() != null
+ && candidate.getDiscriminator().getMapping() != null) {
+ return refName;
+ }
+
+ // Check if this subtype is in another schema's discriminator mapping
+ String baseType = schemas.entrySet().stream()
+ .filter(entry -> {
+ Schema> schema = entry.getValue();
+ if (schema.getDiscriminator() != null && schema.getDiscriminator().getMapping() != null) {
+ return schema.getDiscriminator().getMapping().values().stream()
+ .anyMatch(r -> r.endsWith("/" + refName));
+ }
+ return false;
+ })
+ .map(Map.Entry::getKey)
+ .findFirst()
+ .orElse(null);
+
+ if (baseType != null) {
+ return baseType;
+ }
+ }
+ return null;
+ }
+
+
+ private void replaceInlineOneOfInContent(Content content, Map schemas) {
+ content.values().forEach(mediaType -> {
+ Schema> schema = mediaType.getSchema();
+ if (schema != null && schema.getOneOf() != null && !schema.getOneOf().isEmpty()) {
+ String baseType = findBaseTypeForOneOf(schemas, schema.getOneOf());
+ if (baseType != null) {
+ Schema> refSchema = new Schema<>();
+ refSchema.set$ref("#/components/schemas/" + baseType);
+ mediaType.setSchema(refSchema);
+ log.debug("Replaced oneOf in content with $ref to {}", baseType);
+ }
+ }
+ });
+ }
+
+ @SuppressWarnings("unchecked")
+ private void replaceInlineOneOfProperties(Schema> schema, Map allSchemas) {
+ if (schema == null || schema.getProperties() == null) {
+ return;
+ }
+ schema.getProperties().forEach((propName, propSchema) -> {
+ if (propSchema instanceof Schema) {
+ Schema> prop = (Schema>) propSchema;
+
+ // Check if additionalProperties has oneOf (polymorphic map values)
+ if (prop.getAdditionalProperties() instanceof Schema) {
+ Schema> additionalProps = (Schema>) prop.getAdditionalProperties();
+ if (additionalProps.getOneOf() != null && !additionalProps.getOneOf().isEmpty()) {
+ String baseType = findBaseTypeForOneOf(allSchemas, additionalProps.getOneOf());
+ if (baseType != null) {
+ Schema> refSchema = new Schema<>();
+ refSchema.set$ref("#/components/schemas/" + baseType);
+ prop.setAdditionalProperties(refSchema);
+ log.debug("Replaced oneOf in additionalProperties with $ref to {} in property {}", baseType, propName);
+ }
+ }
+ }
+
+ // If property has oneOf, try to find the base discriminated type
+ if (prop.getOneOf() != null && !prop.getOneOf().isEmpty()) {
+ String baseType = findBaseTypeForOneOf(allSchemas, prop.getOneOf());
+ if (baseType != null) {
+ Schema> refSchema = new Schema<>();
+ refSchema.set$ref("#/components/schemas/" + baseType);
+ if (prop.getDescription() != null) {
+ refSchema.setDescription(prop.getDescription());
+ }
+ schema.getProperties().put(propName, refSchema);
+ log.debug("Replaced oneOf with $ref to {} in property {}", baseType, propName);
+ }
+ }
+ }
+ });
+ }
+
private String tagItemFromPathItem(PathItem item) {
var operations = item.readOperationsMap().values();
var operation = operations.stream().findAny();
@@ -480,28 +609,34 @@ public class SwaggerConfiguration {
private static ApiResponses loginErrorResponses() {
ApiResponses apiResponses = new ApiResponses();
- apiResponses.addApiResponse("401", errorResponse("Unauthorized",
- 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))
- )
- ));
- var credentialsExpiredSchema = new Schema().$ref("#/components/schemas/ThingsboardCredentialsExpiredResponse");
- apiResponses.addApiResponse("401 ", errorResponse("Unauthorized (**Expired credentials**)",
- Map.of(
- "credentials-expired", errorExample("Expired credentials",
- ThingsboardCredentialsExpiredResponse.of("User password expired!", StringUtils.randomAlphanumeric(30)))
- ),
- credentialsExpiredSchema
+ Map unauthorizedExamples = new LinkedHashMap<>();
+
+ unauthorizedExamples.put("bad-credentials", errorExample("Bad credentials",
+ ThingsboardErrorResponse.of("Invalid username or password", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)));
+
+ unauthorizedExamples.put("token-expired", errorExample("JWT token expired",
+ ThingsboardErrorResponse.of("Token has expired", ThingsboardErrorCode.JWT_TOKEN_EXPIRED, HttpStatus.UNAUTHORIZED)));
+
+ unauthorizedExamples.put("account-disabled", errorExample("Disabled account",
+ ThingsboardErrorResponse.of("User account is not active", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)));
+
+ unauthorizedExamples.put("account-locked", errorExample("Locked account",
+ ThingsboardErrorResponse.of("User account is locked due to security policy", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)));
+
+ unauthorizedExamples.put("authentication-failed", errorExample("General authentication error",
+ ThingsboardErrorResponse.of("Authentication failed", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)));
+
+ unauthorizedExamples.put("credentials-expired", errorExample("Expired credentials",
+ ThingsboardCredentialsExpiredResponse.of("User password expired!", StringUtils.randomAlphanumeric(30))));
+
+ Schema extends ThingsboardErrorResponse> unauthorizedSchema = new Schema<>();
+ unauthorizedSchema.oneOf(List.of(
+ new Schema().$ref("#/components/schemas/ThingsboardErrorResponse"),
+ new Schema().$ref("#/components/schemas/ThingsboardCredentialsExpiredResponse")
));
+
+ apiResponses.addApiResponse("401", errorResponse("Unauthorized", unauthorizedExamples, unauthorizedSchema));
+
return apiResponses;
}
@@ -521,9 +656,11 @@ public class SwaggerConfiguration {
}
private static Example errorExample(String summary, ThingsboardErrorResponse example) {
+ var node = (ObjectNode) JacksonUtil.valueToTree(example);
+ node.put("timestamp", 1609459200000L);
return new Example()
.summary(summary)
- .value(example);
+ .value(node);
}
}
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 0b04a6939f..e4394bace3 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AdminController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AdminController.java
@@ -417,7 +417,7 @@ public class AdminController extends BaseController {
"provider sends authorization code to specified redirect uri.)")
@PreAuthorize("hasAuthority('SYS_ADMIN')")
@GetMapping(value = "/mail/oauth2/authorize", produces = "application/text")
- public String getAuthorizationUrl(HttpServletRequest request, HttpServletResponse response) throws ThingsboardException {
+ public String getMailOAuth2AuthorizationUrl(HttpServletRequest request, HttpServletResponse response) throws ThingsboardException {
String state = StringUtils.generateSafeToken();
if (request.getParameter(PREV_URI_PATH_PARAMETER) != null) {
CookieUtils.addCookie(response, PREV_URI_COOKIE_NAME, request.getParameter(PREV_URI_PATH_PARAMETER), 180);
@@ -442,7 +442,7 @@ public class AdminController extends BaseController {
}
@GetMapping(value = "/mail/oauth2/code", params = {"code", "state"})
- public void codeProcessingUrl(
+ public void handleMailOAuth2Callback(
@RequestParam(value = "code") String code, @RequestParam(value = "state") String state,
HttpServletRequest request, HttpServletResponse response) throws ThingsboardException, IOException {
Optional prevUrlOpt = CookieUtils.getCookie(request, PREV_URI_COOKIE_NAME);
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 8f7c8bbbd1..0814e94700 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java
@@ -227,12 +227,12 @@ public class AlarmController extends BaseController {
return tbAlarmService.unassign(alarm, System.currentTimeMillis(), getCurrentUser());
}
- @ApiOperation(value = "Get Alarms (getAlarms)",
+ @ApiOperation(value = "Get Alarms (getAlarmsByEntity)",
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)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/alarm/{entityType}/{entityId}")
- public PageData getAlarms(
+ public PageData getAlarmsByEntity(
@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE"))
@PathVariable(ENTITY_TYPE) String strEntityType,
@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true)
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 e4158d014f..50766106d5 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AssetController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AssetController.java
@@ -16,6 +16,7 @@
package org.thingsboard.server.controller;
import com.google.common.util.concurrent.ListenableFuture;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -23,6 +24,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -217,8 +219,7 @@ public class AssetController extends BaseController {
notes = "Returns a page of assets owned by tenant. " +
PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @RequestMapping(value = "/tenant/assets", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/tenant/assets")
public PageData getTenantAssets(
@Parameter(description = PAGE_SIZE_DESCRIPTION)
@RequestParam int pageSize,
@@ -245,8 +246,7 @@ public class AssetController extends BaseController {
notes = "Returns a page of assets info objects owned by tenant. " +
PAGE_DATA_PARAMETERS + ASSET_INFO_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @RequestMapping(value = "/tenant/assetInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/tenant/assetInfos")
public PageData getTenantAssetInfos(
@Parameter(description = PAGE_SIZE_DESCRIPTION)
@RequestParam int pageSize,
@@ -274,25 +274,30 @@ public class AssetController extends BaseController {
}
}
- @ApiOperation(value = "Get Tenant Asset (getTenantAsset)",
+ @Hidden
+ @PreAuthorize("hasAuthority('TENANT_ADMIN')")
+ @GetMapping(value = "/tenant/assets", params = {"assetName"})
+ public Asset getTenantAsset(@RequestParam String assetName) throws ThingsboardException {
+ TenantId tenantId = getCurrentUser().getTenantId();
+ return checkNotNull(assetService.findAssetByTenantIdAndName(tenantId, assetName));
+ }
+
+ @ApiOperation(value = "Get Tenant Asset (getTenantAssetByName)",
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)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @RequestMapping(value = "/tenant/assets", params = {"assetName"}, method = RequestMethod.GET)
- @ResponseBody
- public Asset getTenantAsset(
+ @GetMapping(value = "/tenant/asset")
+ public Asset getTenantAssetByName(
@Parameter(description = ASSET_NAME_DESCRIPTION)
@RequestParam String assetName) throws ThingsboardException {
- TenantId tenantId = getCurrentUser().getTenantId();
- return checkNotNull(assetService.findAssetByTenantIdAndName(tenantId, assetName));
+ return getTenantAsset(assetName);
}
@ApiOperation(value = "Get Customer Assets (getCustomerAssets)",
notes = "Returns a page of assets objects assigned to customer. " +
PAGE_DATA_PARAMETERS)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @RequestMapping(value = "/customer/{customerId}/assets", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/customer/{customerId}/assets")
public PageData getCustomerAssets(
@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION)
@PathVariable("customerId") String strCustomerId,
@@ -324,8 +329,7 @@ public class AssetController extends BaseController {
notes = "Returns a page of assets info objects assigned to customer. " +
PAGE_DATA_PARAMETERS + ASSET_INFO_DESCRIPTION)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @RequestMapping(value = "/customer/{customerId}/assetInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/customer/{customerId}/assetInfos")
public PageData getCustomerAssetInfos(
@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION)
@PathVariable("customerId") String strCustomerId,
@@ -361,8 +365,7 @@ 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. ")
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @RequestMapping(value = "/assets", params = {"assetIds"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/assets")
public List getAssetsByIds(
@Parameter(description = "A list of assets ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")))
@RequestParam("assetIds") String[] strAssetIds) throws ThingsboardException, ExecutionException, InterruptedException {
@@ -383,14 +386,14 @@ public class AssetController extends BaseController {
return checkNotNull(assets.get());
}
- @ApiOperation(value = "Find related assets (findByQuery)",
+ @ApiOperation(value = "Find related assets (findAssetsByQuery)",
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.")
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/assets", method = RequestMethod.POST)
@ResponseBody
- public List findByQuery(@RequestBody AssetSearchQuery query) throws ThingsboardException, ExecutionException, InterruptedException {
+ public List findAssetsByQuery(@RequestBody AssetSearchQuery query) throws ThingsboardException, ExecutionException, InterruptedException {
checkNotNull(query);
checkNotNull(query.getParameters());
checkNotNull(query.getAssetTypes());
@@ -469,8 +472,7 @@ public class AssetController extends BaseController {
notes = "Returns a page of assets assigned to edge. " +
PAGE_DATA_PARAMETERS)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @RequestMapping(value = "/edge/{edgeId}/assets", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/edge/{edgeId}/assets")
public PageData getEdgeAssets(
@Parameter(description = EDGE_ID_PARAM_DESCRIPTION)
@PathVariable(EDGE_ID) String strEdgeId,
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 65e324a715..86483413df 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AssetProfileController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AssetProfileController.java
@@ -15,6 +15,7 @@
*/
package org.thingsboard.server.controller;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -175,8 +176,7 @@ public class AssetProfileController extends BaseController {
notes = "Returns a page of asset profile objects owned by tenant. " +
PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @RequestMapping(value = "/assetProfiles", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/assetProfiles")
public PageData getAssetProfiles(
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@@ -196,8 +196,7 @@ public class AssetProfileController extends BaseController {
notes = "Returns a page of asset profile info objects owned by tenant. " +
PAGE_DATA_PARAMETERS + ASSET_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @RequestMapping(value = "/assetProfileInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/assetProfileInfos")
public PageData getAssetProfileInfos(
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@@ -227,12 +226,10 @@ public class AssetProfileController extends BaseController {
return checkNotNull(assetProfileService.findAssetProfileNamesByTenantId(tenantId, activeOnly));
}
- @ApiOperation(value = "Get Asset Profiles By Ids (getAssetProfilesByIds)",
- notes = "Requested asset profiles must be owned by tenant which is performing the request. " +
- NEW_LINE)
+ @Hidden
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@GetMapping(value = "/assetProfileInfos", params = {"assetProfileIds"})
- public List getAssetProfilesByIds(
+ public List getAssetProfilesByIdsV1(
@Parameter(description = "A list of asset profile ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
@RequestParam("assetProfileIds") Set assetProfileUUIDs) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
@@ -243,4 +240,15 @@ public class AssetProfileController extends BaseController {
return assetProfileService.findAssetProfilesByIds(tenantId, assetProfileIds);
}
+ @ApiOperation(value = "Get Asset Profiles By Ids (getAssetProfilesByIds)",
+ notes = "Requested asset profiles must be owned by tenant which is performing the request. " +
+ NEW_LINE)
+ @PreAuthorize("hasAuthority('TENANT_ADMIN')")
+ @GetMapping(value = "/assetProfileInfos/list")
+ public List getAssetProfilesByIds(
+ @Parameter(description = "A list of asset profile ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
+ @RequestParam("assetProfileIds") Set assetProfileUUIDs) throws ThingsboardException {
+ return getAssetProfilesByIdsV1(assetProfileUUIDs);
+ }
+
}
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 8c0d0d2243..6a42f034ba 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java
@@ -18,11 +18,10 @@ package org.thingsboard.server.controller;
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.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.audit.ActionType;
@@ -74,8 +73,7 @@ public class AuditLogController extends BaseController {
"and users actions (login, logout, etc.) that belong to this customer. " +
PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @RequestMapping(value = "/audit/logs/customer/{customerId}", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/audit/logs/customer/{customerId}")
public PageData getAuditLogsByCustomerId(
@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION)
@PathVariable("customerId") String strCustomerId,
@@ -107,8 +105,7 @@ public class AuditLogController extends BaseController {
"For example, RPC call to a particular device, or alarm acknowledgment for a specific device, etc. " +
PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @RequestMapping(value = "/audit/logs/user/{userId}", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/audit/logs/user/{userId}")
public PageData getAuditLogsByUserId(
@Parameter(description = USER_ID_PARAM_DESCRIPTION)
@PathVariable("userId") String strUserId,
@@ -141,8 +138,7 @@ public class AuditLogController extends BaseController {
"For example to see when a device was created, updated, assigned to some customer, or even deleted from the system. " +
PAGE_DATA_PARAMETERS + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
- @RequestMapping(value = "/audit/logs/entity/{entityType}/{entityId}", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/audit/logs/entity/{entityType}/{entityId}")
public PageData getAuditLogsByEntityId(
@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE"))
@PathVariable("entityType") String strEntityType,
@@ -176,8 +172,7 @@ public class AuditLogController extends BaseController {
notes = "Returns a page of audit logs related to all entities in the scope of the current user's Tenant. " +
PAGE_DATA_PARAMETERS + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
- @RequestMapping(value = "/audit/logs", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/audit/logs")
public PageData getAuditLogs(
@Parameter(description = PAGE_SIZE_DESCRIPTION)
@RequestParam int pageSize,
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 8bda29e98b..af3a619906 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AuthController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AuthController.java
@@ -136,7 +136,7 @@ public class AuthController extends BaseController {
"If token is valid, returns '303 See Other' (redirect) response code with the correct address of 'Create Password' page and same 'activateToken' specified in the URL parameters. " +
"If token is not valid, returns '409 Conflict'. " +
"If token is expired, redirects to error page.")
- @GetMapping(value = "/noauth/activate", params = {"activateToken"})
+ @GetMapping(value = "/noauth/activate")
public ResponseEntity> checkActivateToken(
@Parameter(description = "The activate token string.")
@RequestParam(value = "activateToken") String activateToken) {
@@ -176,7 +176,7 @@ public class AuthController extends BaseController {
"If token is valid, returns '303 See Other' (redirect) response code with the correct address of 'Reset Password' page and same 'resetToken' specified in the URL parameters. " +
"If token is not valid, returns '409 Conflict'. " +
"If token is expired, redirects to error page.")
- @GetMapping(value = "/noauth/resetPassword", params = {"resetToken"})
+ @GetMapping(value = "/noauth/resetPassword")
public ResponseEntity> checkResetToken(
@Parameter(description = "The reset token string.")
@RequestParam(value = "resetToken") String resetToken) {
diff --git a/application/src/main/java/org/thingsboard/server/controller/CalculatedFieldController.java b/application/src/main/java/org/thingsboard/server/controller/CalculatedFieldController.java
index 8ef957066b..14a9728c6b 100644
--- a/application/src/main/java/org/thingsboard/server/controller/CalculatedFieldController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/CalculatedFieldController.java
@@ -17,7 +17,11 @@ package org.thingsboard.server.controller;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Parameters;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
+import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -163,26 +167,16 @@ public class CalculatedFieldController extends BaseController {
return calculatedField;
}
- @ApiOperation(value = "Get Calculated Fields by Entity Id (getCalculatedFieldsByEntityId)",
- notes = "Fetch the Calculated Fields based on the provided Entity Id."
- )
+ @Hidden
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
@GetMapping(value = "/{entityType}/{entityId}/calculatedFields", params = {"pageSize", "page"})
- public PageData getCalculatedFieldsByEntityId(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE"))
- @PathVariable("entityType") String entityType,
- @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true)
+ public PageData getCalculatedFieldsByEntityIdV1(@PathVariable("entityType") String entityType,
@PathVariable("entityId") String entityIdStr,
- @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
- @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true)
@RequestParam int page,
- @Parameter(description = "Calculated field type. If not specified, all types will be returned.")
@RequestParam(required = false) CalculatedFieldType type,
- @Parameter(description = CF_TEXT_SEARCH_DESCRIPTION)
@RequestParam(required = false) String textSearch,
- @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name"}))
@RequestParam(required = false) String sortProperty,
- @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);
checkParameter("entityId", entityIdStr);
@@ -191,8 +185,29 @@ public class CalculatedFieldController extends BaseController {
return checkNotNull(tbCalculatedFieldService.findByTenantIdAndEntityId(getTenantId(), entityId, type, pageLink));
}
+ @ApiOperation(value = "Get Calculated Fields by Entity Id (getCalculatedFieldsByEntityId)",
+ notes = "Fetch the Calculated Fields based on the provided Entity Id."
+ )
+ @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
+ @GetMapping(value = "/calculatedField/{entityType}/{entityId}")
+ public PageData getCalculatedFieldsByEntityId(
+ @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 = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize,
+ @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page,
+ @Parameter(description = "Calculated field type. If not specified, all types will be returned.")
+ @RequestParam(required = false) CalculatedFieldType type,
+ @Parameter(description = CF_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch,
+ @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name"})) @RequestParam(required = false) String sortProperty,
+ @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException {
+ return getCalculatedFieldsByEntityIdV1(entityType, entityIdStr, pageSize, page, type, textSearch, sortProperty, sortOrder);
+ }
+
@ApiOperation(value = "Get calculated fields (getCalculatedFields)",
notes = "Fetch tenant calculated fields based on the filter.")
+ @Parameters({
+ @Parameter(name = "name", description = "Repeatable name query parameter", in = ParameterIn.QUERY, required = false, array = @ArraySchema(schema = @Schema(type = "string")))
+ })
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
@GetMapping(value = "/calculatedFields")
public PageData getCalculatedFields(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@@ -205,14 +220,13 @@ public class CalculatedFieldController extends BaseController {
@RequestParam(required = false) EntityType entityType,
@Parameter(description = "Entities filter. If not specified, calculated fields for entity type filter will be returned.")
@RequestParam(required = false) Set entities,
- @Parameter(description = "Name filter. To specify multiple names, duplicate 'name' parameter for each name, for example '?name=name1&name=name2")
- @RequestParam(required = false) String name, // for Swagger only, retrieved from MultiValueMap params (due to issues when name contains comma)
@Parameter(description = CF_TEXT_SEARCH_DESCRIPTION)
@RequestParam(required = false) String textSearch,
@Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name"}))
@RequestParam(required = false) String sortProperty,
@Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"}))
@RequestParam(required = false) String sortOrder,
+ @Parameter(hidden = true)
@RequestParam MultiValueMap params) throws ThingsboardException {
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
SecurityUser user = getCurrentUser();
@@ -289,7 +303,7 @@ public class CalculatedFieldController extends BaseController {
notes = TEST_SCRIPT_EXPRESSION + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@PostMapping("/calculatedField/testScript")
- public JsonNode testScript(
+ public JsonNode testCalculatedFieldScript(
@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Test calculated field TBEL expression.")
@RequestBody JsonNode inputParams) {
String expression = inputParams.get("expression").asText();
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 55dbb8fe04..91569261b7 100644
--- a/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java
@@ -19,6 +19,7 @@ import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@@ -81,8 +82,7 @@ public class ComponentDescriptorController extends BaseController {
notes = "Gets the Component Descriptors using coma separated list of rule node types and optional rule chain type request parameters. " +
COMPONENT_DESCRIPTOR_DEFINITION + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN')")
- @RequestMapping(value = "/components", params = {"componentTypes"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/components")
public List getComponentDescriptorsByTypes(
@Parameter(description = "List of types of the Rule Nodes, (ENRICHMENT, FILTER, TRANSFORMATION, ACTION or EXTERNAL)", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
@RequestParam("componentTypes") String[] strComponentTypes,
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 5ae949d92e..5acf09a779 100644
--- a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java
@@ -17,6 +17,7 @@ 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 io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -172,8 +173,7 @@ public class CustomerController extends BaseController {
notes = "Returns a page of customers owned by tenant. " +
PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @RequestMapping(value = "/customers", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/customers")
public PageData getCustomers(
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@@ -193,8 +193,7 @@ public class CustomerController extends BaseController {
@ApiOperation(value = "Get Tenant Customer by Customer title (getTenantCustomer)",
notes = "Get the Customer using Customer Title. " + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @RequestMapping(value = "/tenant/customers", params = {"customerTitle"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/tenant/customers")
public Customer getTenantCustomer(
@Parameter(description = "A string value representing the Customer title.")
@RequestParam String customerTitle) throws ThingsboardException {
@@ -202,12 +201,10 @@ public class CustomerController extends BaseController {
return checkNotNull(customerService.findCustomerByTenantIdAndTitle(tenantId, customerTitle), "Customer with title [" + customerTitle + "] is not found");
}
- @ApiOperation(value = "Get customers by Customer Ids (getCustomersByIds)",
- notes = "Returns a list of Customer objects based on the provided ids." +
- TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
+ @Hidden
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
@GetMapping(value = "/customers", params = {"customerIds"})
- public List getCustomersByIds(
+ public List getCustomersByIdsV1(
@Parameter(description = "A list of customer ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
@RequestParam("customerIds") Set customerUUIDs) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
@@ -218,4 +215,15 @@ public class CustomerController extends BaseController {
return customerService.findCustomersByTenantIdAndIds(tenantId, customerIds);
}
+ @ApiOperation(value = "Get customers by Customer Ids (getCustomersByIds)",
+ notes = "Returns a list of Customer objects based on the provided ids." +
+ TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
+ @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
+ @GetMapping(value = "/customers/list")
+ public List getCustomersByIds(
+ @Parameter(description = "A list of customer ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
+ @RequestParam("customerIds") Set customerUUIDs) throws ThingsboardException {
+ return getCustomersByIdsV1(customerUUIDs);
+ }
+
}
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 b16161437d..0aa74607be 100644
--- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java
@@ -17,10 +17,10 @@ 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 io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
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 jakarta.servlet.http.HttpServletResponse;
@@ -119,7 +119,7 @@ public class DashboardController extends BaseController {
"Used to adjust view of the dashboards according to the difference between browser and server time.")
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/dashboard/serverTime")
- @ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = "application/json", examples = @ExampleObject(value = "1636023857137")))
+ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(type = "integer", format = "int64", example = "1636023857137")))
public long getServerTime() {
return System.currentTimeMillis();
}
@@ -131,7 +131,7 @@ public class DashboardController extends BaseController {
"The actual value of the limit is configurable in the system configuration file.")
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/dashboard/maxDatapointsLimit")
- @ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = "application/json", examples = @ExampleObject(value = "5000")))
+ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(type = "integer", format = "int64", example = "5000")))
public long getMaxDatapointsLimit() {
return maxDatapointsLimit;
}
@@ -176,6 +176,8 @@ 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)
+ @ApiResponse(responseCode = "200", description = "OK",
+ content = @Content(schema = @Schema(implementation = Dashboard.class)))
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@PostMapping(value = "/dashboard")
public void saveDashboard(@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "A JSON value representing the dashboard.")
@@ -325,12 +327,12 @@ public class DashboardController extends BaseController {
return tbDashboardService.unassignDashboardFromPublicCustomer(dashboard, getCurrentUser());
}
- @ApiOperation(value = "Get Tenant Dashboards by System Administrator (getTenantDashboards)",
+ @ApiOperation(value = "Get Tenant Dashboards by System Administrator (getTenantDashboardsByTenantId)",
notes = "Returns a page of dashboard info objects owned by tenant. " + DASHBOARD_INFO_DEFINITION + " " + PAGE_DATA_PARAMETERS +
SYSTEM_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('SYS_ADMIN')")
- @GetMapping(value = "/tenant/{tenantId}/dashboards", params = {"pageSize", "page"})
- public PageData getTenantDashboards(
+ @GetMapping(value = "/tenant/{tenantId}/dashboards")
+ public PageData getTenantDashboardsByTenantId(
@Parameter(description = TENANT_ID_PARAM_DESCRIPTION, required = true)
@PathVariable(TENANT_ID) String strTenantId,
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@@ -353,7 +355,7 @@ public class DashboardController extends BaseController {
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)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @GetMapping(value = "/tenant/dashboards", params = {"pageSize", "page"})
+ @GetMapping(value = "/tenant/dashboards")
public PageData getTenantDashboards(
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@@ -380,7 +382,7 @@ public class DashboardController extends BaseController {
notes = "Returns a page of dashboard info objects owned by the specified customer. "
+ DASHBOARD_INFO_DEFINITION + " " + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @GetMapping(value = "/customer/{customerId}/dashboards", params = {"pageSize", "page"})
+ @GetMapping(value = "/customer/{customerId}/dashboards")
public PageData getCustomerDashboards(
@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true)
@PathVariable(CUSTOMER_ID) String strCustomerId,
@@ -574,7 +576,7 @@ public class DashboardController extends BaseController {
notes = "Returns a page of dashboard info objects assigned to the specified edge. "
+ DASHBOARD_INFO_DEFINITION + " " + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @GetMapping(value = "/edge/{edgeId}/dashboards", params = {"pageSize", "page"})
+ @GetMapping(value = "/edge/{edgeId}/dashboards")
public PageData getEdgeDashboards(
@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true)
@PathVariable(EDGE_ID) String strEdgeId,
@@ -602,13 +604,10 @@ public class DashboardController extends BaseController {
return checkNotNull(filteredResult);
}
- @ApiOperation(value = "Get dashboards by Dashboard Ids (getDashboardsByIds)",
- notes = "Returns a list of DashboardInfo objects based on the provided ids. " +
- TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
+ @Hidden
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/dashboards", params = {"dashboardIds"})
- public List getDashboardsByIds(@Parameter(description = "A list of dashboard ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
- @RequestParam("dashboardIds") Set dashboardUUIDs) throws ThingsboardException {
+ public List getDashboardsByIdsV1(@RequestParam("dashboardIds") Set dashboardUUIDs) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
List dashboardIds = new ArrayList<>();
for (UUID dashboardUUID : dashboardUUIDs) {
@@ -618,6 +617,16 @@ public class DashboardController extends BaseController {
return filterDashboardsByReadPermission(dashboards);
}
+ @ApiOperation(value = "Get dashboards by Dashboard Ids (getDashboardsByIds)",
+ notes = "Returns a list of DashboardInfo objects based on the provided ids. " +
+ TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
+ @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
+ @GetMapping(value = "/dashboards/list")
+ public List getDashboardsByIds(@Parameter(description = "A list of dashboard ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
+ @RequestParam("dashboardIds") Set dashboardUUIDs) throws ThingsboardException {
+ return getDashboardsByIdsV1(dashboardUUIDs);
+ }
+
private Set customerIdFromStr(String[] strCustomerIds) {
Set customerIds = new HashSet<>();
if (strCustomerIds != null) {
diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceConnectivityController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceConnectivityController.java
index 8b899ded41..b7e94d2212 100644
--- a/application/src/main/java/org/thingsboard/server/controller/DeviceConnectivityController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/DeviceConnectivityController.java
@@ -19,6 +19,7 @@ import com.fasterxml.jackson.databind.JsonNode;
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 jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
@@ -75,6 +76,7 @@ public class DeviceConnectivityController extends BaseController {
description = "OK",
content = @Content(
mediaType = MediaType.APPLICATION_JSON_VALUE,
+ schema = @Schema(implementation = JsonNode.class),
examples = {
@ExampleObject(
name = "http",
@@ -105,7 +107,18 @@ public class DeviceConnectivityController extends BaseController {
return deviceConnectivityService.findDevicePublishTelemetryCommands(baseUrl, device);
}
- @ApiOperation(value = "Download server certificate using file path defined in device.connectivity properties (downloadServerCertificate)", notes = "Download server certificate.")
+ @ApiOperation(value = "Download server certificate using file path defined in device.connectivity properties (downloadServerCertificate)",
+ notes = "Download server certificate.",
+ responses = {
+ @ApiResponse(
+ responseCode = "200",
+ description = "OK",
+ content = @Content(
+ mediaType = MediaType.APPLICATION_OCTET_STREAM_VALUE,
+ schema = @Schema(type = "string", format = "binary")
+ )
+ )
+ })
@RequestMapping(value = "/device-connectivity/{protocol}/certificate/download", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity downloadServerCertificate(@Parameter(description = PROTOCOL_PARAM_DESCRIPTION)
@@ -122,7 +135,18 @@ public class DeviceConnectivityController extends BaseController {
.body(pemCert);
}
- @ApiOperation(value = "Download generated docker-compose.yml file for gateway (downloadGatewayDockerCompose)", notes = "Download generated docker-compose.yml for gateway.")
+ @ApiOperation(value = "Download generated docker-compose.yml file for gateway (downloadGatewayDockerCompose)",
+ notes = "Download generated docker-compose.yml for gateway.",
+ responses = {
+ @ApiResponse(
+ responseCode = "200",
+ description = "OK",
+ content = @Content(
+ mediaType = MediaType.APPLICATION_OCTET_STREAM_VALUE,
+ schema = @Schema(type = "string", format = "binary")
+ )
+ )
+ })
@RequestMapping(value = "/device-connectivity/gateway-launch/{deviceId}/docker-compose/download", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity downloadGatewayDockerCompose(@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION)
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 78b4cc9880..8e5aa706c3 100644
--- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java
@@ -19,6 +19,7 @@ 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.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -29,6 +30,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -350,8 +352,7 @@ public class DeviceController extends BaseController {
notes = "Returns a page of devices owned by tenant. " +
PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @RequestMapping(value = "/tenant/devices", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/tenant/devices")
public PageData getTenantDevices(
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@@ -378,8 +379,7 @@ public class DeviceController extends BaseController {
notes = "Returns a page of devices info objects owned by tenant. " +
PAGE_DATA_PARAMETERS + DEVICE_INFO_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @RequestMapping(value = "/tenant/deviceInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/tenant/deviceInfos")
public PageData getTenantDeviceInfos(
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@@ -411,25 +411,31 @@ public class DeviceController extends BaseController {
return checkNotNull(deviceService.findDeviceInfosByFilter(filter.build(), pageLink));
}
- @ApiOperation(value = "Get Tenant Device (getTenantDevice)",
- notes = "Requested device must be owned by tenant that the user belongs to. " +
- "Device name is an unique property of device. So it can be used to identify the device." + TENANT_AUTHORITY_PARAGRAPH)
+ @Hidden
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @RequestMapping(value = "/tenant/devices", params = {"deviceName"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/tenant/devices", params = {"deviceName"})
public Device getTenantDevice(
- @Parameter(description = DEVICE_NAME_DESCRIPTION)
@RequestParam String deviceName) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
return checkNotNull(deviceService.findDeviceByTenantIdAndName(tenantId, deviceName));
}
+ @ApiOperation(value = "Get Tenant Device (getTenantDeviceByName)",
+ notes = "Requested device must be owned by tenant that the user belongs to. " +
+ "Device name is an unique property of device. So it can be used to identify the device." + TENANT_AUTHORITY_PARAGRAPH)
+ @PreAuthorize("hasAuthority('TENANT_ADMIN')")
+ @GetMapping(value = "/tenant/device")
+ public Device getTenantDeviceByName(
+ @Parameter(description = DEVICE_NAME_DESCRIPTION)
+ @RequestParam String deviceName) throws ThingsboardException {
+ return getTenantDevice(deviceName);
+ }
+
@ApiOperation(value = "Get Customer Devices (getCustomerDevices)",
notes = "Returns a page of devices objects assigned to customer. " +
PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @RequestMapping(value = "/customer/{customerId}/devices", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/customer/{customerId}/devices")
public PageData getCustomerDevices(
@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true)
@PathVariable(CUSTOMER_ID) String strCustomerId,
@@ -461,8 +467,7 @@ public class DeviceController extends BaseController {
notes = "Returns a page of devices info objects assigned to customer. " +
PAGE_DATA_PARAMETERS + DEVICE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @RequestMapping(value = "/customer/{customerId}/deviceInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/customer/{customerId}/deviceInfos")
public PageData getCustomerDeviceInfos(
@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true)
@PathVariable("customerId") String strCustomerId,
@@ -502,8 +507,7 @@ public class DeviceController extends BaseController {
@ApiOperation(value = "Get Devices By Ids (getDevicesByIds)",
notes = "Requested devices must be owned by tenant or assigned to customer which user is performing the request. " + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @RequestMapping(value = "/devices", params = {"deviceIds"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/devices")
public List getDevicesByIds(
@Parameter(description = "A list of devices ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")))
@RequestParam("deviceIds") String[] strDeviceIds) throws ThingsboardException, ExecutionException, InterruptedException {
@@ -524,14 +528,14 @@ public class DeviceController extends BaseController {
return checkNotNull(devices.get());
}
- @ApiOperation(value = "Find related devices (findByQuery)",
+ @ApiOperation(value = "Find related devices (findDevicesByQuery)",
notes = "Returns all devices that are related to the specific entity. " +
"The entity id, relation type, device types, depth of the search, and other query parameters defined using complex 'DeviceSearchQuery' object. " +
"See 'Model' tab of the Parameters for more info." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/devices", method = RequestMethod.POST)
@ResponseBody
- public List findByQuery(
+ public List findDevicesByQuery(
@Parameter(description = "The device search query JSON")
@RequestBody DeviceSearchQuery query) throws ThingsboardException, ExecutionException, InterruptedException {
checkNotNull(query);
@@ -730,8 +734,7 @@ public class DeviceController extends BaseController {
notes = "Returns a page of devices assigned to edge. " +
PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @RequestMapping(value = "/edge/{edgeId}/devices", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/edge/{edgeId}/devices")
public PageData getEdgeDevices(
@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true)
@PathVariable(EDGE_ID) String strEdgeId,
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 343703cb7d..f70583f721 100644
--- a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java
@@ -15,6 +15,7 @@
*/
package org.thingsboard.server.controller;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -129,7 +130,7 @@ public class DeviceProfileController extends BaseController {
return checkNotNull(deviceProfileService.findDefaultDeviceProfileInfo(getTenantId()));
}
- @ApiOperation(value = "Get time series keys (getTimeseriesKeys)",
+ @ApiOperation(value = "Get time series keys (getDeviceProfileTimeseriesKeys)",
notes = "Get a set of unique time series keys used by devices that belong to specified profile. " +
"If profile is not set returns a list of unique keys among all profiles. " +
"The call is used for auto-complete in the UI forms. " +
@@ -138,7 +139,7 @@ public class DeviceProfileController extends BaseController {
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/deviceProfile/devices/keys/timeseries", method = RequestMethod.GET)
@ResponseBody
- public List getTimeseriesKeys(
+ public List getDeviceProfileTimeseriesKeys(
@Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION)
@RequestParam(name = DEVICE_PROFILE_ID, required = false) String deviceProfileIdStr) throws ThingsboardException {
DeviceProfileId deviceProfileId;
@@ -228,8 +229,7 @@ public class DeviceProfileController extends BaseController {
notes = "Returns a page of devices profile objects owned by tenant. " +
PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @RequestMapping(value = "/deviceProfiles", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/deviceProfiles")
public PageData getDeviceProfiles(
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@@ -249,8 +249,7 @@ public class DeviceProfileController extends BaseController {
notes = "Returns a page of devices profile info objects owned by tenant. " +
PAGE_DATA_PARAMETERS + DEVICE_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @RequestMapping(value = "/deviceProfileInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/deviceProfileInfos")
public PageData getDeviceProfileInfos(
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@@ -282,14 +281,10 @@ public class DeviceProfileController extends BaseController {
return checkNotNull(deviceProfileService.findDeviceProfileNamesByTenantId(tenantId, activeOnly));
}
- @ApiOperation(value = "Get Device Profile Infos By Ids (getDeviceProfilesByIds)",
- notes = "Requested device profiles must be owned by tenant which is performing the request. " +
- NEW_LINE)
+ @Hidden
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@GetMapping(value = "/deviceProfileInfos", params = {"deviceProfileIds"})
- public List getDeviceProfileInfosByIds(
- @Parameter(description = "A list of device profile ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
- @RequestParam("deviceProfileIds") Set deviceProfileUUIDs) throws ThingsboardException {
+ public List getDeviceProfileInfosByIdsV1(@RequestParam("deviceProfileIds") Set deviceProfileUUIDs) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
List deviceProfileIds = new ArrayList<>();
for (UUID deviceProfileUUID : deviceProfileUUIDs) {
@@ -298,4 +293,15 @@ public class DeviceProfileController extends BaseController {
return deviceProfileService.findDeviceProfilesByIds(tenantId, deviceProfileIds);
}
+ @ApiOperation(value = "Get Device Profile Infos By Ids (getDeviceProfileInfosByIds)",
+ notes = "Requested device profiles must be owned by tenant which is performing the request. " +
+ NEW_LINE)
+ @PreAuthorize("hasAuthority('TENANT_ADMIN')")
+ @GetMapping(value = "/deviceProfileInfos/list")
+ public List getDeviceProfileInfosByIds(
+ @Parameter(description = "A list of device profile ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
+ @RequestParam("deviceProfileIds") Set deviceProfileUUIDs) throws ThingsboardException {
+ return getDeviceProfileInfosByIdsV1(deviceProfileUUIDs);
+ }
+
}
diff --git a/application/src/main/java/org/thingsboard/server/controller/DomainController.java b/application/src/main/java/org/thingsboard/server/controller/DomainController.java
index 0afffda159..04e750d0e4 100644
--- a/application/src/main/java/org/thingsboard/server/controller/DomainController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/DomainController.java
@@ -81,12 +81,12 @@ public class DomainController extends BaseController {
return tbDomainService.save(domain, getOAuth2ClientIds(ids), getCurrentUser());
}
- @ApiOperation(value = "Update oauth2 clients (updateOauth2Clients)",
+ @ApiOperation(value = "Update oauth2 clients (updateDomainOauth2Clients)",
notes = "Update oauth2 clients for the specified domain. ")
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')")
@PutMapping(value = "/domain/{id}/oauth2Clients")
- public void updateOauth2Clients(@PathVariable UUID id,
- @RequestBody UUID[] clientIds) throws ThingsboardException {
+ public void updateDomainOauth2Clients(@PathVariable UUID id,
+ @RequestBody UUID[] clientIds) throws ThingsboardException {
DomainId domainId = new DomainId(id);
Domain domain = checkDomainId(domainId, Operation.WRITE);
List oAuth2ClientIds = getOAuth2ClientIds(clientIds);
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 f0d9e39d6a..361104d9a2 100644
--- a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java
@@ -16,6 +16,7 @@
package org.thingsboard.server.controller;
import com.google.common.util.concurrent.ListenableFuture;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -277,7 +278,7 @@ public class EdgeController extends BaseController {
notes = "Returns a page of edges info objects owned by tenant. " +
PAGE_DATA_PARAMETERS + EDGE_INFO_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @GetMapping(value = "/tenant/edgeInfos", params = {"pageSize", "page"})
+ @GetMapping(value = "/tenant/edgeInfos")
public PageData getTenantEdgeInfos(
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@@ -300,17 +301,24 @@ 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)
+ @Hidden
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@GetMapping(value = "/tenant/edges", params = {"edgeName"})
- public Edge getTenantEdge(@Parameter(description = "Unique name of the edge", required = true)
- @RequestParam String edgeName) throws ThingsboardException {
+ public Edge getTenantEdge(@RequestParam String edgeName) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
return checkNotNull(edgeService.findEdgeByTenantIdAndName(tenantId, edgeName));
}
+ @ApiOperation(value = "Get Tenant Edge by name (getTenantEdgeByName)",
+ 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)
+ @PreAuthorize("hasAuthority('TENANT_ADMIN')")
+ @GetMapping(value = "/tenant/edge")
+ public Edge getTenantEdgeByName(@Parameter(description = "Unique name of the edge", required = true)
+ @RequestParam String edgeName) throws ThingsboardException {
+ return getTenantEdge(edgeName);
+ }
+
@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)
@@ -334,7 +342,7 @@ public class EdgeController extends BaseController {
notes = "Returns a page of edges objects assigned to customer. " +
PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @GetMapping(value = "/customer/{customerId}/edges", params = {"pageSize", "page"})
+ @GetMapping(value = "/customer/{customerId}/edges")
public PageData getCustomerEdges(
@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION)
@PathVariable("customerId") String strCustomerId,
@@ -369,7 +377,7 @@ public class EdgeController extends BaseController {
notes = "Returns a page of edges info objects assigned to customer. " +
PAGE_DATA_PARAMETERS + EDGE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @GetMapping(value = "/customer/{customerId}/edgeInfos", params = {"pageSize", "page"})
+ @GetMapping(value = "/customer/{customerId}/edgeInfos")
public PageData getCustomerEdgeInfos(
@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION)
@PathVariable("customerId") String strCustomerId,
@@ -400,12 +408,10 @@ public class EdgeController extends BaseController {
return checkNotNull(result);
}
- @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)
+ @Hidden
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/edges", params = {"edgeIds"})
public List getEdgesByIds(
- @Parameter(description = "A list of edges ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
@RequestParam("edgeIds") String[] strEdgeIds) throws ThingsboardException, ExecutionException, InterruptedException {
checkArrayParameter("edgeIds", strEdgeIds);
SecurityUser user = getCurrentUser();
@@ -425,13 +431,23 @@ public class EdgeController extends BaseController {
return checkNotNull(edges);
}
- @ApiOperation(value = "Find related edges (findByQuery)",
+ @ApiOperation(value = "Get Edges By Ids (getEdgeList)",
+ notes = "Requested edges must be owned by tenant or assigned to customer which user is performing the request." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
+ @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
+ @GetMapping(value = "/edges/list")
+ public List getEdgeList(
+ @Parameter(description = "A list of edges ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
+ @RequestParam("edgeIds") String[] strEdgeIds) throws ThingsboardException, ExecutionException, InterruptedException {
+ return getEdgesByIds(strEdgeIds);
+ }
+
+ @ApiOperation(value = "Find related edges (findEdgesByQuery)",
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)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@PostMapping(value = "/edges")
- public List findByQuery(@RequestBody EdgeSearchQuery query) throws ThingsboardException, ExecutionException, InterruptedException {
+ public List findEdgesByQuery(@RequestBody EdgeSearchQuery query) throws ThingsboardException, ExecutionException, InterruptedException {
checkNotNull(query);
checkNotNull(query.getParameters());
checkNotNull(query.getEdgeTypes());
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 10f4cd2f51..cf632531ce 100644
--- a/application/src/main/java/org/thingsboard/server/controller/EntitiesVersionControlController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/EntitiesVersionControlController.java
@@ -19,6 +19,7 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
@@ -234,7 +235,7 @@ public class EntitiesVersionControlController extends BaseController {
"}" +
MARKDOWN_CODE_BLOCK_END +
TENANT_AUTHORITY_PARAGRAPH)
- @GetMapping(value = "/version/{entityType}/{externalEntityUuid}", params = {"branch", "pageSize", "page"})
+ @GetMapping(value = "/version/{entityType}/{externalEntityUuid}")
public DeferredResult> listEntityVersions(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true)
@PathVariable EntityType entityType,
@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.")
@@ -263,7 +264,7 @@ public class EntitiesVersionControlController extends BaseController {
"If specified branch does not exist - empty page data will be returned. " +
"The response structure is the same as for `listEntityVersions` API method." +
TENANT_AUTHORITY_PARAGRAPH)
- @GetMapping(value = "/version/{entityType}", params = {"branch", "pageSize", "page"})
+ @GetMapping(value = "/version/{entityType}")
public DeferredResult> listEntityTypeVersions(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true)
@PathVariable EntityType entityType,
@Parameter(description = BRANCH_PARAM_DESCRIPTION, required = true)
@@ -288,7 +289,7 @@ public class EntitiesVersionControlController extends BaseController {
"If specified branch does not exist - empty page data will be returned. " +
"The response format is the same as for `listEntityVersions` API method." +
TENANT_AUTHORITY_PARAGRAPH)
- @GetMapping(value = "/version", params = {"branch", "pageSize", "page"})
+ @GetMapping(value = "/version")
public DeferredResult> listVersions(@Parameter(description = BRANCH_PARAM_DESCRIPTION, required = true)
@RequestParam String branch,
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@@ -355,7 +356,7 @@ public class EntitiesVersionControlController extends BaseController {
"Returns an object with current entity data and the one at a specific version. " +
"Entity data structure is the same as stored in a repository. " +
TENANT_AUTHORITY_PARAGRAPH)
- @GetMapping(value = "/diff/{entityType}/{internalEntityUuid}", params = {"versionId"})
+ @GetMapping(value = "/diff/{entityType}/{internalEntityUuid}")
public DeferredResult compareEntityDataToVersion(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true)
@PathVariable EntityType entityType,
@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true)
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 9314f584ab..a5c82f11f4 100644
--- a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java
@@ -15,11 +15,13 @@
*/
package org.thingsboard.server.controller;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -71,25 +73,22 @@ public class EntityRelationController extends BaseController {
"If the user has the authority of 'Tenant Administrator', the server checks that the entity is owned by the same tenant. " +
"If the user has the authority of 'Customer User', the server checks that the entity is assigned to the same customer.";
- @ApiOperation(value = "Create Relation (saveRelation)",
- notes = "Creates or updates a relation between two entities in the platform. " +
- "Relations unique key is a combination of from/to entity id and relation type group and relation type. " +
- SECURITY_CHECKS_ENTITIES_DESCRIPTION)
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
- @PostMapping("/relation")
- public void saveRelation(@Parameter(description = "A JSON value representing the relation.", required = true)
+ @PostMapping(value = "/relation")
+ public void saveRelationV1(@Parameter(description = "A JSON value representing the relation.", required = true)
@RequestBody EntityRelation relation) throws ThingsboardException {
doSave(relation);
}
- @ApiOperation(value = "Create Relation (saveRelationV2)",
+ @ApiOperation(value = "Create Relation (saveRelation)",
notes = "Creates or updates a relation between two entities in the platform. " +
"Relations unique key is a combination of from/to entity id and relation type group and relation type. " +
SECURITY_CHECKS_ENTITIES_DESCRIPTION)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
- @PostMapping("/v2/relation")
- public EntityRelation saveRelationV2(@Parameter(description = "A JSON value representing the relation.", required = true)
- @RequestBody EntityRelation relation) throws ThingsboardException {
+ @PostMapping(value = "/v2/relation")
+ public EntityRelation saveRelation(@Parameter(description = "A JSON value representing the relation.", required = true)
+ @RequestBody EntityRelation relation) throws ThingsboardException {
return doSave(relation);
}
@@ -103,11 +102,10 @@ public class EntityRelationController extends BaseController {
return tbEntityRelationService.save(getTenantId(), getCurrentUser().getCustomerId(), relation, getCurrentUser());
}
- @ApiOperation(value = "Delete Relation (deleteRelation)",
- notes = "Deletes a relation between two entities in the platform. " + SECURITY_CHECKS_ENTITIES_DESCRIPTION)
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
- @DeleteMapping(value = "/relation", params = {FROM_ID, FROM_TYPE, RELATION_TYPE, TO_ID, TO_TYPE})
- public void deleteRelation(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId,
+ @DeleteMapping(value = "/relation")
+ public void deleteRelationV1(@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,
@@ -116,16 +114,16 @@ public class EntityRelationController extends BaseController {
doDelete(strFromId, strFromType, strRelationType, strRelationTypeGroup, strToId, strToType);
}
- @ApiOperation(value = "Delete Relation (deleteRelationV2)",
+ @ApiOperation(value = "Delete Relation (deleteRelation)",
notes = "Deletes a relation between two entities in the platform. " + SECURITY_CHECKS_ENTITIES_DESCRIPTION)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
- @DeleteMapping(value = "/v2/relation", params = {FROM_ID, FROM_TYPE, RELATION_TYPE, TO_ID, TO_TYPE})
- public EntityRelation deleteRelationV2(@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 {
+ @DeleteMapping(value = "/v2/relation")
+ public EntityRelation 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 {
return doDelete(strFromId, strFromType, strRelationType, strRelationTypeGroup, strToId, strToType);
}
@@ -144,11 +142,11 @@ public class EntityRelationController extends BaseController {
return tbEntityRelationService.delete(getTenantId(), getCurrentUser().getCustomerId(), relation, getCurrentUser());
}
- @ApiOperation(value = "Delete common relations (deleteCommonRelations)",
+ @ApiOperation(value = "Delete common relations (deleteRelations)",
notes = "Deletes all the relations ('from' and 'to' direction) for the specified entity and relation type group: 'COMMON'. " +
SECURITY_CHECKS_ENTITY_DESCRIPTION)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN', 'CUSTOMER_USER')")
- @DeleteMapping(value = "/relations", params = {"entityId", "entityType"})
+ @DeleteMapping(value = "/relations")
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);
@@ -161,7 +159,7 @@ 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)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
- @GetMapping(value = "/relation", params = {FROM_ID, FROM_TYPE, RELATION_TYPE, TO_ID, TO_TYPE})
+ @GetMapping(value = "/relation")
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,
@@ -180,14 +178,11 @@ public class EntityRelationController extends BaseController {
return checkNotNull(relationService.getRelation(getTenantId(), fromId, toId, strRelationType, typeGroup));
}
- @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)
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/relations", params = {FROM_ID, FROM_TYPE})
- 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)
+ public List findByFrom(@RequestParam(FROM_ID) String strFromId,
+ @RequestParam(FROM_TYPE) String strFromType,
@RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException {
checkParameter(FROM_ID, strFromId);
checkParameter(FROM_TYPE, strFromType);
@@ -197,9 +192,19 @@ public class EntityRelationController extends BaseController {
return checkNotNull(filterRelationsByReadPermission(relationService.findByFrom(getTenantId(), entityId, typeGroup)));
}
- @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)
+ @ApiOperation(value = "Get List of Relations (findEntityRelationsByFrom)",
+ notes = "Returns list of relation objects for the specified entity by the 'from' direction. " +
+ SECURITY_CHECKS_ENTITY_DESCRIPTION)
+ @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
+ @GetMapping(value = "/relations/from/{fromType}/{fromId}")
+ public List findEntityRelationsByFrom(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(FROM_TYPE) String strFromType,
+ @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(FROM_ID) String strFromId,
+ @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION)
+ @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException {
+ return findByFrom(strFromId, strFromType, strRelationTypeGroup);
+ }
+
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/relations/info", params = {FROM_ID, FROM_TYPE})
public List findInfoByFrom(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId,
@@ -214,15 +219,24 @@ public class EntityRelationController extends BaseController {
return checkNotNull(filterRelationsByReadPermission(relationService.findInfoByFrom(getTenantId(), entityId, typeGroup).get()));
}
- @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)
+ @ApiOperation(value = "Get List of Relation Infos (findEntityRelationInfosByFrom)",
+ notes = "Returns list of relation info objects for the specified entity by the 'from' direction. " +
+ SECURITY_CHECKS_ENTITY_DESCRIPTION + " " + RELATION_INFO_DESCRIPTION)
+ @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
+ @GetMapping(value = "/relations/info/from/{fromType}/{fromId}")
+ public List findEntityRelationInfosByFrom(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(FROM_TYPE) String strFromType,
+ @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(FROM_ID) String strFromId,
+ @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION)
+ @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException, ExecutionException, InterruptedException {
+ return findInfoByFrom(strFromId, strFromType, strRelationTypeGroup);
+ }
+
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/relations", params = {FROM_ID, FROM_TYPE, RELATION_TYPE})
- 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)
+ public List findByFrom(@RequestParam(FROM_ID) String strFromId,
+ @RequestParam(FROM_TYPE) String strFromType,
+ @RequestParam(RELATION_TYPE) String strRelationType,
@RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException {
checkParameter(FROM_ID, strFromId);
checkParameter(FROM_TYPE, strFromType);
@@ -233,10 +247,21 @@ public class EntityRelationController extends BaseController {
return checkNotNull(filterRelationsByReadPermission(relationService.findByFromAndType(getTenantId(), entityId, strRelationType, typeGroup)));
}
- @ApiOperation(value = "Get List of Relations (findByTo)",
- notes = "Returns list of relation objects for the specified entity by the 'to' direction. " +
+ @ApiOperation(value = "Get List of Relations (findEntityRelationsByFromAndRelationType)",
+ notes = "Returns list of relation objects for the specified entity by the 'from' direction and relation type. " +
SECURITY_CHECKS_ENTITY_DESCRIPTION)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
+ @GetMapping(value = "/relations/from/{fromType}/{fromId}/{relationType}")
+ public List findEntityRelationsByFromAndRelationType(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(FROM_TYPE) String strFromType,
+ @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(FROM_ID) String strFromId,
+ @Parameter(description = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(RELATION_TYPE) String strRelationType,
+ @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION)
+ @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException {
+ return findByFrom(strFromId, strFromType, strRelationType, strRelationTypeGroup);
+ }
+
+ @Hidden
+ @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/relations", params = {TO_ID, TO_TYPE})
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,
@@ -250,9 +275,19 @@ public class EntityRelationController extends BaseController {
return checkNotNull(filterRelationsByReadPermission(relationService.findByTo(getTenantId(), entityId, typeGroup)));
}
- @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)
+ @ApiOperation(value = "Get List of Relations (findEntityRelationsByTo)",
+ notes = "Returns list of relation objects for the specified entity by the 'to' direction. " +
+ SECURITY_CHECKS_ENTITY_DESCRIPTION)
+ @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
+ @GetMapping(value = "/relations/to/{toType}/{toId}")
+ public List findEntityRelationsByTo(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(TO_TYPE) String strToType,
+ @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(TO_ID) String strToId,
+ @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION)
+ @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException {
+ return findByTo(strToId, strToType, strRelationTypeGroup);
+ }
+
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/relations/info", params = {TO_ID, TO_TYPE})
public List findInfoByTo(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId,
@@ -267,9 +302,19 @@ public class EntityRelationController extends BaseController {
return checkNotNull(filterRelationsByReadPermission(relationService.findInfoByTo(getTenantId(), entityId, typeGroup).get()));
}
- @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)
+ @ApiOperation(value = "Get List of Relation Infos (findEntityRelationInfosByTo)",
+ notes = "Returns list of relation info objects for the specified entity by the 'to' direction. " +
+ SECURITY_CHECKS_ENTITY_DESCRIPTION + " " + RELATION_INFO_DESCRIPTION)
+ @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
+ @GetMapping(value = "/relations/info/to/{toType}/{toId}")
+ public List findEntityRelationInfosByTo(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(TO_TYPE) String strToType,
+ @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(TO_ID) String strToId,
+ @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION)
+ @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException, ExecutionException, InterruptedException {
+ return findInfoByTo(strToId, strToType, strRelationTypeGroup);
+ }
+
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/relations", params = {TO_ID, TO_TYPE, RELATION_TYPE})
public List findByTo(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId,
@@ -286,28 +331,41 @@ public class EntityRelationController extends BaseController {
return checkNotNull(filterRelationsByReadPermission(relationService.findByToAndType(getTenantId(), entityId, strRelationType, typeGroup)));
}
- @ApiOperation(value = "Find related entities (findByQuery)",
+ @ApiOperation(value = "Get List of Relations (findEntityRelationsByToAndRelationType)",
+ notes = "Returns list of relation objects for the specified entity by the 'to' direction and relation type. " +
+ SECURITY_CHECKS_ENTITY_DESCRIPTION)
+ @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
+ @GetMapping(value = "/relations/to/{toType}/{toId}/{relationType}")
+ public List findEntityRelationsByToAndRelationType(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(TO_TYPE) String strToType,
+ @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(TO_ID) String strToId,
+ @Parameter(description = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(RELATION_TYPE) String strRelationType,
+ @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION)
+ @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException {
+ return findByTo(strToId, strToType, strRelationType, strRelationTypeGroup);
+ }
+
+ @ApiOperation(value = "Find related entities (findEntityRelationsByQuery)",
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.")
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@PostMapping("/relations")
- public List findByQuery(@Parameter(description = "A JSON value representing the entity relations query object.", required = true)
- @RequestBody EntityRelationsQuery query) throws ThingsboardException, ExecutionException, InterruptedException {
+ public List findEntityRelationsByQuery(@Parameter(description = "A JSON value representing the entity relations query object.", required = true)
+ @RequestBody EntityRelationsQuery query) throws ThingsboardException, ExecutionException, InterruptedException {
checkNotNull(query.getParameters());
checkNotNull(query.getFilters());
checkEntityId(query.getParameters().getEntityId(), Operation.READ);
return checkNotNull(filterRelationsByReadPermission(relationService.findByQuery(getTenantId(), query).get()));
}
- @ApiOperation(value = "Find related entity infos (findInfoByQuery)",
+ @ApiOperation(value = "Find related entity infos (findEntityRelationInfosByQuery)",
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)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@PostMapping("/relations/info")
- public List findInfoByQuery(@Parameter(description = "A JSON value representing the entity relations query object.", required = true)
- @RequestBody EntityRelationsQuery query) throws ThingsboardException, ExecutionException, InterruptedException {
+ public List findEntityRelationInfosByQuery(@Parameter(description = "A JSON value representing the entity relations query object.", required = true)
+ @RequestBody EntityRelationsQuery query) throws ThingsboardException, ExecutionException, InterruptedException {
checkNotNull(query.getParameters());
checkNotNull(query.getFilters());
checkEntityId(query.getParameters().getEntityId(), Operation.READ);
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 e061c691ac..821a3c77a1 100644
--- a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java
@@ -16,6 +16,7 @@
package org.thingsboard.server.controller;
import com.google.common.util.concurrent.ListenableFuture;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -23,7 +24,6 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -79,7 +79,6 @@ import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_
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.NAME_CONFLICT_POLICY_DESC;
-import static org.thingsboard.server.controller.ControllerConstants.UNIQUIFY_SEPARATOR_DESC;
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;
@@ -87,6 +86,7 @@ import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_D
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.UNIQUIFY_SEPARATOR_DESC;
import static org.thingsboard.server.controller.ControllerConstants.UNIQUIFY_STRATEGY_DESC;
import static org.thingsboard.server.controller.EdgeController.EDGE_ID;
@@ -167,17 +167,25 @@ public class EntityViewController extends BaseController {
tbEntityViewService.delete(entityView, getCurrentUser());
}
- @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)
+ @Hidden
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@GetMapping(value = "/tenant/entityViews", params = {"entityViewName"})
public EntityView getTenantEntityView(
- @Parameter(description = "Entity View name")
@RequestParam String entityViewName) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
return checkNotNull(entityViewService.findEntityViewByTenantIdAndName(tenantId, entityViewName));
}
+ @ApiOperation(value = "Get Entity View by name (getTenantEntityViewByName)",
+ notes = "Fetch the Entity View object based on the tenant id and entity view name. " + TENANT_AUTHORITY_PARAGRAPH)
+ @PreAuthorize("hasAuthority('TENANT_ADMIN')")
+ @GetMapping(value = "/tenant/entityView")
+ public EntityView getTenantEntityViewByName(
+ @Parameter(description = "Entity View name")
+ @RequestParam String entityViewName) throws ThingsboardException {
+ return getTenantEntityView(entityViewName);
+ }
+
@ApiOperation(value = "Assign Entity View to customer (assignEntityViewToCustomer)",
notes = "Creates assignment of the Entity View to customer. Customer will be able to query Entity View afterwards." + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@@ -222,7 +230,7 @@ public class EntityViewController extends BaseController {
notes = "Returns a page of Entity View objects assigned to customer. " +
PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @GetMapping(value = "/customer/{customerId}/entityViews", params = {"pageSize", "page"})
+ @GetMapping(value = "/customer/{customerId}/entityViews")
public PageData getCustomerEntityViews(
@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true)
@PathVariable(CUSTOMER_ID) String strCustomerId,
@@ -254,7 +262,7 @@ public class EntityViewController extends BaseController {
notes = "Returns a page of Entity View info objects assigned to customer. " + ENTITY_VIEW_DESCRIPTION +
PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @GetMapping(value = "/customer/{customerId}/entityViewInfos", params = {"pageSize", "page"})
+ @GetMapping(value = "/customer/{customerId}/entityViewInfos")
public PageData getCustomerEntityViewInfos(
@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true)
@PathVariable(CUSTOMER_ID) String strCustomerId,
@@ -286,7 +294,7 @@ public class EntityViewController extends BaseController {
notes = "Returns a page of entity views owned by tenant. " + ENTITY_VIEW_DESCRIPTION +
PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @GetMapping(value = "/tenant/entityViews", params = {"pageSize", "page"})
+ @GetMapping(value = "/tenant/entityViews")
public PageData getTenantEntityViews(
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@@ -314,7 +322,7 @@ public class EntityViewController extends BaseController {
notes = "Returns a page of entity views info owned by tenant. " + ENTITY_VIEW_DESCRIPTION +
PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @GetMapping(value = "/tenant/entityViewInfos", params = {"pageSize", "page"})
+ @GetMapping(value = "/tenant/entityViewInfos")
public PageData getTenantEntityViewInfos(
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@@ -337,13 +345,13 @@ public class EntityViewController extends BaseController {
}
}
- @ApiOperation(value = "Find related entity views (findByQuery)",
+ @ApiOperation(value = "Find related entity views (findEntityViewsByQuery)",
notes = "Returns all entity views that are related to the specific entity. " +
"The entity id, relation type, entity view types, depth of the search, and other query parameters defined using complex 'EntityViewSearchQuery' object. " +
"See 'Model' tab of the Parameters for more info." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@PostMapping(value = "/entityViews")
- public List findByQuery(
+ public List findEntityViewsByQuery(
@Parameter(description = "The entity view search query JSON")
@RequestBody EntityViewSearchQuery query) throws ThingsboardException, ExecutionException, InterruptedException {
checkNotNull(query);
@@ -429,7 +437,7 @@ public class EntityViewController extends BaseController {
}
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @GetMapping(value = "/edge/{edgeId}/entityViews", params = {"pageSize", "page"})
+ @GetMapping(value = "/edge/{edgeId}/entityViews")
public PageData getEdgeEntityViews(
@PathVariable(EDGE_ID) String strEdgeId,
@RequestParam int pageSize,
@@ -459,11 +467,10 @@ public class EntityViewController extends BaseController {
return checkNotNull(filteredResult);
}
- @ApiOperation(value = "Get Entity Views By Ids (getEntityViewsByIds)",
- notes = "Requested entity views must be owned by tenant or assigned to customer which user is performing the request. ")
+ @Hidden
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/entityViews", params = {"entityViewIds"})
- public List getEntityViewsByIds(@Parameter(description = "A list of entity view ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
+ public List getEntityViewsByIdsV1(@Parameter(description = "A list of entity view ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
@RequestParam("entityViewIds") Set entityViewUUIDs) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
List entityViewIds = new ArrayList<>();
@@ -474,6 +481,15 @@ public class EntityViewController extends BaseController {
return filterEntityViewsByReadPermission(entityViews);
}
+ @ApiOperation(value = "Get Entity Views By Ids (getEntityViewsByIds)",
+ notes = "Requested entity views must be owned by tenant or assigned to customer which user is performing the request. ")
+ @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
+ @GetMapping(value = "/entityViews/list")
+ public List getEntityViewsByIds(@Parameter(description = "A list of entity view ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
+ @RequestParam("entityViewIds") Set entityViewUUIDs) throws ThingsboardException {
+ return getEntityViewsByIdsV1(entityViewUUIDs);
+ }
+
private List filterEntityViewsByReadPermission(List entityViews) {
return entityViews.stream().filter(entityView -> {
try {
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 7bb2d33366..6e8c17c674 100644
--- a/application/src/main/java/org/thingsboard/server/controller/EventController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/EventController.java
@@ -15,6 +15,7 @@
*/
package org.thingsboard.server.controller;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import org.springframework.beans.factory.annotation.Autowired;
@@ -113,13 +114,13 @@ public class EventController extends BaseController {
@Autowired
private EventService eventService;
- @ApiOperation(value = "Get Events by type (getEvents)",
+ @ApiOperation(value = "Get Events by type (getEventsByType)",
notes = "Returns a page of events for specified entity by specifying event type. " +
PAGE_DATA_PARAMETERS)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/events/{entityType}/{entityId}/{eventType}", method = RequestMethod.GET)
@ResponseBody
- public PageData getEvents(
+ public PageData getEventsByType(
@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true)
@PathVariable(ENTITY_TYPE) String strEntityType,
@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true)
@@ -152,16 +153,12 @@ public class EventController extends BaseController {
return checkNotNull(eventService.findEvents(tenantId, entityId, resolveEventType(eventType), pageLink));
}
- @ApiOperation(value = "Get Events (Deprecated)",
- notes = "Returns a page of events for specified entity. Deprecated and will be removed in next minor release. " +
- "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)
+
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.GET)
@ResponseBody
- public PageData getEvents(
+ public PageData getEventsDeprecated(
@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true)
@PathVariable(ENTITY_TYPE) String strEntityType,
@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true)
@@ -194,14 +191,14 @@ public class EventController extends BaseController {
return checkNotNull(eventService.findEvents(tenantId, entityId, EventType.LC_EVENT, pageLink));
}
- @ApiOperation(value = "Get Events by event filter (getEvents)",
+ @ApiOperation(value = "Get Events by event filter (getEventsByFilter)",
notes = "Returns a page of events for the chosen entity by specifying the event filter. " +
PAGE_DATA_PARAMETERS + NEW_LINE +
EVENT_FILTER_DEFINITION)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.POST)
@ResponseBody
- public PageData getEvents(
+ public PageData getEventsByFilter(
@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true)
@PathVariable(ENTITY_TYPE) String strEntityType,
@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true)
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 5e3f3be442..5566c11a4a 100644
--- a/application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java
@@ -69,11 +69,11 @@ public class Lwm2mController extends BaseController {
return lwM2MService.getServerSecurityInfo(bootstrapServer);
}
- @ApiOperation(hidden = true, value = "Save device with credentials (Deprecated)")
+ @ApiOperation(hidden = true, value = "Save LwM2M device with credentials (saveLwm2mDeviceWithCredentials) (Deprecated)")
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/lwm2m/device-credentials", method = RequestMethod.POST)
@ResponseBody
- public Device saveDeviceWithCredentials(@RequestBody Map, Object> deviceWithDeviceCredentials) throws ThingsboardException {
+ public Device saveLwm2mDeviceWithCredentials(@RequestBody Map, Object> deviceWithDeviceCredentials) throws ThingsboardException {
Device device = checkNotNull(JacksonUtil.convertValue(deviceWithDeviceCredentials.get(Device.class), Device.class));
DeviceCredentials credentials = checkNotNull(JacksonUtil.convertValue(deviceWithDeviceCredentials.get(DeviceCredentials.class), DeviceCredentials.class));
return deviceController.saveDeviceWithCredentials(new SaveDeviceWithCredentialsRequest(device, credentials), DEFAULT.policy(), DEFAULT.separator(), DEFAULT.uniquifyStrategy());
diff --git a/application/src/main/java/org/thingsboard/server/controller/MailConfigTemplateController.java b/application/src/main/java/org/thingsboard/server/controller/MailConfigTemplateController.java
index 70ac96db67..f8a3f8ad0b 100644
--- a/application/src/main/java/org/thingsboard/server/controller/MailConfigTemplateController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/MailConfigTemplateController.java
@@ -43,12 +43,12 @@ public class MailConfigTemplateController extends BaseController {
private static final String MAIL_CONFIG_TEMPLATE_DEFINITION = "Mail configuration template is set of default smtp settings for mail server that specific provider supports";
private final TbMailConfigTemplateService mailConfigTemplateService;
- @ApiOperation(value = "Get the list of all OAuth2 client registration templates (getClientRegistrationTemplates)" + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH,
+ @ApiOperation(value = "Get the list of all OAuth2 client registration templates (getMailConfigTemplates)" + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH,
notes = MAIL_CONFIG_TEMPLATE_DEFINITION)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
@ResponseBody
- public JsonNode getClientRegistrationTemplates() throws ThingsboardException, IOException {
+ public JsonNode getMailConfigTemplates() throws ThingsboardException, IOException {
accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
return mailConfigTemplateService.findAllMailConfigTemplates();
}
diff --git a/application/src/main/java/org/thingsboard/server/controller/MobileAppBundleController.java b/application/src/main/java/org/thingsboard/server/controller/MobileAppBundleController.java
index 304805a820..feb4aed0e3 100644
--- a/application/src/main/java/org/thingsboard/server/controller/MobileAppBundleController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/MobileAppBundleController.java
@@ -81,12 +81,12 @@ public class MobileAppBundleController extends BaseController {
return tbMobileAppBundleService.save(mobileAppBundle, getOAuth2ClientIds(ids), getCurrentUser());
}
- @ApiOperation(value = "Update oauth2 clients (updateOauth2Clients)",
+ @ApiOperation(value = "Update oauth2 clients (updateMobileAppBundleOauth2Clients)",
notes = "Update oauth2 clients of the specified mobile app bundle." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@PutMapping(value = "/mobile/bundle/{id}/oauth2Clients")
- public void updateOauth2Clients(@PathVariable UUID id,
- @RequestBody UUID[] clientIds) throws ThingsboardException {
+ public void updateMobileAppBundleOauth2Clients(@PathVariable UUID id,
+ @RequestBody UUID[] clientIds) throws ThingsboardException {
MobileAppBundleId mobileAppBundleId = new MobileAppBundleId(id);
MobileAppBundle mobileAppBundle = checkMobileAppBundleId(mobileAppBundleId, Operation.WRITE);
List oAuth2ClientIds = getOAuth2ClientIds(clientIds);
diff --git a/application/src/main/java/org/thingsboard/server/controller/MobileAppController.java b/application/src/main/java/org/thingsboard/server/controller/MobileAppController.java
index 7c77a26e42..3ca23b2ddc 100644
--- a/application/src/main/java/org/thingsboard/server/controller/MobileAppController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/MobileAppController.java
@@ -123,7 +123,7 @@ public class MobileAppController extends BaseController {
return tbMobileAppService.save(mobileApp, getCurrentUser());
}
- @ApiOperation(value = "Get mobile app infos (getTenantMobileAppInfos)", notes = SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
+ @ApiOperation(value = "Get mobile app infos (getTenantMobileApps)", notes = SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@GetMapping(value = "/mobile/app")
public PageData getTenantMobileApps(@Parameter(description = "Platform type: ANDROID or IOS")
@@ -142,7 +142,7 @@ public class MobileAppController extends BaseController {
return mobileAppService.findMobileAppsByTenantId(getTenantId(), platformType, pageLink);
}
- @ApiOperation(value = "Get mobile info by id (getMobileAppInfoById)", notes = SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
+ @ApiOperation(value = "Get mobile info by id (getMobileAppById)", notes = SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@GetMapping(value = "/mobile/app/{id}")
public MobileApp getMobileAppById(@PathVariable UUID id) throws ThingsboardException {
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 72c7f15a3b..17bb87233e 100644
--- a/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java
@@ -15,6 +15,7 @@
*/
package org.thingsboard.server.controller;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -153,12 +154,10 @@ public class NotificationTargetController extends BaseController {
return notificationTargetService.findRecipientsForNotificationTargetConfig(user.getTenantId(), (PlatformUsersNotificationTargetConfig) notificationTarget.getConfiguration(), pageLink);
}
- @ApiOperation(value = "Get notification targets by ids (getNotificationTargetsByIds)",
- notes = "Returns the list of notification targets found by provided ids." +
- SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
+ @Hidden
@GetMapping(value = "/targets", params = {"ids"})
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
- public List getNotificationTargetsByIds(@Parameter(description = "Comma-separated list of uuids representing targets ids", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
+ public List getNotificationTargetsByIdsV1(@Parameter(description = "Comma-separated list of uuids representing targets ids", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
@RequestParam("ids") UUID[] ids,
@AuthenticationPrincipal SecurityUser user) {
// PE: generic permission
@@ -166,6 +165,17 @@ public class NotificationTargetController extends BaseController {
return notificationTargetService.findNotificationTargetsByTenantIdAndIds(user.getTenantId(), targetsIds);
}
+ @ApiOperation(value = "Get notification targets by ids (getNotificationTargetsByIds)",
+ notes = "Returns the list of notification targets found by provided ids." +
+ SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
+ @GetMapping(value = "/targets/list")
+ @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
+ public List getNotificationTargetsByIds(@Parameter(description = "Comma-separated list of uuids representing targets ids", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
+ @RequestParam("ids") UUID[] ids,
+ @AuthenticationPrincipal SecurityUser user) {
+ return getNotificationTargetsByIdsV1(ids, user);
+ }
+
@ApiOperation(value = "Get notification targets (getNotificationTargets)",
notes = "Returns the page of notification targets owned by sysadmin or tenant." + NEW_LINE +
PAGE_DATA_PARAMETERS +
@@ -188,13 +198,10 @@ public class NotificationTargetController extends BaseController {
return notificationTargetService.findNotificationTargetsByTenantId(user.getTenantId(), pageLink);
}
- @ApiOperation(value = "Get notification targets by supported notification type (getNotificationTargetsBySupportedNotificationType)",
- notes = "Returns the page of notification targets filtered by notification type that they can be used for." + NEW_LINE +
- PAGE_DATA_PARAMETERS +
- SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
+ @Hidden
@GetMapping(value = "/targets", params = "notificationType")
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
- public PageData getNotificationTargetsBySupportedNotificationType(@RequestParam int pageSize,
+ public PageData getNotificationTargetsBySupportedNotificationTypeV1(@RequestParam int pageSize,
@RequestParam int page,
@RequestParam(required = false) String textSearch,
@RequestParam(required = false) String sortProperty,
@@ -206,6 +213,22 @@ public class NotificationTargetController extends BaseController {
return notificationTargetService.findNotificationTargetsByTenantIdAndSupportedNotificationType(user.getTenantId(), notificationType, pageLink);
}
+ @ApiOperation(value = "Get notification targets by supported notification type (getNotificationTargetsBySupportedNotificationType)",
+ notes = "Returns the page of notification targets filtered by notification type that they can be used for." + NEW_LINE +
+ PAGE_DATA_PARAMETERS +
+ SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
+ @GetMapping(value = "/targets/notificationType/{notificationType}")
+ @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
+ public PageData getNotificationTargetsBySupportedNotificationType(@PathVariable NotificationType notificationType,
+ @RequestParam int pageSize,
+ @RequestParam int page,
+ @RequestParam(required = false) String textSearch,
+ @RequestParam(required = false) String sortProperty,
+ @RequestParam(required = false) String sortOrder,
+ @AuthenticationPrincipal SecurityUser user) throws ThingsboardException {
+ return getNotificationTargetsBySupportedNotificationTypeV1(pageSize, page, textSearch, sortProperty, sortOrder, notificationType, user);
+ }
+
@ApiOperation(value = "Delete notification target by id (deleteNotificationTargetById)",
notes = "Deletes notification target by its id." + NEW_LINE +
"This target cannot be referenced by existing scheduled notification requests or any notification rules." +
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 8891fcc64e..6c773c9509 100644
--- a/application/src/main/java/org/thingsboard/server/controller/OAuth2ConfigTemplateController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/OAuth2ConfigTemplateController.java
@@ -71,12 +71,12 @@ public class OAuth2ConfigTemplateController extends BaseController {
oAuth2ConfigTemplateService.deleteClientRegistrationTemplateById(clientRegistrationTemplateId);
}
- @ApiOperation(value = "Get the list of all OAuth2 client registration templates (getClientRegistrationTemplates)" + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH,
+ @ApiOperation(value = "Get the list of all OAuth2 client registration templates (getOAuth2ClientRegistrationTemplates)" + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH,
notes = OAUTH2_CLIENT_REGISTRATION_TEMPLATE_DEFINITION)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
@ResponseBody
- public List getClientRegistrationTemplates() throws ThingsboardException {
+ public List getOAuth2ClientRegistrationTemplates() throws ThingsboardException {
accessControlService.checkPermission(getCurrentUser(), Resource.OAUTH2_CONFIGURATION_TEMPLATE, Operation.READ);
return oAuth2ConfigTemplateService.findAllClientRegistrationTemplates();
}
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 71b8ac27a9..a1d6f667f9 100644
--- a/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java
+++ b/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java
@@ -15,6 +15,7 @@
*/
package org.thingsboard.server.controller;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -132,15 +133,23 @@ public class OAuth2Controller extends BaseController {
return oAuth2ClientService.findOAuth2ClientInfosByTenantId(getTenantId(), pageLink);
}
+ @Hidden
+ @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
+ @GetMapping(value = "/oauth2/client/infos", params = {"clientIds"})
+ public List findTenantOAuth2ClientInfosByIdsV1(
+ @RequestParam("clientIds") UUID[] clientIds) throws ThingsboardException {
+ List oAuth2ClientIds = getOAuth2ClientIds(clientIds);
+ return oAuth2ClientService.findOAuth2ClientInfosByIds(getTenantId(), oAuth2ClientIds);
+ }
+
@ApiOperation(value = "Get OAuth2 Client infos By Ids (findTenantOAuth2ClientInfosByIds)",
notes = "Fetch OAuth2 Client info objects based on the provided ids. " + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
- @GetMapping(value = "/oauth2/client/infos", params = {"clientIds"})
+ @GetMapping(value = "/oauth2/client/list")
public List findTenantOAuth2ClientInfosByIds(
@Parameter(description = "A list of oauth2 ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
@RequestParam("clientIds") UUID[] clientIds) throws ThingsboardException {
- List oAuth2ClientIds = getOAuth2ClientIds(clientIds);
- return oAuth2ClientService.findOAuth2ClientInfosByIds(getTenantId(), oAuth2ClientIds);
+ return findTenantOAuth2ClientInfosByIdsV1(clientIds);
}
@ApiOperation(value = "Get OAuth2 Client by id (getOAuth2ClientById)", notes = SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
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 4967023ec0..ab93a29db5 100644
--- a/application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java
@@ -181,25 +181,25 @@ public class OtaPackageController extends BaseController {
return checkNotNull(otaPackageService.findTenantOtaPackagesByTenantId(getTenantId(), pageLink));
}
- @ApiOperation(value = "Get OTA Package Infos (getOtaPackages)",
+ @ApiOperation(value = "Get OTA Package Infos by device profile and type (getOtaPackagesByDeviceProfileAndType)",
notes = "Returns a page of OTA Package Info objects owned by tenant. " +
PAGE_DATA_PARAMETERS + OTA_PACKAGE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/otaPackages/{deviceProfileId}/{type}")
- public PageData getOtaPackages(@Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION)
- @PathVariable("deviceProfileId") String strDeviceProfileId,
- @Parameter(description = "OTA Package type.", schema = @Schema(allowableValues = {"FIRMWARE", "SOFTWARE"}))
- @PathVariable("type") String strType,
- @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
- @RequestParam int pageSize,
- @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true)
- @RequestParam int page,
- @Parameter(description = OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION)
- @RequestParam(required = false) String textSearch,
- @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "type", "title", "version", "tag", "url", "fileName", "dataSize", "checksum"}))
- @RequestParam(required = false) String sortProperty,
- @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"}))
- @RequestParam(required = false) String sortOrder) throws ThingsboardException {
+ public PageData getOtaPackagesByDeviceProfileAndType(@Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION)
+ @PathVariable("deviceProfileId") String strDeviceProfileId,
+ @Parameter(description = "OTA Package type.", schema = @Schema(allowableValues = {"FIRMWARE", "SOFTWARE"}))
+ @PathVariable("type") String strType,
+ @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
+ @RequestParam int pageSize,
+ @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true)
+ @RequestParam int page,
+ @Parameter(description = OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION)
+ @RequestParam(required = false) String textSearch,
+ @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "type", "title", "version", "tag", "url", "fileName", "dataSize", "checksum"}))
+ @RequestParam(required = false) String sortProperty,
+ @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"}))
+ @RequestParam(required = false) String sortOrder) throws ThingsboardException {
checkParameter("deviceProfileId", strDeviceProfileId);
checkParameter("type", strType);
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
diff --git a/application/src/main/java/org/thingsboard/server/controller/QrCodeSettingsController.java b/application/src/main/java/org/thingsboard/server/controller/QrCodeSettingsController.java
index d266b684d8..6b90fb142f 100644
--- a/application/src/main/java/org/thingsboard/server/controller/QrCodeSettingsController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/QrCodeSettingsController.java
@@ -129,7 +129,7 @@ public class QrCodeSettingsController extends BaseController {
return qrCodeSettingService.saveQrCodeSettings(currentUser.getTenantId(), qrCodeSettings);
}
- @ApiOperation(value = "Get Mobile application settings (getMobileAppSettings)",
+ @ApiOperation(value = "Get Mobile application settings (getQrCodeSettings)",
notes = "The response payload contains configuration for android/iOS applications and platform qr code widget settings." + AVAILABLE_FOR_ANY_AUTHORIZED_USER)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/api/mobile/qr/settings")
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 2d584a6e27..dd2cc19fd6 100644
--- a/application/src/main/java/org/thingsboard/server/controller/QueueController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/QueueController.java
@@ -19,7 +19,9 @@ 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;
import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@@ -65,8 +67,7 @@ public class QueueController extends BaseController {
notes = "Returns a page of queues registered in the platform. " +
PAGE_DATA_PARAMETERS + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
- @RequestMapping(value = "/queues", params = {"serviceType", "pageSize", "page"}, method = RequestMethod.GET)
- @ResponseBody
+ @GetMapping(value = "/queues")
public PageData getTenantQueuesByServiceType(@Parameter(description = QUEUE_SERVICE_TYPE_DESCRIPTION, schema = @Schema(allowableValues = {"TB-RULE-ENGINE", "TB-CORE", "TB-TRANSPORT", "JS-EXECUTOR"}, requiredMode = Schema.RequiredMode.REQUIRED))
@RequestParam String serviceType,
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@@ -122,8 +123,7 @@ public class QueueController extends BaseController {
"Remove 'id', 'tenantId' from the request body example (below) to create new Queue entity. " +
SYSTEM_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN')")
- @RequestMapping(value = "/queues", params = {"serviceType"}, method = RequestMethod.POST)
- @ResponseBody
+ @PostMapping(value = "/queues")
public Queue saveQueue(@Parameter(description = "A JSON value representing the queue.")
@RequestBody Queue queue,
@Parameter(description = QUEUE_SERVICE_TYPE_DESCRIPTION, schema = @Schema(allowableValues = {"TB-RULE-ENGINE", "TB-CORE", "TB-TRANSPORT", "JS-EXECUTOR"}, requiredMode = Schema.RequiredMode.REQUIRED))
diff --git a/application/src/main/java/org/thingsboard/server/controller/QueueStatsController.java b/application/src/main/java/org/thingsboard/server/controller/QueueStatsController.java
index 1ccc35b875..57ec9a43c9 100644
--- a/application/src/main/java/org/thingsboard/server/controller/QueueStatsController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/QueueStatsController.java
@@ -15,6 +15,7 @@
*/
package org.thingsboard.server.controller;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -85,12 +86,10 @@ public class QueueStatsController extends BaseController {
return checkNotNull(queueStatsService.findQueueStatsById(getTenantId(), queueStatsId));
}
- @ApiOperation(value = "Get QueueStats By Ids (getQueueStatsByIds)",
- notes = "Fetch the Queue stats objects based on the provided ids. ")
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@GetMapping(value = "/queueStats", params = {"queueStatsIds"})
- public List getQueueStatsByIds(
- @Parameter(description = "A list of queue stats ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
+ public List getQueueStatsByIdsV1(
@RequestParam("queueStatsIds") String[] strQueueStatsIds) throws ThingsboardException {
checkArrayParameter("queueStatsIds", strQueueStatsIds);
List queueStatsIds = new ArrayList<>();
@@ -99,4 +98,14 @@ public class QueueStatsController extends BaseController {
}
return queueStatsService.findQueueStatsByIds(getTenantId(), queueStatsIds);
}
+
+ @ApiOperation(value = "Get QueueStats By Ids (getQueueStatsByIds)",
+ notes = "Fetch the Queue stats objects based on the provided ids. ")
+ @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
+ @GetMapping(value = "/queueStats/list")
+ public List getQueueStatsByIds(
+ @Parameter(description = "A list of queue stats ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
+ @RequestParam("queueStatsIds") String[] strQueueStatsIds) throws ThingsboardException {
+ return getQueueStatsByIdsV1(strQueueStatsIds);
+ }
}
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 dc17136d63..08ef1a85c8 100644
--- a/application/src/main/java/org/thingsboard/server/controller/RpcV1Controller.java
+++ b/application/src/main/java/org/thingsboard/server/controller/RpcV1Controller.java
@@ -43,11 +43,11 @@ import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CU
@Slf4j
public class RpcV1Controller extends AbstractRpcController {
- @ApiOperation(value = "Send one-way RPC request (handleOneWayDeviceRPCRequest)", notes = "Deprecated. See 'Rpc V 2 Controller' instead." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
+ @ApiOperation(value = "Send one-way RPC request (handleOneWayDeviceRPCRequestV1)", notes = "Deprecated. See 'Rpc V 2 Controller' instead." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/oneway/{deviceId}", method = RequestMethod.POST)
@ResponseBody
- public DeferredResult handleOneWayDeviceRPCRequest(
+ public DeferredResult handleOneWayDeviceRPCRequestV1(
@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION)
@PathVariable("deviceId") String deviceIdStr,
@Parameter(description = "A JSON value representing the RPC request.")
@@ -55,11 +55,11 @@ public class RpcV1Controller extends AbstractRpcController {
return handleDeviceRPCRequest(true, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.REQUEST_TIMEOUT, HttpStatus.CONFLICT);
}
- @ApiOperation(value = "Send two-way RPC request (handleTwoWayDeviceRPCRequest)", notes = "Deprecated. See 'Rpc V 2 Controller' instead." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
+ @ApiOperation(value = "Send two-way RPC request (handleTwoWayDeviceRPCRequestV1)", notes = "Deprecated. See 'Rpc V 2 Controller' instead." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/twoway/{deviceId}", method = RequestMethod.POST)
@ResponseBody
- public DeferredResult handleTwoWayDeviceRPCRequest(
+ public DeferredResult handleTwoWayDeviceRPCRequestV1(
@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION)
@PathVariable("deviceId") String deviceIdStr,
@Parameter(description = "A JSON value representing the RPC request.")
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 412e775327..fdcb853343 100644
--- a/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java
+++ b/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java
@@ -113,7 +113,7 @@ public class RpcV2Controller extends AbstractRpcController {
private static final String TWO_WAY_RPC_REQUEST_DESCRIPTION = "Sends the two-way remote-procedure call (RPC) request to device. " + RPC_REQUEST_DESCRIPTION + TWO_WAY_RPC_RESULT + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH;
- @ApiOperation(value = "Send one-way RPC request", notes = ONE_WAY_RPC_REQUEST_DESCRIPTION)
+ @ApiOperation(value = "Send one-way RPC request (handleOneWayDeviceRPCRequestV2)", notes = ONE_WAY_RPC_REQUEST_DESCRIPTION)
@ApiResponses(value = {
@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."),
@@ -124,7 +124,7 @@ public class RpcV2Controller extends AbstractRpcController {
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/oneway/{deviceId}", method = RequestMethod.POST)
@ResponseBody
- public DeferredResult handleOneWayDeviceRPCRequest(
+ public DeferredResult handleOneWayDeviceRPCRequestV2(
@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION)
@PathVariable("deviceId") String deviceIdStr,
@Parameter(description = "A JSON value representing the RPC request.")
@@ -132,7 +132,7 @@ public class RpcV2Controller extends AbstractRpcController {
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)
+ @ApiOperation(value = "Send two-way RPC request (handleTwoWayDeviceRPCRequestV2)", notes = TWO_WAY_RPC_REQUEST_DESCRIPTION)
@ApiResponses(value = {
@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."),
@@ -143,7 +143,7 @@ public class RpcV2Controller extends AbstractRpcController {
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/twoway/{deviceId}", method = RequestMethod.POST)
@ResponseBody
- public DeferredResult handleTwoWayDeviceRPCRequest(
+ public DeferredResult handleTwoWayDeviceRPCRequestV2(
@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION)
@PathVariable(DEVICE_ID) String deviceIdStr,
@Parameter(description = "A JSON value representing the RPC request.")
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 accec11afe..0ac6fcdac1 100644
--- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java
@@ -19,6 +19,7 @@ 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.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -229,12 +230,12 @@ public class RuleChainController extends BaseController {
return tbRuleChainService.save(ruleChain, getCurrentUser());
}
- @ApiOperation(value = "Create Default Rule Chain",
+ @ApiOperation(value = "Create Default Rule Chain (setDeviceDefaultRuleChain)",
notes = "Create rule chain from template, based on the specified name in the request. " +
"Creates the rule chain based on the template that is used to create root rule chain. " + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@PostMapping("/ruleChain/device/default")
- public RuleChain saveRuleChain(
+ public RuleChain setDeviceDefaultRuleChain(
@Parameter(description = "A JSON value representing the request.")
@RequestBody DefaultRuleChainCreateRequest request) throws Exception {
checkNotNull(request);
@@ -281,7 +282,7 @@ public class RuleChainController extends BaseController {
@ApiOperation(value = "Get Rule Chains (getRuleChains)",
notes = "Returns a page of Rule Chains owned by tenant. " + RULE_CHAIN_DESCRIPTION + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @GetMapping(value = "/ruleChains", params = {"pageSize", "page"})
+ @GetMapping(value = "/ruleChains")
public PageData getRuleChains(
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@@ -347,7 +348,7 @@ public class RuleChainController extends BaseController {
notes = TEST_SCRIPT_FUNCTION + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@PostMapping("/ruleChain/testScript")
- public JsonNode testScript(
+ public JsonNode testRuleChainScript(
@Parameter(description = "Script language: JS or TBEL")
@RequestParam(required = false) ScriptLanguage scriptLang,
@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Test JS request. See API call description above.")
@@ -409,7 +410,7 @@ public class RuleChainController extends BaseController {
@ApiOperation(value = "Export Rule Chains", notes = "Exports all tenant rule chains as one JSON." + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @GetMapping(value = "/ruleChains/export", params = {"limit"})
+ @GetMapping(value = "/ruleChains/export")
public RuleChainData exportRuleChains(
@Parameter(description = "A limit of rule chains to export.", required = true)
@RequestParam("limit") int limit) throws ThingsboardException {
@@ -505,7 +506,7 @@ public class RuleChainController extends BaseController {
@ApiOperation(value = "Get Edge Rule Chains (getEdgeRuleChains)",
notes = "Returns a page of Rule Chains assigned to the specified edge. " + RULE_CHAIN_DESCRIPTION + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @GetMapping(value = "/edge/{edgeId}/ruleChains", params = {"pageSize", "page"})
+ @GetMapping(value = "/edge/{edgeId}/ruleChains")
public PageData getEdgeRuleChains(
@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true)
@PathVariable(EDGE_ID) String strEdgeId,
@@ -582,14 +583,10 @@ public class RuleChainController extends BaseController {
return checkNotNull(result);
}
- @ApiOperation(value = "Get Rule Chains By Ids (getRuleChainsByIds)",
- notes = "Requested rule chains must be owned by tenant which is performing the request. " +
- NEW_LINE)
+ @Hidden
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@GetMapping(value = "/ruleChains", params = {"ruleChainIds"})
- public List getRuleChainsByIds(
- @Parameter(description = "A list of rule chain ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
- @RequestParam("ruleChainIds") Set ruleChainUUIDs) throws Exception {
+ public List getRuleChainsByIdsV1(@RequestParam("ruleChainIds") Set ruleChainUUIDs) throws Exception {
TenantId tenantId = getCurrentUser().getTenantId();
List ruleChainIds = new ArrayList<>();
for (UUID ruleChainUUID : ruleChainUUIDs) {
@@ -598,4 +595,15 @@ public class RuleChainController extends BaseController {
return ruleChainService.findRuleChainsByIds(tenantId, ruleChainIds);
}
+ @ApiOperation(value = "Get Rule Chains By Ids (getRuleChainsByIds)",
+ notes = "Requested rule chains must be owned by tenant which is performing the request. " +
+ NEW_LINE)
+ @PreAuthorize("hasAuthority('TENANT_ADMIN')")
+ @GetMapping(value = "/ruleChains/list")
+ public List getRuleChainsByIds(
+ @Parameter(description = "A list of rule chain ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
+ @RequestParam("ruleChainIds") Set ruleChainUUIDs) throws Exception {
+ return getRuleChainsByIdsV1(ruleChainUUIDs);
+ }
+
}
diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleEngineController.java b/application/src/main/java/org/thingsboard/server/controller/RuleEngineController.java
index 2b4489e387..ec39bb97aa 100644
--- a/application/src/main/java/org/thingsboard/server/controller/RuleEngineController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/RuleEngineController.java
@@ -77,7 +77,7 @@ public class RuleEngineController extends BaseController {
@Autowired
private AccessValidator accessValidator;
- @ApiOperation(value = "Push user message to the rule engine (handleRuleEngineRequest)",
+ @ApiOperation(value = "Push user message to the rule engine (handleRuleEngineRequestForUser)",
notes = MSG_DESCRIPTION_PREFIX +
"Uses current User Id ( the one which credentials is used to perform the request) as the Rule Engine message originator. " +
MSG_DESCRIPTION +
@@ -86,13 +86,13 @@ public class RuleEngineController extends BaseController {
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/", method = RequestMethod.POST)
@ResponseBody
- public DeferredResult handleRuleEngineRequest(
+ public DeferredResult handleRuleEngineRequestForUser(
@Parameter(description = "A JSON value representing the message.", required = true)
@RequestBody String requestBody) throws ThingsboardException {
- return handleRuleEngineRequest(null, null, null, defaultResponseTimeout, requestBody);
+ return handleRuleEngineRequestForEntityWithQueueAndTimeout(null, null, null, defaultResponseTimeout, requestBody);
}
- @ApiOperation(value = "Push entity message to the rule engine (handleRuleEngineRequest)",
+ @ApiOperation(value = "Push entity message to the rule engine (handleRuleEngineRequestForEntity)",
notes = MSG_DESCRIPTION_PREFIX +
"Uses specified Entity Id as the Rule Engine message originator. " +
MSG_DESCRIPTION +
@@ -101,17 +101,17 @@ public class RuleEngineController extends BaseController {
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/{entityType}/{entityId}", method = RequestMethod.POST)
@ResponseBody
- public DeferredResult handleRuleEngineRequest(
+ public DeferredResult handleRuleEngineRequestForEntity(
@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true)
@PathVariable("entityType") String entityType,
@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true)
@PathVariable("entityId") String entityIdStr,
@Parameter(description = "A JSON value representing the message.", required = true)
@RequestBody String requestBody) throws ThingsboardException {
- return handleRuleEngineRequest(entityType, entityIdStr, null, defaultResponseTimeout, requestBody);
+ return handleRuleEngineRequestForEntityWithQueueAndTimeout(entityType, entityIdStr, null, defaultResponseTimeout, requestBody);
}
- @ApiOperation(value = "Push entity message with timeout to the rule engine (handleRuleEngineRequest)",
+ @ApiOperation(value = "Push entity message with timeout to the rule engine (handleRuleEngineRequestForEntityWithTimeout)",
notes = MSG_DESCRIPTION_PREFIX +
"Uses specified Entity Id as the Rule Engine message originator. " +
MSG_DESCRIPTION +
@@ -120,7 +120,7 @@ public class RuleEngineController extends BaseController {
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/{entityType}/{entityId}/{timeout}", method = RequestMethod.POST)
@ResponseBody
- public DeferredResult handleRuleEngineRequest(
+ public DeferredResult handleRuleEngineRequestForEntityWithTimeout(
@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true)
@PathVariable("entityType") String entityType,
@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true)
@@ -129,10 +129,10 @@ public class RuleEngineController extends BaseController {
@PathVariable("timeout") int timeout,
@Parameter(description = "A JSON value representing the message.", required = true)
@RequestBody String requestBody) throws ThingsboardException {
- return handleRuleEngineRequest(entityType, entityIdStr, null, timeout, requestBody);
+ return handleRuleEngineRequestForEntityWithQueueAndTimeout(entityType, entityIdStr, null, timeout, requestBody);
}
- @ApiOperation(value = "Push entity message with timeout and specified queue to the rule engine (handleRuleEngineRequest)",
+ @ApiOperation(value = "Push entity message with timeout and specified queue to the rule engine (handleRuleEngineRequestForEntityWithQueueAndTimeout)",
notes = MSG_DESCRIPTION_PREFIX +
"Uses specified Entity Id as the Rule Engine message originator. " +
MSG_DESCRIPTION +
@@ -142,7 +142,7 @@ public class RuleEngineController extends BaseController {
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/{entityType}/{entityId}/{queueName}/{timeout}", method = RequestMethod.POST)
@ResponseBody
- public DeferredResult handleRuleEngineRequest(
+ public DeferredResult handleRuleEngineRequestForEntityWithQueueAndTimeout(
@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true)
@PathVariable("entityType") String entityType,
@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true)
@@ -244,5 +244,7 @@ public class RuleEngineController extends BaseController {
response != null ? response.getData() : "");
}
- private record LocalRequestMetaData(TbMsg request, SecurityUser user, DeferredResult responseWriter) {}
+ private record LocalRequestMetaData(TbMsg request, SecurityUser user,
+ DeferredResult responseWriter) {
+ }
}
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 a7aaf37ffd..429f9b9cf2 100644
--- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java
@@ -15,6 +15,7 @@
*/
package org.thingsboard.server.controller;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -118,7 +119,7 @@ public class TbResourceController extends BaseController {
.body(resource);
}
- @ApiOperation(value = "Download resource (downloadResource)",
+ @ApiOperation(value = "Download resource (downloadResourceIfChanged)",
notes = "Download resource with a given type and key for the given scope" + AVAILABLE_FOR_ANY_AUTHORIZED_USER)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/resource/{resourceType}/{scope}/{key}")
@@ -336,11 +337,10 @@ public class TbResourceController extends BaseController {
}
}
- @ApiOperation(value = "Get Resource Infos by ids (getSystemOrTenantResourcesByIds)")
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@GetMapping(value = "/resource", params = {"resourceIds"})
- public List getSystemOrTenantResourcesByIds(
- @Parameter(description = "A list of resource ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")))
+ public List getSystemOrTenantResourcesByIdsV1(
@RequestParam("resourceIds") Set resourceUuids) throws ThingsboardException {
SecurityUser user = getCurrentUser();
List resourceIds = new ArrayList<>();
@@ -350,7 +350,16 @@ public class TbResourceController extends BaseController {
return resourceService.findSystemOrTenantResourcesByIds(user.getTenantId(), resourceIds);
}
- @ApiOperation(value = "Get All Resource Infos (getAllResources)",
+ @ApiOperation(value = "Get Resource Infos by ids (getSystemOrTenantResourcesByIds)")
+ @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
+ @GetMapping(value = "/resource/list")
+ public List getSystemOrTenantResourcesByIds(
+ @Parameter(description = "A list of resource ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")))
+ @RequestParam("resourceIds") Set resourceUuids) throws ThingsboardException {
+ return getSystemOrTenantResourcesByIdsV1(resourceUuids);
+ }
+
+ @ApiOperation(value = "Get All Resource Infos (getTenantResources)",
notes = "Returns a page of Resource Info objects owned by tenant. " +
PAGE_DATA_PARAMETERS + RESOURCE_INFO_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
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 856b17fc61..70b730d588 100644
--- a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java
@@ -24,7 +24,12 @@ 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.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Parameters;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
+import io.swagger.v3.oas.annotations.media.ArraySchema;
+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;
@@ -166,7 +171,8 @@ public class TelemetryController extends BaseController {
"\n\n * SERVER_SCOPE - supported for all entity types;" +
"\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)
+ + "\n\n" + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
+ responses = @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(type = "string")))))
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/{entityType}/{entityId}/keys/attributes")
public DeferredResult getAttributeKeys(
@@ -180,7 +186,8 @@ public class TelemetryController extends BaseController {
"\n\n * SERVER_SCOPE - supported for all entity types;" +
"\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)
+ + "\n\n" + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
+ responses = @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(type = "string")))))
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/{entityType}/{entityId}/keys/attributes/{scope}")
public DeferredResult getAttributeKeysByScope(
@@ -197,13 +204,18 @@ public class TelemetryController extends BaseController {
+ MARKDOWN_CODE_BLOCK_START
+ ATTRIBUTE_DATA_EXAMPLE
+ MARKDOWN_CODE_BLOCK_END
- + "\n\n " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
+ + "\n\n " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
+ responses = @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = AttributeData.class)))))
+ @Parameters({
+ @Parameter(name = "key", description = "Repeatable key query parameter (alternative to comma-separated 'keys')", in = ParameterIn.QUERY, required = false, array = @ArraySchema(schema = @Schema(type = "string")))
+ })
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/{entityType}/{entityId}/values/attributes")
public DeferredResult getAttributes(
@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,
+ @Parameter(hidden = true)
@RequestParam MultiValueMap params) throws ThingsboardException {
List keys = getKeys(keysStr, params);
SecurityUser user = getCurrentUser();
@@ -220,7 +232,11 @@ public class TelemetryController extends BaseController {
+ MARKDOWN_CODE_BLOCK_START
+ ATTRIBUTE_DATA_EXAMPLE
+ MARKDOWN_CODE_BLOCK_END
- + "\n\n " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
+ + "\n\n " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
+ responses = @ApiResponse(content = @Content(mediaType = "application/json", array = @ArraySchema(schema = @Schema(implementation = AttributeData.class)))))
+ @Parameters({
+ @Parameter(name = "key", description = "Repeatable key query parameter (alternative to comma-separated 'keys')", in = ParameterIn.QUERY, required = false, array = @ArraySchema(schema = @Schema(type = "string")))
+ })
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/{entityType}/{entityId}/values/attributes/{scope}")
public DeferredResult getAttributesByScope(
@@ -228,6 +244,7 @@ public class TelemetryController extends BaseController {
@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"}, requiredMode = Schema.RequiredMode.REQUIRED)) @PathVariable("scope") AttributeScope scope,
@Parameter(description = ATTRIBUTES_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr,
+ @Parameter(hidden = true)
@RequestParam MultiValueMap params) throws ThingsboardException {
List keys = getKeys(keysStr, params);
SecurityUser user = getCurrentUser();
@@ -237,7 +254,8 @@ public class TelemetryController extends BaseController {
@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)
+ "\n\n" + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
+ responses = @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(type = "string")))))
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/{entityType}/{entityId}/keys/timeseries")
public DeferredResult getTimeseriesKeys(
@@ -258,7 +276,11 @@ public class TelemetryController extends BaseController {
+ MARKDOWN_CODE_BLOCK_START
+ LATEST_TS_STRICT_DATA_EXAMPLE
+ MARKDOWN_CODE_BLOCK_END
- + "\n\n " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
+ + "\n\n " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
+ responses = @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(type = "object", additionalPropertiesSchema = TsData[].class))))
+ @Parameters({
+ @Parameter(name = "key", description = "Repeatable key query parameter (alternative to comma-separated 'keys')", in = ParameterIn.QUERY, required = false, array = @ArraySchema(schema = @Schema(type = "string")))
+ })
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/{entityType}/{entityId}/values/timeseries")
public DeferredResult getLatestTimeseries(
@@ -267,6 +289,7 @@ public class TelemetryController extends BaseController {
@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,
+ @Parameter(hidden = true)
@RequestParam MultiValueMap params) throws ThingsboardException {
List keys = getKeys(keysStr, params);
SecurityUser user = getCurrentUser();
@@ -274,7 +297,32 @@ public class TelemetryController extends BaseController {
(result, tenantId, entityId) -> getLatestTimeseriesValuesCallback(result, user, entityId, keys, useStrictDataTypes));
}
- @ApiOperation(value = "Get time series data (getTimeseries)",
+ @Hidden
+ @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
+ @GetMapping(value = "/{entityType}/{entityId}/values/timeseries", params = {"startTs", "endTs"})
+ public DeferredResult getTimeseries(
+ @PathVariable("entityType") String entityType,
+ @PathVariable("entityId") String entityIdStr,
+ @RequestParam(name = "keys", required = false) String keysStr,
+ @RequestParam(name = "startTs") Long startTs,
+ @RequestParam(name = "endTs") Long endTs,
+ @RequestParam(name = "intervalType", required = false) IntervalType intervalType,
+ @RequestParam(name = "interval", defaultValue = "0") Long interval,
+ @RequestParam(name = "timeZone", required = false) String timeZone,
+ @RequestParam(name = "limit", defaultValue = "100") Integer limit,
+ @RequestParam(name = "agg", defaultValue = "NONE") String aggStr,
+ @RequestParam(name = "orderBy", defaultValue = "DESC") String orderBy,
+ @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes,
+ @RequestParam MultiValueMap params) throws ThingsboardException {
+ List keys = getKeys(keysStr, params);
+ DeferredResult response = new DeferredResult<>();
+ Futures.addCallback(tbTelemetryService.getTimeseries(EntityIdFactory.getByTypeAndId(entityType, entityIdStr), keys, startTs, endTs,
+ intervalType, interval, timeZone, limit, Aggregation.valueOf(aggStr), orderBy, useStrictDataTypes, getCurrentUser()),
+ getTsKvListCallback(response, useStrictDataTypes), MoreExecutors.directExecutor());
+ return response;
+ }
+
+ @ApiOperation(value = "Get time series data (getTimeseriesHistory)",
notes = "Returns a range of time series values for specified entity. " +
"Returns not aggregated data by default. " +
"Use aggregation function ('agg') and aggregation interval ('interval') to enable aggregation of the results on the database / server side. " +
@@ -282,10 +330,14 @@ public class TelemetryController extends BaseController {
+ MARKDOWN_CODE_BLOCK_START
+ TS_STRICT_DATA_EXAMPLE
+ MARKDOWN_CODE_BLOCK_END
- + "\n\n" + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
+ + "\n\n" + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
+ responses = @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(type = "object", additionalPropertiesSchema = TsData[].class))))
+ @Parameters({
+ @Parameter(name = "key", description = "Repeatable key query parameter (alternative to comma-separated 'keys')", in = ParameterIn.QUERY, required = false, array = @ArraySchema(schema = @Schema(type = "string")))
+ })
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
- @GetMapping(value = "/{entityType}/{entityId}/values/timeseries", params = {"startTs", "endTs"})
- public DeferredResult getTimeseries(
+ @GetMapping(value = "/{entityType}/{entityId}/values/timeseries/history")
+ public DeferredResult getTimeseriesHistory(
@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) @RequestParam(name = "keys", required = false) String keysStr,
@@ -310,13 +362,9 @@ public class TelemetryController extends BaseController {
@RequestParam(name = "orderBy", defaultValue = "DESC") String orderBy,
@Parameter(description = STRICT_DATA_TYPES_DESCRIPTION)
@RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes,
+ @Parameter(hidden = true)
@RequestParam MultiValueMap params) throws ThingsboardException {
- List keys = getKeys(keysStr, params);
- DeferredResult response = new DeferredResult<>();
- Futures.addCallback(tbTelemetryService.getTimeseries(EntityIdFactory.getByTypeAndId(entityType, entityIdStr), keys, startTs, endTs,
- intervalType, interval, timeZone, limit, Aggregation.valueOf(aggStr), orderBy, useStrictDataTypes, getCurrentUser()),
- getTsKvListCallback(response, useStrictDataTypes), MoreExecutors.directExecutor());
- return response;
+ return getTimeseries(entityType, entityIdStr, keysStr, startTs, endTs, intervalType, interval, timeZone, limit, aggStr, orderBy, useStrictDataTypes, params);
}
@ApiOperation(value = "Save device attributes (saveDeviceAttributes)",
@@ -449,6 +497,9 @@ public class TelemetryController extends BaseController {
" Use 'rewriteLatestIfDeleted' to rewrite latest value (stored in separate table for performance) if the value's timestamp matches the time-range and 'deleteLatest' param is true." +
" The replacement value will be fetched from the 'time series' table, and its timestamp will be the most recent one before the defined time-range. " +
TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
+ @Parameters({
+ @Parameter(name = "key", description = "Repeatable key query parameter (alternative to comma-separated 'keys')", in = ParameterIn.QUERY, required = false, array = @ArraySchema(schema = @Schema(type = "string")))
+ })
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Time series for the selected keys in the request was removed. " +
"Platform creates an audit log event about entity time series removal with action type 'TIMESERIES_DELETED'."),
@@ -473,6 +524,7 @@ public class TelemetryController extends BaseController {
@RequestParam(name = "deleteLatest", required = false, defaultValue = "true") boolean deleteLatest,
@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,
+ @Parameter(hidden = true)
@RequestParam MultiValueMap params) throws ThingsboardException {
List keys = getKeys(keysStr, params);
EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);
@@ -530,6 +582,9 @@ 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)
+ @Parameters({
+ @Parameter(name = "key", description = "Repeatable key query parameter (alternative to comma-separated 'keys')", in = ParameterIn.QUERY, required = false, array = @ArraySchema(schema = @Schema(type = "string")))
+ })
@ApiResponses(value = {
@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'."),
@@ -544,6 +599,7 @@ public class TelemetryController extends BaseController {
@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"}, requiredMode = Schema.RequiredMode.REQUIRED)) @PathVariable("scope") AttributeScope scope,
@Parameter(description = ATTRIBUTES_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr,
+ @Parameter(hidden = true)
@RequestParam MultiValueMap params) throws ThingsboardException {
List keys = getKeys(keysStr, params);
EntityId entityId = EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE, deviceIdStr);
@@ -553,6 +609,9 @@ 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)
+ @Parameters({
+ @Parameter(name = "key", description = "Repeatable key query parameter (alternative to comma-separated 'keys')", in = ParameterIn.QUERY, required = false, array = @ArraySchema(schema = @Schema(type = "string")))
+ })
@ApiResponses(value = {
@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'."),
@@ -568,6 +627,7 @@ public class TelemetryController extends BaseController {
@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") AttributeScope scope,
@Parameter(description = ATTRIBUTES_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr,
+ @Parameter(hidden = true)
@RequestParam MultiValueMap params) throws ThingsboardException {
List keys = getKeys(keysStr, params);
EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);
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 efa1d36cff..dcd53f7762 100644
--- a/application/src/main/java/org/thingsboard/server/controller/TenantController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/TenantController.java
@@ -15,6 +15,7 @@
*/
package org.thingsboard.server.controller;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -22,7 +23,6 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -133,7 +133,7 @@ public class TenantController extends BaseController {
@ApiOperation(value = "Get Tenants (getTenants)", notes = "Returns a page of tenants registered in the platform. " + PAGE_DATA_PARAMETERS + SYSTEM_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('SYS_ADMIN')")
- @GetMapping(value = "/tenants", params = {"pageSize", "page"})
+ @GetMapping(value = "/tenants")
public PageData getTenants(
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@@ -152,7 +152,7 @@ public class TenantController extends BaseController {
@ApiOperation(value = "Get Tenants Info (getTenants)", notes = "Returns a page of tenant info objects registered in the platform. "
+ TENANT_INFO_DESCRIPTION + PAGE_DATA_PARAMETERS + SYSTEM_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('SYS_ADMIN')")
- @GetMapping(value = "/tenantInfos", params = {"pageSize", "page"})
+ @GetMapping(value = "/tenantInfos")
public PageData getTenantInfos(
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@@ -169,9 +169,10 @@ public class TenantController extends BaseController {
return checkNotNull(tenantService.findTenantInfos(pageLink));
}
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@GetMapping(value = "/tenants", params = {"tenantIds"})
- public List getTenantsByIds(
+ public List getTenantsByIdsV1(
@Parameter(description = "A list of tenant ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")))
@RequestParam("tenantIds") Set tenantUUIDs) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
@@ -183,6 +184,15 @@ public class TenantController extends BaseController {
return filterTenantsByReadPermission(tenants);
}
+ @ApiOperation(value = "Get Tenants list (getTenantsByIds)")
+ @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
+ @GetMapping(value = "/tenants/list")
+ public List getTenantsByIds(
+ @Parameter(description = "A list of tenant ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")))
+ @RequestParam("tenantIds") Set tenantUUIDs) throws ThingsboardException {
+ return getTenantsByIdsV1(tenantUUIDs);
+ }
+
private List filterTenantsByReadPermission(List tenants) {
return tenants.stream().filter(tenant -> {
try {
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 18bc488394..a47768e91c 100644
--- a/application/src/main/java/org/thingsboard/server/controller/TenantProfileController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/TenantProfileController.java
@@ -15,6 +15,7 @@
*/
package org.thingsboard.server.controller;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -242,7 +243,7 @@ public class TenantProfileController extends BaseController {
@ApiOperation(value = "Get Tenant Profiles Info (getTenantProfileInfos)", notes = "Returns a page of tenant profile info objects registered in the platform. "
+ TENANT_PROFILE_INFO_DESCRIPTION + PAGE_DATA_PARAMETERS + SYSTEM_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('SYS_ADMIN')")
- @GetMapping(value = "/tenantProfileInfos", params = {"pageSize", "page"})
+ @GetMapping(value = "/tenantProfileInfos")
public PageData getTenantProfileInfos(
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@@ -258,11 +259,19 @@ public class TenantProfileController extends BaseController {
return checkNotNull(tenantProfileService.findTenantProfileInfos(getTenantId(), pageLink));
}
+ @Hidden
@GetMapping(value = "/tenantProfiles", params = {"ids"})
@PreAuthorize("hasAuthority('SYS_ADMIN')")
- public List getTenantProfilesByIds(@Parameter(description = "Comma-separated list of tenant profile ids", array = @ArraySchema(schema = @Schema(type = "string")))
- @RequestParam("ids") UUID[] ids) {
+ public List getTenantProfilesByIds(@RequestParam("ids") UUID[] ids) {
return tenantProfileService.findTenantProfilesByIds(TenantId.SYS_TENANT_ID, ids);
}
+ @ApiOperation(value = "Get Tenant Profile list (getTenantProfileList)")
+ @GetMapping(value = "/tenantProfiles/list")
+ @PreAuthorize("hasAuthority('SYS_ADMIN')")
+ public List getTenantProfileList(@Parameter(description = "Comma-separated list of tenant profile ids", array = @ArraySchema(schema = @Schema(type = "string")))
+ @RequestParam("ids") UUID[] ids) {
+ return getTenantProfilesByIds(ids);
+ }
+
}
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 fddeabfeaa..3b15085651 100644
--- a/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthConfigController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthConfigController.java
@@ -16,7 +16,11 @@
package org.thingsboard.server.controller;
import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.ArraySchema;
+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.validation.Valid;
import lombok.Data;
import lombok.RequiredArgsConstructor;
@@ -187,7 +191,7 @@ public class TwoFactorAuthConfigController extends BaseController {
return twoFaConfigManager.deleteTwoFaAccountConfig(user.getTenantId(), user, providerType);
}
- @ApiOperation(value = "Get available 2FA providers (getAvailableTwoFaProviders)", notes =
+ @ApiOperation(value = "Get available 2FA providers (getAvailableTwoFaProviderTypes)", notes =
"Get the list of provider types available for user to use (the ones configured by tenant or sysadmin).\n" +
"Example of response:\n" +
"```\n[\n \"TOTP\",\n \"EMAIL\",\n \"SMS\"\n]\n```" +
@@ -195,7 +199,7 @@ public class TwoFactorAuthConfigController extends BaseController {
)
@GetMapping("/providers")
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER', 'MFA_CONFIGURATION_TOKEN')")
- public List getAvailableTwoFaProviders() throws ThingsboardException {
+ public List getAvailableTwoFaProviderTypes() throws ThingsboardException {
return twoFaConfigManager.getPlatformTwoFaSettings(getTenantId(), true)
.map(PlatformTwoFaSettings::getProviders).orElse(Collections.emptyList()).stream()
.map(TwoFaProviderConfig::getProviderType)
@@ -261,6 +265,7 @@ public class TwoFactorAuthConfigController extends BaseController {
}
@Data
+ @Schema
public static class TwoFaAccountConfigUpdateRequest {
private boolean useByDefault;
}
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 e26932ff22..269e02818a 100644
--- a/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthController.java
@@ -99,7 +99,7 @@ public class TwoFactorAuthController extends BaseController {
}
}
- @ApiOperation(value = "Get available 2FA providers (getAvailableTwoFaProviders)", notes =
+ @ApiOperation(value = "Get available 2FA providers (getAvailableTwoFaProviderInfos)", notes =
"Get the list of 2FA provider infos available for user to use. Example:\n" +
"```\n[\n" +
" {\n \"type\": \"EMAIL\",\n \"default\": true,\n \"contact\": \"ab*****ko@gmail.com\"\n },\n" +
@@ -108,7 +108,7 @@ public class TwoFactorAuthController extends BaseController {
"]\n```")
@GetMapping("/providers")
@PreAuthorize("hasAuthority('PRE_VERIFICATION_TOKEN')")
- public List getAvailableTwoFaProviders() throws ThingsboardException {
+ public List getAvailableTwoFaProviderInfos() throws ThingsboardException {
SecurityUser user = getCurrentUser();
Optional platformTwoFaSettings = twoFaConfigManager.getPlatformTwoFaSettings(user.getTenantId(), true);
return twoFaConfigManager.getAccountTwoFaSettings(user.getTenantId(), user)
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 878a3287bc..1796e959ab 100644
--- a/application/src/main/java/org/thingsboard/server/controller/UserController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/UserController.java
@@ -16,6 +16,7 @@
package org.thingsboard.server.controller;
import com.fasterxml.jackson.databind.JsonNode;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -273,7 +274,7 @@ public class UserController extends BaseController {
notes = "Returns a page of users owned by tenant or customer. The scope depends on authority of the user that performs the request." +
PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @GetMapping(value = "/users", params = {"pageSize", "page"})
+ @GetMapping(value = "/users")
public PageData getUsers(
@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
@RequestParam int pageSize,
@@ -334,7 +335,7 @@ public class UserController extends BaseController {
@ApiOperation(value = "Get Tenant Users (getTenantAdmins)",
notes = "Returns a page of users owned by tenant. " + PAGE_DATA_PARAMETERS + SYSTEM_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('SYS_ADMIN')")
- @GetMapping(value = "/tenant/{tenantId}/users", params = {"pageSize", "page"})
+ @GetMapping(value = "/tenant/{tenantId}/users")
public PageData getTenantAdmins(
@Parameter(description = TENANT_ID_PARAM_DESCRIPTION, required = true)
@PathVariable(TENANT_ID) String strTenantId,
@@ -357,7 +358,7 @@ public class UserController extends BaseController {
@ApiOperation(value = "Get Customer Users (getCustomerUsers)",
notes = "Returns a page of users owned by customer. " + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
- @GetMapping(value = "/customer/{customerId}/users", params = {"pageSize", "page"})
+ @GetMapping(value = "/customer/{customerId}/users")
public PageData getCustomerUsers(
@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true)
@PathVariable(CUSTOMER_ID) String strCustomerId,
@@ -404,7 +405,7 @@ public class UserController extends BaseController {
"Search is been executed by email, firstName and lastName fields. " +
PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
- @GetMapping(value = "/users/assign/{alarmId}", params = {"pageSize", "page"})
+ @GetMapping(value = "/users/assign/{alarmId}")
public PageData getUsersForAssign(
@Parameter(description = ALARM_ID_PARAM_DESCRIPTION, required = true)
@PathVariable("alarmId") String strAlarmId,
@@ -456,10 +457,7 @@ public class UserController extends BaseController {
return userSettingsService.saveUserSettings(currentUser.getTenantId(), userSettings).getSettings();
}
- @ApiOperation(value = "Update user settings (saveUserSettings)",
- notes = "Update user settings for authorized user. Only specified json elements will be updated." +
- "Example: you have such settings: {A:5, B:{C:10, D:20}}. Updating it with {B:{C:10, D:30}} will result in" +
- "{A:5, B:{C:10, D:30}}. The same could be achieved by putting {B.D:30}")
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@PutMapping(value = "/user/settings")
public void putUserSettings(@RequestBody JsonNode settings) throws ThingsboardException {
@@ -467,8 +465,17 @@ public class UserController extends BaseController {
userSettingsService.updateUserSettings(currentUser.getTenantId(), currentUser.getId(), UserSettingsType.GENERAL, settings);
}
- @ApiOperation(value = "Get user settings (getUserSettings)",
- notes = "Fetch the User settings based on authorized user. ")
+ @ApiOperation(value = "Update user settings (putGeneralUserSettings)",
+ notes = "Update user settings for authorized user. Only specified json elements will be updated." +
+ "Example: you have such settings: {A:5, B:{C:10, D:20}}. Updating it with {B:{C:10, D:30}} will result in" +
+ "{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/general")
+ public void putGeneralUserSettings(@RequestBody JsonNode settings) throws ThingsboardException {
+ putUserSettings(settings);
+ }
+
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/user/settings")
public JsonNode getUserSettings() throws ThingsboardException {
@@ -478,20 +485,28 @@ public class UserController extends BaseController {
return userSettings == null ? JacksonUtil.newObjectNode() : userSettings.getSettings();
}
- @ApiOperation(value = "Delete user settings (deleteUserSettings)",
+ @ApiOperation(value = "Get user settings (getGeneralUserSettings)",
+ notes = "Fetch the User settings based on authorized user. ")
+ @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
+ @GetMapping(value = "/user/settings/general")
+ public JsonNode getGeneralUserSettings() throws ThingsboardException {
+ return getUserSettings();
+ }
+
+ @ApiOperation(value = "Delete user settings (deleteGeneralUserSettings)",
notes = "Delete user settings by specifying list of json element xpaths. \n " +
"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')")
@DeleteMapping(value = "/user/settings/{paths}")
- public void deleteUserSettings(@Parameter(description = PATHS)
- @PathVariable(PATHS) String paths) throws ThingsboardException {
+ public void deleteGeneralUserSettings(@Parameter(description = PATHS)
+ @PathVariable(PATHS) String paths) throws ThingsboardException {
checkParameter(USER_ID, paths);
SecurityUser currentUser = getCurrentUser();
userSettingsService.deleteUserSettings(currentUser.getTenantId(), currentUser.getId(), UserSettingsType.GENERAL, Arrays.asList(paths.split(",")));
}
- @ApiOperation(value = "Update user settings (saveUserSettings)",
+ @ApiOperation(value = "Update user settings (putUserSettings)",
notes = "Update user settings for authorized user. Only specified json elements will be updated." +
"Example: you have such settings: {A:5, B:{C:10, D:20}}. Updating it with {B:{C:10, D:30}} will result in" +
"{A:5, B:{C:10, D:30}}. The same could be achieved by putting {B.D:30}")
@@ -518,15 +533,15 @@ public class UserController extends BaseController {
return userSettings == null ? JacksonUtil.newObjectNode() : userSettings.getSettings();
}
- @ApiOperation(value = "Delete user settings (deleteUserSettings)",
+ @ApiOperation(value = "Delete user settings by type (deleteUserSettingsByType)",
notes = "Delete user settings by specifying list of json element xpaths. \n " +
"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')")
@DeleteMapping(value = "/user/settings/{type}/{paths}")
- public void deleteUserSettings(@Parameter(description = PATHS)
- @PathVariable(PATHS) String paths,
- @Parameter(description = "Settings type, case insensitive, one of: \"general\", \"quick_links\", \"doc_links\" or \"dashboards\".")
- @PathVariable("type") String strType) throws ThingsboardException {
+ public void deleteUserSettingsByType(@Parameter(description = PATHS)
+ @PathVariable(PATHS) String paths,
+ @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);
checkNotReserved(strType, type);
@@ -534,7 +549,7 @@ public class UserController extends BaseController {
userSettingsService.deleteUserSettings(currentUser.getTenantId(), currentUser.getId(), type, Arrays.asList(paths.split(",")));
}
- @ApiOperation(value = "Get information about last visited and starred dashboards (getLastVisitedDashboards)",
+ @ApiOperation(value = "Get information about last visited and starred dashboards (getUserDashboardsInfo)",
notes = "Fetch the list of last visited and starred dashboards. Both lists are limited to 10 items." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/user/dashboards")
@@ -583,12 +598,10 @@ public class UserController extends BaseController {
userService.removeMobileSession(user.getTenantId(), mobileToken);
}
- @ApiOperation(value = "Get Users By Ids (getUsersByIds)",
- notes = "Requested users must be owned by tenant or assigned to customer which user is performing the request. ")
+ @Hidden
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/users", params = {"userIds"})
- public List getUsersByIds(
- @Parameter(description = "A list of user ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
+ public List getUsersByIdsV1(
@RequestParam("userIds") Set userUUIDs) throws ThingsboardException {
TenantId tenantId = getCurrentUser().getTenantId();
List userIds = new ArrayList<>();
@@ -599,6 +612,16 @@ public class UserController extends BaseController {
return filterUsersByReadPermission(users);
}
+ @ApiOperation(value = "Get Users By Ids (getUsersByIds)",
+ notes = "Requested users must be owned by tenant or assigned to customer which user is performing the request. ")
+ @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
+ @GetMapping(value = "/users/list")
+ public List getUsersByIds(
+ @Parameter(description = "A list of user ids, separated by comma ','", array = @ArraySchema(schema = @Schema(type = "string")), required = true)
+ @RequestParam("userIds") Set userUUIDs) throws ThingsboardException {
+ return getUsersByIdsV1(userUUIDs);
+ }
+
private List filterUsersByReadPermission(List users) {
return users.stream().filter(user -> {
try {
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 a519d92e3a..cfc50543a1 100644
--- a/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java
@@ -15,6 +15,7 @@
*/
package org.thingsboard.server.controller;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -209,8 +210,7 @@ public class WidgetTypeController extends AutoCommitController {
}
}
- @ApiOperation(value = "Get all Widget types for specified Bundle (getBundleWidgetTypesByBundleAlias) (Deprecated)",
- notes = "Returns an array of Widget Type objects that belong to specified Widget Bundle." + WIDGET_TYPE_DESCRIPTION + " " + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@GetMapping(value = "/widgetTypes", params = {"isSystem", "bundleAlias"})
@Deprecated
@@ -229,19 +229,27 @@ public class WidgetTypeController extends AutoCommitController {
return checkNotNull(widgetTypeService.findWidgetTypesByWidgetsBundleId(getTenantId(), widgetsBundle.getId()));
}
- @ApiOperation(value = "Get all Widget types for specified Bundle (getBundleWidgetTypes)",
- notes = "Returns an array of Widget Type objects that belong to specified Widget Bundle." + WIDGET_TYPE_DESCRIPTION + " " + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/widgetTypes", params = {"widgetsBundleId"})
- public List getBundleWidgetTypes(
+ public List getBundleWidgetTypesV1(
@Parameter(description = "Widget Bundle Id", required = true)
@RequestParam("widgetsBundleId") String strWidgetsBundleId) throws ThingsboardException {
WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId));
return checkNotNull(widgetTypeService.findWidgetTypesByWidgetsBundleId(getTenantId(), widgetsBundleId));
}
- @ApiOperation(value = "Get all Widget types details for specified Bundle (getBundleWidgetTypesDetailsByBundleAlias) (Deprecated)",
- notes = "Returns an array of Widget Type Details objects that belong to specified Widget Bundle." + WIDGET_TYPE_DETAILS_DESCRIPTION + " " + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
+ @ApiOperation(value = "Get all Widget types for specified Bundle (getBundleWidgetTypes)",
+ notes = "Returns an array of Widget Type objects that belong to specified Widget Bundle." + WIDGET_TYPE_DESCRIPTION + " " + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
+ @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
+ @GetMapping(value = "/widgetsBundles/{widgetsBundleId}/widgetTypes")
+ public List getBundleWidgetTypes(
+ @Parameter(description = "Widget Bundle Id", required = true)
+ @PathVariable("widgetsBundleId") String strWidgetsBundleId) throws ThingsboardException {
+ return getBundleWidgetTypesV1(strWidgetsBundleId);
+ }
+
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@GetMapping(value = "/widgetTypesDetails", params = {"isSystem", "bundleAlias"})
@Deprecated
@@ -284,7 +292,7 @@ public class WidgetTypeController extends AutoCommitController {
@ApiOperation(value = "Get all Widget type fqns for specified Bundle (getBundleWidgetTypeFqns)",
notes = "Returns an array of Widget Type fqns that belong to specified Widget Bundle." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
- @GetMapping(value = "/widgetTypeFqns", params = {"widgetsBundleId"})
+ @GetMapping(value = "/widgetTypeFqns")
public List getBundleWidgetTypeFqns(
@Parameter(description = "Widget Bundle Id", required = true)
@RequestParam("widgetsBundleId") String strWidgetsBundleId) throws ThingsboardException {
@@ -292,8 +300,7 @@ public class WidgetTypeController extends AutoCommitController {
return checkNotNull(widgetTypeService.findWidgetFqnsByWidgetsBundleId(getTenantId(), widgetsBundleId));
}
- @ApiOperation(value = "Get Widget Type Info objects (getBundleWidgetTypesInfosByBundleAlias) (Deprecated)",
- notes = "Get the Widget Type Info objects based on the provided parameters. " + WIDGET_TYPE_INFO_DESCRIPTION + AVAILABLE_FOR_ANY_AUTHORIZED_USER)
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/widgetTypesInfos", params = {"isSystem", "bundleAlias"})
@Deprecated
@@ -344,8 +351,7 @@ public class WidgetTypeController extends AutoCommitController {
widgetTypeDeprecatedFilter, widgetTypes, pageLink));
}
- @ApiOperation(value = "Get Widget Type (getWidgetTypeByBundleAliasAndTypeAlias) (Deprecated)",
- notes = "Get the Widget Type based on the provided parameters. " + WIDGET_TYPE_DESCRIPTION + AVAILABLE_FOR_ANY_AUTHORIZED_USER)
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/widgetType", params = {"isSystem", "bundleAlias", "alias"})
@Deprecated
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 c2d612f014..af087c5fd2 100644
--- a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java
@@ -15,13 +15,13 @@
*/
package org.thingsboard.server.controller;
+import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -222,11 +222,10 @@ public class WidgetsBundleController extends BaseController {
}
}
- @ApiOperation(value = "Get all Widget Bundles (getWidgetsBundles)",
- notes = "Returns an array of Widget Bundle objects that are available for current user." + WIDGET_BUNDLE_DESCRIPTION + " " + AVAILABLE_FOR_ANY_AUTHORIZED_USER)
+ @Hidden
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@GetMapping(value = "/widgetsBundles")
- public List