1200 changed files with 38802 additions and 10086 deletions
@ -1,49 +0,0 @@ |
|||||
-- |
|
||||
-- Copyright © 2016-2022 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. |
|
||||
-- |
|
||||
|
|
||||
ALTER TABLE device_profile |
|
||||
ADD COLUMN IF NOT EXISTS default_queue_id uuid; |
|
||||
|
|
||||
DO |
|
||||
$$ |
|
||||
BEGIN |
|
||||
IF EXISTS |
|
||||
(SELECT column_name |
|
||||
FROM information_schema.columns |
|
||||
WHERE table_name = 'device_profile' |
|
||||
AND column_name = 'default_queue_name' |
|
||||
) |
|
||||
THEN |
|
||||
UPDATE device_profile |
|
||||
SET default_queue_id = q.id |
|
||||
FROM queue as q |
|
||||
WHERE default_queue_name = q.name; |
|
||||
END IF; |
|
||||
END |
|
||||
$$; |
|
||||
|
|
||||
DO |
|
||||
$$ |
|
||||
BEGIN |
|
||||
IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'fk_default_queue_device_profile') THEN |
|
||||
ALTER TABLE device_profile |
|
||||
ADD CONSTRAINT fk_default_queue_device_profile FOREIGN KEY (default_queue_id) REFERENCES queue (id); |
|
||||
END IF; |
|
||||
END; |
|
||||
$$; |
|
||||
|
|
||||
ALTER TABLE device_profile |
|
||||
DROP COLUMN IF EXISTS default_queue_name; |
|
||||
@ -0,0 +1,234 @@ |
|||||
|
-- |
||||
|
-- Copyright © 2016-2022 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,74 @@ |
|||||
|
-- |
||||
|
-- Copyright © 2016-2022 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. |
||||
|
-- |
||||
|
|
||||
|
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; |
||||
|
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 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 * FROM old_audit_log |
||||
|
WHERE created_time >= start_time_ms AND created_time < end_time_ms; |
||||
|
END; |
||||
|
$$; |
||||
@ -0,0 +1,21 @@ |
|||||
|
-- |
||||
|
-- Copyright © 2016-2022 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,45 @@ |
|||||
|
-- |
||||
|
-- Copyright © 2016-2022 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 as a SET asset_profile_id = p.id |
||||
|
FROM |
||||
|
(SELECT id, tenant_id, name from asset_profile) as p |
||||
|
WHERE a.asset_profile_id IS NULL AND p.tenant_id = a.tenant_id AND a.type = p.name; |
||||
|
END; |
||||
|
$$; |
||||
@ -0,0 +1,227 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.controller; |
||||
|
|
||||
|
import io.swagger.annotations.ApiOperation; |
||||
|
import io.swagger.annotations.ApiParam; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.http.HttpStatus; |
||||
|
import org.springframework.security.access.prepost.PreAuthorize; |
||||
|
import org.springframework.web.bind.annotation.PathVariable; |
||||
|
import org.springframework.web.bind.annotation.RequestBody; |
||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestMethod; |
||||
|
import org.springframework.web.bind.annotation.RequestParam; |
||||
|
import org.springframework.web.bind.annotation.ResponseBody; |
||||
|
import org.springframework.web.bind.annotation.ResponseStatus; |
||||
|
import org.springframework.web.bind.annotation.RestController; |
||||
|
import org.thingsboard.server.common.data.asset.AssetProfile; |
||||
|
import org.thingsboard.server.common.data.asset.AssetProfileInfo; |
||||
|
import org.thingsboard.server.common.data.exception.ThingsboardException; |
||||
|
import org.thingsboard.server.common.data.id.AssetProfileId; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
import org.thingsboard.server.dao.timeseries.TimeseriesService; |
||||
|
import org.thingsboard.server.queue.util.TbCoreComponent; |
||||
|
import org.thingsboard.server.service.entitiy.asset.profile.TbAssetProfileService; |
||||
|
import org.thingsboard.server.service.security.permission.Operation; |
||||
|
import org.thingsboard.server.service.security.permission.Resource; |
||||
|
|
||||
|
import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_ID; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_ID_PARAM_DESCRIPTION; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_INFO_DESCRIPTION; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_TEXT_SEARCH_DESCRIPTION; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH; |
||||
|
import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK; |
||||
|
|
||||
|
@RestController |
||||
|
@TbCoreComponent |
||||
|
@RequestMapping("/api") |
||||
|
@RequiredArgsConstructor |
||||
|
@Slf4j |
||||
|
public class AssetProfileController extends BaseController { |
||||
|
|
||||
|
private final TbAssetProfileService tbAssetProfileService; |
||||
|
|
||||
|
@ApiOperation(value = "Get Asset Profile (getAssetProfileById)", |
||||
|
notes = "Fetch the Asset Profile object based on the provided Asset Profile Id. " + |
||||
|
"The server checks that the asset profile is owned by the same tenant. " + TENANT_AUTHORITY_PARAGRAPH, |
||||
|
produces = "application/json") |
||||
|
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") |
||||
|
@RequestMapping(value = "/assetProfile/{assetProfileId}", method = RequestMethod.GET) |
||||
|
@ResponseBody |
||||
|
public AssetProfile getAssetProfileById( |
||||
|
@ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION) |
||||
|
@PathVariable(ASSET_PROFILE_ID) String strAssetProfileId) throws ThingsboardException { |
||||
|
checkParameter(ASSET_PROFILE_ID, strAssetProfileId); |
||||
|
try { |
||||
|
AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId)); |
||||
|
return checkAssetProfileId(assetProfileId, Operation.READ); |
||||
|
} catch (Exception e) { |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@ApiOperation(value = "Get Asset Profile Info (getAssetProfileInfoById)", |
||||
|
notes = "Fetch the Asset Profile Info object based on the provided Asset Profile Id. " |
||||
|
+ ASSET_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, |
||||
|
produces = "application/json") |
||||
|
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
||||
|
@RequestMapping(value = "/assetProfileInfo/{assetProfileId}", method = RequestMethod.GET) |
||||
|
@ResponseBody |
||||
|
public AssetProfileInfo getAssetProfileInfoById( |
||||
|
@ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION) |
||||
|
@PathVariable(ASSET_PROFILE_ID) String strAssetProfileId) throws ThingsboardException { |
||||
|
checkParameter(ASSET_PROFILE_ID, strAssetProfileId); |
||||
|
try { |
||||
|
AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId)); |
||||
|
return new AssetProfileInfo(checkAssetProfileId(assetProfileId, Operation.READ)); |
||||
|
} catch (Exception e) { |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@ApiOperation(value = "Get Default Asset Profile (getDefaultAssetProfileInfo)", |
||||
|
notes = "Fetch the Default Asset Profile Info object. " + |
||||
|
ASSET_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, |
||||
|
produces = "application/json") |
||||
|
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
||||
|
@RequestMapping(value = "/assetProfileInfo/default", method = RequestMethod.GET) |
||||
|
@ResponseBody |
||||
|
public AssetProfileInfo getDefaultAssetProfileInfo() throws ThingsboardException { |
||||
|
try { |
||||
|
return checkNotNull(assetProfileService.findDefaultAssetProfileInfo(getTenantId())); |
||||
|
} catch (Exception e) { |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@ApiOperation(value = "Create Or Update Asset Profile (saveAssetProfile)", |
||||
|
notes = "Create or update the Asset Profile. When creating asset profile, platform generates asset profile id as " + UUID_WIKI_LINK + |
||||
|
"The newly created asset profile id will be present in the response. " + |
||||
|
"Specify existing asset profile id to update the asset profile. " + |
||||
|
"Referencing non-existing asset profile Id will cause 'Not Found' error. " + NEW_LINE + |
||||
|
"Asset profile name is unique in the scope of tenant. Only one 'default' asset profile may exist in scope of tenant. " + |
||||
|
"Remove 'id', 'tenantId' from the request body example (below) to create new Asset Profile entity. " + |
||||
|
TENANT_AUTHORITY_PARAGRAPH, |
||||
|
produces = "application/json", |
||||
|
consumes = "application/json") |
||||
|
@PreAuthorize("hasAuthority('TENANT_ADMIN')") |
||||
|
@RequestMapping(value = "/assetProfile", method = RequestMethod.POST) |
||||
|
@ResponseBody |
||||
|
public AssetProfile saveAssetProfile( |
||||
|
@ApiParam(value = "A JSON value representing the asset profile.") |
||||
|
@RequestBody AssetProfile assetProfile) throws Exception { |
||||
|
assetProfile.setTenantId(getTenantId()); |
||||
|
checkEntity(assetProfile.getId(), assetProfile, Resource.ASSET_PROFILE); |
||||
|
return tbAssetProfileService.save(assetProfile, getCurrentUser()); |
||||
|
} |
||||
|
|
||||
|
@ApiOperation(value = "Delete asset profile (deleteAssetProfile)", |
||||
|
notes = "Deletes the asset profile. Referencing non-existing asset profile Id will cause an error. " + |
||||
|
"Can't delete the asset profile if it is referenced by existing assets." + TENANT_AUTHORITY_PARAGRAPH, |
||||
|
produces = "application/json") |
||||
|
@PreAuthorize("hasAuthority('TENANT_ADMIN')") |
||||
|
@RequestMapping(value = "/assetProfile/{assetProfileId}", method = RequestMethod.DELETE) |
||||
|
@ResponseStatus(value = HttpStatus.OK) |
||||
|
public void deleteAssetProfile( |
||||
|
@ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION) |
||||
|
@PathVariable(ASSET_PROFILE_ID) String strAssetProfileId) throws ThingsboardException { |
||||
|
checkParameter(ASSET_PROFILE_ID, strAssetProfileId); |
||||
|
AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId)); |
||||
|
AssetProfile assetProfile = checkAssetProfileId(assetProfileId, Operation.DELETE); |
||||
|
tbAssetProfileService.delete(assetProfile, getCurrentUser()); |
||||
|
} |
||||
|
|
||||
|
@ApiOperation(value = "Make Asset Profile Default (setDefaultAssetProfile)", |
||||
|
notes = "Marks asset profile as default within a tenant scope." + TENANT_AUTHORITY_PARAGRAPH, |
||||
|
produces = "application/json") |
||||
|
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") |
||||
|
@RequestMapping(value = "/assetProfile/{assetProfileId}/default", method = RequestMethod.POST) |
||||
|
@ResponseBody |
||||
|
public AssetProfile setDefaultAssetProfile( |
||||
|
@ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION) |
||||
|
@PathVariable(ASSET_PROFILE_ID) String strAssetProfileId) throws ThingsboardException { |
||||
|
checkParameter(ASSET_PROFILE_ID, strAssetProfileId); |
||||
|
AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId)); |
||||
|
AssetProfile assetProfile = checkAssetProfileId(assetProfileId, Operation.WRITE); |
||||
|
AssetProfile previousDefaultAssetProfile = assetProfileService.findDefaultAssetProfile(getTenantId()); |
||||
|
return tbAssetProfileService.setDefaultAssetProfile(assetProfile, previousDefaultAssetProfile, getCurrentUser()); |
||||
|
} |
||||
|
|
||||
|
@ApiOperation(value = "Get Asset Profiles (getAssetProfiles)", |
||||
|
notes = "Returns a page of asset profile objects owned by tenant. " + |
||||
|
PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, |
||||
|
produces = "application/json") |
||||
|
@PreAuthorize("hasAuthority('TENANT_ADMIN')") |
||||
|
@RequestMapping(value = "/assetProfiles", params = {"pageSize", "page"}, method = RequestMethod.GET) |
||||
|
@ResponseBody |
||||
|
public PageData<AssetProfile> getAssetProfiles( |
||||
|
@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) |
||||
|
@RequestParam int pageSize, |
||||
|
@ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) |
||||
|
@RequestParam int page, |
||||
|
@ApiParam(value = ASSET_PROFILE_TEXT_SEARCH_DESCRIPTION) |
||||
|
@RequestParam(required = false) String textSearch, |
||||
|
@ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES) |
||||
|
@RequestParam(required = false) String sortProperty, |
||||
|
@ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) |
||||
|
@RequestParam(required = false) String sortOrder) throws ThingsboardException { |
||||
|
try { |
||||
|
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); |
||||
|
return checkNotNull(assetProfileService.findAssetProfiles(getTenantId(), pageLink)); |
||||
|
} catch (Exception e) { |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@ApiOperation(value = "Get Asset Profile infos (getAssetProfileInfos)", |
||||
|
notes = "Returns a page of asset profile info objects owned by tenant. " + |
||||
|
PAGE_DATA_PARAMETERS + ASSET_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, |
||||
|
produces = "application/json") |
||||
|
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
||||
|
@RequestMapping(value = "/assetProfileInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) |
||||
|
@ResponseBody |
||||
|
public PageData<AssetProfileInfo> getAssetProfileInfos( |
||||
|
@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) |
||||
|
@RequestParam int pageSize, |
||||
|
@ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) |
||||
|
@RequestParam int page, |
||||
|
@ApiParam(value = ASSET_PROFILE_TEXT_SEARCH_DESCRIPTION) |
||||
|
@RequestParam(required = false) String textSearch, |
||||
|
@ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES) |
||||
|
@RequestParam(required = false) String sortProperty, |
||||
|
@ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) |
||||
|
@RequestParam(required = false) String sortOrder) throws ThingsboardException { |
||||
|
try { |
||||
|
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); |
||||
|
return checkNotNull(assetProfileService.findAssetProfileInfos(getTenantId(), pageLink)); |
||||
|
} catch (Exception e) { |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,62 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.service.edge.rpc.constructor; |
||||
|
|
||||
|
import com.google.protobuf.ByteString; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.thingsboard.server.common.data.asset.AssetProfile; |
||||
|
import org.thingsboard.server.common.data.id.AssetProfileId; |
||||
|
import org.thingsboard.server.gen.edge.v1.AssetProfileUpdateMsg; |
||||
|
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; |
||||
|
import org.thingsboard.server.queue.util.TbCoreComponent; |
||||
|
|
||||
|
import java.nio.charset.StandardCharsets; |
||||
|
|
||||
|
@Component |
||||
|
@TbCoreComponent |
||||
|
public class AssetProfileMsgConstructor { |
||||
|
|
||||
|
public AssetProfileUpdateMsg constructAssetProfileUpdatedMsg(UpdateMsgType msgType, AssetProfile assetProfile) { |
||||
|
AssetProfileUpdateMsg.Builder builder = AssetProfileUpdateMsg.newBuilder() |
||||
|
.setMsgType(msgType) |
||||
|
.setIdMSB(assetProfile.getId().getId().getMostSignificantBits()) |
||||
|
.setIdLSB(assetProfile.getId().getId().getLeastSignificantBits()) |
||||
|
.setName(assetProfile.getName()) |
||||
|
.setDefault(assetProfile.isDefault()); |
||||
|
if (assetProfile.getDefaultDashboardId() != null) { |
||||
|
builder.setDefaultDashboardIdMSB(assetProfile.getDefaultDashboardId().getId().getMostSignificantBits()) |
||||
|
.setDefaultDashboardIdLSB(assetProfile.getDefaultDashboardId().getId().getLeastSignificantBits()); |
||||
|
} |
||||
|
if (assetProfile.getDefaultQueueName() != null) { |
||||
|
builder.setDefaultQueueName(assetProfile.getDefaultQueueName()); |
||||
|
} |
||||
|
if (assetProfile.getDescription() != null) { |
||||
|
builder.setDescription(assetProfile.getDescription()); |
||||
|
} |
||||
|
if (assetProfile.getImage() != null) { |
||||
|
builder.setImage(ByteString.copyFrom(assetProfile.getImage().getBytes(StandardCharsets.UTF_8))); |
||||
|
} |
||||
|
return builder.build(); |
||||
|
} |
||||
|
|
||||
|
public AssetProfileUpdateMsg constructAssetProfileDeleteMsg(AssetProfileId assetProfileId) { |
||||
|
return AssetProfileUpdateMsg.newBuilder() |
||||
|
.setMsgType(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE) |
||||
|
.setIdMSB(assetProfileId.getId().getMostSignificantBits()) |
||||
|
.setIdLSB(assetProfileId.getId().getLeastSignificantBits()).build(); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.service.edge.rpc.constructor; |
||||
|
|
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.thingsboard.common.util.JacksonUtil; |
||||
|
import org.thingsboard.server.common.data.edge.Edge; |
||||
|
import org.thingsboard.server.gen.edge.v1.EdgeConfiguration; |
||||
|
import org.thingsboard.server.queue.util.TbCoreComponent; |
||||
|
|
||||
|
@Component |
||||
|
@TbCoreComponent |
||||
|
public class EdgeMsgConstructor { |
||||
|
|
||||
|
public EdgeConfiguration constructEdgeConfiguration(Edge edge) { |
||||
|
EdgeConfiguration.Builder builder = EdgeConfiguration.newBuilder() |
||||
|
.setEdgeIdMSB(edge.getId().getId().getMostSignificantBits()) |
||||
|
.setEdgeIdLSB(edge.getId().getId().getLeastSignificantBits()) |
||||
|
.setTenantIdMSB(edge.getTenantId().getId().getMostSignificantBits()) |
||||
|
.setTenantIdLSB(edge.getTenantId().getId().getLeastSignificantBits()) |
||||
|
.setName(edge.getName()) |
||||
|
.setType(edge.getType()) |
||||
|
.setRoutingKey(edge.getRoutingKey()) |
||||
|
.setSecret(edge.getSecret()) |
||||
|
.setAdditionalInfo(JacksonUtil.toString(edge.getAdditionalInfo())) |
||||
|
.setCloudType("CE"); |
||||
|
if (edge.getCustomerId() != null) { |
||||
|
builder.setCustomerIdMSB(edge.getCustomerId().getId().getMostSignificantBits()) |
||||
|
.setCustomerIdLSB(edge.getCustomerId().getId().getLeastSignificantBits()); |
||||
|
} |
||||
|
return builder.build(); |
||||
|
} |
||||
|
} |
||||
@ -1,50 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2022 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.service.edge.rpc.constructor.rule; |
|
||||
|
|
||||
import com.fasterxml.jackson.core.JsonProcessingException; |
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.thingsboard.server.common.data.id.TenantId; |
|
||||
import org.thingsboard.server.common.data.rule.RuleChainMetaData; |
|
||||
import org.thingsboard.server.common.data.rule.RuleNode; |
|
||||
import org.thingsboard.server.dao.queue.QueueService; |
|
||||
import org.thingsboard.server.gen.edge.v1.RuleChainMetadataUpdateMsg; |
|
||||
|
|
||||
import java.util.List; |
|
||||
import java.util.TreeSet; |
|
||||
|
|
||||
@Slf4j |
|
||||
public class RuleChainMetadataConstructorV333 extends AbstractRuleChainMetadataConstructor { |
|
||||
|
|
||||
public RuleChainMetadataConstructorV333(QueueService queueService) { |
|
||||
super(queueService); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
protected void constructRuleChainMetadataUpdatedMsg(TenantId tenantId, |
|
||||
RuleChainMetadataUpdateMsg.Builder builder, |
|
||||
RuleChainMetaData ruleChainMetaData) throws JsonProcessingException { |
|
||||
List<RuleNode> nodes = updateQueueIdToQueueNameNodeConfiguration(tenantId, ruleChainMetaData.getNodes()); |
|
||||
builder.addAllNodes(constructNodes(nodes)) |
|
||||
.addAllConnections(constructConnections(ruleChainMetaData.getConnections())) |
|
||||
.addAllRuleChainConnections(constructRuleChainConnections(ruleChainMetaData.getRuleChainConnections(), new TreeSet<>())); |
|
||||
if (ruleChainMetaData.getFirstNodeIndex() != null) { |
|
||||
builder.setFirstNodeIndex(ruleChainMetaData.getFirstNodeIndex()); |
|
||||
} else { |
|
||||
builder.setFirstNodeIndex(-1); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,47 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.service.edge.rpc.fetch; |
||||
|
|
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.thingsboard.server.common.data.EdgeUtils; |
||||
|
import org.thingsboard.server.common.data.asset.AssetProfile; |
||||
|
import org.thingsboard.server.common.data.edge.Edge; |
||||
|
import org.thingsboard.server.common.data.edge.EdgeEvent; |
||||
|
import org.thingsboard.server.common.data.edge.EdgeEventActionType; |
||||
|
import org.thingsboard.server.common.data.edge.EdgeEventType; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
import org.thingsboard.server.dao.asset.AssetProfileService; |
||||
|
|
||||
|
@AllArgsConstructor |
||||
|
@Slf4j |
||||
|
public class AssetProfilesEdgeEventFetcher extends BasePageableEdgeEventFetcher<AssetProfile> { |
||||
|
|
||||
|
private final AssetProfileService assetProfileService; |
||||
|
|
||||
|
@Override |
||||
|
PageData<AssetProfile> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) { |
||||
|
return assetProfileService.findAssetProfiles(tenantId, pageLink); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, AssetProfile assetProfile) { |
||||
|
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.ASSET_PROFILE, |
||||
|
EdgeEventActionType.ADDED, assetProfile.getId(), null); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,47 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.service.edge.rpc.fetch; |
||||
|
|
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.thingsboard.server.common.data.Device; |
||||
|
import org.thingsboard.server.common.data.EdgeUtils; |
||||
|
import org.thingsboard.server.common.data.edge.Edge; |
||||
|
import org.thingsboard.server.common.data.edge.EdgeEvent; |
||||
|
import org.thingsboard.server.common.data.edge.EdgeEventActionType; |
||||
|
import org.thingsboard.server.common.data.edge.EdgeEventType; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
import org.thingsboard.server.dao.device.DeviceService; |
||||
|
|
||||
|
@AllArgsConstructor |
||||
|
@Slf4j |
||||
|
public class DevicesEdgeEventFetcher extends BasePageableEdgeEventFetcher<Device> { |
||||
|
|
||||
|
private final DeviceService deviceService; |
||||
|
|
||||
|
@Override |
||||
|
PageData<Device> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) { |
||||
|
return deviceService.findDevicesByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, Device device) { |
||||
|
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, |
||||
|
EdgeEventActionType.ADDED, device.getId(), null); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,47 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.service.edge.rpc.fetch; |
||||
|
|
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.thingsboard.server.common.data.EdgeUtils; |
||||
|
import org.thingsboard.server.common.data.EntityView; |
||||
|
import org.thingsboard.server.common.data.edge.Edge; |
||||
|
import org.thingsboard.server.common.data.edge.EdgeEvent; |
||||
|
import org.thingsboard.server.common.data.edge.EdgeEventActionType; |
||||
|
import org.thingsboard.server.common.data.edge.EdgeEventType; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageLink; |
||||
|
import org.thingsboard.server.dao.entityview.EntityViewService; |
||||
|
|
||||
|
@AllArgsConstructor |
||||
|
@Slf4j |
||||
|
public class EntityViewsEdgeEventFetcher extends BasePageableEdgeEventFetcher<EntityView> { |
||||
|
|
||||
|
private final EntityViewService entityViewService; |
||||
|
|
||||
|
@Override |
||||
|
PageData<EntityView> fetchPageData(TenantId tenantId, Edge edge, PageLink pageLink) { |
||||
|
return entityViewService.findEntityViewsByTenantIdAndEdgeId(tenantId, edge.getId(), pageLink); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
EdgeEvent constructEdgeEvent(TenantId tenantId, Edge edge, EntityView entityView) { |
||||
|
return EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.ENTITY_VIEW, |
||||
|
EdgeEventActionType.ADDED, entityView.getId(), null); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,70 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.service.edge.rpc.processor; |
||||
|
|
||||
|
import com.google.common.util.concurrent.ListenableFuture; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.thingsboard.server.common.data.EdgeUtils; |
||||
|
import org.thingsboard.server.common.data.asset.AssetProfile; |
||||
|
import org.thingsboard.server.common.data.edge.EdgeEvent; |
||||
|
import org.thingsboard.server.common.data.id.AssetProfileId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.gen.edge.v1.AssetProfileUpdateMsg; |
||||
|
import org.thingsboard.server.gen.edge.v1.DownlinkMsg; |
||||
|
import org.thingsboard.server.gen.edge.v1.UpdateMsgType; |
||||
|
import org.thingsboard.server.gen.transport.TransportProtos; |
||||
|
import org.thingsboard.server.queue.util.TbCoreComponent; |
||||
|
|
||||
|
@Component |
||||
|
@Slf4j |
||||
|
@TbCoreComponent |
||||
|
public class AssetProfileEdgeProcessor extends BaseEdgeProcessor { |
||||
|
|
||||
|
public DownlinkMsg convertAssetProfileEventToDownlink(EdgeEvent edgeEvent) { |
||||
|
AssetProfileId assetProfileId = new AssetProfileId(edgeEvent.getEntityId()); |
||||
|
DownlinkMsg downlinkMsg = null; |
||||
|
switch (edgeEvent.getAction()) { |
||||
|
case ADDED: |
||||
|
case UPDATED: |
||||
|
AssetProfile assetProfile = assetProfileService.findAssetProfileById(edgeEvent.getTenantId(), assetProfileId); |
||||
|
if (assetProfile != null) { |
||||
|
UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction()); |
||||
|
AssetProfileUpdateMsg assetProfileUpdateMsg = |
||||
|
assetProfileMsgConstructor.constructAssetProfileUpdatedMsg(msgType, assetProfile); |
||||
|
downlinkMsg = DownlinkMsg.newBuilder() |
||||
|
.setDownlinkMsgId(EdgeUtils.nextPositiveInt()) |
||||
|
.addAssetProfileUpdateMsg(assetProfileUpdateMsg) |
||||
|
.build(); |
||||
|
} |
||||
|
break; |
||||
|
case DELETED: |
||||
|
AssetProfileUpdateMsg assetProfileUpdateMsg = |
||||
|
assetProfileMsgConstructor.constructAssetProfileDeleteMsg(assetProfileId); |
||||
|
downlinkMsg = DownlinkMsg.newBuilder() |
||||
|
.setDownlinkMsgId(EdgeUtils.nextPositiveInt()) |
||||
|
.addAssetProfileUpdateMsg(assetProfileUpdateMsg) |
||||
|
.build(); |
||||
|
break; |
||||
|
} |
||||
|
return downlinkMsg; |
||||
|
} |
||||
|
|
||||
|
public ListenableFuture<Void> processAssetProfileNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { |
||||
|
return processEntityNotificationForAllEdges(tenantId, edgeNotificationMsg); |
||||
|
} |
||||
|
|
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue