Browse Source
# Conflicts: # application/pom.xml # application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java # application/src/test/java/org/thingsboard/server/transport/mqtt/AbstractMqttIntegrationTest.java # common/actor/pom.xml # common/cache/pom.xml # common/cluster-api/pom.xml # common/coap-server/pom.xml # common/dao-api/pom.xml # common/data/pom.xml # common/edge-api/pom.xml # common/message/pom.xml # common/pom.xml # common/queue/pom.xml # common/stats/pom.xml # common/transport/coap/pom.xml # common/transport/http/pom.xml # common/transport/lwm2m/pom.xml # common/transport/mqtt/pom.xml # common/transport/pom.xml # common/transport/snmp/pom.xml # common/transport/transport-api/pom.xml # common/util/pom.xml # common/version-control/pom.xml # dao/pom.xml # msa/black-box-tests/pom.xml # msa/js-executor/pom.xml # msa/pom.xml # msa/tb-node/pom.xml # msa/tb/pom.xml # msa/transport/coap/pom.xml # msa/transport/http/pom.xml # msa/transport/lwm2m/pom.xml # msa/transport/mqtt/pom.xml # msa/transport/pom.xml # msa/transport/snmp/pom.xml # msa/vc-executor-docker/pom.xml # msa/vc-executor/pom.xml # msa/web-ui/pom.xml # netty-mqtt/pom.xml # pom.xml # rest-client/pom.xml # rule-engine/pom.xml # rule-engine/rule-engine-api/pom.xml # rule-engine/rule-engine-components/pom.xml # tools/pom.xml # transport/coap/pom.xml # transport/http/pom.xml # transport/lwm2m/pom.xml # transport/mqtt/pom.xml # transport/pom.xml # transport/snmp/pom.xml # ui-ngx/pom.xml # ui-ngx/src/assets/locale/locale.constant-zh_CN.jsonpull/6986/head
5002 changed files with 104508 additions and 36575 deletions
@ -0,0 +1,88 @@ |
|||
# |
|||
# Copyright © 2016-2023 The Thingsboard Authors |
|||
# |
|||
# Licensed under the Apache License, Version 2.0 (the "License"); |
|||
# you may not use this file except in compliance with the License. |
|||
# You may obtain a copy of the License at |
|||
# |
|||
# http://www.apache.org/licenses/LICENSE-2.0 |
|||
# |
|||
# Unless required by applicable law or agreed to in writing, software |
|||
# distributed under the License is distributed on an "AS IS" BASIS, |
|||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
# See the License for the specific language governing permissions and |
|||
# limitations under the License. |
|||
# |
|||
|
|||
changelog: |
|||
exclude: |
|||
labels: |
|||
- Ignore for release |
|||
categories: |
|||
- title: 'Major Core & Rule Engine' |
|||
labels: |
|||
- 'Major Core' |
|||
- 'Major Rule Engine' |
|||
exclude: |
|||
labels: |
|||
- 'Bug' |
|||
- title: 'Major UI' |
|||
labels: |
|||
- 'Major UI' |
|||
exclude: |
|||
labels: |
|||
- 'Bug' |
|||
- title: 'Major Transport' |
|||
labels: |
|||
- 'Major Transport' |
|||
exclude: |
|||
labels: |
|||
- 'Bug' |
|||
- title: 'Major Edge' |
|||
labels: |
|||
- 'Major Edge' |
|||
exclude: |
|||
labels: |
|||
- 'Bug' |
|||
- title: 'Core & Rule Engine' |
|||
labels: |
|||
- 'Core' |
|||
- 'Rule Engine' |
|||
exclude: |
|||
labels: |
|||
- 'Bug' |
|||
- title: 'UI' |
|||
labels: |
|||
- 'UI' |
|||
exclude: |
|||
labels: |
|||
- 'Bug' |
|||
- title: 'Transport' |
|||
labels: |
|||
- 'Transport' |
|||
exclude: |
|||
labels: |
|||
- 'Bug' |
|||
- title: 'Edge' |
|||
labels: |
|||
- 'Edge' |
|||
exclude: |
|||
labels: |
|||
- 'Bug' |
|||
- title: 'Bug: Core & Rule Engine' |
|||
labels: |
|||
- 'Core' |
|||
- 'Rule Engine' |
|||
- 'Bug' |
|||
- title: 'Bug: UI' |
|||
labels: |
|||
- 'UI' |
|||
- 'Bug' |
|||
- title: 'Bug: Transport' |
|||
labels: |
|||
- 'Transport' |
|||
- 'Bug' |
|||
- title: 'Bug: Edge' |
|||
labels: |
|||
- 'Edge' |
|||
- 'Bug' |
|||
@ -0,0 +1,107 @@ |
|||
## Install ThingsBoard Edge and connect to cloud instructions |
|||
|
|||
Here is the list of commands, that can be used to quickly install and connect ThingsBoard Edge to the cloud using docker compose. |
|||
|
|||
### Prerequisites |
|||
|
|||
Install <a href="https://docs.docker.com/engine/install/" target="_blank"> Docker CE</a> and <a href="https://docs.docker.com/compose/install/" target="_blank"> Docker Compose</a>. |
|||
|
|||
### Create data and logs folders |
|||
|
|||
Run following commands, before starting docker container(s), to create folders for storing data and logs. |
|||
These commands additionally will change owner of newly created folders to docker container user. |
|||
To do this (to change user) **chown** command is used, and this command requires *sudo* permissions (command will request password for a *sudo* access): |
|||
|
|||
```bash |
|||
mkdir -p ~/.mytb-edge-data && sudo chown -R 799:799 ~/.mytb-edge-data |
|||
mkdir -p ~/.mytb-edge-logs && sudo chown -R 799:799 ~/.mytb-edge-logs |
|||
{:copy-code} |
|||
``` |
|||
|
|||
### Running ThingsBoard Edge as docker service |
|||
|
|||
${LOCALHOST_WARNING} |
|||
|
|||
Create docker compose file for ThingsBoard Edge service: |
|||
|
|||
```bash |
|||
nano docker-compose.yml |
|||
{:copy-code} |
|||
``` |
|||
|
|||
Add the following lines to the yml file: |
|||
|
|||
```bash |
|||
version: '3.0' |
|||
services: |
|||
mytbedge: |
|||
restart: always |
|||
image: "thingsboard/tb-edge:${TB_EDGE_VERSION}" |
|||
ports: |
|||
- "8080:8080" |
|||
- "1883:1883" |
|||
- "5683-5688:5683-5688/udp" |
|||
environment: |
|||
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/tb-edge |
|||
CLOUD_ROUTING_KEY: ${CLOUD_ROUTING_KEY} |
|||
CLOUD_ROUTING_SECRET: ${CLOUD_ROUTING_SECRET} |
|||
CLOUD_RPC_HOST: ${BASE_URL} |
|||
CLOUD_RPC_PORT: ${CLOUD_RPC_PORT} |
|||
CLOUD_RPC_SSL_ENABLED: ${CLOUD_RPC_SSL_ENABLED} |
|||
volumes: |
|||
- ~/.mytb-edge-data:/data |
|||
- ~/.mytb-edge-logs:/var/log/tb-edge |
|||
postgres: |
|||
restart: always |
|||
image: "postgres:12" |
|||
ports: |
|||
- "5432" |
|||
environment: |
|||
POSTGRES_DB: tb-edge |
|||
POSTGRES_PASSWORD: postgres |
|||
volumes: |
|||
- ~/.mytb-edge-data/db:/var/lib/postgresql/data |
|||
{:copy-code} |
|||
``` |
|||
|
|||
#### [Optional] Update bind ports |
|||
If ThingsBoard Edge is going to be running on the same machine where ThingsBoard server (cloud) is running, you'll need to update docker compose port mapping to avoid port collision between ThingsBoard server and ThingsBoard Edge. |
|||
|
|||
Please update next lines of `docker-compose.yml` file: |
|||
|
|||
```bash |
|||
ports: |
|||
- "18080:8080" |
|||
- "11883:1883" |
|||
- "15683-15688:5683-5688/udp" |
|||
``` |
|||
Make sure that ports above (18080, 11883, 15683-15688) are not used by any other application. |
|||
|
|||
#### Start ThingsBoard Edge |
|||
Set the terminal in the directory which contains the `docker-compose.yml` file and execute the following commands to up this docker compose directly: |
|||
|
|||
```bash |
|||
docker compose up -d |
|||
docker compose logs -f mytbedge |
|||
{:copy-code} |
|||
``` |
|||
|
|||
###### NOTE: Docker Compose V2 vs docker-compose (with a hyphen) |
|||
|
|||
ThingsBoard supports Docker Compose V2 (Docker Desktop or Compose plugin) starting from **3.4.2** release, because **docker-compose** as standalone setup is no longer supported by Docker. |
|||
We **strongly** recommend to update to Docker Compose V2 and use it. |
|||
If you still rely on using Docker Compose as docker-compose (with a hyphen), then please execute the following commands to start ThingsBoard Edge: |
|||
|
|||
```bash |
|||
docker-compose up -d |
|||
docker-compose logs -f mytbedge |
|||
``` |
|||
|
|||
#### Open ThingsBoard Edge UI |
|||
|
|||
Once started, you will be able to open **ThingsBoard Edge UI** using the following link http://localhost:8080. |
|||
|
|||
###### NOTE: Edge HTTP bind port update |
|||
|
|||
Use next **ThingsBoard Edge UI** link **http://localhost:18080** if you updated HTTP 8080 bind port to **18080**. |
|||
|
|||
@ -0,0 +1,3 @@ |
|||
###### WARNING NOTE: 'localhost' can not be used as CLOUD_RPC_HOST |
|||
|
|||
Please note that your ThingsBoard base URL is **'localhost'** at the moment. **'localhost'** cannot be used for docker containers - please update **CLOUD_RPC_HOST** environment variable below to the IP address of your machine (*docker **host** machine*). IP address must be `192.168.1.XX` or similar format. In other case - ThingsBoard Edge service, that is running in docker container, will not be able to connect to the cloud. |
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,234 @@ |
|||
-- |
|||
-- Copyright © 2016-2023 The Thingsboard Authors |
|||
-- |
|||
-- Licensed under the Apache License, Version 2.0 (the "License"); |
|||
-- you may not use this file except in compliance with the License. |
|||
-- You may obtain a copy of the License at |
|||
-- |
|||
-- http://www.apache.org/licenses/LICENSE-2.0 |
|||
-- |
|||
-- Unless required by applicable law or agreed to in writing, software |
|||
-- distributed under the License is distributed on an "AS IS" BASIS, |
|||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
-- See the License for the specific language governing permissions and |
|||
-- limitations under the License. |
|||
-- |
|||
|
|||
CREATE TABLE IF NOT EXISTS rule_node_debug_event ( |
|||
id uuid NOT NULL, |
|||
tenant_id uuid NOT NULL , |
|||
ts bigint NOT NULL, |
|||
entity_id uuid NOT NULL, |
|||
service_id varchar, |
|||
e_type varchar, |
|||
e_entity_id uuid, |
|||
e_entity_type varchar, |
|||
e_msg_id uuid, |
|||
e_msg_type varchar, |
|||
e_data_type varchar, |
|||
e_relation_type varchar, |
|||
e_data varchar, |
|||
e_metadata varchar, |
|||
e_error varchar |
|||
) PARTITION BY RANGE (ts); |
|||
|
|||
CREATE TABLE IF NOT EXISTS rule_chain_debug_event ( |
|||
id uuid NOT NULL, |
|||
tenant_id uuid NOT NULL, |
|||
ts bigint NOT NULL, |
|||
entity_id uuid NOT NULL, |
|||
service_id varchar NOT NULL, |
|||
e_message varchar, |
|||
e_error varchar |
|||
) PARTITION BY RANGE (ts); |
|||
|
|||
CREATE TABLE IF NOT EXISTS stats_event ( |
|||
id uuid NOT NULL, |
|||
tenant_id uuid NOT NULL, |
|||
ts bigint NOT NULL, |
|||
entity_id uuid NOT NULL, |
|||
service_id varchar NOT NULL, |
|||
e_messages_processed bigint NOT NULL, |
|||
e_errors_occurred bigint NOT NULL |
|||
) PARTITION BY RANGE (ts); |
|||
|
|||
CREATE TABLE IF NOT EXISTS lc_event ( |
|||
id uuid NOT NULL, |
|||
tenant_id uuid NOT NULL, |
|||
ts bigint NOT NULL, |
|||
entity_id uuid NOT NULL, |
|||
service_id varchar NOT NULL, |
|||
e_type varchar NOT NULL, |
|||
e_success boolean NOT NULL, |
|||
e_error varchar |
|||
) PARTITION BY RANGE (ts); |
|||
|
|||
CREATE TABLE IF NOT EXISTS error_event ( |
|||
id uuid NOT NULL, |
|||
tenant_id uuid NOT NULL, |
|||
ts bigint NOT NULL, |
|||
entity_id uuid NOT NULL, |
|||
service_id varchar NOT NULL, |
|||
e_method varchar NOT NULL, |
|||
e_error varchar |
|||
) PARTITION BY RANGE (ts); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_rule_node_debug_event_main |
|||
ON rule_node_debug_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_rule_chain_debug_event_main |
|||
ON rule_chain_debug_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_stats_event_main |
|||
ON stats_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_lc_event_main |
|||
ON lc_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_error_event_main |
|||
ON error_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95); |
|||
|
|||
CREATE OR REPLACE FUNCTION to_safe_json(p_json text) RETURNS json |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
BEGIN |
|||
return REPLACE(p_json, '\u0000', '' )::json; |
|||
EXCEPTION |
|||
WHEN OTHERS THEN |
|||
return '{}'::json; |
|||
END; |
|||
$$; |
|||
|
|||
-- Useful to migrate old events to the new table structure; |
|||
CREATE OR REPLACE PROCEDURE migrate_regular_events(IN start_ts_in_ms bigint, IN end_ts_in_ms bigint, IN partition_size_in_hours int) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
partition_size_in_ms bigint; |
|||
p record; |
|||
table_name varchar; |
|||
BEGIN |
|||
partition_size_in_ms = partition_size_in_hours * 3600 * 1000; |
|||
|
|||
FOR p IN SELECT DISTINCT event_type as event_type, (created_time - created_time % partition_size_in_ms) as partition_ts FROM event e WHERE e.event_type in ('STATS', 'LC_EVENT', 'ERROR') and ts >= start_ts_in_ms and ts < end_ts_in_ms |
|||
LOOP |
|||
IF p.event_type = 'STATS' THEN |
|||
table_name := 'stats_event'; |
|||
ELSEIF p.event_type = 'LC_EVENT' THEN |
|||
table_name := 'lc_event'; |
|||
ELSEIF p.event_type = 'ERROR' THEN |
|||
table_name := 'error_event'; |
|||
END IF; |
|||
RAISE NOTICE '[%] Partition to create : [%-%]', table_name, p.partition_ts, (p.partition_ts + partition_size_in_ms); |
|||
EXECUTE format('CREATE TABLE IF NOT EXISTS %s_%s PARTITION OF %s FOR VALUES FROM ( %s ) TO ( %s )', table_name, p.partition_ts, table_name, p.partition_ts, (p.partition_ts + partition_size_in_ms)); |
|||
END LOOP; |
|||
|
|||
INSERT INTO stats_event |
|||
SELECT id, |
|||
tenant_id, |
|||
ts, |
|||
entity_id, |
|||
body ->> 'server', |
|||
(body ->> 'messagesProcessed')::bigint, |
|||
(body ->> 'errorsOccurred')::bigint |
|||
FROM |
|||
(select id, tenant_id, ts, entity_id, to_safe_json(body) as body |
|||
FROM event WHERE ts >= start_ts_in_ms and ts < end_ts_in_ms AND event_type = 'STATS' AND to_safe_json(body) ->> 'server' IS NOT NULL |
|||
) safe_event |
|||
ON CONFLICT DO NOTHING; |
|||
|
|||
INSERT INTO lc_event |
|||
SELECT id, |
|||
tenant_id, |
|||
ts, |
|||
entity_id, |
|||
body ->> 'server', |
|||
body ->> 'event', |
|||
(body ->> 'success')::boolean, |
|||
body ->> 'error' |
|||
FROM |
|||
(select id, tenant_id, ts, entity_id, to_safe_json(body) as body |
|||
FROM event WHERE ts >= start_ts_in_ms and ts < end_ts_in_ms AND event_type = 'LC_EVENT' AND to_safe_json(body) ->> 'server' IS NOT NULL |
|||
) safe_event |
|||
ON CONFLICT DO NOTHING; |
|||
|
|||
INSERT INTO error_event |
|||
SELECT id, |
|||
tenant_id, |
|||
ts, |
|||
entity_id, |
|||
body ->> 'server', |
|||
body ->> 'method', |
|||
body ->> 'error' |
|||
FROM |
|||
(select id, tenant_id, ts, entity_id, to_safe_json(body) as body |
|||
FROM event WHERE ts >= start_ts_in_ms and ts < end_ts_in_ms AND event_type = 'ERROR' AND to_safe_json(body) ->> 'server' IS NOT NULL |
|||
) safe_event |
|||
ON CONFLICT DO NOTHING; |
|||
|
|||
END |
|||
$$; |
|||
|
|||
-- Useful to migrate old debug events to the new table structure; |
|||
CREATE OR REPLACE PROCEDURE migrate_debug_events(IN start_ts_in_ms bigint, IN end_ts_in_ms bigint, IN partition_size_in_hours int) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
partition_size_in_ms bigint; |
|||
p record; |
|||
table_name varchar; |
|||
BEGIN |
|||
partition_size_in_ms = partition_size_in_hours * 3600 * 1000; |
|||
|
|||
FOR p IN SELECT DISTINCT event_type as event_type, (created_time - created_time % partition_size_in_ms) as partition_ts FROM event e WHERE e.event_type in ('DEBUG_RULE_NODE', 'DEBUG_RULE_CHAIN') and ts >= start_ts_in_ms and ts < end_ts_in_ms |
|||
LOOP |
|||
IF p.event_type = 'DEBUG_RULE_NODE' THEN |
|||
table_name := 'rule_node_debug_event'; |
|||
ELSEIF p.event_type = 'DEBUG_RULE_CHAIN' THEN |
|||
table_name := 'rule_chain_debug_event'; |
|||
END IF; |
|||
RAISE NOTICE '[%] Partition to create : [%-%]', table_name, p.partition_ts, (p.partition_ts + partition_size_in_ms); |
|||
EXECUTE format('CREATE TABLE IF NOT EXISTS %s_%s PARTITION OF %s FOR VALUES FROM ( %s ) TO ( %s )', table_name, p.partition_ts, table_name, p.partition_ts, (p.partition_ts + partition_size_in_ms)); |
|||
END LOOP; |
|||
|
|||
INSERT INTO rule_node_debug_event |
|||
SELECT id, |
|||
tenant_id, |
|||
ts, |
|||
entity_id, |
|||
body ->> 'server', |
|||
body ->> 'type', |
|||
(body ->> 'entityId')::uuid, |
|||
body ->> 'entityName', |
|||
(body ->> 'msgId')::uuid, |
|||
body ->> 'msgType', |
|||
body ->> 'dataType', |
|||
body ->> 'relationType', |
|||
body ->> 'data', |
|||
body ->> 'metadata', |
|||
body ->> 'error' |
|||
FROM |
|||
(select id, tenant_id, ts, entity_id, to_safe_json(body) as body |
|||
FROM event WHERE ts >= start_ts_in_ms and ts < end_ts_in_ms AND event_type = 'DEBUG_RULE_NODE' AND to_safe_json(body) ->> 'server' IS NOT NULL |
|||
) safe_event |
|||
ON CONFLICT DO NOTHING; |
|||
|
|||
INSERT INTO rule_chain_debug_event |
|||
SELECT id, |
|||
tenant_id, |
|||
ts, |
|||
entity_id, |
|||
body ->> 'server', |
|||
body ->> 'message', |
|||
body ->> 'error' |
|||
FROM |
|||
(select id, tenant_id, ts, entity_id, to_safe_json(body) as body |
|||
FROM event WHERE ts >= start_ts_in_ms and ts < end_ts_in_ms AND event_type = 'DEBUG_RULE_CHAIN' AND to_safe_json(body) ->> 'server' IS NOT NULL |
|||
) safe_event |
|||
ON CONFLICT DO NOTHING; |
|||
END |
|||
$$; |
|||
|
|||
UPDATE tb_user |
|||
SET additional_info = REPLACE(additional_info, '"lang":"ja_JA"', '"lang":"ja_JP"') |
|||
WHERE additional_info LIKE '%"lang":"ja_JA"%'; |
|||
@ -0,0 +1,142 @@ |
|||
-- |
|||
-- Copyright © 2016-2023 The Thingsboard Authors |
|||
-- |
|||
-- Licensed under the Apache License, Version 2.0 (the "License"); |
|||
-- you may not use this file except in compliance with the License. |
|||
-- You may obtain a copy of the License at |
|||
-- |
|||
-- http://www.apache.org/licenses/LICENSE-2.0 |
|||
-- |
|||
-- Unless required by applicable law or agreed to in writing, software |
|||
-- distributed under the License is distributed on an "AS IS" BASIS, |
|||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
-- See the License for the specific language governing permissions and |
|||
-- limitations under the License. |
|||
-- |
|||
|
|||
-- AUDIT LOGS MIGRATION START |
|||
DO |
|||
$$ |
|||
DECLARE table_partition RECORD; |
|||
BEGIN |
|||
-- in case of running the upgrade script a second time: |
|||
IF NOT (SELECT exists(SELECT FROM pg_tables WHERE tablename = 'old_audit_log')) THEN |
|||
ALTER TABLE audit_log RENAME TO old_audit_log; |
|||
CREATE INDEX IF NOT EXISTS idx_old_audit_log_created_time ON old_audit_log(created_time); |
|||
|
|||
ALTER INDEX IF EXISTS idx_audit_log_tenant_id_and_created_time RENAME TO idx_old_audit_log_tenant_id_and_created_time; |
|||
|
|||
FOR table_partition IN SELECT tablename AS name, split_part(tablename, '_', 3) AS partition_ts |
|||
FROM pg_tables WHERE tablename LIKE 'audit_log_%' |
|||
LOOP |
|||
EXECUTE format('ALTER TABLE %s RENAME TO old_audit_log_%s', table_partition.name, table_partition.partition_ts); |
|||
END LOOP; |
|||
ELSE |
|||
RAISE NOTICE 'Table old_audit_log already exists, leaving as is'; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
CREATE TABLE IF NOT EXISTS audit_log ( |
|||
id uuid NOT NULL, |
|||
created_time bigint NOT NULL, |
|||
tenant_id uuid, |
|||
customer_id uuid, |
|||
entity_id uuid, |
|||
entity_type varchar(255), |
|||
entity_name varchar(255), |
|||
user_id uuid, |
|||
user_name varchar(255), |
|||
action_type varchar(255), |
|||
action_data varchar(1000000), |
|||
action_status varchar(255), |
|||
action_failure_details varchar(1000000) |
|||
) PARTITION BY RANGE (created_time); |
|||
CREATE INDEX IF NOT EXISTS idx_audit_log_tenant_id_and_created_time ON audit_log(tenant_id, created_time DESC); |
|||
CREATE INDEX IF NOT EXISTS idx_audit_log_id ON audit_log(id); |
|||
|
|||
CREATE OR REPLACE PROCEDURE migrate_audit_logs(IN start_time_ms BIGINT, IN end_time_ms BIGINT, IN partition_size_ms BIGINT) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
p RECORD; |
|||
partition_end_ts BIGINT; |
|||
BEGIN |
|||
FOR p IN SELECT DISTINCT (created_time - created_time % partition_size_ms) AS partition_ts FROM old_audit_log |
|||
WHERE created_time >= start_time_ms AND created_time < end_time_ms |
|||
LOOP |
|||
partition_end_ts = p.partition_ts + partition_size_ms; |
|||
RAISE NOTICE '[audit_log] Partition to create : [%-%]', p.partition_ts, partition_end_ts; |
|||
EXECUTE format('CREATE TABLE IF NOT EXISTS audit_log_%s PARTITION OF audit_log ' || |
|||
'FOR VALUES FROM ( %s ) TO ( %s )', p.partition_ts, p.partition_ts, partition_end_ts); |
|||
END LOOP; |
|||
|
|||
INSERT INTO audit_log |
|||
SELECT id, created_time, tenant_id, customer_id, entity_id, entity_type, entity_name, user_id, user_name, action_type, action_data, action_status, action_failure_details |
|||
FROM old_audit_log |
|||
WHERE created_time >= start_time_ms AND created_time < end_time_ms; |
|||
END; |
|||
$$; |
|||
-- AUDIT LOGS MIGRATION END |
|||
|
|||
|
|||
-- EDGE EVENTS MIGRATION START |
|||
DO |
|||
$$ |
|||
DECLARE table_partition RECORD; |
|||
BEGIN |
|||
-- in case of running the upgrade script a second time: |
|||
IF NOT (SELECT exists(SELECT FROM pg_tables WHERE tablename = 'old_edge_event')) THEN |
|||
ALTER TABLE edge_event RENAME TO old_edge_event; |
|||
CREATE INDEX IF NOT EXISTS idx_old_edge_event_created_time_tmp ON old_edge_event(created_time); |
|||
ALTER INDEX IF EXISTS idx_edge_event_tenant_id_and_created_time RENAME TO idx_old_edge_event_tenant_id_and_created_time; |
|||
|
|||
FOR table_partition IN SELECT tablename AS name, split_part(tablename, '_', 3) AS partition_ts |
|||
FROM pg_tables WHERE tablename LIKE 'edge_event_%' |
|||
LOOP |
|||
EXECUTE format('ALTER TABLE %s RENAME TO old_edge_event_%s', table_partition.name, table_partition.partition_ts); |
|||
END LOOP; |
|||
ELSE |
|||
RAISE NOTICE 'Table old_edge_event already exists, leaving as is'; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
CREATE TABLE IF NOT EXISTS edge_event ( |
|||
id uuid NOT NULL, |
|||
created_time bigint NOT NULL, |
|||
edge_id uuid, |
|||
edge_event_type varchar(255), |
|||
edge_event_uid varchar(255), |
|||
entity_id uuid, |
|||
edge_event_action varchar(255), |
|||
body varchar(10000000), |
|||
tenant_id uuid, |
|||
ts bigint NOT NULL |
|||
) PARTITION BY RANGE (created_time); |
|||
CREATE INDEX IF NOT EXISTS idx_edge_event_tenant_id_and_created_time ON edge_event(tenant_id, created_time DESC); |
|||
CREATE INDEX IF NOT EXISTS idx_edge_event_id ON edge_event(id); |
|||
|
|||
CREATE OR REPLACE PROCEDURE migrate_edge_event(IN start_time_ms BIGINT, IN end_time_ms BIGINT, IN partition_size_ms BIGINT) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
p RECORD; |
|||
partition_end_ts BIGINT; |
|||
BEGIN |
|||
FOR p IN SELECT DISTINCT (created_time - created_time % partition_size_ms) AS partition_ts FROM old_edge_event |
|||
WHERE created_time >= start_time_ms AND created_time < end_time_ms |
|||
LOOP |
|||
partition_end_ts = p.partition_ts + partition_size_ms; |
|||
RAISE NOTICE '[edge_event] Partition to create : [%-%]', p.partition_ts, partition_end_ts; |
|||
EXECUTE format('CREATE TABLE IF NOT EXISTS edge_event_%s PARTITION OF edge_event ' || |
|||
'FOR VALUES FROM ( %s ) TO ( %s )', p.partition_ts, p.partition_ts, partition_end_ts); |
|||
END LOOP; |
|||
|
|||
INSERT INTO edge_event |
|||
SELECT id, created_time, edge_id, edge_event_type, edge_event_uid, entity_id, edge_event_action, body, tenant_id, ts |
|||
FROM old_edge_event |
|||
WHERE created_time >= start_time_ms AND created_time < end_time_ms; |
|||
END; |
|||
$$; |
|||
-- EDGE EVENTS MIGRATION END |
|||
@ -0,0 +1,21 @@ |
|||
-- |
|||
-- Copyright © 2016-2023 The Thingsboard Authors |
|||
-- |
|||
-- Licensed under the Apache License, Version 2.0 (the "License"); |
|||
-- you may not use this file except in compliance with the License. |
|||
-- You may obtain a copy of the License at |
|||
-- |
|||
-- http://www.apache.org/licenses/LICENSE-2.0 |
|||
-- |
|||
-- Unless required by applicable law or agreed to in writing, software |
|||
-- distributed under the License is distributed on an "AS IS" BASIS, |
|||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
-- See the License for the specific language governing permissions and |
|||
-- limitations under the License. |
|||
-- |
|||
|
|||
DROP PROCEDURE IF EXISTS update_asset_profiles; |
|||
|
|||
ALTER TABLE asset ALTER COLUMN asset_profile_id SET NOT NULL; |
|||
ALTER TABLE asset DROP CONSTRAINT IF EXISTS fk_asset_profile; |
|||
ALTER TABLE asset ADD CONSTRAINT fk_asset_profile FOREIGN KEY (asset_profile_id) REFERENCES asset_profile(id); |
|||
@ -0,0 +1,46 @@ |
|||
-- |
|||
-- Copyright © 2016-2023 The Thingsboard Authors |
|||
-- |
|||
-- Licensed under the Apache License, Version 2.0 (the "License"); |
|||
-- you may not use this file except in compliance with the License. |
|||
-- You may obtain a copy of the License at |
|||
-- |
|||
-- http://www.apache.org/licenses/LICENSE-2.0 |
|||
-- |
|||
-- Unless required by applicable law or agreed to in writing, software |
|||
-- distributed under the License is distributed on an "AS IS" BASIS, |
|||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
-- See the License for the specific language governing permissions and |
|||
-- limitations under the License. |
|||
-- |
|||
|
|||
CREATE TABLE IF NOT EXISTS asset_profile ( |
|||
id uuid NOT NULL CONSTRAINT asset_profile_pkey PRIMARY KEY, |
|||
created_time bigint NOT NULL, |
|||
name varchar(255), |
|||
image varchar(1000000), |
|||
description varchar, |
|||
search_text varchar(255), |
|||
is_default boolean, |
|||
tenant_id uuid, |
|||
default_rule_chain_id uuid, |
|||
default_dashboard_id uuid, |
|||
default_queue_name varchar(255), |
|||
external_id uuid, |
|||
CONSTRAINT asset_profile_name_unq_key UNIQUE (tenant_id, name), |
|||
CONSTRAINT asset_profile_external_id_unq_key UNIQUE (tenant_id, external_id), |
|||
CONSTRAINT fk_default_rule_chain_asset_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id), |
|||
CONSTRAINT fk_default_dashboard_asset_profile FOREIGN KEY (default_dashboard_id) REFERENCES dashboard(id) |
|||
); |
|||
|
|||
CREATE OR REPLACE PROCEDURE update_asset_profiles() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
BEGIN |
|||
UPDATE asset a SET asset_profile_id = COALESCE( |
|||
(SELECT id from asset_profile p WHERE p.tenant_id = a.tenant_id AND a.type = p.name), |
|||
(SELECT id from asset_profile p WHERE p.tenant_id = a.tenant_id AND p.name = 'default') |
|||
) |
|||
WHERE a.asset_profile_id IS NULL; |
|||
END; |
|||
$$; |
|||
@ -0,0 +1,349 @@ |
|||
-- |
|||
-- Copyright © 2016-2023 The Thingsboard Authors |
|||
-- |
|||
-- Licensed under the Apache License, Version 2.0 (the "License"); |
|||
-- you may not use this file except in compliance with the License. |
|||
-- You may obtain a copy of the License at |
|||
-- |
|||
-- http://www.apache.org/licenses/LICENSE-2.0 |
|||
-- |
|||
-- Unless required by applicable law or agreed to in writing, software |
|||
-- distributed under the License is distributed on an "AS IS" BASIS, |
|||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
-- See the License for the specific language governing permissions and |
|||
-- limitations under the License. |
|||
-- |
|||
|
|||
-- USER CREDENTIALS START |
|||
|
|||
ALTER TABLE user_credentials |
|||
ADD COLUMN IF NOT EXISTS additional_info varchar NOT NULL DEFAULT '{}'; |
|||
|
|||
UPDATE user_credentials |
|||
SET additional_info = json_build_object('userPasswordHistory', (u.additional_info::json -> 'userPasswordHistory')) |
|||
FROM tb_user u WHERE user_credentials.user_id = u.id AND u.additional_info::jsonb ? 'userPasswordHistory'; |
|||
|
|||
UPDATE tb_user SET additional_info = tb_user.additional_info::jsonb - 'userPasswordHistory' WHERE additional_info::jsonb ? 'userPasswordHistory'; |
|||
|
|||
-- USER CREDENTIALS END |
|||
|
|||
-- ALARM ASSIGN TO USER START |
|||
|
|||
ALTER TABLE alarm ADD COLUMN IF NOT EXISTS assign_ts BIGINT DEFAULT 0; |
|||
ALTER TABLE alarm ADD COLUMN IF NOT EXISTS assignee_id UUID; |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_alarm_tenant_assignee_created_time ON alarm(tenant_id, assignee_id, created_time DESC); |
|||
|
|||
-- ALARM ASSIGN TO USER END |
|||
|
|||
-- ALARM STATUS REFACTORING START |
|||
|
|||
ALTER TABLE alarm ADD COLUMN IF NOT EXISTS acknowledged boolean; |
|||
ALTER TABLE alarm ADD COLUMN IF NOT EXISTS cleared boolean; |
|||
|
|||
ALTER TABLE alarm ADD COLUMN IF NOT EXISTS status varchar; -- to avoid failure of the subsequent upgrade. |
|||
UPDATE alarm SET acknowledged = true, cleared = true WHERE status = 'CLEARED_ACK'; |
|||
UPDATE alarm SET acknowledged = true, cleared = false WHERE status = 'ACTIVE_ACK'; |
|||
UPDATE alarm SET acknowledged = false, cleared = true WHERE status = 'CLEARED_UNACK'; |
|||
UPDATE alarm SET acknowledged = false, cleared = false WHERE status = 'ACTIVE_UNACK'; |
|||
|
|||
-- Drop index by 'status' column and replace with new one that has only active alarms; |
|||
DROP INDEX IF EXISTS idx_alarm_originator_alarm_type_active; |
|||
CREATE INDEX IF NOT EXISTS idx_alarm_originator_alarm_type_active |
|||
ON alarm USING btree (originator_id, type) WHERE cleared = false; |
|||
|
|||
-- Cover index by alarm type to optimize propagated alarm queries; |
|||
DROP INDEX IF EXISTS idx_entity_alarm_entity_id_alarm_type_created_time_alarm_id; |
|||
CREATE INDEX IF NOT EXISTS idx_entity_alarm_entity_id_alarm_type_created_time_alarm_id ON entity_alarm |
|||
USING btree (tenant_id, entity_id, alarm_type, created_time DESC) INCLUDE(alarm_id); |
|||
|
|||
DROP INDEX IF EXISTS idx_alarm_tenant_status_created_time; |
|||
ALTER TABLE alarm DROP COLUMN IF EXISTS status; |
|||
|
|||
-- Update old alarms and set their state to clear, if there are newer alarms. |
|||
UPDATE alarm a |
|||
SET cleared = TRUE |
|||
WHERE cleared = FALSE |
|||
AND id != (SELECT l.id |
|||
FROM alarm l |
|||
WHERE l.tenant_id = a.tenant_id |
|||
AND l.originator_id = a.originator_id |
|||
AND l.type = a.type |
|||
ORDER BY l.created_time DESC, l.id |
|||
LIMIT 1); |
|||
|
|||
VACUUM FULL ANALYZE alarm; |
|||
|
|||
-- ALARM STATUS REFACTORING END |
|||
|
|||
-- ALARM COMMENTS START |
|||
|
|||
CREATE TABLE IF NOT EXISTS alarm_comment ( |
|||
id uuid NOT NULL, |
|||
created_time bigint NOT NULL, |
|||
alarm_id uuid NOT NULL, |
|||
user_id uuid, |
|||
type varchar(255) NOT NULL, |
|||
comment varchar(10000), |
|||
CONSTRAINT fk_alarm_comment_alarm_id FOREIGN KEY (alarm_id) REFERENCES alarm(id) ON DELETE CASCADE |
|||
) PARTITION BY RANGE (created_time); |
|||
CREATE INDEX IF NOT EXISTS idx_alarm_comment_alarm_id ON alarm_comment(alarm_id); |
|||
|
|||
CREATE TABLE IF NOT EXISTS user_settings ( |
|||
user_id uuid NOT NULL CONSTRAINT user_settings_pkey PRIMARY KEY, |
|||
settings varchar(100000), |
|||
CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES tb_user(id) ON DELETE CASCADE |
|||
); |
|||
|
|||
-- ALARM COMMENTS END |
|||
|
|||
-- ALARM INFO VIEW |
|||
|
|||
DROP VIEW IF EXISTS alarm_info CASCADE; |
|||
CREATE VIEW alarm_info AS |
|||
SELECT a.*, |
|||
(CASE WHEN a.acknowledged AND a.cleared THEN 'CLEARED_ACK' |
|||
WHEN NOT a.acknowledged AND a.cleared THEN 'CLEARED_UNACK' |
|||
WHEN a.acknowledged AND NOT a.cleared THEN 'ACTIVE_ACK' |
|||
WHEN NOT a.acknowledged AND NOT a.cleared THEN 'ACTIVE_UNACK' END) as status, |
|||
COALESCE(CASE WHEN a.originator_type = 0 THEN (select title from tenant where id = a.originator_id) |
|||
WHEN a.originator_type = 1 THEN (select title from customer where id = a.originator_id) |
|||
WHEN a.originator_type = 2 THEN (select email from tb_user where id = a.originator_id) |
|||
WHEN a.originator_type = 3 THEN (select title from dashboard where id = a.originator_id) |
|||
WHEN a.originator_type = 4 THEN (select name from asset where id = a.originator_id) |
|||
WHEN a.originator_type = 5 THEN (select name from device where id = a.originator_id) |
|||
WHEN a.originator_type = 9 THEN (select name from entity_view where id = a.originator_id) |
|||
WHEN a.originator_type = 13 THEN (select name from device_profile where id = a.originator_id) |
|||
WHEN a.originator_type = 14 THEN (select name from asset_profile where id = a.originator_id) |
|||
WHEN a.originator_type = 18 THEN (select name from edge where id = a.originator_id) END |
|||
, 'Deleted') originator_name, |
|||
COALESCE(CASE WHEN a.originator_type = 0 THEN (select title from tenant where id = a.originator_id) |
|||
WHEN a.originator_type = 1 THEN (select COALESCE(title, email) from customer where id = a.originator_id) |
|||
WHEN a.originator_type = 2 THEN (select email from tb_user where id = a.originator_id) |
|||
WHEN a.originator_type = 3 THEN (select title from dashboard where id = a.originator_id) |
|||
WHEN a.originator_type = 4 THEN (select COALESCE(label, name) from asset where id = a.originator_id) |
|||
WHEN a.originator_type = 5 THEN (select COALESCE(label, name) from device where id = a.originator_id) |
|||
WHEN a.originator_type = 9 THEN (select name from entity_view where id = a.originator_id) |
|||
WHEN a.originator_type = 13 THEN (select name from device_profile where id = a.originator_id) |
|||
WHEN a.originator_type = 14 THEN (select name from asset_profile where id = a.originator_id) |
|||
WHEN a.originator_type = 18 THEN (select COALESCE(label, name) from edge where id = a.originator_id) END |
|||
, 'Deleted') as originator_label, |
|||
u.first_name as assignee_first_name, u.last_name as assignee_last_name, u.email as assignee_email |
|||
FROM alarm a |
|||
LEFT JOIN tb_user u ON u.id = a.assignee_id; |
|||
|
|||
-- ALARM INFO VIEW END |
|||
|
|||
-- ALARM FUNCTIONS START |
|||
|
|||
DROP FUNCTION IF EXISTS create_or_update_active_alarm; |
|||
CREATE OR REPLACE FUNCTION create_or_update_active_alarm( |
|||
t_id uuid, c_id uuid, a_id uuid, a_created_ts bigint, |
|||
a_o_id uuid, a_o_type integer, a_type varchar, |
|||
a_severity varchar, a_start_ts bigint, a_end_ts bigint, |
|||
a_details varchar, |
|||
a_propagate boolean, a_propagate_to_owner boolean, |
|||
a_propagate_to_tenant boolean, a_propagation_types varchar, |
|||
a_creation_enabled boolean) |
|||
RETURNS varchar |
|||
LANGUAGE plpgsql |
|||
AS |
|||
$$ |
|||
DECLARE |
|||
null_id constant uuid = '13814000-1dd2-11b2-8080-808080808080'::uuid; |
|||
existing alarm; |
|||
result alarm_info; |
|||
row_count integer; |
|||
BEGIN |
|||
SELECT * INTO existing FROM alarm a WHERE a.originator_id = a_o_id AND a.type = a_type AND a.cleared = false ORDER BY a.start_ts DESC FOR UPDATE; |
|||
IF existing.id IS NULL THEN |
|||
IF a_creation_enabled = FALSE THEN |
|||
RETURN json_build_object('success', false)::text; |
|||
END IF; |
|||
IF c_id = null_id THEN |
|||
c_id = NULL; |
|||
end if; |
|||
INSERT INTO alarm |
|||
(tenant_id, customer_id, id, created_time, |
|||
originator_id, originator_type, type, |
|||
severity, start_ts, end_ts, |
|||
additional_info, |
|||
propagate, propagate_to_owner, propagate_to_tenant, propagate_relation_types, |
|||
acknowledged, ack_ts, |
|||
cleared, clear_ts, |
|||
assignee_id, assign_ts) |
|||
VALUES |
|||
(t_id, c_id, a_id, a_created_ts, |
|||
a_o_id, a_o_type, a_type, |
|||
a_severity, a_start_ts, a_end_ts, |
|||
a_details, |
|||
a_propagate, a_propagate_to_owner, a_propagate_to_tenant, a_propagation_types, |
|||
false, 0, false, 0, NULL, 0); |
|||
SELECT * INTO result FROM alarm_info a WHERE a.id = a_id AND a.tenant_id = t_id; |
|||
RETURN json_build_object('success', true, 'created', true, 'modified', true, 'alarm', row_to_json(result))::text; |
|||
ELSE |
|||
UPDATE alarm a |
|||
SET severity = a_severity, |
|||
start_ts = a_start_ts, |
|||
end_ts = a_end_ts, |
|||
additional_info = a_details, |
|||
propagate = a_propagate, |
|||
propagate_to_owner = a_propagate_to_owner, |
|||
propagate_to_tenant = a_propagate_to_tenant, |
|||
propagate_relation_types = a_propagation_types |
|||
WHERE a.id = existing.id |
|||
AND a.tenant_id = t_id |
|||
AND (severity != a_severity OR start_ts != a_start_ts OR end_ts != a_end_ts OR additional_info != a_details |
|||
OR propagate != a_propagate OR propagate_to_owner != a_propagate_to_owner OR |
|||
propagate_to_tenant != a_propagate_to_tenant OR propagate_relation_types != a_propagation_types); |
|||
GET DIAGNOSTICS row_count = ROW_COUNT; |
|||
SELECT * INTO result FROM alarm_info a WHERE a.id = existing.id AND a.tenant_id = t_id; |
|||
IF row_count > 0 THEN |
|||
RETURN json_build_object('success', true, 'modified', true, 'alarm', row_to_json(result), 'old', row_to_json(existing))::text; |
|||
ELSE |
|||
RETURN json_build_object('success', true, 'modified', false, 'alarm', row_to_json(result))::text; |
|||
END IF; |
|||
END IF; |
|||
END |
|||
$$; |
|||
|
|||
DROP FUNCTION IF EXISTS update_alarm; |
|||
CREATE OR REPLACE FUNCTION update_alarm(t_id uuid, a_id uuid, a_severity varchar, a_start_ts bigint, a_end_ts bigint, |
|||
a_details varchar, |
|||
a_propagate boolean, a_propagate_to_owner boolean, |
|||
a_propagate_to_tenant boolean, a_propagation_types varchar) |
|||
RETURNS varchar |
|||
LANGUAGE plpgsql |
|||
AS |
|||
$$ |
|||
DECLARE |
|||
existing alarm; |
|||
result alarm_info; |
|||
row_count integer; |
|||
BEGIN |
|||
SELECT * INTO existing FROM alarm a WHERE a.id = a_id AND a.tenant_id = t_id FOR UPDATE; |
|||
IF existing IS NULL THEN |
|||
RETURN json_build_object('success', false)::text; |
|||
END IF; |
|||
UPDATE alarm a |
|||
SET severity = a_severity, |
|||
start_ts = a_start_ts, |
|||
end_ts = a_end_ts, |
|||
additional_info = a_details, |
|||
propagate = a_propagate, |
|||
propagate_to_owner = a_propagate_to_owner, |
|||
propagate_to_tenant = a_propagate_to_tenant, |
|||
propagate_relation_types = a_propagation_types |
|||
WHERE a.id = a_id |
|||
AND a.tenant_id = t_id |
|||
AND (severity != a_severity OR start_ts != a_start_ts OR end_ts != a_end_ts OR additional_info != a_details |
|||
OR propagate != a_propagate OR propagate_to_owner != a_propagate_to_owner OR |
|||
propagate_to_tenant != a_propagate_to_tenant OR propagate_relation_types != a_propagation_types); |
|||
GET DIAGNOSTICS row_count = ROW_COUNT; |
|||
SELECT * INTO result FROM alarm_info a WHERE a.id = a_id AND a.tenant_id = t_id; |
|||
IF row_count > 0 THEN |
|||
RETURN json_build_object('success', true, 'modified', row_count > 0, 'alarm', row_to_json(result), 'old', row_to_json(existing))::text; |
|||
ELSE |
|||
RETURN json_build_object('success', true, 'modified', row_count > 0, 'alarm', row_to_json(result))::text; |
|||
END IF; |
|||
END |
|||
$$; |
|||
|
|||
DROP FUNCTION IF EXISTS acknowledge_alarm; |
|||
CREATE OR REPLACE FUNCTION acknowledge_alarm(t_id uuid, a_id uuid, a_ts bigint) |
|||
RETURNS varchar |
|||
LANGUAGE plpgsql |
|||
AS |
|||
$$ |
|||
DECLARE |
|||
existing alarm; |
|||
result alarm_info; |
|||
modified boolean = FALSE; |
|||
BEGIN |
|||
SELECT * INTO existing FROM alarm a WHERE a.id = a_id AND a.tenant_id = t_id FOR UPDATE; |
|||
IF existing IS NULL THEN |
|||
RETURN json_build_object('success', false)::text; |
|||
END IF; |
|||
|
|||
IF NOT (existing.acknowledged) THEN |
|||
modified = TRUE; |
|||
UPDATE alarm a SET acknowledged = true, ack_ts = a_ts WHERE a.id = a_id AND a.tenant_id = t_id; |
|||
END IF; |
|||
SELECT * INTO result FROM alarm_info a WHERE a.id = a_id AND a.tenant_id = t_id; |
|||
RETURN json_build_object('success', true, 'modified', modified, 'alarm', row_to_json(result))::text; |
|||
END |
|||
$$; |
|||
|
|||
DROP FUNCTION IF EXISTS clear_alarm; |
|||
CREATE OR REPLACE FUNCTION clear_alarm(t_id uuid, a_id uuid, a_ts bigint, a_details varchar) |
|||
RETURNS varchar |
|||
LANGUAGE plpgsql |
|||
AS |
|||
$$ |
|||
DECLARE |
|||
existing alarm; |
|||
result alarm_info; |
|||
cleared boolean = FALSE; |
|||
BEGIN |
|||
SELECT * INTO existing FROM alarm a WHERE a.id = a_id AND a.tenant_id = t_id FOR UPDATE; |
|||
IF existing IS NULL THEN |
|||
RETURN json_build_object('success', false)::text; |
|||
END IF; |
|||
IF NOT(existing.cleared) THEN |
|||
cleared = TRUE; |
|||
UPDATE alarm a SET cleared = true, clear_ts = a_ts, additional_info = a_details WHERE a.id = a_id AND a.tenant_id = t_id; |
|||
END IF; |
|||
SELECT * INTO result FROM alarm_info a WHERE a.id = a_id AND a.tenant_id = t_id; |
|||
RETURN json_build_object('success', true, 'cleared', cleared, 'alarm', row_to_json(result))::text; |
|||
END |
|||
$$; |
|||
|
|||
DROP FUNCTION IF EXISTS assign_alarm; |
|||
CREATE OR REPLACE FUNCTION assign_alarm(t_id uuid, a_id uuid, u_id uuid, a_ts bigint) |
|||
RETURNS varchar |
|||
LANGUAGE plpgsql |
|||
AS |
|||
$$ |
|||
DECLARE |
|||
existing alarm; |
|||
result alarm_info; |
|||
modified boolean = FALSE; |
|||
BEGIN |
|||
SELECT * INTO existing FROM alarm a WHERE a.id = a_id AND a.tenant_id = t_id FOR UPDATE; |
|||
IF existing IS NULL THEN |
|||
RETURN json_build_object('success', false)::text; |
|||
END IF; |
|||
IF existing.assignee_id IS NULL OR existing.assignee_id != u_id THEN |
|||
modified = TRUE; |
|||
UPDATE alarm a SET assignee_id = u_id, assign_ts = a_ts WHERE a.id = a_id AND a.tenant_id = t_id; |
|||
END IF; |
|||
SELECT * INTO result FROM alarm_info a WHERE a.id = a_id AND a.tenant_id = t_id; |
|||
RETURN json_build_object('success', true, 'modified', modified, 'alarm', row_to_json(result))::text; |
|||
END |
|||
$$; |
|||
|
|||
DROP FUNCTION IF EXISTS unassign_alarm; |
|||
CREATE OR REPLACE FUNCTION unassign_alarm(t_id uuid, a_id uuid, a_ts bigint) |
|||
RETURNS varchar |
|||
LANGUAGE plpgsql |
|||
AS |
|||
$$ |
|||
DECLARE |
|||
existing alarm; |
|||
result alarm_info; |
|||
modified boolean = FALSE; |
|||
BEGIN |
|||
SELECT * INTO existing FROM alarm a WHERE a.id = a_id AND a.tenant_id = t_id FOR UPDATE; |
|||
IF existing IS NULL THEN |
|||
RETURN json_build_object('success', false)::text; |
|||
END IF; |
|||
IF existing.assignee_id IS NOT NULL THEN |
|||
modified = TRUE; |
|||
UPDATE alarm a SET assignee_id = NULL, assign_ts = a_ts WHERE a.id = a_id AND a.tenant_id = t_id; |
|||
END IF; |
|||
SELECT * INTO result FROM alarm_info a WHERE a.id = a_id AND a.tenant_id = t_id; |
|||
RETURN json_build_object('success', true, 'modified', modified, 'alarm', row_to_json(result))::text; |
|||
END |
|||
$$; |
|||
|
|||
-- ALARM FUNCTIONS END |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue