Skip to content

Commit 829c73f

Browse files
caoccaovanch3d
andauthored
Refactor Errors for DataHub Validation (#993)
Co-authored-by: Nicolas Van Labeke <[email protected]>
1 parent 9245eee commit 829c73f

File tree

101 files changed

+4299
-548
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+4299
-548
lines changed

ext/hivemq-edge-openapi-2025.19-SNAPSHOT.yaml

Lines changed: 1754 additions & 242 deletions
Large diffs are not rendered by default.

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ digitalpetri-modbus-tcp = "2.1.3"
1313
dropwizard-metrics = "4.2.37"
1414
equalsverifier = "3.17.5"
1515
errorprone = "2.38.0"
16+
freemarker = "2.3.34"
1617
future-converter = "1.2.0"
1718
guava = "33.4.8-jre"
1819
hikari = "6.2.1"
@@ -94,6 +95,7 @@ dropwizard-metrics-jvm = { module = "io.dropwizard.metrics:metrics-jvm", version
9495
dropwizard-metrics-logback = { module = "io.dropwizard.metrics:metrics-logback", version.ref = "dropwizard-metrics" }
9596
equalsverifier = { module = "nl.jqno.equalsverifier:equalsverifier", version.ref = "equalsverifier" }
9697
errorprone = { module = "com.google.errorprone:error_prone_core", version.ref = "errorprone" }
98+
freemarker = { module = "org.freemarker:freemarker", version.ref = "freemarker" }
9799
guava = { module = "com.google.guava:guava", version.ref = "guava" }
98100
hikari = { module = "com.zaxxer:HikariCP", version.ref = "hikari" }
99101
hivemq-edge-adaptersdk = { module = "com.hivemq:hivemq-edge-adapter-sdk", version.ref = "hivemq-edge-adaptersdk" }

hivemq-edge-frontend/src/api/hooks/useHttpClient/useHttpClient.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ export const useHttpClient = () => {
6363
{
6464
BASE: config.apiBaseUrl,
6565
TOKEN: credentials?.token,
66+
HEADERS: {
67+
Accept: 'application/json, application/problem+json',
68+
},
6669
},
6770
AxiosHttpRequestWithInterceptors
6871
)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { useMemo } from 'react'
2+
3+
import { BehaviorPolicyTransitionEvent, type FunctionSpecs } from '@/api/__generated__'
4+
import { DataHubNodeType } from '@datahub/types.ts'
5+
import { useGetAllFunctionSpecs } from '@datahub/api/hooks/DataHubFunctionsService/useGetAllFunctionSpecs.ts'
6+
7+
export const MqttTransformFunction: FunctionSpecs = {
8+
functionId: 'DataHub.transform',
9+
metadata: {
10+
inLicenseAllowed: true,
11+
isTerminal: false,
12+
isDataOnly: false,
13+
hasArguments: true,
14+
supportedEvents: [
15+
BehaviorPolicyTransitionEvent.EVENT_ON_ANY,
16+
BehaviorPolicyTransitionEvent.MQTT_ON_INBOUND_CONNECT,
17+
BehaviorPolicyTransitionEvent.MQTT_ON_INBOUND_PUBLISH,
18+
BehaviorPolicyTransitionEvent.MQTT_ON_INBOUND_SUBSCRIBE,
19+
BehaviorPolicyTransitionEvent.MQTT_ON_INBOUND_DISCONNECT,
20+
BehaviorPolicyTransitionEvent.CONNECTION_ON_DISCONNECT,
21+
],
22+
},
23+
schema: {
24+
title: 'Transformation',
25+
description:
26+
'The list of Javascript functions used in this transformation operation. Add them directly on the graph',
27+
properties: {
28+
transform: {
29+
type: 'array',
30+
title: 'Execution order',
31+
description: 'Change the order in which the transform functions will be executed',
32+
items: {
33+
type: 'string',
34+
title: 'Function name',
35+
},
36+
},
37+
},
38+
},
39+
}
40+
41+
export const useGetFilteredFunction = (
42+
type: DataHubNodeType = DataHubNodeType.DATA_POLICY,
43+
transition?: BehaviorPolicyTransitionEvent
44+
) => {
45+
const { isError, error, isLoading, isSuccess, data } = useGetAllFunctionSpecs()
46+
47+
const filteredFunctions = useMemo(() => {
48+
if (!data || !data.items?.length) return []
49+
50+
return data.items.filter((functionSpec) => {
51+
if (!functionSpec.metadata.inLicenseAllowed) return false
52+
if (
53+
functionSpec.metadata.supportedEvents?.length &&
54+
transition &&
55+
!functionSpec.metadata.supportedEvents.includes(transition)
56+
)
57+
return false
58+
if (functionSpec.metadata.isDataOnly && type !== DataHubNodeType.DATA_POLICY) return false
59+
60+
// In all other cases, the function is valid
61+
return true
62+
})
63+
}, [data, transition, type])
64+
65+
return { data: [...filteredFunctions, MqttTransformFunction], isError, error, isLoading, isSuccess }
66+
}

hivemq-edge-openapi/openapi/components/schemas/ProblemDetails.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ properties:
66
detail:
77
type: string
88
errors:
9+
deprecated: true
910
type: array
1011
items:
1112
$ref: ./Error.yaml
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
allOf:
2+
- $ref: "../ProblemDetails.yaml"
3+
- type: object
4+
required:
5+
- detail
6+
- status
7+
- type
8+
discriminator:
9+
propertyName: type
10+
mapping:
11+
# DataHub
12+
https://hivemq.com/edge/api/model/BehaviorPolicyAlreadyPresentError: "./datahub/BehaviorPolicyAlreadyPresentError.yaml"
13+
https://hivemq.com/edge/api/model/BehaviorPolicyCreationFailureError: "./datahub/BehaviorPolicyCreationFailureError.yaml"
14+
https://hivemq.com/edge/api/model/BehaviorPolicyInvalidErrors: "./datahub/BehaviorPolicyInvalidErrors.yaml"
15+
https://hivemq.com/edge/api/model/BehaviorPolicyNotFoundError: "./datahub/BehaviorPolicyNotFoundError.yaml"
16+
https://hivemq.com/edge/api/model/BehaviorPolicyRejectedError: "./datahub/BehaviorPolicyRejectedError.yaml"
17+
https://hivemq.com/edge/api/model/BehaviorPolicyUpdateFailureError: "./datahub/BehaviorPolicyUpdateFailureError.yaml"
18+
https://hivemq.com/edge/api/model/ClientDisconnectedError: "./datahub/ClientDisconnectedError.yaml"
19+
https://hivemq.com/edge/api/model/ClientNotFoundError: "./datahub/ClientNotFoundError.yaml"
20+
https://hivemq.com/edge/api/model/DataPolicyAlreadyPresentError: "./datahub/DataPolicyAlreadyPresentError.yaml"
21+
https://hivemq.com/edge/api/model/DataPolicyCreationFailureError: "./datahub/DataPolicyCreationFailureError.yaml"
22+
https://hivemq.com/edge/api/model/DataPolicyInvalidErrors: "./datahub/DataPolicyInvalidErrors.yaml"
23+
https://hivemq.com/edge/api/model/DataPolicyNotFoundError: "./datahub/DataPolicyNotFoundError.yaml"
24+
https://hivemq.com/edge/api/model/DataPolicyRejectedError: "./datahub/DataPolicyRejectedError.yaml"
25+
https://hivemq.com/edge/api/model/DataPolicyUpdateFailureError: "./datahub/DataPolicyUpdateFailureError.yaml"
26+
https://hivemq.com/edge/api/model/PolicyIdMismatchError: "./datahub/PolicyIdMismatchError.yaml"
27+
https://hivemq.com/edge/api/model/PolicyInsufficientStorageError: "./datahub/PolicyInsufficientStorageError.yaml"
28+
https://hivemq.com/edge/api/model/PolicyNotFoundError: "./datahub/PolicyNotFoundError.yaml"
29+
https://hivemq.com/edge/api/model/SchemaAlreadyPresentError: "./datahub/SchemaAlreadyPresentError.yaml"
30+
https://hivemq.com/edge/api/model/SchemaEtagMismatchError: "./datahub/SchemaEtagMismatchError.yaml"
31+
https://hivemq.com/edge/api/model/SchemaInsufficientStorageError: "./datahub/SchemaInsufficientStorageError.yaml"
32+
https://hivemq.com/edge/api/model/SchemaInvalidErrors: "./datahub/SchemaInvalidErrors.yaml"
33+
https://hivemq.com/edge/api/model/SchemaNotFoundError: "./datahub/SchemaNotFoundError.yaml"
34+
https://hivemq.com/edge/api/model/SchemaParsingFailureError: "./datahub/SchemaParsingFailureError.yaml"
35+
https://hivemq.com/edge/api/model/SchemaReferencedError: "./datahub/SchemaReferencedError.yaml"
36+
https://hivemq.com/edge/api/model/ScriptAlreadyPresentError: "./datahub/ScriptAlreadyPresentError.yaml"
37+
https://hivemq.com/edge/api/model/ScriptCreationFailureError: "./datahub/ScriptCreationFailureError.yaml"
38+
https://hivemq.com/edge/api/model/ScriptEtagMismatchError: "./datahub/ScriptEtagMismatchError.yaml"
39+
https://hivemq.com/edge/api/model/ScriptInsufficientStorageError: "./datahub/ScriptInsufficientStorageError.yaml"
40+
https://hivemq.com/edge/api/model/ScriptInvalidErrors: "./datahub/ScriptInvalidErrors.yaml"
41+
https://hivemq.com/edge/api/model/ScriptNotFoundError: "./datahub/ScriptNotFoundError.yaml"
42+
https://hivemq.com/edge/api/model/ScriptParsingFailureError: "./datahub/ScriptParsingFailureError.yaml"
43+
https://hivemq.com/edge/api/model/ScriptReferencedError: "./datahub/ScriptReferencedError.yaml"
44+
https://hivemq.com/edge/api/model/ScriptSanitationFailureError: "./datahub/ScriptSanitationFailureError.yaml"
45+
https://hivemq.com/edge/api/model/TopicFilterMismatchError: "./datahub/TopicFilterMismatchError.yaml"
46+
# HTTP
47+
https://hivemq.com/edge/api/model/InsufficientStorageError: "./http/InsufficientStorageError.yaml"
48+
https://hivemq.com/edge/api/model/InternalServerError: "./http/InternalServerError.yaml"
49+
https://hivemq.com/edge/api/model/InvalidQueryParameterError: "./http/InvalidQueryParameterError.yaml"
50+
https://hivemq.com/edge/api/model/PreconditionFailedError: "./http/PreconditionFailedError.yaml"
51+
https://hivemq.com/edge/api/model/RequestBodyMissingError: "./http/RequestBodyMissingError.yaml"
52+
https://hivemq.com/edge/api/model/RequestBodyParameterMissingError: "./http/RequestBodyParameterMissingError.yaml"
53+
https://hivemq.com/edge/api/model/TemporaryNotAvailableError: "./http/TemporaryNotAvailableError.yaml"
54+
https://hivemq.com/edge/api/model/UrlParameterMissingError: "./http/UrlParameterMissingError.yaml"
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
allOf:
2+
- $ref: "../validation/ValidationError.yaml"
3+
- type: object
4+
properties:
5+
function:
6+
type: string
7+
description: The function.
8+
example: "function1"
9+
occurrences:
10+
type: integer
11+
format: int32
12+
description: The occurrences of the function.
13+
minimum: 0
14+
example: 3
15+
paths:
16+
type: array
17+
items:
18+
type: string
19+
format: json-path
20+
description: The json paths where the function occurs.
21+
example:
22+
- "$.path1"
23+
- "$.path2"
24+
- "$.path3"
25+
required:
26+
- function
27+
- occurrences
28+
- paths
29+
example:
30+
general:
31+
detail: "The pipeline must contain at most one 'function1' function, but 3 were found at ['$.path1', '$.path2', '$.path3']."
32+
function: "function1"
33+
occurrences: 3
34+
paths:
35+
- "$.path1"
36+
- "$.path2"
37+
- "$.path3"
38+
type: "https://hivemq.com/edge/api/model/AtMostOneFunctionValidationError"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
allOf:
2+
- $ref: "../ApiProblemDetails.yaml"
3+
- type: object
4+
properties:
5+
id:
6+
type: string
7+
description: The behavior policy id.
8+
example: "abc"
9+
required:
10+
- id
11+
example:
12+
general:
13+
status: 409
14+
title: "Behavior Policy Already Present"
15+
detail: "The given behavior policy 'abc' is already present."
16+
id: "abc"
17+
type: "https://hivemq.com/edge/api/model/BehaviorPolicyAlreadyPresentError"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
allOf:
2+
- $ref: "../ApiProblemDetails.yaml"
3+
example:
4+
general:
5+
status: 400
6+
title: "Behavior Policy Creation Failed"
7+
detail: "Behavior policy creation failed: The policy was rejected."
8+
type: "https://hivemq.com/edge/api/model/BehaviorPolicyCreationFailureError"
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
allOf:
2+
- $ref: "../ApiProblemDetails.yaml"
3+
- type: object
4+
properties:
5+
childErrors:
6+
type: array
7+
description: List of child validation errors.
8+
items:
9+
$ref: "./BehaviorPolicyValidationError.yaml"
10+
required:
11+
- childErrors
12+
example:
13+
general:
14+
status: 400
15+
title: "Behavior Policy Invalid"
16+
detail: "Behavior policy is invalid due to validation errors."
17+
type: "https://hivemq.com/edge/api/model/BehaviorPolicyInvalidErrors"
18+
childErrors:
19+
- detail: "The transition from state 'state1' to state 'state2' on event 'event1' in '$.path' is not defined for behavior 'id1'."
20+
fromState: "state1"
21+
toState: "state2"
22+
path: "$.path"
23+
id: "id1"
24+
type: "https://hivemq.com/edge/api/model/IllegalEventTransitionValidationError"

0 commit comments

Comments
 (0)