AI rule node: add validation using annotations
This commit is contained in:
parent
1e82a332e4
commit
f2278f86c9
@ -17,7 +17,9 @@ package org.thingsboard.server.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@ -45,6 +47,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;
|
||||
|
||||
@Validated
|
||||
@RestController
|
||||
@RequestMapping("/api/ai/model/settings")
|
||||
class AiModelSettingsController extends BaseController {
|
||||
@ -59,7 +62,7 @@ class AiModelSettingsController extends BaseController {
|
||||
)
|
||||
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
|
||||
@PostMapping
|
||||
public AiModelSettings saveAiModelSettings(@RequestBody AiModelSettings settings) throws ThingsboardException {
|
||||
public AiModelSettings saveAiModelSettings(@RequestBody @Valid AiModelSettings settings) throws ThingsboardException {
|
||||
var user = getCurrentUser();
|
||||
settings.setTenantId(user.getTenantId());
|
||||
checkEntity(settings.getId(), settings, Resource.AI_MODEL_SETTINGS);
|
||||
|
||||
@ -16,6 +16,9 @@
|
||||
package org.thingsboard.server.common.data.ai;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
@ -27,6 +30,8 @@ import org.thingsboard.server.common.data.HasVersion;
|
||||
import org.thingsboard.server.common.data.ai.model.AiModel;
|
||||
import org.thingsboard.server.common.data.id.AiModelSettingsId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.validation.Length;
|
||||
import org.thingsboard.server.common.data.validation.NoNullChar;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
@ -56,6 +61,9 @@ public final class AiModelSettings extends BaseData<AiModelSettingsId> implement
|
||||
)
|
||||
private Long version;
|
||||
|
||||
@NotBlank
|
||||
@NoNullChar
|
||||
@Length(min = 1, max = 255)
|
||||
@Schema(
|
||||
requiredMode = Schema.RequiredMode.REQUIRED,
|
||||
accessMode = Schema.AccessMode.READ_WRITE,
|
||||
@ -64,6 +72,8 @@ public final class AiModelSettings extends BaseData<AiModelSettingsId> implement
|
||||
)
|
||||
private String name;
|
||||
|
||||
@NotNull
|
||||
@Valid
|
||||
@Schema(
|
||||
requiredMode = Schema.RequiredMode.NOT_REQUIRED,
|
||||
accessMode = Schema.AccessMode.READ_WRITE,
|
||||
|
||||
@ -16,6 +16,12 @@
|
||||
package org.thingsboard.server.common.data.ai.model.chat;
|
||||
|
||||
import dev.langchain4j.model.chat.ChatModel;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.validation.constraints.PositiveOrZero;
|
||||
import lombok.With;
|
||||
import org.thingsboard.server.common.data.ai.model.AiModelType;
|
||||
import org.thingsboard.server.common.data.ai.provider.AiProvider;
|
||||
@ -25,8 +31,8 @@ import java.util.List;
|
||||
|
||||
public record AmazonBedrockChatModel(
|
||||
AiModelType modelType,
|
||||
AmazonBedrockProviderConfig providerConfig,
|
||||
@With Config modelConfig
|
||||
@NotNull @Valid AmazonBedrockProviderConfig providerConfig,
|
||||
@With @NotNull @Valid Config modelConfig
|
||||
) implements AiChatModel<AmazonBedrockChatModel.Config> {
|
||||
|
||||
@Override
|
||||
@ -36,13 +42,13 @@ public record AmazonBedrockChatModel(
|
||||
|
||||
@With
|
||||
public record Config(
|
||||
String modelId,
|
||||
Double temperature,
|
||||
Double topP,
|
||||
Integer maxOutputTokens,
|
||||
@NotBlank String modelId,
|
||||
@PositiveOrZero Double temperature,
|
||||
@Positive @Max(1) Double topP,
|
||||
@Positive Integer maxOutputTokens,
|
||||
List<String> stopSequences,
|
||||
Integer timeoutSeconds,
|
||||
Integer maxRetries
|
||||
@Positive Integer timeoutSeconds,
|
||||
@PositiveOrZero Integer maxRetries
|
||||
) implements AiChatModelConfig<AmazonBedrockChatModel.Config> {}
|
||||
|
||||
@Override
|
||||
|
||||
@ -16,6 +16,12 @@
|
||||
package org.thingsboard.server.common.data.ai.model.chat;
|
||||
|
||||
import dev.langchain4j.model.chat.ChatModel;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.validation.constraints.PositiveOrZero;
|
||||
import lombok.With;
|
||||
import org.thingsboard.server.common.data.ai.model.AiModelType;
|
||||
import org.thingsboard.server.common.data.ai.provider.AiProvider;
|
||||
@ -25,8 +31,8 @@ import java.util.List;
|
||||
|
||||
public record AnthropicChatModel(
|
||||
AiModelType modelType,
|
||||
AnthropicProviderConfig providerConfig,
|
||||
@With Config modelConfig
|
||||
@NotNull @Valid AnthropicProviderConfig providerConfig,
|
||||
@With @NotNull @Valid Config modelConfig
|
||||
) implements AiChatModel<AnthropicChatModel.Config> {
|
||||
|
||||
@Override
|
||||
@ -36,14 +42,14 @@ public record AnthropicChatModel(
|
||||
|
||||
@With
|
||||
public record Config(
|
||||
String modelId,
|
||||
Double temperature,
|
||||
Double topP,
|
||||
Integer topK,
|
||||
Integer maxOutputTokens,
|
||||
@NotBlank String modelId,
|
||||
@PositiveOrZero Double temperature,
|
||||
@Positive @Max(1) Double topP,
|
||||
@Positive Integer topK,
|
||||
@Positive Integer maxOutputTokens,
|
||||
List<String> stopSequences,
|
||||
Integer timeoutSeconds,
|
||||
Integer maxRetries
|
||||
@Positive Integer timeoutSeconds,
|
||||
@PositiveOrZero Integer maxRetries
|
||||
) implements AiChatModelConfig<AnthropicChatModel.Config> {}
|
||||
|
||||
@Override
|
||||
|
||||
@ -16,6 +16,12 @@
|
||||
package org.thingsboard.server.common.data.ai.model.chat;
|
||||
|
||||
import dev.langchain4j.model.chat.ChatModel;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.validation.constraints.PositiveOrZero;
|
||||
import lombok.With;
|
||||
import org.thingsboard.server.common.data.ai.model.AiModelType;
|
||||
import org.thingsboard.server.common.data.ai.provider.AiProvider;
|
||||
@ -25,8 +31,8 @@ import java.util.List;
|
||||
|
||||
public record AzureOpenAiChatModel(
|
||||
AiModelType modelType,
|
||||
AzureOpenAiProviderConfig providerConfig,
|
||||
@With Config modelConfig
|
||||
@NotNull @Valid AzureOpenAiProviderConfig providerConfig,
|
||||
@With @NotNull @Valid Config modelConfig
|
||||
) implements AiChatModel<AzureOpenAiChatModel.Config> {
|
||||
|
||||
@Override
|
||||
@ -36,15 +42,15 @@ public record AzureOpenAiChatModel(
|
||||
|
||||
@With
|
||||
public record Config(
|
||||
String modelId,
|
||||
Double temperature,
|
||||
Double topP,
|
||||
@NotBlank String modelId,
|
||||
@PositiveOrZero Double temperature,
|
||||
@Positive @Max(1) Double topP,
|
||||
Double frequencyPenalty,
|
||||
Double presencePenalty,
|
||||
Integer maxOutputTokens,
|
||||
@Positive Integer maxOutputTokens,
|
||||
List<String> stopSequences,
|
||||
Integer timeoutSeconds,
|
||||
Integer maxRetries
|
||||
@Positive Integer timeoutSeconds,
|
||||
@PositiveOrZero Integer maxRetries
|
||||
) implements AiChatModelConfig<AzureOpenAiChatModel.Config> {}
|
||||
|
||||
@Override
|
||||
|
||||
@ -16,6 +16,12 @@
|
||||
package org.thingsboard.server.common.data.ai.model.chat;
|
||||
|
||||
import dev.langchain4j.model.chat.ChatModel;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.validation.constraints.PositiveOrZero;
|
||||
import lombok.With;
|
||||
import org.thingsboard.server.common.data.ai.model.AiModelType;
|
||||
import org.thingsboard.server.common.data.ai.provider.AiProvider;
|
||||
@ -25,8 +31,8 @@ import java.util.List;
|
||||
|
||||
public record GitHubModelsChatModel(
|
||||
AiModelType modelType,
|
||||
GitHubModelsProviderConfig providerConfig,
|
||||
@With Config modelConfig
|
||||
@NotNull @Valid GitHubModelsProviderConfig providerConfig,
|
||||
@With @NotNull @Valid Config modelConfig
|
||||
) implements AiChatModel<GitHubModelsChatModel.Config> {
|
||||
|
||||
@Override
|
||||
@ -36,15 +42,15 @@ public record GitHubModelsChatModel(
|
||||
|
||||
@With
|
||||
public record Config(
|
||||
String modelId,
|
||||
Double temperature,
|
||||
Double topP,
|
||||
@NotBlank String modelId,
|
||||
@PositiveOrZero Double temperature,
|
||||
@Positive @Max(1) Double topP,
|
||||
Double frequencyPenalty,
|
||||
Double presencePenalty,
|
||||
Integer maxOutputTokens,
|
||||
@Positive Integer maxOutputTokens,
|
||||
List<String> stopSequences,
|
||||
Integer timeoutSeconds,
|
||||
Integer maxRetries
|
||||
@Positive Integer timeoutSeconds,
|
||||
@PositiveOrZero Integer maxRetries
|
||||
) implements AiChatModelConfig<GitHubModelsChatModel.Config> {}
|
||||
|
||||
@Override
|
||||
|
||||
@ -16,6 +16,12 @@
|
||||
package org.thingsboard.server.common.data.ai.model.chat;
|
||||
|
||||
import dev.langchain4j.model.chat.ChatModel;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.validation.constraints.PositiveOrZero;
|
||||
import lombok.With;
|
||||
import org.thingsboard.server.common.data.ai.model.AiModelType;
|
||||
import org.thingsboard.server.common.data.ai.provider.AiProvider;
|
||||
@ -25,8 +31,8 @@ import java.util.List;
|
||||
|
||||
public record GoogleAiGeminiChatModel(
|
||||
AiModelType modelType,
|
||||
GoogleAiGeminiProviderConfig providerConfig,
|
||||
@With Config modelConfig
|
||||
@NotNull @Valid GoogleAiGeminiProviderConfig providerConfig,
|
||||
@With @NotNull @Valid Config modelConfig
|
||||
) implements AiChatModel<GoogleAiGeminiChatModel.Config> {
|
||||
|
||||
@Override
|
||||
@ -36,16 +42,16 @@ public record GoogleAiGeminiChatModel(
|
||||
|
||||
@With
|
||||
public record Config(
|
||||
String modelId,
|
||||
Double temperature,
|
||||
Double topP,
|
||||
Integer topK,
|
||||
@NotBlank String modelId,
|
||||
@PositiveOrZero Double temperature,
|
||||
@Positive @Max(1) Double topP,
|
||||
@Positive Integer topK,
|
||||
Double frequencyPenalty,
|
||||
Double presencePenalty,
|
||||
Integer maxOutputTokens,
|
||||
@Positive Integer maxOutputTokens,
|
||||
List<String> stopSequences,
|
||||
Integer timeoutSeconds,
|
||||
Integer maxRetries
|
||||
@Positive Integer timeoutSeconds,
|
||||
@PositiveOrZero Integer maxRetries
|
||||
) implements AiChatModelConfig<GoogleAiGeminiChatModel.Config> {}
|
||||
|
||||
@Override
|
||||
|
||||
@ -16,6 +16,12 @@
|
||||
package org.thingsboard.server.common.data.ai.model.chat;
|
||||
|
||||
import dev.langchain4j.model.chat.ChatModel;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.validation.constraints.PositiveOrZero;
|
||||
import lombok.With;
|
||||
import org.thingsboard.server.common.data.ai.model.AiModelType;
|
||||
import org.thingsboard.server.common.data.ai.provider.AiProvider;
|
||||
@ -25,8 +31,8 @@ import java.util.List;
|
||||
|
||||
public record GoogleVertexAiGeminiChatModel(
|
||||
AiModelType modelType,
|
||||
GoogleVertexAiGeminiProviderConfig providerConfig,
|
||||
@With Config modelConfig
|
||||
@NotNull @Valid GoogleVertexAiGeminiProviderConfig providerConfig,
|
||||
@With @NotNull @Valid Config modelConfig
|
||||
) implements AiChatModel<GoogleVertexAiGeminiChatModel.Config> {
|
||||
|
||||
@Override
|
||||
@ -36,16 +42,16 @@ public record GoogleVertexAiGeminiChatModel(
|
||||
|
||||
@With
|
||||
public record Config(
|
||||
String modelId,
|
||||
Double temperature,
|
||||
Double topP,
|
||||
Integer topK,
|
||||
@NotBlank String modelId,
|
||||
@PositiveOrZero Double temperature,
|
||||
@Positive @Max(1) Double topP,
|
||||
@Positive Integer topK,
|
||||
Double frequencyPenalty,
|
||||
Double presencePenalty,
|
||||
Integer maxOutputTokens,
|
||||
@Positive Integer maxOutputTokens,
|
||||
List<String> stopSequences,
|
||||
Integer timeoutSeconds,
|
||||
Integer maxRetries
|
||||
@Positive Integer timeoutSeconds,
|
||||
@PositiveOrZero Integer maxRetries
|
||||
) implements AiChatModelConfig<GoogleVertexAiGeminiChatModel.Config> {}
|
||||
|
||||
@Override
|
||||
|
||||
@ -16,6 +16,12 @@
|
||||
package org.thingsboard.server.common.data.ai.model.chat;
|
||||
|
||||
import dev.langchain4j.model.chat.ChatModel;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.validation.constraints.PositiveOrZero;
|
||||
import lombok.With;
|
||||
import org.thingsboard.server.common.data.ai.model.AiModelType;
|
||||
import org.thingsboard.server.common.data.ai.provider.AiProvider;
|
||||
@ -25,8 +31,8 @@ import java.util.List;
|
||||
|
||||
public record MistralAiChatModel(
|
||||
AiModelType modelType,
|
||||
MistralAiProviderConfig providerConfig,
|
||||
@With Config modelConfig
|
||||
@NotNull @Valid MistralAiProviderConfig providerConfig,
|
||||
@With @NotNull @Valid Config modelConfig
|
||||
) implements AiChatModel<MistralAiChatModel.Config> {
|
||||
|
||||
@Override
|
||||
@ -36,15 +42,15 @@ public record MistralAiChatModel(
|
||||
|
||||
@With
|
||||
public record Config(
|
||||
String modelId,
|
||||
Double temperature,
|
||||
Double topP,
|
||||
@NotBlank String modelId,
|
||||
@PositiveOrZero Double temperature,
|
||||
@Positive @Max(1) Double topP,
|
||||
Double frequencyPenalty,
|
||||
Double presencePenalty,
|
||||
Integer maxOutputTokens,
|
||||
@Positive Integer maxOutputTokens,
|
||||
List<String> stopSequences,
|
||||
Integer timeoutSeconds,
|
||||
Integer maxRetries
|
||||
@Positive Integer timeoutSeconds,
|
||||
@PositiveOrZero Integer maxRetries
|
||||
) implements AiChatModelConfig<MistralAiChatModel.Config> {}
|
||||
|
||||
@Override
|
||||
|
||||
@ -16,6 +16,12 @@
|
||||
package org.thingsboard.server.common.data.ai.model.chat;
|
||||
|
||||
import dev.langchain4j.model.chat.ChatModel;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.validation.constraints.PositiveOrZero;
|
||||
import lombok.With;
|
||||
import org.thingsboard.server.common.data.ai.model.AiModelType;
|
||||
import org.thingsboard.server.common.data.ai.provider.AiProvider;
|
||||
@ -25,8 +31,8 @@ import java.util.List;
|
||||
|
||||
public record OpenAiChatModel(
|
||||
AiModelType modelType,
|
||||
OpenAiProviderConfig providerConfig,
|
||||
@With Config modelConfig
|
||||
@NotNull @Valid OpenAiProviderConfig providerConfig,
|
||||
@With @NotNull @Valid Config modelConfig
|
||||
) implements AiChatModel<OpenAiChatModel.Config> {
|
||||
|
||||
@Override
|
||||
@ -36,15 +42,15 @@ public record OpenAiChatModel(
|
||||
|
||||
@With
|
||||
public record Config(
|
||||
String modelId,
|
||||
Double temperature,
|
||||
Double topP,
|
||||
@NotBlank String modelId,
|
||||
@PositiveOrZero Double temperature,
|
||||
@Positive @Max(1) Double topP,
|
||||
Double frequencyPenalty,
|
||||
Double presencePenalty,
|
||||
Integer maxOutputTokens,
|
||||
@Positive Integer maxOutputTokens,
|
||||
List<String> stopSequences,
|
||||
Integer timeoutSeconds,
|
||||
Integer maxRetries
|
||||
@Positive Integer timeoutSeconds,
|
||||
@PositiveOrZero Integer maxRetries
|
||||
) implements AiChatModelConfig<OpenAiChatModel.Config> {}
|
||||
|
||||
@Override
|
||||
|
||||
@ -15,4 +15,10 @@
|
||||
*/
|
||||
package org.thingsboard.server.common.data.ai.provider;
|
||||
|
||||
public record AmazonBedrockProviderConfig(String region, String accessKeyId, String secretAccessKey) implements AiProviderConfig {}
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public record AmazonBedrockProviderConfig(
|
||||
@NotBlank String region,
|
||||
@NotBlank String accessKeyId,
|
||||
@NotBlank String secretAccessKey
|
||||
) implements AiProviderConfig {}
|
||||
|
||||
@ -15,4 +15,8 @@
|
||||
*/
|
||||
package org.thingsboard.server.common.data.ai.provider;
|
||||
|
||||
public record AnthropicProviderConfig(String apiKey) implements AiProviderConfig {}
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public record AnthropicProviderConfig(
|
||||
@NotBlank String apiKey
|
||||
) implements AiProviderConfig {}
|
||||
|
||||
@ -15,4 +15,10 @@
|
||||
*/
|
||||
package org.thingsboard.server.common.data.ai.provider;
|
||||
|
||||
public record AzureOpenAiProviderConfig(String endpoint, String serviceVersion, String apiKey) implements AiProviderConfig {}
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public record AzureOpenAiProviderConfig(
|
||||
@NotBlank String endpoint,
|
||||
String serviceVersion,
|
||||
@NotBlank String apiKey
|
||||
) implements AiProviderConfig {}
|
||||
|
||||
@ -15,4 +15,8 @@
|
||||
*/
|
||||
package org.thingsboard.server.common.data.ai.provider;
|
||||
|
||||
public record GitHubModelsProviderConfig(String personalAccessToken) implements AiProviderConfig {}
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public record GitHubModelsProviderConfig(
|
||||
@NotBlank String personalAccessToken
|
||||
) implements AiProviderConfig {}
|
||||
|
||||
@ -15,4 +15,8 @@
|
||||
*/
|
||||
package org.thingsboard.server.common.data.ai.provider;
|
||||
|
||||
public record GoogleAiGeminiProviderConfig(String apiKey) implements AiProviderConfig {}
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public record GoogleAiGeminiProviderConfig(
|
||||
@NotBlank String apiKey
|
||||
) implements AiProviderConfig {}
|
||||
|
||||
@ -15,9 +15,11 @@
|
||||
*/
|
||||
package org.thingsboard.server.common.data.ai.provider;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public record GoogleVertexAiGeminiProviderConfig(
|
||||
String fileName, // not used on BE, but needed for UI
|
||||
String projectId,
|
||||
String location,
|
||||
String serviceAccountKey
|
||||
@NotBlank String fileName, // not used on BE, but needed for UI
|
||||
@NotBlank String projectId,
|
||||
@NotBlank String location,
|
||||
@NotBlank String serviceAccountKey
|
||||
) implements AiProviderConfig {}
|
||||
|
||||
@ -15,4 +15,8 @@
|
||||
*/
|
||||
package org.thingsboard.server.common.data.ai.provider;
|
||||
|
||||
public record MistralAiProviderConfig(String apiKey) implements AiProviderConfig {}
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public record MistralAiProviderConfig(
|
||||
@NotBlank String apiKey
|
||||
) implements AiProviderConfig {}
|
||||
|
||||
@ -15,4 +15,8 @@
|
||||
*/
|
||||
package org.thingsboard.server.common.data.ai.provider;
|
||||
|
||||
public record OpenAiProviderConfig(String apiKey) implements AiProviderConfig {}
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public record OpenAiProviderConfig(
|
||||
@NotBlank String apiKey
|
||||
) implements AiProviderConfig {}
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright © 2016-2025 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.thingsboard.server.common.data.validation;
|
||||
|
||||
import jakarta.validation.Constraint;
|
||||
import jakarta.validation.Payload;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Documented
|
||||
@Constraint(validatedBy = {})
|
||||
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.RECORD_COMPONENT})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface NoNullChar {
|
||||
|
||||
String message() default "should not contain 0x00 symbol";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
}
|
||||
@ -21,7 +21,6 @@ import jakarta.validation.Validation;
|
||||
import jakarta.validation.Validator;
|
||||
import jakarta.validation.constraints.AssertTrue;
|
||||
import jakarta.validation.metadata.ConstraintDescriptor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hibernate.validator.HibernateValidator;
|
||||
import org.hibernate.validator.HibernateValidatorConfiguration;
|
||||
@ -32,6 +31,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
import org.thingsboard.server.common.data.validation.Length;
|
||||
import org.thingsboard.server.common.data.validation.NoNullChar;
|
||||
import org.thingsboard.server.common.data.validation.NoXss;
|
||||
import org.thingsboard.server.common.data.validation.RateLimit;
|
||||
import org.thingsboard.server.dao.exception.DataValidationException;
|
||||
@ -40,7 +40,6 @@ import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class ConstraintValidator {
|
||||
|
||||
@ -88,7 +87,9 @@ public class ConstraintValidator {
|
||||
ConstraintMapping constraintMapping = getCustomConstraintMapping();
|
||||
validatorConfiguration.addMapping(constraintMapping);
|
||||
|
||||
fieldsValidator = validatorConfiguration.buildValidatorFactory().getValidator();
|
||||
try (var validatorFactory = validatorConfiguration.buildValidatorFactory()) {
|
||||
fieldsValidator = validatorFactory.getValidator();
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ -105,6 +106,7 @@ public class ConstraintValidator {
|
||||
constraintMapping.constraintDefinition(NoXss.class).validatedBy(NoXssValidator.class);
|
||||
constraintMapping.constraintDefinition(Length.class).validatedBy(StringLengthValidator.class);
|
||||
constraintMapping.constraintDefinition(RateLimit.class).validatedBy(RateLimitValidator.class);
|
||||
constraintMapping.constraintDefinition(NoNullChar.class).validatedBy(NoNullCharValidator.class);
|
||||
return constraintMapping;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright © 2016-2025 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.thingsboard.server.dao.service;
|
||||
|
||||
import jakarta.validation.ConstraintValidator;
|
||||
import jakarta.validation.ConstraintValidatorContext;
|
||||
import org.thingsboard.server.common.data.validation.NoNullChar;
|
||||
|
||||
public final class NoNullCharValidator implements ConstraintValidator<NoNullChar, String> {
|
||||
|
||||
@Override
|
||||
public boolean isValid(String value, ConstraintValidatorContext context) {
|
||||
return value == null || !value.contains("\u0000");
|
||||
}
|
||||
|
||||
}
|
||||
@ -64,17 +64,6 @@ class AiModelSettingsDataValidator extends DataValidator<AiModelSettings> {
|
||||
if (!tenantService.tenantExists(tenantId)) {
|
||||
throw new DataValidationException("AI model settings reference a non-existent tenant!");
|
||||
}
|
||||
|
||||
// name validation
|
||||
validateString("AI model settings name", settings.getName());
|
||||
if (settings.getName().length() > 255) {
|
||||
throw new DataValidationException("AI model settings name should be between 1 and 255 symbols!");
|
||||
}
|
||||
|
||||
// model config validation
|
||||
if (settings.getConfiguration() == null) {
|
||||
throw new DataValidationException("AI model settings configuration should be specified!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user