From 2286a4aabf992930d0b47985470484f9c2c447b3 Mon Sep 17 00:00:00 2001 From: nyagamunene Date: Tue, 21 Jan 2025 00:09:11 +0300 Subject: [PATCH 1/3] add rules engine Signed-off-by: nyagamunene --- apidocs/openapi/rules.yml | 322 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 apidocs/openapi/rules.yml diff --git a/apidocs/openapi/rules.yml b/apidocs/openapi/rules.yml new file mode 100644 index 000000000..c6fe3fbd4 --- /dev/null +++ b/apidocs/openapi/rules.yml @@ -0,0 +1,322 @@ +openapi: 3.0.1 +info: + title: Magistrala Rules Engine API + description: | + Rules Engine API for Magistrala IoT platform. + Enables creation and management of rules for processing and routing messages. + version: 1.0.0 + +servers: + - url: http://localhost:9021 + description: Local development server + +paths: + /{domainID}/rules: + post: + summary: Create Rule + description: Creates a new rule for message processing + tags: + - Rules + parameters: + - $ref: '#/components/parameters/DomainID' + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Rule' + responses: + '201': + description: Rule created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Rule' + '400': + description: Failed due to malformed JSON + '401': + description: Missing or invalid access token + '415': + description: Missing or invalid content type + get: + summary: List Rules + description: Retrieves a list of rules with optional filtering + tags: + - Rules + parameters: + - $ref: '#/components/parameters/DomainID' + - $ref: '#/components/parameters/Offset' + - $ref: '#/components/parameters/Limit' + - $ref: '#/components/parameters/InputChannel' + - $ref: '#/components/parameters/OutputChannel' + - $ref: '#/components/parameters/Status' + security: + - bearerAuth: [] + responses: + '200': + description: Rules retrieved successfully + content: + application/json: + schema: + type: object + properties: + total: + type: integer + description: Total number of rules + offset: + type: integer + description: Number of items to skip + limit: + type: integer + description: Size of the subset + rules: + type: array + items: + $ref: '#/components/schemas/Rule' + '400': + description: Failed due to malformed query parameters + '401': + description: Missing or invalid access token + + /{domainID}/rules/{ruleID}: + get: + summary: View Rule + description: Retrieves a rule by ID + tags: + - Rules + parameters: + - $ref: '#/components/parameters/DomainID' + - $ref: '#/components/parameters/RuleID' + security: + - bearerAuth: [] + responses: + '200': + description: Rule retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Rule' + '401': + description: Missing or invalid access token + '404': + description: Rule not found + put: + summary: Update Rule + description: Updates an existing rule + tags: + - Rules + parameters: + - $ref: '#/components/parameters/DomainID' + - $ref: '#/components/parameters/RuleID' + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Rule' + responses: + '200': + description: Rule updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Rule' + '400': + description: Failed due to malformed JSON + '401': + description: Missing or invalid access token + '404': + description: Rule not found + delete: + summary: Delete Rule + description: Deletes a rule + tags: + - Rules + parameters: + - $ref: '#/components/parameters/DomainID' + - $ref: '#/components/parameters/RuleID' + security: + - bearerAuth: [] + responses: + '204': + description: Rule deleted successfully + '401': + description: Missing or invalid access token + '404': + description: Rule not found + + /{domainID}/rules/{ruleID}/enable: + put: + summary: Enable Rule + description: Enables a rule for processing + tags: + - Rules + parameters: + - $ref: '#/components/parameters/DomainID' + - $ref: '#/components/parameters/RuleID' + security: + - bearerAuth: [] + responses: + '200': + description: Rule enabled successfully + '401': + description: Missing or invalid access token + '404': + description: Rule not found + + /{domainID}/rules/{ruleID}/disable: + put: + summary: Disable Rule + description: Disables a rule from processing + tags: + - Rules + parameters: + - $ref: '#/components/parameters/DomainID' + - $ref: '#/components/parameters/RuleID' + security: + - bearerAuth: [] + responses: + '200': + description: Rule disabled successfully + '401': + description: Missing or invalid access token + '404': + description: Rule not found + +components: + parameters: + DomainID: + name: domainID + description: Domain ID + in: path + required: true + schema: + type: string + RuleID: + name: ruleID + description: Rule ID + in: path + required: true + schema: + type: string + Offset: + name: offset + description: Number of items to skip + in: query + required: false + schema: + type: integer + default: 0 + minimum: 0 + Limit: + name: limit + description: Size of the subset + in: query + required: false + schema: + type: integer + default: 10 + minimum: 1 + InputChannel: + name: input_channel + description: Filter by input channel + in: query + required: false + schema: + type: string + OutputChannel: + name: output_channel + description: Filter by output channel + in: query + required: false + schema: + type: string + Status: + name: status + description: Filter by rule status + in: query + required: false + schema: + type: string + enum: [enabled, disabled] + default: enabled + + schemas: + Rule: + type: object + properties: + id: + type: string + description: Unique rule identifier + readOnly: true + name: + type: string + description: Rule name + description: + type: string + description: Rule description + input_channel: + type: string + description: Channel to receive messages from + output_channel: + type: string + description: Channel to send processed messages to + conditions: + type: array + description: List of conditions that trigger the rule + items: + type: object + properties: + field: + type: string + description: Message field to evaluate + operation: + type: string + description: Comparison operation + value: + type: string + description: Value to compare against + transformations: + type: array + description: List of transformations to apply to messages + items: + type: object + properties: + field: + type: string + description: Message field to transform + operation: + type: string + description: Transformation operation + value: + type: string + description: Value for transformation + status: + type: string + description: Rule status + enum: [enabled, disabled] + default: enabled + created_at: + type: string + format: date-time + description: Creation timestamp + readOnly: true + updated_at: + type: string + format: date-time + description: Last update timestamp + readOnly: true + required: + - name + - input_channel + - output_channel + + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT From e8f5b710bd8ba0840df66251806345596aef55c1 Mon Sep 17 00:00:00 2001 From: nyagamunene Date: Tue, 21 Jan 2025 00:15:51 +0300 Subject: [PATCH 2/3] update header license Signed-off-by: nyagamunene --- apidocs/openapi/rules.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apidocs/openapi/rules.yml b/apidocs/openapi/rules.yml index c6fe3fbd4..0d66fdfac 100644 --- a/apidocs/openapi/rules.yml +++ b/apidocs/openapi/rules.yml @@ -1,3 +1,6 @@ +# Copyright (c) Abstract Machines +# SPDX-License-Identifier: Apache-2.0 + openapi: 3.0.1 info: title: Magistrala Rules Engine API From 9a5a0adab447e9916a13cfd797f9c32573355f1b Mon Sep 17 00:00:00 2001 From: nyagamunene Date: Thu, 23 Jan 2025 17:19:37 +0300 Subject: [PATCH 3/3] update the api docs Signed-off-by: nyagamunene --- apidocs/openapi/rules.yml | 450 +++++++++++++++++++++++++++----------- 1 file changed, 326 insertions(+), 124 deletions(-) diff --git a/apidocs/openapi/rules.yml b/apidocs/openapi/rules.yml index 0d66fdfac..ab5c352e9 100644 --- a/apidocs/openapi/rules.yml +++ b/apidocs/openapi/rules.yml @@ -5,49 +5,62 @@ openapi: 3.0.1 info: title: Magistrala Rules Engine API description: | - Rules Engine API for Magistrala IoT platform. - Enables creation and management of rules for processing and routing messages. - version: 1.0.0 + HTTP API for managing rules engine service. + Some useful links: + - [The Magistrala repository](https://github.com/absmach/magistrala) + contact: + email: info@abstractmachines.fr + license: + name: Apache 2.0 + url: https://github.com/absmach/magistrala/blob/main/LICENSE + version: 0.15.1 servers: - - url: http://localhost:9021 - description: Local development server + - url: http://localhost:9008 + - url: http://localhost:9008 + +tags: + - name: rules engine + description: Everything about your Rules Engine + externalDocs: + description: Find out more about rules engine + url: https://docs.magistrala.abstractmachines.fr/ paths: /{domainID}/rules: post: + operationId: createRule summary: Create Rule - description: Creates a new rule for message processing + description: | + Creates a new rule for message processing tags: - - Rules + - rules parameters: - $ref: '#/components/parameters/DomainID' security: - bearerAuth: [] requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Rule' + - $ref: '#/components/requestBodies/RuleCreateReq' responses: '201': - description: Rule created successfully - content: - application/json: - schema: - $ref: '#/components/schemas/Rule' + $ref: '#/components/responses/RuleCreateRes' '400': description: Failed due to malformed JSON '401': description: Missing or invalid access token '415': description: Missing or invalid content type + "500": + $ref: "#/components/responses/ServiceError" + "503": + description: Failed to receive response from the clients service. get: + operationId: getRules summary: List Rules - description: Retrieves a list of rules with optional filtering + description: | + Retrieves a list of rules with optional filtering tags: - - Rules + - rules parameters: - $ref: '#/components/parameters/DomainID' - $ref: '#/components/parameters/Offset' @@ -59,36 +72,23 @@ paths: - bearerAuth: [] responses: '200': - description: Rules retrieved successfully - content: - application/json: - schema: - type: object - properties: - total: - type: integer - description: Total number of rules - offset: - type: integer - description: Number of items to skip - limit: - type: integer - description: Size of the subset - rules: - type: array - items: - $ref: '#/components/schemas/Rule' + $ref: '#/components/responses/RuleListRes' '400': description: Failed due to malformed query parameters '401': description: Missing or invalid access token + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" /{domainID}/rules/{ruleID}: get: + operationId: getRule summary: View Rule description: Retrieves a rule by ID tags: - - Rules + - rules parameters: - $ref: '#/components/parameters/DomainID' - $ref: '#/components/parameters/RuleID' @@ -96,49 +96,53 @@ paths: - bearerAuth: [] responses: '200': - description: Rule retrieved successfully - content: - application/json: - schema: - $ref: '#/components/schemas/Rule' + $ref: '#/components/responses/RuleRes' + "400": + description: Missing or invalid rule + "403": + description: Failed to perform authorization over the entity '401': description: Missing or invalid access token '404': - description: Rule not found + description: Rule does not exist + "422": + description: Database can't process request + "500": + $ref: "#/components/responses/ServiceError" put: + operationId: updateRule summary: Update Rule description: Updates an existing rule tags: - - Rules + - rules parameters: - $ref: '#/components/parameters/DomainID' - $ref: '#/components/parameters/RuleID' security: - bearerAuth: [] requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Rule' + $ref: '#/components/schemas/Rule' responses: '200': - description: Rule updated successfully - content: - application/json: - schema: - $ref: '#/components/schemas/Rule' + $ref: '#/components/responses/RuleRes' '400': description: Failed due to malformed JSON '401': description: Missing or invalid access token '404': - description: Rule not found + description: Rule does not exist + "415": + description: Missing or invalid content type. + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" delete: + operationId: removeRule summary: Delete Rule description: Deletes a rule tags: - - Rules + - rules parameters: - $ref: '#/components/parameters/DomainID' - $ref: '#/components/parameters/RuleID' @@ -147,17 +151,24 @@ paths: responses: '204': description: Rule deleted successfully + "400": + description: Failed due to malformed rule ID '401': description: Missing or invalid access token - '404': - description: Rule not found + "403": + description: Failed to perform authorization over the entity + "422": + description: Database can't process request + "500": + $ref: "#/components/responses/ServiceError" /{domainID}/rules/{ruleID}/enable: put: + operationId: enableRule summary: Enable Rule description: Enables a rule for processing tags: - - Rules + - rules parameters: - $ref: '#/components/parameters/DomainID' - $ref: '#/components/parameters/RuleID' @@ -166,13 +177,22 @@ paths: responses: '200': description: Rule enabled successfully + "400": + description: Failed due to malformed JSON '401': description: Missing or invalid access token + "403": + description: Failed to perform authorization over the entity '404': - description: Rule not found + description: Rule does not exist + "422": + description: Database can't process request. + "500": + $ref: "#/components/responses/ServiceError" /{domainID}/rules/{ruleID}/disable: put: + operationId: disableRule summary: Disable Rule description: Disables a rule from processing tags: @@ -185,12 +205,143 @@ paths: responses: '200': description: Rule disabled successfully + "400": + description: Failed due to malformed JSON '401': description: Missing or invalid access token + "403": + description: Failed to perform authorization over the entity '404': - description: Rule not found + description: Rule does not exist + "422": + description: Database can't process request + "500": + $ref: "#/components/responses/ServiceError" + + /health: + get: + summary: Retrieves service health check info. + tags: + - health + security: [] + responses: + "200": + $ref: "#/components/responses/HealthRes" + "500": + $ref: "#/components/responses/ServiceError" components: + schemas: + RulesListRes: + type: object + properties: + total: + type: integer + description: Total number of results + minimum: 0 + offset: + type: integer + description: Number of items to skip during retrieval + minimum: 0 + default: 0 + limit: + type: integer + description: Size of the subset to retrieve + maximum: 100 + default: 10 + rules: + type: array + minItems: 0 + uniqueItems: true + items: + $ref: '#/components/schemas/Rule' + required: + - rules + + Rule: + type: object + properties: + id: + type: string + description: Unique rule identifier + name: + type: string + description: Rule name + domain: + type: string + description: Domain ID this rule belongs to + metadata: + type: object + description: Custom metadata + additionalProperties: + type: string + input_channel: + type: string + description: Input channel for receiving messages + input_topic: + type: string + description: Input topic for receiving messages + logic: + type: object + description: Rule processing logic script + properties: + script: + type: string + description: Script content + output_channel: + type: string + description: Output channel for processed messages + output_topic: + type: string + description: Output topic for processed messages + schedule: + type: object + description: Rule execution schedule + properties: + start_datetime: + type: string + format: date-time + description: When the schedule becomes active + time: + type: string + format: date-time + description: Specific time for the rule to run + recurring: + type: string + description: Schedule recurrence pattern + enum: [None, Daily, Weekly, Monthly] + recurring_period: + type: integer + minimum: 1 + description: Controls how many intervals to skip between executions (1 = every interval, 2 = every second interval, etc.) + status: + type: string + description: Rule status + enum: [enabled, disabled] + created_at: + type: string + format: date-time + description: Creation timestamp + readOnly: true + created_by: + type: string + description: User who created the rule + updated_at: + type: string + format: date-time + description: Last update timestamp + readOnly: true + updated_by: + type: string + description: User who last updated the rule + required: + - name + - domain + - input_channel + - input_topic + - logic + - status + parameters: DomainID: name: domainID @@ -248,78 +399,129 @@ components: enum: [enabled, disabled] default: enabled - schemas: - Rule: - type: object - properties: - id: - type: string - description: Unique rule identifier - readOnly: true - name: - type: string - description: Rule name - description: - type: string - description: Rule description - input_channel: - type: string - description: Channel to receive messages from - output_channel: - type: string - description: Channel to send processed messages to - conditions: - type: array - description: List of conditions that trigger the rule - items: + requestBodies: + RuleCreateReq: + description: JSON-formatted document describing the new rule + required: true + content: + application/json: + schema: type: object properties: - field: + name: type: string - description: Message field to evaluate - operation: + description: Rule name + domain: type: string - description: Comparison operation - value: + description: Domain ID this rule belongs to + metadata: + type: object + description: Custom metadata + additionalProperties: + type: string + input_channel: type: string - description: Value to compare against - transformations: - type: array - description: List of transformations to apply to messages - items: - type: object - properties: - field: + description: Input channel for receiving messages + input_topic: type: string - description: Message field to transform - operation: + description: Input topic for receiving messages + logic: + type: object + description: Rule processing logic script + properties: + script: + type: string + description: Script content + output_channel: type: string - description: Transformation operation - value: + description: Output channel for processed messages + output_topic: type: string - description: Value for transformation - status: - type: string - description: Rule status - enum: [enabled, disabled] - default: enabled - created_at: - type: string - format: date-time - description: Creation timestamp - readOnly: true - updated_at: - type: string - format: date-time - description: Last update timestamp - readOnly: true - required: - - name - - input_channel - - output_channel + description: Output topic for processed messages + schedule: + type: object + description: Rule execution schedule + properties: + start_datetime: + type: string + format: date-time + description: When the schedule becomes active + time: + type: string + format: date-time + description: Specific time for the rule to run + recurring: + type: string + description: Schedule recurrence pattern + enum: [None, Daily, Weekly, Monthly] + recurring_period: + type: integer + minimum: 1 + description: Controls how many intervals to skip between executions + status: + type: string + description: Rule status + enum: [enabled, disabled] + required: + - name + - domain + - input_channel + - input_topic + - logic + - schedule + + responses: + RuleCreateRes: + description: Rule registered + headers: + Location: + content: + text/plain: + schema: + type: string + description: Created rule's relative URL (i.e. /rules/{ruleID}) + RuleListRes: + description: Data retrieved + content: + application/json: + schema: + $ref: '#/components/schemas/RulesListRes' + RuleRes: + description: Data retrieved + content: + application/json: + schema: + $ref: '#/components/schemas/Rule' + links: + update: + operationId: updateRule + parameters: + ruleID: $response.body#/id + enable: + operationId: enableRule + parameters: + ruleID: $response.body#/id + disable: + operationId: disableRule + parameters: + ruleID: $response.body#/id + delete: + operationId: removeRule + parameters: + ruleID: $response.body#/id + ServiceError: + description: Unexpected server-side error occurred + HealthRes: + description: Service Health Check + content: + application/health+json: + schema: + $ref: "./schemas/health_info.yml" securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT + description: | + * Users access: "Authorization: Bearer "