Commit b0b6ee06bdeb0d7b6c5f1f6c6825b36540d97123
Committed by
GitHub
Merge pull request #1053 from ViktorBasanets/master
Entity View server side
Showing
30 changed files
with
1674 additions
and
4 deletions
1 | +-- | ||
2 | +-- Copyright © 2016-2018 The Thingsboard Authors | ||
3 | +-- | ||
4 | +-- Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | +-- you may not use this file except in compliance with the License. | ||
6 | +-- You may obtain a copy of the License at | ||
7 | +-- | ||
8 | +-- http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | +-- | ||
10 | +-- Unless required by applicable law or agreed to in writing, software | ||
11 | +-- distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | +-- See the License for the specific language governing permissions and | ||
14 | +-- limitations under the License. | ||
15 | +-- | ||
16 | + | ||
17 | +DROP MATERIALIZED VIEW IF EXISTS thingsboard.entity_views_by_tenant_and_name; | ||
18 | +DROP MATERIALIZED VIEW IF EXISTS thingsboard.entity_views_by_tenant_and_entity; | ||
19 | +DROP MATERIALIZED VIEW IF EXISTS thingsboard.entity_views_by_tenant_and_customer; | ||
20 | +DROP MATERIALIZED VIEW IF EXISTS thingsboard.entity_views_by_tenant_and_customer_and_entity; | ||
21 | + | ||
22 | +DROP TABLE IF EXISTS thingsboard.entity_views; | ||
23 | + | ||
24 | +CREATE TABLE IF NOT EXISTS thingsboard.entity_views ( | ||
25 | + id timeuuid, | ||
26 | + entity_id timeuuid, | ||
27 | + tenant_id timeuuid, | ||
28 | + customer_id timeuuid, | ||
29 | + name text, | ||
30 | + keys text, | ||
31 | + ts_begin bigint, | ||
32 | + ts_end bigint, | ||
33 | + search_text text, | ||
34 | + additional_info text, | ||
35 | + PRIMARY KEY (id, entity_id, tenant_id, customer_id) | ||
36 | + ); | ||
37 | + | ||
38 | +CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_name AS | ||
39 | + SELECT * | ||
40 | + from thingsboard.entity_views | ||
41 | + WHERE entity_id IS NOT NULL | ||
42 | + AND tenant_id IS NOT NULL | ||
43 | + AND customer_id IS NOT NULL | ||
44 | + AND keys IS NOT NULL | ||
45 | + AND ts_begin IS NOT NULL | ||
46 | + AND ts_end IS NOT NULL | ||
47 | + AND name IS NOT NULL | ||
48 | + AND id IS NOT NULL | ||
49 | + PRIMARY KEY (tenant_id, name, id, entity_id, customer_id) | ||
50 | + WITH CLUSTERING ORDER BY (name ASC, id DESC, entity_id DESC, customer_id DESC); | ||
51 | + | ||
52 | +CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_entity AS | ||
53 | + SELECT * | ||
54 | + from thingsboard.entity_views | ||
55 | + WHERE entity_id IS NOT NULL | ||
56 | + AND tenant_id IS NOT NULL | ||
57 | + AND customer_id IS NOT NULL | ||
58 | + AND keys IS NOT NULL | ||
59 | + AND ts_begin IS NOT NULL | ||
60 | + AND ts_end IS NOT NULL | ||
61 | + AND name IS NOT NULL | ||
62 | + AND id IS NOT NULL | ||
63 | + PRIMARY KEY (tenant_id, entity_id, id, customer_id, name) | ||
64 | + WITH CLUSTERING ORDER BY (entity_id ASC, customer_id ASC, id DESC, name DESC); | ||
65 | + | ||
66 | +CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer AS | ||
67 | + SELECT * | ||
68 | + from thingsboard.entity_views | ||
69 | + WHERE entity_id IS NOT NULL | ||
70 | + AND tenant_id IS NOT NULL | ||
71 | + AND customer_id IS NOT NULL | ||
72 | + AND keys IS NOT NULL | ||
73 | + AND ts_begin IS NOT NULL | ||
74 | + AND ts_end IS NOT NULL | ||
75 | + AND name IS NOT NULL | ||
76 | + AND id IS NOT NULL | ||
77 | + PRIMARY KEY (tenant_id, customer_id, id, entity_id, name) | ||
78 | + WITH CLUSTERING ORDER BY (customer_id ASC, id DESC, entity_id DESC, name DESC); | ||
79 | + | ||
80 | +CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer_and_entity AS | ||
81 | + SELECT * | ||
82 | + from thingsboard.entity_views | ||
83 | + WHERE entity_id IS NOT NULL | ||
84 | + AND tenant_id IS NOT NULL | ||
85 | + AND customer_id IS NOT NULL | ||
86 | + AND keys IS NOT NULL | ||
87 | + AND ts_begin IS NOT NULL | ||
88 | + AND ts_end IS NOT NULL | ||
89 | + AND name IS NOT NULL | ||
90 | + AND id IS NOT NULL | ||
91 | + PRIMARY KEY (tenant_id, customer_id, entity_id, id, name) | ||
92 | + WITH CLUSTERING ORDER BY (customer_id ASC, entity_id DESC, id DESC, name DESC); |
1 | +-- | ||
2 | +-- Copyright © 2016-2018 The Thingsboard Authors | ||
3 | +-- | ||
4 | +-- Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | +-- you may not use this file except in compliance with the License. | ||
6 | +-- You may obtain a copy of the License at | ||
7 | +-- | ||
8 | +-- http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | +-- | ||
10 | +-- Unless required by applicable law or agreed to in writing, software | ||
11 | +-- distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | +-- See the License for the specific language governing permissions and | ||
14 | +-- limitations under the License. | ||
15 | +-- | ||
16 | + | ||
17 | +DROP TABLE IF EXISTS entity_views; | ||
18 | + | ||
19 | +CREATE TABLE IF NOT EXISTS entity_views ( | ||
20 | + id varchar(31) NOT NULL CONSTRAINT entity_view_pkey PRIMARY KEY, | ||
21 | + entity_id varchar(31), | ||
22 | + entity_type varchar(255), | ||
23 | + tenant_id varchar(31), | ||
24 | + customer_id varchar(31), | ||
25 | + name varchar(255), | ||
26 | + keys varchar(255), | ||
27 | + ts_begin varchar(255), | ||
28 | + ts_end varchar(255), | ||
29 | + search_text varchar(255), | ||
30 | + additional_info varchar | ||
31 | +); |
@@ -56,6 +56,7 @@ import org.thingsboard.server.dao.customer.CustomerService; | @@ -56,6 +56,7 @@ import org.thingsboard.server.dao.customer.CustomerService; | ||
56 | import org.thingsboard.server.dao.dashboard.DashboardService; | 56 | import org.thingsboard.server.dao.dashboard.DashboardService; |
57 | import org.thingsboard.server.dao.device.DeviceCredentialsService; | 57 | import org.thingsboard.server.dao.device.DeviceCredentialsService; |
58 | import org.thingsboard.server.dao.device.DeviceService; | 58 | import org.thingsboard.server.dao.device.DeviceService; |
59 | +import org.thingsboard.server.dao.entityview.EntityViewService; | ||
59 | import org.thingsboard.server.dao.exception.DataValidationException; | 60 | import org.thingsboard.server.dao.exception.DataValidationException; |
60 | import org.thingsboard.server.dao.exception.IncorrectParameterException; | 61 | import org.thingsboard.server.dao.exception.IncorrectParameterException; |
61 | import org.thingsboard.server.dao.model.ModelConstants; | 62 | import org.thingsboard.server.dao.model.ModelConstants; |
@@ -139,6 +140,9 @@ public abstract class BaseController { | @@ -139,6 +140,9 @@ public abstract class BaseController { | ||
139 | @Autowired | 140 | @Autowired |
140 | protected DeviceStateService deviceStateService; | 141 | protected DeviceStateService deviceStateService; |
141 | 142 | ||
143 | + @Autowired | ||
144 | + protected EntityViewService entityViewService; | ||
145 | + | ||
142 | @ExceptionHandler(ThingsboardException.class) | 146 | @ExceptionHandler(ThingsboardException.class) |
143 | public void handleThingsboardException(ThingsboardException ex, HttpServletResponse response) { | 147 | public void handleThingsboardException(ThingsboardException ex, HttpServletResponse response) { |
144 | errorResponseHandler.handle(ex, response); | 148 | errorResponseHandler.handle(ex, response); |
@@ -313,6 +317,9 @@ public abstract class BaseController { | @@ -313,6 +317,9 @@ public abstract class BaseController { | ||
313 | case USER: | 317 | case USER: |
314 | checkUserId(new UserId(entityId.getId())); | 318 | checkUserId(new UserId(entityId.getId())); |
315 | return; | 319 | return; |
320 | + case ENTITY_VIEW: | ||
321 | + checkEntityView(entityViewService.findEntityViewById(new EntityViewId(entityId.getId()))); | ||
322 | + return; | ||
316 | default: | 323 | default: |
317 | throw new IllegalArgumentException("Unsupported entity type: " + entityId.getEntityType()); | 324 | throw new IllegalArgumentException("Unsupported entity type: " + entityId.getEntityType()); |
318 | } | 325 | } |
@@ -340,6 +347,25 @@ public abstract class BaseController { | @@ -340,6 +347,25 @@ public abstract class BaseController { | ||
340 | } | 347 | } |
341 | } | 348 | } |
342 | 349 | ||
350 | + protected EntityView checkEntityViewId(EntityViewId entityViewId) throws ThingsboardException { | ||
351 | + try { | ||
352 | + validateId(entityViewId, "Incorrect entityViewId " + entityViewId); | ||
353 | + EntityView entityView = entityViewService.findEntityViewById(entityViewId); | ||
354 | + checkEntityView(entityView); | ||
355 | + return entityView; | ||
356 | + } catch (Exception e) { | ||
357 | + throw handleException(e, false); | ||
358 | + } | ||
359 | + } | ||
360 | + | ||
361 | + protected void checkEntityView(EntityView entityView) throws ThingsboardException { | ||
362 | + checkNotNull(entityView); | ||
363 | + checkTenantId(entityView.getTenantId()); | ||
364 | + if (entityView.getCustomerId() != null && !entityView.getCustomerId().getId().equals(ModelConstants.NULL_UUID)) { | ||
365 | + checkCustomerId(entityView.getCustomerId()); | ||
366 | + } | ||
367 | + } | ||
368 | + | ||
343 | Asset checkAssetId(AssetId assetId) throws ThingsboardException { | 369 | Asset checkAssetId(AssetId assetId) throws ThingsboardException { |
344 | try { | 370 | try { |
345 | validateId(assetId, "Incorrect assetId " + assetId); | 371 | validateId(assetId, "Incorrect assetId " + assetId); |
1 | +/** | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.controller; | ||
17 | + | ||
18 | +import com.google.common.util.concurrent.ListenableFuture; | ||
19 | +import org.springframework.http.HttpStatus; | ||
20 | +import org.springframework.security.access.prepost.PreAuthorize; | ||
21 | +import org.springframework.web.bind.annotation.*; | ||
22 | +import org.thingsboard.server.common.data.EntityType; | ||
23 | +import org.thingsboard.server.common.data.EntityView; | ||
24 | +import org.thingsboard.server.common.data.audit.ActionType; | ||
25 | +import org.thingsboard.server.common.data.exception.ThingsboardException; | ||
26 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
27 | +import org.thingsboard.server.common.data.id.EntityViewId; | ||
28 | +import org.thingsboard.server.common.data.id.TenantId; | ||
29 | +import org.thingsboard.server.service.security.model.SecurityUser; | ||
30 | + | ||
31 | +import java.util.ArrayList; | ||
32 | +import java.util.List; | ||
33 | + | ||
34 | +/** | ||
35 | + * Created by Victor Basanets on 8/28/2017. | ||
36 | + */ | ||
37 | +@RestController | ||
38 | +@RequestMapping("/api") | ||
39 | +public class EntityViewController extends BaseController { | ||
40 | + | ||
41 | + public static final String ENTITY_VIEW_ID = "entityViewId"; | ||
42 | + | ||
43 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | ||
44 | + @RequestMapping(value = "/entity-view/{entityViewId}", method = RequestMethod.GET) | ||
45 | + @ResponseBody | ||
46 | + public EntityView getEntityViewById(@PathVariable(ENTITY_VIEW_ID) String strEntityViewId) | ||
47 | + throws ThingsboardException { | ||
48 | + | ||
49 | + checkParameter(ENTITY_VIEW_ID, strEntityViewId); | ||
50 | + try { | ||
51 | + EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId)); | ||
52 | + return checkEntityViewId(entityViewId); | ||
53 | + } catch (Exception e) { | ||
54 | + throw handleException(e); | ||
55 | + } | ||
56 | + } | ||
57 | + | ||
58 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | ||
59 | + @RequestMapping(value = "/entity-view", method = RequestMethod.POST) | ||
60 | + @ResponseBody | ||
61 | + public EntityView saveEntityView(@RequestBody EntityView entityView) throws ThingsboardException { | ||
62 | + try { | ||
63 | + entityView.setTenantId(getCurrentUser().getTenantId()); | ||
64 | + EntityView savedEntityView = checkNotNull(entityViewService.saveEntityView(entityView)); | ||
65 | + logEntityAction(savedEntityView.getId(), savedEntityView, null, | ||
66 | + entityView.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); | ||
67 | + | ||
68 | + return savedEntityView; | ||
69 | + | ||
70 | + } catch (Exception e) { | ||
71 | + logEntityAction(emptyId(EntityType.ENTITY_VIEW), entityView, null, | ||
72 | + entityView.getId() == null ? ActionType.ADDED : ActionType.UPDATED, e); | ||
73 | + | ||
74 | + throw handleException(e); | ||
75 | + } | ||
76 | + } | ||
77 | + | ||
78 | + @PreAuthorize("hasAuthority('TENANT_ADMIN')") | ||
79 | + @RequestMapping(value = "/entity-view/{entityViewId}", method = RequestMethod.DELETE) | ||
80 | + @ResponseStatus(value = HttpStatus.OK) | ||
81 | + public void deleteEntityView(@PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { | ||
82 | + checkParameter(ENTITY_VIEW_ID, strEntityViewId); | ||
83 | + try { | ||
84 | + EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId)); | ||
85 | + EntityView entityView = checkEntityViewId(entityViewId); | ||
86 | + entityViewService.deleteEntityView(entityViewId); | ||
87 | + | ||
88 | + logEntityAction(entityViewId, entityView, entityView.getCustomerId(), | ||
89 | + ActionType.DELETED,null, strEntityViewId); | ||
90 | + } catch (Exception e) { | ||
91 | + logEntityAction(emptyId(EntityType.ENTITY_VIEW), | ||
92 | + null, | ||
93 | + null, | ||
94 | + ActionType.DELETED, e, strEntityViewId); | ||
95 | + throw handleException(e); | ||
96 | + } | ||
97 | + } | ||
98 | +} |
@@ -88,6 +88,13 @@ public class ThingsboardInstallService { | @@ -88,6 +88,13 @@ public class ThingsboardInstallService { | ||
88 | 88 | ||
89 | dataUpdateService.updateData("1.4.0"); | 89 | dataUpdateService.updateData("1.4.0"); |
90 | 90 | ||
91 | + case "2.0.0": | ||
92 | + log.info("Upgrading ThingsBoard from version 2.0.0 to 2.1.1 ..."); | ||
93 | + | ||
94 | + databaseUpgradeService.upgradeDatabase("2.0.0"); | ||
95 | + | ||
96 | + dataUpdateService.updateData("2.0.0"); | ||
97 | + | ||
91 | log.info("Updating system data..."); | 98 | log.info("Updating system data..."); |
92 | 99 | ||
93 | systemDataLoaderService.deleteSystemWidgetBundle("charts"); | 100 | systemDataLoaderService.deleteSystemWidgetBundle("charts"); |
@@ -49,6 +49,10 @@ public class DefaultDataUpdateService implements DataUpdateService { | @@ -49,6 +49,10 @@ public class DefaultDataUpdateService implements DataUpdateService { | ||
49 | log.info("Updating data from version 1.4.0 to 2.0.0 ..."); | 49 | log.info("Updating data from version 1.4.0 to 2.0.0 ..."); |
50 | tenantsDefaultRuleChainUpdater.updateEntities(null); | 50 | tenantsDefaultRuleChainUpdater.updateEntities(null); |
51 | break; | 51 | break; |
52 | + case "2.0.0": | ||
53 | + log.info("Updating data from version 2.0.0 to 2.1.1 ..."); | ||
54 | + tenantsDefaultRuleChainUpdater.updateEntities(null); | ||
55 | + break; | ||
52 | default: | 56 | default: |
53 | throw new RuntimeException("Unable to update data, unsupported fromVersion: " + fromVersion); | 57 | throw new RuntimeException("Unable to update data, unsupported fromVersion: " + fromVersion); |
54 | } | 58 | } |
@@ -107,6 +107,15 @@ public class SqlDatabaseUpgradeService implements DatabaseUpgradeService { | @@ -107,6 +107,15 @@ public class SqlDatabaseUpgradeService implements DatabaseUpgradeService { | ||
107 | log.info("Schema updated."); | 107 | log.info("Schema updated."); |
108 | } | 108 | } |
109 | break; | 109 | break; |
110 | + case "2.0.0": | ||
111 | + try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { | ||
112 | + log.info("Updating schema ..."); | ||
113 | + schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.1.1", SCHEMA_UPDATE_SQL); | ||
114 | + loadSql(schemaUpdateFile, conn); | ||
115 | + log.info("Schema updated."); | ||
116 | + } | ||
117 | + break; | ||
118 | + | ||
110 | default: | 119 | default: |
111 | throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); | 120 | throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); |
112 | } | 121 | } |
@@ -359,7 +359,7 @@ spring: | @@ -359,7 +359,7 @@ spring: | ||
359 | password: "${SPRING_DATASOURCE_PASSWORD:}" | 359 | password: "${SPRING_DATASOURCE_PASSWORD:}" |
360 | 360 | ||
361 | # PostgreSQL DAO Configuration | 361 | # PostgreSQL DAO Configuration |
362 | -#spring: | 362 | +# spring: |
363 | # data: | 363 | # data: |
364 | # sql: | 364 | # sql: |
365 | # repositories: | 365 | # repositories: |
application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.controller; | ||
17 | + | ||
18 | +import org.junit.After; | ||
19 | +import org.junit.Assert; | ||
20 | +import org.junit.Before; | ||
21 | +import org.junit.Test; | ||
22 | +import org.thingsboard.server.common.data.Device; | ||
23 | +import org.thingsboard.server.common.data.EntityView; | ||
24 | +import org.thingsboard.server.common.data.Tenant; | ||
25 | +import org.thingsboard.server.common.data.User; | ||
26 | +import org.thingsboard.server.common.data.objects.AttributesEntityView; | ||
27 | +import org.thingsboard.server.common.data.objects.TelemetryEntityView; | ||
28 | +import org.thingsboard.server.common.data.security.Authority; | ||
29 | + | ||
30 | +import java.util.Arrays; | ||
31 | + | ||
32 | +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||
33 | +import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; | ||
34 | + | ||
35 | +public abstract class BaseEntityViewControllerTest extends AbstractControllerTest { | ||
36 | + | ||
37 | + private Tenant savedTenant; | ||
38 | + private User tenantAdmin; | ||
39 | + private Device testDevice; | ||
40 | + private TelemetryEntityView obj; | ||
41 | + | ||
42 | + @Before | ||
43 | + public void beforeTest() throws Exception { | ||
44 | + loginSysAdmin(); | ||
45 | + | ||
46 | + Tenant tenant = new Tenant(); | ||
47 | + tenant.setTitle("My tenant"); | ||
48 | + savedTenant = doPost("/api/tenant", tenant, Tenant.class); | ||
49 | + | ||
50 | + Assert.assertNotNull(savedTenant); | ||
51 | + | ||
52 | + tenantAdmin = new User(); | ||
53 | + tenantAdmin.setAuthority(Authority.TENANT_ADMIN); | ||
54 | + tenantAdmin.setTenantId(savedTenant.getId()); | ||
55 | + tenantAdmin.setEmail("tenant2@thingsboard.org"); | ||
56 | + tenantAdmin.setFirstName("Joe"); | ||
57 | + tenantAdmin.setLastName("Downs"); | ||
58 | + | ||
59 | + tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); | ||
60 | + | ||
61 | + Device device = new Device(); | ||
62 | + device.setName("Test device"); | ||
63 | + device.setType("default"); | ||
64 | + testDevice = doPost("/api/device", device, Device.class); | ||
65 | + | ||
66 | + obj = new TelemetryEntityView( | ||
67 | + Arrays.asList("109L", "209L"), | ||
68 | + new AttributesEntityView( | ||
69 | + Arrays.asList("caKey1", "caKey2", "caKey3"), | ||
70 | + Arrays.asList("saKey1", "saKey2", "saKey3", "saKey4"), | ||
71 | + Arrays.asList("shKey1", "shKey2", "shKey3", "shKey4", "shKey5"))); | ||
72 | + } | ||
73 | + | ||
74 | + @After | ||
75 | + public void afterTest() throws Exception { | ||
76 | + loginSysAdmin(); | ||
77 | + | ||
78 | + doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) | ||
79 | + .andExpect(status().isOk()); | ||
80 | + } | ||
81 | + | ||
82 | + @Test | ||
83 | + public void testFindEntityViewById() throws Exception { | ||
84 | + EntityView view = new EntityView(); | ||
85 | + view.setName("Test entity view"); | ||
86 | + view.setEntityId(testDevice.getId()); | ||
87 | + view.setKeys(new TelemetryEntityView(obj)); | ||
88 | + EntityView savedView = doPost("/api/entity-view", view, EntityView.class); | ||
89 | + EntityView foundView = doGet("/api/entity-view/" + savedView.getId().getId().toString(), EntityView.class); | ||
90 | + Assert.assertNotNull(foundView); | ||
91 | + Assert.assertEquals(savedView, foundView); | ||
92 | + } | ||
93 | + | ||
94 | + @Test | ||
95 | + public void testSaveEntityViewWithIdOfDevice() throws Exception { | ||
96 | + EntityView view = new EntityView(); | ||
97 | + view.setEntityId(testDevice.getId()); | ||
98 | + view.setName("Test entity view"); | ||
99 | + view.setTenantId(savedTenant.getId()); | ||
100 | + view.setKeys(new TelemetryEntityView(obj)); | ||
101 | + EntityView savedView = doPost("/api/entity-view", view, EntityView.class); | ||
102 | + | ||
103 | + Assert.assertNotNull(savedView); | ||
104 | + Assert.assertNotNull(savedView.getId()); | ||
105 | + Assert.assertTrue(savedView.getCreatedTime() > 0); | ||
106 | + Assert.assertEquals(savedTenant.getId(), savedView.getTenantId()); | ||
107 | + Assert.assertNotNull(savedView.getCustomerId()); | ||
108 | + Assert.assertEquals(NULL_UUID, savedView.getCustomerId().getId()); | ||
109 | + Assert.assertEquals(savedView.getName(), savedView.getName()); | ||
110 | + | ||
111 | + savedView.setName("New test entity view"); | ||
112 | + doPost("/api/entity-view", savedView, EntityView.class); | ||
113 | + | ||
114 | + EntityView foundEntityView = doGet("/api/entity-view/" | ||
115 | + + savedView.getId().getId().toString(), EntityView.class); | ||
116 | + | ||
117 | + Assert.assertEquals(foundEntityView.getName(), savedView.getName()); | ||
118 | + } | ||
119 | + | ||
120 | + @Test | ||
121 | + public void testDeleteEntityView() throws Exception { | ||
122 | + EntityView view = new EntityView(); | ||
123 | + view.setName("Test entity view"); | ||
124 | + view.setEntityId(testDevice.getId()); | ||
125 | + view.setKeys(new TelemetryEntityView((TelemetryEntityView) obj)); | ||
126 | + EntityView savedView = doPost("/api/entity-view", view, EntityView.class); | ||
127 | + | ||
128 | + doDelete("/api/entity-view/" + savedView.getId().getId().toString()) | ||
129 | + .andExpect(status().isOk()); | ||
130 | + | ||
131 | + doGet("/api/entity-view/" + savedView.getId().getId().toString()) | ||
132 | + .andExpect(status().isNotFound()); | ||
133 | + } | ||
134 | +} |
@@ -24,7 +24,7 @@ import java.util.Arrays; | @@ -24,7 +24,7 @@ import java.util.Arrays; | ||
24 | 24 | ||
25 | @RunWith(ClasspathSuite.class) | 25 | @RunWith(ClasspathSuite.class) |
26 | @ClasspathSuite.ClassnameFilters({ | 26 | @ClasspathSuite.ClassnameFilters({ |
27 | - "org.thingsboard.server.controller.sql.*SqlTest", | 27 | + "org.thingsboard.server.controller.sql.EntityViewControllerSqlTest", |
28 | }) | 28 | }) |
29 | public class ControllerSqlTestSuite { | 29 | public class ControllerSqlTestSuite { |
30 | 30 |
application/src/test/java/org/thingsboard/server/controller/nosql/EntityViewControllerNoSqlTest.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.controller.nosql; | ||
17 | + | ||
18 | +import org.thingsboard.server.controller.BaseEntityViewControllerTest; | ||
19 | + | ||
20 | +/** | ||
21 | + * Created by Victor Basanets on 8/27/2017. | ||
22 | + */ | ||
23 | +public class EntityViewControllerNoSqlTest extends BaseEntityViewControllerTest { | ||
24 | +} |
application/src/test/java/org/thingsboard/server/controller/sql/EntityViewControllerSqlTest.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.controller.sql; | ||
17 | + | ||
18 | +import org.junit.Assert; | ||
19 | +import org.junit.Test; | ||
20 | +import org.thingsboard.server.common.data.EntityView; | ||
21 | +import org.thingsboard.server.controller.BaseEntityViewControllerTest; | ||
22 | +import org.thingsboard.server.dao.service.DaoSqlTest; | ||
23 | + | ||
24 | +import java.util.Arrays; | ||
25 | + | ||
26 | +/** | ||
27 | + * Created by Victor Basanets on 8/27/2017. | ||
28 | + */ | ||
29 | +@DaoSqlTest | ||
30 | +public class EntityViewControllerSqlTest extends BaseEntityViewControllerTest { | ||
31 | +} |
@@ -20,4 +20,5 @@ public class CacheConstants { | @@ -20,4 +20,5 @@ public class CacheConstants { | ||
20 | public static final String RELATIONS_CACHE = "relations"; | 20 | public static final String RELATIONS_CACHE = "relations"; |
21 | public static final String DEVICE_CACHE = "devices"; | 21 | public static final String DEVICE_CACHE = "devices"; |
22 | public static final String ASSET_CACHE = "assets"; | 22 | public static final String ASSET_CACHE = "assets"; |
23 | + public static final String ENTITY_VIEW_CACHE = "entityViews"; | ||
23 | } | 24 | } |
@@ -19,5 +19,5 @@ package org.thingsboard.server.common.data; | @@ -19,5 +19,5 @@ package org.thingsboard.server.common.data; | ||
19 | * @author Andrew Shvayka | 19 | * @author Andrew Shvayka |
20 | */ | 20 | */ |
21 | public enum EntityType { | 21 | public enum EntityType { |
22 | - TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE; | 22 | + TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW |
23 | } | 23 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data; | ||
17 | + | ||
18 | +import lombok.*; | ||
19 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
20 | +import org.thingsboard.server.common.data.id.EntityId; | ||
21 | +import org.thingsboard.server.common.data.id.EntityViewId; | ||
22 | +import org.thingsboard.server.common.data.id.TenantId; | ||
23 | +import org.thingsboard.server.common.data.objects.TelemetryEntityView; | ||
24 | + | ||
25 | +/** | ||
26 | + * Created by Victor Basanets on 8/27/2017. | ||
27 | + */ | ||
28 | + | ||
29 | +@Data | ||
30 | +@AllArgsConstructor | ||
31 | +@EqualsAndHashCode(callSuper = true) | ||
32 | +public class EntityView extends SearchTextBasedWithAdditionalInfo<EntityViewId> | ||
33 | + implements HasName, HasTenantId, HasCustomerId { | ||
34 | + | ||
35 | + private static final long serialVersionUID = 5582010124562018986L; | ||
36 | + | ||
37 | + private EntityId entityId; | ||
38 | + private TenantId tenantId; | ||
39 | + private CustomerId customerId; | ||
40 | + private String name; | ||
41 | + private TelemetryEntityView keys; | ||
42 | + private Long tsBegin; | ||
43 | + private Long tsEnd; | ||
44 | + | ||
45 | + public EntityView() { | ||
46 | + super(); | ||
47 | + } | ||
48 | + | ||
49 | + public EntityView(EntityViewId id) { | ||
50 | + super(id); | ||
51 | + } | ||
52 | + | ||
53 | + public EntityView(EntityView entityView) { | ||
54 | + super(entityView); | ||
55 | + } | ||
56 | + | ||
57 | + @Override | ||
58 | + public String getSearchText() { | ||
59 | + return getName() /*What the ...*/; | ||
60 | + } | ||
61 | + | ||
62 | + @Override | ||
63 | + public CustomerId getCustomerId() { | ||
64 | + return customerId; | ||
65 | + } | ||
66 | + | ||
67 | + @Override | ||
68 | + public String getName() { | ||
69 | + return name; | ||
70 | + } | ||
71 | + | ||
72 | + @Override | ||
73 | + public TenantId getTenantId() { | ||
74 | + return tenantId; | ||
75 | + } | ||
76 | +} |
@@ -57,6 +57,8 @@ public class EntityIdFactory { | @@ -57,6 +57,8 @@ public class EntityIdFactory { | ||
57 | return new RuleChainId(uuid); | 57 | return new RuleChainId(uuid); |
58 | case RULE_NODE: | 58 | case RULE_NODE: |
59 | return new RuleNodeId(uuid); | 59 | return new RuleNodeId(uuid); |
60 | + case ENTITY_VIEW: | ||
61 | + return new EntityViewId(uuid); | ||
60 | } | 62 | } |
61 | throw new IllegalArgumentException("EntityType " + type + " is not supported!"); | 63 | throw new IllegalArgumentException("EntityType " + type + " is not supported!"); |
62 | } | 64 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.id; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.annotation.JsonCreator; | ||
19 | +import com.fasterxml.jackson.annotation.JsonProperty; | ||
20 | +import org.thingsboard.server.common.data.EntityType; | ||
21 | + | ||
22 | +import java.util.UUID; | ||
23 | + | ||
24 | +/** | ||
25 | + * Created by Victor Basanets on 8/27/2017. | ||
26 | + */ | ||
27 | +public class EntityViewId extends UUIDBased implements EntityId { | ||
28 | + | ||
29 | + private static final long serialVersionUID = 1L; | ||
30 | + | ||
31 | + @JsonCreator | ||
32 | + public EntityViewId(@JsonProperty("id") UUID id) { | ||
33 | + super(id); | ||
34 | + } | ||
35 | + | ||
36 | + public static EntityViewId fromString(String entityViewID) { | ||
37 | + return new EntityViewId(UUID.fromString(entityViewID)); | ||
38 | + } | ||
39 | + | ||
40 | + @Override | ||
41 | + public EntityType getEntityType() { | ||
42 | + return EntityType.ENTITY_VIEW; | ||
43 | + } | ||
44 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/objects/AttributesEntityView.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.objects; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import lombok.NoArgsConstructor; | ||
20 | + | ||
21 | +import java.util.ArrayList; | ||
22 | +import java.util.List; | ||
23 | + | ||
24 | +/** | ||
25 | + * Created by Victor Basanets on 9/05/2017. | ||
26 | + */ | ||
27 | +@Data | ||
28 | +@NoArgsConstructor | ||
29 | +public class AttributesEntityView { | ||
30 | + | ||
31 | + private List<String> cs = new ArrayList<>(); | ||
32 | + private List<String> ss = new ArrayList<>(); | ||
33 | + private List<String> sh = new ArrayList<>(); | ||
34 | + | ||
35 | + public AttributesEntityView(List<String> cs, | ||
36 | + List<String> ss, | ||
37 | + List<String> sh) { | ||
38 | + | ||
39 | + this.cs = new ArrayList<>(cs); | ||
40 | + this.ss = new ArrayList<>(ss); | ||
41 | + this.sh = new ArrayList<>(sh); | ||
42 | + } | ||
43 | + | ||
44 | + public AttributesEntityView(AttributesEntityView obj) { | ||
45 | + this(obj.getCs(), obj.getSs(), obj.getSh()); | ||
46 | + } | ||
47 | + | ||
48 | + @Override | ||
49 | + public String toString() { | ||
50 | + return "{cs=" + cs + ", ss=" + ss + ", sh=" + sh + '}'; | ||
51 | + } | ||
52 | +} |
common/data/src/main/java/org/thingsboard/server/common/data/objects/TelemetryEntityView.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data.objects; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | +import lombok.NoArgsConstructor; | ||
20 | + | ||
21 | +import java.util.ArrayList; | ||
22 | +import java.util.List; | ||
23 | + | ||
24 | +/** | ||
25 | + * Created by Victor Basanets on 9/05/2017. | ||
26 | + */ | ||
27 | +@Data | ||
28 | +@NoArgsConstructor | ||
29 | +public class TelemetryEntityView { | ||
30 | + | ||
31 | + private List<String> timeseries; | ||
32 | + private AttributesEntityView attributes; | ||
33 | + | ||
34 | + public TelemetryEntityView(List<String> timeseries, AttributesEntityView attributes) { | ||
35 | + | ||
36 | + this.timeseries = new ArrayList<>(timeseries); | ||
37 | + this.attributes = attributes; | ||
38 | + } | ||
39 | + | ||
40 | + public TelemetryEntityView(TelemetryEntityView obj) { | ||
41 | + this(obj.getTimeseries(), obj.getAttributes()); | ||
42 | + } | ||
43 | + | ||
44 | + @Override | ||
45 | + public String toString() { | ||
46 | + return "{timeseries=" + timeseries + ", attributes=" + attributes + '}'; | ||
47 | + } | ||
48 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.dao.entityview; | ||
17 | + | ||
18 | +import org.thingsboard.server.common.data.EntityView; | ||
19 | +import org.thingsboard.server.common.data.id.EntityId; | ||
20 | +import org.thingsboard.server.common.data.page.TextPageLink; | ||
21 | +import org.thingsboard.server.dao.Dao; | ||
22 | + | ||
23 | +import java.util.List; | ||
24 | +import java.util.Optional; | ||
25 | +import java.util.UUID; | ||
26 | + | ||
27 | +/** | ||
28 | + * Created by Victor Basanets on 8/28/2017. | ||
29 | + */ | ||
30 | +public interface EntityViewDao extends Dao<EntityView> { | ||
31 | + | ||
32 | + /** | ||
33 | + * Find entity views by tenantId and page link. | ||
34 | + * | ||
35 | + * @param tenantId the tenantId | ||
36 | + * @param pageLink the page link | ||
37 | + * @return the list of entity view objects | ||
38 | + */ | ||
39 | + List<EntityView> findEntityViewByTenantId(UUID tenantId, TextPageLink pageLink); | ||
40 | + | ||
41 | + /** | ||
42 | + * Find entity views by tenantId and entity view name. | ||
43 | + * | ||
44 | + * @param tenantId the tenantId | ||
45 | + * @param name the entity view name | ||
46 | + * @return the optional entity view object | ||
47 | + */ | ||
48 | + Optional<EntityView> findEntityViewByTenantIdAndName(UUID tenantId, String name); | ||
49 | + | ||
50 | + /** | ||
51 | + * Find entity views by tenantId, entityId and page link. | ||
52 | + * | ||
53 | + * @param tenantId the tenantId | ||
54 | + * @param entityId the entityId | ||
55 | + * @param pageLink the page link | ||
56 | + * @return the list of entity view objects | ||
57 | + */ | ||
58 | + List<EntityView> findEntityViewByTenantIdAndEntityId(UUID tenantId, | ||
59 | + UUID entityId, | ||
60 | + TextPageLink pageLink); | ||
61 | + | ||
62 | + /** | ||
63 | + * Find entity views by tenantId, customerId and page link. | ||
64 | + * | ||
65 | + * @param tenantId the tenantId | ||
66 | + * @param customerId the customerId | ||
67 | + * @param pageLink the page link | ||
68 | + * @return the list of entity view objects | ||
69 | + */ | ||
70 | + List<EntityView> findEntityViewsByTenantIdAndCustomerId(UUID tenantId, | ||
71 | + UUID customerId, | ||
72 | + TextPageLink pageLink); | ||
73 | + | ||
74 | + /** | ||
75 | + * Find entity views by tenantId, customerId, entityId and page link. | ||
76 | + * | ||
77 | + * @param tenantId the tenantId | ||
78 | + * @param customerId the customerId | ||
79 | + * @param entityId the entityId | ||
80 | + * @param pageLink the page link | ||
81 | + * @return the list of entity view objects | ||
82 | + */ | ||
83 | + List<EntityView> findEntityViewsByTenantIdAndCustomerIdAndEntityId(UUID tenantId, | ||
84 | + UUID customerId, | ||
85 | + UUID entityId, | ||
86 | + TextPageLink pageLink); | ||
87 | + | ||
88 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.dao.entityview; | ||
17 | + | ||
18 | +import org.thingsboard.server.common.data.EntityType; | ||
19 | +import org.thingsboard.server.common.data.EntityView; | ||
20 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
21 | +import org.thingsboard.server.common.data.id.EntityId; | ||
22 | +import org.thingsboard.server.common.data.id.EntityViewId; | ||
23 | +import org.thingsboard.server.common.data.id.TenantId; | ||
24 | +import org.thingsboard.server.common.data.page.TextPageData; | ||
25 | +import org.thingsboard.server.common.data.page.TextPageLink; | ||
26 | + | ||
27 | +/** | ||
28 | + * Created by Victor Basanets on 8/27/2017. | ||
29 | + */ | ||
30 | +public interface EntityViewService { | ||
31 | + | ||
32 | + EntityView findEntityViewById(EntityViewId entityViewId); | ||
33 | + | ||
34 | + EntityView findEntityViewByTenantIdAndName(TenantId tenantId, String name); | ||
35 | + | ||
36 | + EntityView saveEntityView(EntityView entityView); | ||
37 | + | ||
38 | + EntityView assignEntityViewToCustomer(EntityViewId entityViewId, CustomerId customerId); | ||
39 | + | ||
40 | + EntityView unassignEntityViewFromCustomer(EntityViewId entityViewId); | ||
41 | + | ||
42 | + void deleteEntityView(EntityViewId entityViewId); | ||
43 | + | ||
44 | + TextPageData<EntityView> findEntityViewByTenantId(TenantId tenantId, TextPageLink pageLink); | ||
45 | + | ||
46 | + TextPageData<EntityView> findEntityViewByTenantIdAndEntityId(TenantId tenantId, EntityId entityId, | ||
47 | + TextPageLink pageLink); | ||
48 | + | ||
49 | + void deleteEntityViewByTenantId(TenantId tenantId); | ||
50 | + | ||
51 | + TextPageData<EntityView> findEntityViewsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, | ||
52 | + TextPageLink pageLink); | ||
53 | + | ||
54 | + TextPageData<EntityView> findEntityViewsByTenantIdAndCustomerIdAndEntityId(TenantId tenantId, | ||
55 | + CustomerId customerId, | ||
56 | + EntityId entityId, | ||
57 | + TextPageLink pageLink); | ||
58 | + | ||
59 | + void unassignCustomerEntityViews(TenantId tenantId, CustomerId customerId); | ||
60 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.dao.entityview; | ||
17 | + | ||
18 | +import lombok.extern.slf4j.Slf4j; | ||
19 | +import org.apache.commons.lang3.StringUtils; | ||
20 | +import org.springframework.beans.factory.annotation.Autowired; | ||
21 | +import org.springframework.cache.Cache; | ||
22 | +import org.springframework.cache.CacheManager; | ||
23 | +import org.springframework.stereotype.Service; | ||
24 | +import org.thingsboard.server.common.data.Customer; | ||
25 | +import org.thingsboard.server.common.data.EntityView; | ||
26 | +import org.thingsboard.server.common.data.Tenant; | ||
27 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
28 | +import org.thingsboard.server.common.data.id.EntityId; | ||
29 | +import org.thingsboard.server.common.data.id.EntityViewId; | ||
30 | +import org.thingsboard.server.common.data.id.TenantId; | ||
31 | +import org.thingsboard.server.common.data.page.TextPageData; | ||
32 | +import org.thingsboard.server.common.data.page.TextPageLink; | ||
33 | +import org.thingsboard.server.dao.customer.CustomerDao; | ||
34 | +import org.thingsboard.server.dao.entity.AbstractEntityService; | ||
35 | +import org.thingsboard.server.dao.exception.DataValidationException; | ||
36 | +import org.thingsboard.server.dao.service.DataValidator; | ||
37 | +import org.thingsboard.server.dao.service.PaginatedRemover; | ||
38 | +import org.thingsboard.server.dao.tenant.TenantDao; | ||
39 | + | ||
40 | +import java.util.ArrayList; | ||
41 | +import java.util.List; | ||
42 | + | ||
43 | +import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; | ||
44 | +import static org.thingsboard.server.dao.service.Validator.validateId; | ||
45 | +import static org.thingsboard.server.dao.service.Validator.validatePageLink; | ||
46 | +import static org.thingsboard.server.dao.service.Validator.validateString; | ||
47 | + | ||
48 | +/** | ||
49 | + * Created by Victor Basanets on 8/28/2017. | ||
50 | + */ | ||
51 | +@Service | ||
52 | +@Slf4j | ||
53 | +public class EntityViewServiceImpl extends AbstractEntityService | ||
54 | + implements EntityViewService { | ||
55 | + | ||
56 | + public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; | ||
57 | + public static final String INCORRECT_PAGE_LINK = "Incorrect page link "; | ||
58 | + public static final String INCORRECT_CUSTOMER_ID = "Incorrect customerId "; | ||
59 | + public static final String INCORRECT_ENTITY_VIEW_ID = "Incorrect entityViewId "; | ||
60 | + | ||
61 | + @Autowired | ||
62 | + private EntityViewDao entityViewDao; | ||
63 | + | ||
64 | + @Autowired | ||
65 | + private TenantDao tenantDao; | ||
66 | + | ||
67 | + @Autowired | ||
68 | + private CustomerDao customerDao; | ||
69 | + | ||
70 | + @Override | ||
71 | + public EntityView findEntityViewById(EntityViewId entityViewId) { | ||
72 | + log.trace("Executing findEntityViewById [{}]", entityViewId); | ||
73 | + validateId(entityViewId, INCORRECT_ENTITY_VIEW_ID + entityViewId); | ||
74 | + return entityViewDao.findById(entityViewId.getId()); | ||
75 | + } | ||
76 | + | ||
77 | + @Override | ||
78 | + public EntityView findEntityViewByTenantIdAndName(TenantId tenantId, String name) { | ||
79 | + log.trace("Executing findEntityViewByTenantIdAndName [{}][{}]", tenantId, name); | ||
80 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
81 | + return entityViewDao.findEntityViewByTenantIdAndName(tenantId.getId(), name) | ||
82 | + .orElse(null); | ||
83 | + } | ||
84 | + | ||
85 | + @Override | ||
86 | + public EntityView saveEntityView(EntityView entityView) { | ||
87 | + log.trace("Executing save entity view [{}]", entityView); | ||
88 | + entityViewValidator.validate(entityView); | ||
89 | + return entityViewDao.save(entityView); | ||
90 | + } | ||
91 | + | ||
92 | + @Override | ||
93 | + public EntityView assignEntityViewToCustomer(EntityViewId entityViewId, CustomerId customerId) { | ||
94 | + EntityView entityView = findEntityViewById(entityViewId); | ||
95 | + entityView.setCustomerId(customerId); | ||
96 | + return saveEntityView(entityView); | ||
97 | + } | ||
98 | + | ||
99 | + @Override | ||
100 | + public EntityView unassignEntityViewFromCustomer(EntityViewId entityViewId) { | ||
101 | + EntityView entityView = findEntityViewById(entityViewId); | ||
102 | + entityView.setCustomerId(null); | ||
103 | + return saveEntityView(entityView); | ||
104 | + } | ||
105 | + | ||
106 | + @Override | ||
107 | + public void deleteEntityView(EntityViewId entityViewId) { | ||
108 | + log.trace("Executing deleteEntityView [{}]", entityViewId); | ||
109 | + validateId(entityViewId, INCORRECT_ENTITY_VIEW_ID + entityViewId); | ||
110 | + deleteEntityRelations(entityViewId); | ||
111 | + EntityView entityView = entityViewDao.findById(entityViewId.getId()); | ||
112 | + List<Object> list = new ArrayList<>(); | ||
113 | + list.add(entityView.getTenantId()); | ||
114 | + list.add(entityView.getName()); | ||
115 | + entityViewDao.removeById(entityViewId.getId()); | ||
116 | + } | ||
117 | + | ||
118 | + @Override | ||
119 | + public TextPageData<EntityView> findEntityViewByTenantId(TenantId tenantId, TextPageLink pageLink) { | ||
120 | + log.trace("Executing findEntityViewByTenantId, tenantId [{}], pageLink [{}]", tenantId, pageLink); | ||
121 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
122 | + validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); | ||
123 | + List<EntityView> entityViews = entityViewDao.findEntityViewByTenantId(tenantId.getId(), pageLink); | ||
124 | + return new TextPageData<>(entityViews, pageLink); | ||
125 | + } | ||
126 | + | ||
127 | + @Override | ||
128 | + public TextPageData<EntityView> findEntityViewByTenantIdAndEntityId(TenantId tenantId, EntityId entityId, | ||
129 | + TextPageLink pageLink) { | ||
130 | + | ||
131 | + log.trace("Executing findEntityViewByTenantIdAndType, tenantId [{}], entityId [{}], pageLink [{}]", | ||
132 | + tenantId, entityId, pageLink); | ||
133 | + | ||
134 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
135 | + validateString(entityId.toString(), "Incorrect entityId " + entityId.toString()); | ||
136 | + validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); | ||
137 | + List<EntityView> entityViews = entityViewDao.findEntityViewByTenantIdAndEntityId(tenantId.getId(), | ||
138 | + entityId.getId(), pageLink); | ||
139 | + | ||
140 | + return new TextPageData<>(entityViews, pageLink); | ||
141 | + } | ||
142 | + | ||
143 | + @Override | ||
144 | + public void deleteEntityViewByTenantId(TenantId tenantId) { | ||
145 | + log.trace("Executing deleteEntityViewByTenantId, tenantId [{}]", tenantId); | ||
146 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
147 | + tenantEntityViewRemover.removeEntities(tenantId); | ||
148 | + } | ||
149 | + | ||
150 | + @Override | ||
151 | + public TextPageData<EntityView> findEntityViewsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, | ||
152 | + TextPageLink pageLink) { | ||
153 | + | ||
154 | + log.trace("Executing findEntityViewByTenantIdAndCustomerId, tenantId [{}], customerId [{}]," + | ||
155 | + " pageLink [{}]", tenantId, customerId, pageLink); | ||
156 | + | ||
157 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
158 | + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); | ||
159 | + validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); | ||
160 | + List<EntityView> entityViews = entityViewDao.findEntityViewsByTenantIdAndCustomerId(tenantId.getId(), | ||
161 | + customerId.getId(), pageLink); | ||
162 | + | ||
163 | + return new TextPageData<>(entityViews, pageLink); | ||
164 | + } | ||
165 | + | ||
166 | + @Override | ||
167 | + public TextPageData<EntityView> findEntityViewsByTenantIdAndCustomerIdAndEntityId(TenantId tenantId, | ||
168 | + CustomerId customerId, | ||
169 | + EntityId entityId, | ||
170 | + TextPageLink pageLink) { | ||
171 | + | ||
172 | + log.trace("Executing findEntityViewsByTenantIdAndCustomerIdAndType, tenantId [{}], customerId [{}]," + | ||
173 | + " entityId [{}], pageLink [{}]", tenantId, customerId, entityId, pageLink); | ||
174 | + | ||
175 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
176 | + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); | ||
177 | + validateString(entityId.toString(), "Incorrect entityId " + entityId.toString()); | ||
178 | + validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); | ||
179 | + List<EntityView> entityViews = entityViewDao.findEntityViewsByTenantIdAndCustomerIdAndEntityId( | ||
180 | + tenantId.getId(), customerId.getId(), entityId.getId(), pageLink); | ||
181 | + | ||
182 | + return new TextPageData<>(entityViews, pageLink); | ||
183 | + } | ||
184 | + | ||
185 | + @Override | ||
186 | + public void unassignCustomerEntityViews(TenantId tenantId, CustomerId customerId) { | ||
187 | + log.trace("Executing unassignCustomerEntityViews, tenantId [{}], customerId [{}]", tenantId, customerId); | ||
188 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
189 | + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); | ||
190 | + new CustomerEntityViewsUnAssigner(tenantId).removeEntities(customerId); | ||
191 | + } | ||
192 | + | ||
193 | + private DataValidator<EntityView> entityViewValidator = | ||
194 | + new DataValidator<EntityView>() { | ||
195 | + | ||
196 | + @Override | ||
197 | + protected void validateCreate(EntityView entityView) { | ||
198 | + entityViewDao.findEntityViewByTenantIdAndName(entityView.getTenantId().getId(), entityView.getName()) | ||
199 | + .ifPresent( e -> { | ||
200 | + throw new DataValidationException("Entity view with such name already exists!"); | ||
201 | + }); | ||
202 | + } | ||
203 | + | ||
204 | + @Override | ||
205 | + protected void validateUpdate(EntityView entityView) { | ||
206 | + entityViewDao.findEntityViewByTenantIdAndName(entityView.getTenantId().getId(), entityView.getName()) | ||
207 | + .ifPresent( e -> { | ||
208 | + if (!e.getUuidId().equals(entityView.getUuidId())) { | ||
209 | + throw new DataValidationException("Entity view with such name already exists!"); | ||
210 | + } | ||
211 | + }); | ||
212 | + } | ||
213 | + | ||
214 | + @Override | ||
215 | + protected void validateDataImpl(EntityView entityView) { | ||
216 | + if (StringUtils.isEmpty(entityView.getKeys().toString())) { | ||
217 | + throw new DataValidationException("Entity view type should be specified!"); | ||
218 | + } | ||
219 | + if (StringUtils.isEmpty(entityView.getName())) { | ||
220 | + throw new DataValidationException("Entity view name should be specified!"); | ||
221 | + } | ||
222 | + if (entityView.getTenantId() == null) { | ||
223 | + throw new DataValidationException("Entity view should be assigned to tenant!"); | ||
224 | + } else { | ||
225 | + Tenant tenant = tenantDao.findById(entityView.getTenantId().getId()); | ||
226 | + if (tenant == null) { | ||
227 | + throw new DataValidationException("Entity view is referencing to non-existent tenant!"); | ||
228 | + } | ||
229 | + } | ||
230 | + if (entityView.getCustomerId() == null) { | ||
231 | + entityView.setCustomerId(new CustomerId(NULL_UUID)); | ||
232 | + } else if (!entityView.getCustomerId().getId().equals(NULL_UUID)) { | ||
233 | + Customer customer = customerDao.findById(entityView.getCustomerId().getId()); | ||
234 | + if (customer == null) { | ||
235 | + throw new DataValidationException("Can't assign entity view to non-existent customer!"); | ||
236 | + } | ||
237 | + if (!customer.getTenantId().getId().equals(entityView.getTenantId().getId())) { | ||
238 | + throw new DataValidationException("Can't assign entity view to customer from different tenant!"); | ||
239 | + } | ||
240 | + } | ||
241 | + } | ||
242 | + }; | ||
243 | + | ||
244 | + private PaginatedRemover<TenantId, EntityView> tenantEntityViewRemover = | ||
245 | + new PaginatedRemover<TenantId, EntityView>() { | ||
246 | + | ||
247 | + @Override | ||
248 | + protected List<EntityView> findEntities(TenantId id, TextPageLink pageLink) { | ||
249 | + return entityViewDao.findEntityViewByTenantId(id.getId(), pageLink); | ||
250 | + } | ||
251 | + | ||
252 | + @Override | ||
253 | + protected void removeEntity(EntityView entity) { | ||
254 | + deleteEntityView(new EntityViewId(entity.getUuidId())); | ||
255 | + } | ||
256 | + }; | ||
257 | + | ||
258 | + private class CustomerEntityViewsUnAssigner extends PaginatedRemover<CustomerId, EntityView> { | ||
259 | + | ||
260 | + private TenantId tenantId; | ||
261 | + | ||
262 | + CustomerEntityViewsUnAssigner(TenantId tenantId) { | ||
263 | + this.tenantId = tenantId; | ||
264 | + } | ||
265 | + | ||
266 | + @Override | ||
267 | + protected List<EntityView> findEntities(CustomerId id, TextPageLink pageLink) { | ||
268 | + return entityViewDao.findEntityViewsByTenantIdAndCustomerId(tenantId.getId(), id.getId(), pageLink); | ||
269 | + } | ||
270 | + | ||
271 | + @Override | ||
272 | + protected void removeEntity(EntityView entity) { | ||
273 | + unassignEntityViewFromCustomer(new EntityViewId(entity.getUuidId())); | ||
274 | + } | ||
275 | + } | ||
276 | +} |
@@ -45,6 +45,7 @@ public class ModelConstants { | @@ -45,6 +45,7 @@ public class ModelConstants { | ||
45 | public static final String SEARCH_TEXT_PROPERTY = "search_text"; | 45 | public static final String SEARCH_TEXT_PROPERTY = "search_text"; |
46 | public static final String ADDITIONAL_INFO_PROPERTY = "additional_info"; | 46 | public static final String ADDITIONAL_INFO_PROPERTY = "additional_info"; |
47 | public static final String ENTITY_TYPE_PROPERTY = "entity_type"; | 47 | public static final String ENTITY_TYPE_PROPERTY = "entity_type"; |
48 | + /*public static final String ENTITY_VIEW_ID_PROPERTY = "entity_view_id";*/ | ||
48 | 49 | ||
49 | public static final String ENTITY_TYPE_COLUMN = ENTITY_TYPE_PROPERTY; | 50 | public static final String ENTITY_TYPE_COLUMN = ENTITY_TYPE_PROPERTY; |
50 | public static final String ENTITY_ID_COLUMN = "entity_id"; | 51 | public static final String ENTITY_ID_COLUMN = "entity_id"; |
@@ -144,6 +145,20 @@ public class ModelConstants { | @@ -144,6 +145,20 @@ public class ModelConstants { | ||
144 | public static final String DEVICE_TYPES_BY_TENANT_VIEW_NAME = "device_types_by_tenant"; | 145 | public static final String DEVICE_TYPES_BY_TENANT_VIEW_NAME = "device_types_by_tenant"; |
145 | 146 | ||
146 | /** | 147 | /** |
148 | + * Cassandra entityView constants. | ||
149 | + */ | ||
150 | + public static final String ENTITY_VIEW_TABLE_FAMILY_NAME = "entity_views"; | ||
151 | + public static final String ENTITY_VIEW_ENTITY_ID_PROPERTY = ENTITY_ID_COLUMN; | ||
152 | + public static final String ENTITY_VIEW_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; | ||
153 | + public static final String ENTITY_VIEW_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY; | ||
154 | + public static final String ENTITY_VIEW_NAME_PROPERTY = DEVICE_NAME_PROPERTY; | ||
155 | + public static final String ENTITY_VIEW_TYPE_PROPERTY = "type_entity"; | ||
156 | + public static final String ENTITY_VIEW_KEYS_PROPERTY = "keys"; | ||
157 | + public static final String ENTITY_VIEW_TS_BEGIN_PROPERTY = "ts_begin"; | ||
158 | + public static final String ENTITY_VIEW_TS_END_PROPERTY = "ts_end"; | ||
159 | + public static final String ENTITY_VIEW_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; | ||
160 | + | ||
161 | + /** | ||
147 | * Cassandra audit log constants. | 162 | * Cassandra audit log constants. |
148 | */ | 163 | */ |
149 | public static final String AUDIT_LOG_COLUMN_FAMILY_NAME = "audit_log"; | 164 | public static final String AUDIT_LOG_COLUMN_FAMILY_NAME = "audit_log"; |
1 | +/** | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.dao.model.nosql; | ||
17 | + | ||
18 | +import com.datastax.driver.core.utils.UUIDs; | ||
19 | +import com.datastax.driver.mapping.annotations.PartitionKey; | ||
20 | +import com.datastax.driver.mapping.annotations.Table; | ||
21 | +import com.fasterxml.jackson.databind.JsonNode; | ||
22 | +import lombok.Data; | ||
23 | +import lombok.EqualsAndHashCode; | ||
24 | +import lombok.ToString; | ||
25 | +import org.hibernate.annotations.Type; | ||
26 | +import org.thingsboard.server.common.data.EntityView; | ||
27 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
28 | +import org.thingsboard.server.common.data.id.DeviceId; | ||
29 | +import org.thingsboard.server.common.data.id.EntityViewId; | ||
30 | +import org.thingsboard.server.common.data.id.TenantId; | ||
31 | +import org.thingsboard.server.common.data.objects.TelemetryEntityView; | ||
32 | +import org.thingsboard.server.dao.model.ModelConstants; | ||
33 | +import org.thingsboard.server.dao.model.SearchTextEntity; | ||
34 | + | ||
35 | +import javax.persistence.Column; | ||
36 | + | ||
37 | +import java.io.IOException; | ||
38 | +import java.util.UUID; | ||
39 | + | ||
40 | +import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_VIEW_TABLE_FAMILY_NAME; | ||
41 | +import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY; | ||
42 | + | ||
43 | +/** | ||
44 | + * Created by Victor Basanets on 8/31/2017. | ||
45 | + */ | ||
46 | +@Data | ||
47 | +@Table(name = ENTITY_VIEW_TABLE_FAMILY_NAME) | ||
48 | +@EqualsAndHashCode | ||
49 | +@ToString | ||
50 | +public class EntityViewEntity implements SearchTextEntity<EntityView> { | ||
51 | + | ||
52 | + @PartitionKey(value = 0) | ||
53 | + @Column(name = ID_PROPERTY) | ||
54 | + private UUID id; | ||
55 | + | ||
56 | + @PartitionKey(value = 1) | ||
57 | + @Column(name = ModelConstants.ENTITY_VIEW_ENTITY_ID_PROPERTY) | ||
58 | + private UUID entityId; | ||
59 | + | ||
60 | + @PartitionKey(value = 2) | ||
61 | + @Column(name = ModelConstants.ENTITY_VIEW_TENANT_ID_PROPERTY) | ||
62 | + private UUID tenantId; | ||
63 | + | ||
64 | + @PartitionKey(value = 3) | ||
65 | + @Column(name = ModelConstants.ENTITY_VIEW_CUSTOMER_ID_PROPERTY) | ||
66 | + private UUID customerId; | ||
67 | + | ||
68 | + @Column(name = ModelConstants.ENTITY_VIEW_NAME_PROPERTY) | ||
69 | + private String name; | ||
70 | + | ||
71 | + @Type(type = "json") | ||
72 | + @Column(name = ModelConstants.ENTITY_VIEW_KEYS_PROPERTY) | ||
73 | + private JsonNode keys; | ||
74 | + | ||
75 | + @Column(name = ModelConstants.ENTITY_VIEW_TS_BEGIN_PROPERTY) | ||
76 | + private String tsBegin; | ||
77 | + | ||
78 | + @Column(name = ModelConstants.ENTITY_VIEW_TS_END_PROPERTY) | ||
79 | + private String tsEnd; | ||
80 | + | ||
81 | + @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) | ||
82 | + private String searchText; | ||
83 | + | ||
84 | + @Type(type = "json") | ||
85 | + @Column(name = ModelConstants.ENTITY_VIEW_ADDITIONAL_INFO_PROPERTY) | ||
86 | + private JsonNode additionalInfo; | ||
87 | + | ||
88 | + public EntityViewEntity() { | ||
89 | + super(); | ||
90 | + } | ||
91 | + | ||
92 | + public EntityViewEntity(EntityView entityView) { | ||
93 | + if (entityView.getId() != null) { | ||
94 | + this.id = entityView.getId().getId(); | ||
95 | + } | ||
96 | + if (entityView.getEntityId() != null) { | ||
97 | + this.entityId = entityView.getEntityId().getId(); | ||
98 | + } | ||
99 | + if (entityView.getTenantId() != null) { | ||
100 | + this.tenantId = entityView.getTenantId().getId(); | ||
101 | + } | ||
102 | + if (entityView.getCustomerId() != null) { | ||
103 | + this.customerId = entityView.getCustomerId().getId(); | ||
104 | + } | ||
105 | + this.name = entityView.getName(); | ||
106 | +// try { | ||
107 | +// this.keys = entityView.getKeys(); | ||
108 | +// } catch (IOException e) { | ||
109 | +// e.printStackTrace(); | ||
110 | +// } | ||
111 | + this.tsBegin = entityView.getTsBegin() != null ? String.valueOf(entityView.getTsBegin()) : "0"; | ||
112 | + this.tsEnd = entityView.getTsEnd() != null ? String.valueOf(entityView.getTsEnd()) : "0"; | ||
113 | + this.searchText = entityView.getSearchText(); | ||
114 | + this.additionalInfo = entityView.getAdditionalInfo(); | ||
115 | + } | ||
116 | + | ||
117 | + @Override | ||
118 | + public String getSearchTextSource() { | ||
119 | + return name; | ||
120 | + } | ||
121 | + | ||
122 | + @Override | ||
123 | + public EntityView toData() { | ||
124 | + EntityView entityView = new EntityView(new EntityViewId(id)); | ||
125 | + entityView.setCreatedTime(UUIDs.unixTimestamp(id)); | ||
126 | + if (entityId != null) { | ||
127 | + entityView.setEntityId(new DeviceId(entityId)); | ||
128 | + } | ||
129 | + if (tenantId != null) { | ||
130 | + entityView.setTenantId(new TenantId(tenantId)); | ||
131 | + } | ||
132 | + if (customerId != null) { | ||
133 | + entityView.setCustomerId(new CustomerId(customerId)); | ||
134 | + } | ||
135 | + entityView.setName(name); | ||
136 | +// try { | ||
137 | +// entityView.setKeys((TelemetryEntityView) entityView.getKeys().toObject(keys)); | ||
138 | +// } catch (IOException e) { | ||
139 | +// e.printStackTrace(); | ||
140 | +// } | ||
141 | + entityView.setTsBegin(Long.parseLong(tsBegin)); | ||
142 | + entityView.setTsEnd(Long.parseLong(tsEnd)); | ||
143 | + entityView.setAdditionalInfo(additionalInfo); | ||
144 | + return entityView; | ||
145 | + } | ||
146 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.dao.model.sql; | ||
17 | + | ||
18 | +import com.datastax.driver.core.utils.UUIDs; | ||
19 | +import com.fasterxml.jackson.databind.JsonNode; | ||
20 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
21 | +import lombok.Data; | ||
22 | +import lombok.EqualsAndHashCode; | ||
23 | +import org.hibernate.annotations.Type; | ||
24 | +import org.hibernate.annotations.TypeDef; | ||
25 | +import org.thingsboard.server.common.data.EntityType; | ||
26 | +import org.thingsboard.server.common.data.EntityView; | ||
27 | +import org.thingsboard.server.common.data.id.*; | ||
28 | +import org.thingsboard.server.common.data.objects.TelemetryEntityView; | ||
29 | +import org.thingsboard.server.dao.model.BaseSqlEntity; | ||
30 | +import org.thingsboard.server.dao.model.ModelConstants; | ||
31 | +import org.thingsboard.server.dao.model.SearchTextEntity; | ||
32 | +import org.thingsboard.server.dao.util.mapping.JsonStringType; | ||
33 | + | ||
34 | +import javax.persistence.*; | ||
35 | +import java.io.IOException; | ||
36 | + | ||
37 | +import static org.thingsboard.server.dao.model.ModelConstants.AUDIT_LOG_ENTITY_TYPE_PROPERTY; | ||
38 | +import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_TYPE_PROPERTY; | ||
39 | + | ||
40 | +/** | ||
41 | + * Created by Victor Basanets on 8/30/2017. | ||
42 | + */ | ||
43 | + | ||
44 | +@Data | ||
45 | +@EqualsAndHashCode(callSuper = true) | ||
46 | +@Entity | ||
47 | +@TypeDef(name = "json", typeClass = JsonStringType.class) | ||
48 | +@Table(name = ModelConstants.ENTITY_VIEW_TABLE_FAMILY_NAME) | ||
49 | +public class EntityViewEntity extends BaseSqlEntity<EntityView> implements SearchTextEntity<EntityView> { | ||
50 | + | ||
51 | + @Column(name = ModelConstants.ENTITY_VIEW_ENTITY_ID_PROPERTY) | ||
52 | + private String entityId; | ||
53 | + | ||
54 | + @Enumerated(EnumType.STRING) | ||
55 | + @Column(name = ENTITY_TYPE_PROPERTY) | ||
56 | + private EntityType entityType; | ||
57 | + | ||
58 | + @Column(name = ModelConstants.ENTITY_VIEW_TENANT_ID_PROPERTY) | ||
59 | + private String tenantId; | ||
60 | + | ||
61 | + @Column(name = ModelConstants.ENTITY_VIEW_CUSTOMER_ID_PROPERTY) | ||
62 | + private String customerId; | ||
63 | + | ||
64 | + @Column(name = ModelConstants.ENTITY_VIEW_NAME_PROPERTY) | ||
65 | + private String name; | ||
66 | + | ||
67 | + @Column(name = ModelConstants.ENTITY_VIEW_KEYS_PROPERTY) | ||
68 | + private String keys; | ||
69 | + | ||
70 | + @Column(name = ModelConstants.ENTITY_VIEW_TS_BEGIN_PROPERTY) | ||
71 | + private String tsBegin; | ||
72 | + | ||
73 | + @Column(name = ModelConstants.ENTITY_VIEW_TS_END_PROPERTY) | ||
74 | + private String tsEnd; | ||
75 | + | ||
76 | + @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) | ||
77 | + private String searchText; | ||
78 | + | ||
79 | + @Type(type = "json") | ||
80 | + @Column(name = ModelConstants.ENTITY_VIEW_ADDITIONAL_INFO_PROPERTY) | ||
81 | + private JsonNode additionalInfo; | ||
82 | + | ||
83 | + private static final ObjectMapper mapper = new ObjectMapper(); | ||
84 | + | ||
85 | + public EntityViewEntity() { | ||
86 | + super(); | ||
87 | + } | ||
88 | + | ||
89 | + public EntityViewEntity(EntityView entityView) { | ||
90 | + if (entityView.getId() != null) { | ||
91 | + this.setId(entityView.getId().getId()); | ||
92 | + } | ||
93 | + if (entityView.getEntityId() != null) { | ||
94 | + this.entityId = toString(entityView.getEntityId().getId()); | ||
95 | + this.entityType = entityView.getEntityId().getEntityType(); | ||
96 | + } | ||
97 | + if (entityView.getTenantId() != null) { | ||
98 | + this.tenantId = toString(entityView.getTenantId().getId()); | ||
99 | + } | ||
100 | + if (entityView.getCustomerId() != null) { | ||
101 | + this.customerId = toString(entityView.getCustomerId().getId()); | ||
102 | + } | ||
103 | + this.name = entityView.getName(); | ||
104 | + try { | ||
105 | + this.keys = mapper.writeValueAsString(entityView.getKeys()); | ||
106 | + } catch (IOException e) { | ||
107 | + e.printStackTrace(); | ||
108 | + } | ||
109 | + this.tsBegin = entityView.getTsBegin() != null ? String.valueOf(entityView.getTsBegin()) : "0"; | ||
110 | + this.tsEnd = entityView.getTsEnd() != null ? String.valueOf(entityView.getTsEnd()) : "0"; | ||
111 | + this.searchText = entityView.getSearchText(); | ||
112 | + this.additionalInfo = entityView.getAdditionalInfo(); | ||
113 | + } | ||
114 | + | ||
115 | + @Override | ||
116 | + public String getSearchTextSource() { | ||
117 | + return name; | ||
118 | + } | ||
119 | + | ||
120 | + @Override | ||
121 | + public void setSearchText(String searchText) { | ||
122 | + this.searchText = searchText; | ||
123 | + } | ||
124 | + | ||
125 | + @Override | ||
126 | + public EntityView toData() { | ||
127 | + EntityView entityView = new EntityView(new EntityViewId(getId())); | ||
128 | + entityView.setCreatedTime(UUIDs.unixTimestamp(getId())); | ||
129 | + | ||
130 | + if (entityId != null) { | ||
131 | + entityView.setEntityId(EntityIdFactory.getByTypeAndId(entityType.name(), toUUID(entityId).toString())); | ||
132 | + } | ||
133 | + if (tenantId != null) { | ||
134 | + entityView.setTenantId(new TenantId(toUUID(tenantId))); | ||
135 | + } | ||
136 | + if (customerId != null) { | ||
137 | + entityView.setCustomerId(new CustomerId(toUUID(customerId))); | ||
138 | + } | ||
139 | + entityView.setName(name); | ||
140 | + try { | ||
141 | + entityView.setKeys(mapper.readValue(keys, TelemetryEntityView.class)); | ||
142 | + } catch (IOException e) { | ||
143 | + e.printStackTrace(); | ||
144 | + } | ||
145 | + entityView.setTsBegin(Long.parseLong(tsBegin)); | ||
146 | + entityView.setTsEnd(Long.parseLong(tsEnd)); | ||
147 | + entityView.setAdditionalInfo(additionalInfo); | ||
148 | + return entityView; | ||
149 | + } | ||
150 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.dao.sql.entityview; | ||
17 | + | ||
18 | +import org.springframework.data.domain.Pageable; | ||
19 | +import org.springframework.data.jpa.repository.Query; | ||
20 | +import org.springframework.data.repository.CrudRepository; | ||
21 | +import org.springframework.data.repository.query.Param; | ||
22 | +import org.thingsboard.server.common.data.id.EntityId; | ||
23 | +import org.thingsboard.server.dao.model.sql.EntityViewEntity; | ||
24 | +import org.thingsboard.server.dao.util.SqlDao; | ||
25 | + | ||
26 | +import java.util.List; | ||
27 | + | ||
28 | +/** | ||
29 | + * Created by Victor Basanets on 8/31/2017. | ||
30 | + */ | ||
31 | +@SqlDao | ||
32 | +public interface EntityViewRepository extends CrudRepository<EntityViewEntity, String> { | ||
33 | + | ||
34 | + @Query("SELECT e FROM EntityViewEntity e WHERE e.tenantId = :tenantId " + | ||
35 | + "AND LOWER(e.searchText) LIKE LOWER(CONCAT(:textSearch, '%')) " + | ||
36 | + "AND e.id > :idOffset ORDER BY e.id") | ||
37 | + List<EntityViewEntity> findByTenantId(@Param("tenantId") String tenantId, | ||
38 | + @Param("textSearch") String textSearch, | ||
39 | + @Param("idOffset") String idOffset, | ||
40 | + Pageable pageable); | ||
41 | + | ||
42 | + @Query("SELECT e FROM EntityViewEntity e WHERE e.tenantId = :tenantId " + | ||
43 | + "AND e.entityId = :entityId " + | ||
44 | + "AND LOWER(e.searchText) LIKE LOWER(CONCAT(:textSearch, '%')) " + | ||
45 | + "AND e.id > :idOffset ORDER BY e.id") | ||
46 | + List<EntityViewEntity> findByTenantIdAndEntityId(@Param("tenantId") String tenantId, | ||
47 | + @Param("entityId") String entityId, | ||
48 | + @Param("textSearch") String textSearch, | ||
49 | + @Param("idOffset") String idOffset, | ||
50 | + Pageable pageable); | ||
51 | + | ||
52 | + @Query("SELECT e FROM EntityViewEntity e WHERE e.tenantId = :tenantId " + | ||
53 | + "AND e.customerId = :customerId " + | ||
54 | + "AND LOWER(e.searchText) LIKE LOWER(CONCAT(:searchText, '%')) " + | ||
55 | + "AND e.id > :idOffset ORDER BY e.id") | ||
56 | + List<EntityViewEntity> findByTenantIdAndCustomerId(@Param("tenantId") String tenantId, | ||
57 | + @Param("customerId") String customerId, | ||
58 | + @Param("searchText") String searchText, | ||
59 | + @Param("idOffset") String idOffset, | ||
60 | + Pageable pageable); | ||
61 | + | ||
62 | + @Query("SELECT e FROM EntityViewEntity e WHERE e.tenantId = :tenantId " + | ||
63 | + "AND e.customerId = :customerId " + | ||
64 | + "AND e.entityId = :entityId " + | ||
65 | + "AND LOWER(e.searchText) LIKE LOWER(CONCAT(:textSearch, '%')) " + | ||
66 | + "AND e.id > :idOffset ORDER BY e.id") | ||
67 | + List<EntityViewEntity> findByTenantIdAndCustomerIdAndEntityId(@Param("tenantId") String tenantId, | ||
68 | + @Param("customerId") String customerId, | ||
69 | + @Param("entityId") String entityId, | ||
70 | + @Param("textSearch") String textSearch, | ||
71 | + @Param("idOffset") String idOffset, | ||
72 | + Pageable pageable); | ||
73 | + | ||
74 | + EntityViewEntity findByTenantIdAndName(String tenantId, String name); | ||
75 | + | ||
76 | + List<EntityViewEntity> findAllByTenantIdAndCustomerIdAndIdIn(String tenantId, | ||
77 | + String customerId, | ||
78 | + List<String> entityViewsIds); | ||
79 | + | ||
80 | + List<EntityViewEntity> findAllByTenantIdAndIdIn(String tenantId, List<String> entityViewsIds); | ||
81 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2018 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.dao.sql.entityview; | ||
17 | + | ||
18 | +import org.springframework.beans.factory.annotation.Autowired; | ||
19 | +import org.springframework.data.domain.PageRequest; | ||
20 | +import org.springframework.data.repository.CrudRepository; | ||
21 | +import org.springframework.stereotype.Component; | ||
22 | +import org.thingsboard.server.common.data.EntityView; | ||
23 | +import org.thingsboard.server.common.data.id.EntityId; | ||
24 | +import org.thingsboard.server.common.data.page.TextPageLink; | ||
25 | +import org.thingsboard.server.dao.DaoUtil; | ||
26 | +import org.thingsboard.server.dao.entityview.EntityViewDao; | ||
27 | +import org.thingsboard.server.dao.model.sql.EntityViewEntity; | ||
28 | +import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; | ||
29 | +import org.thingsboard.server.dao.util.SqlDao; | ||
30 | + | ||
31 | +import java.util.List; | ||
32 | +import java.util.Objects; | ||
33 | +import java.util.Optional; | ||
34 | +import java.util.UUID; | ||
35 | + | ||
36 | +import static org.thingsboard.server.common.data.UUIDConverter.fromTimeUUID; | ||
37 | +import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID_STR; | ||
38 | + | ||
39 | +/** | ||
40 | + * Created by Victor Basanets on 8/31/2017. | ||
41 | + */ | ||
42 | +@Component | ||
43 | +@SqlDao | ||
44 | +public class JpaEntityViewDao extends JpaAbstractSearchTextDao<EntityViewEntity, EntityView> | ||
45 | + implements EntityViewDao { | ||
46 | + | ||
47 | + @Autowired | ||
48 | + EntityViewRepository entityViewRepository; | ||
49 | + | ||
50 | + @Override | ||
51 | + protected Class<EntityViewEntity> getEntityClass() { | ||
52 | + return EntityViewEntity.class; | ||
53 | + } | ||
54 | + | ||
55 | + @Override | ||
56 | + protected CrudRepository<EntityViewEntity, String> getCrudRepository() { | ||
57 | + return entityViewRepository; | ||
58 | + } | ||
59 | + | ||
60 | + @Override | ||
61 | + public List<EntityView> findEntityViewByTenantId(UUID tenantId, TextPageLink pageLink) { | ||
62 | + return DaoUtil.convertDataList( | ||
63 | + entityViewRepository.findByTenantId( | ||
64 | + fromTimeUUID(tenantId), | ||
65 | + Objects.toString(pageLink.getTextSearch(), ""), | ||
66 | + pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()), | ||
67 | + new PageRequest(0, pageLink.getLimit()))); | ||
68 | + } | ||
69 | + | ||
70 | + @Override | ||
71 | + public Optional<EntityView> findEntityViewByTenantIdAndName(UUID tenantId, String name) { | ||
72 | + return Optional.ofNullable( | ||
73 | + DaoUtil.getData(entityViewRepository.findByTenantIdAndName(fromTimeUUID(tenantId), name))); | ||
74 | + } | ||
75 | + | ||
76 | + @Override | ||
77 | + public List<EntityView> findEntityViewByTenantIdAndEntityId(UUID tenantId, | ||
78 | + UUID entityId, | ||
79 | + TextPageLink pageLink) { | ||
80 | + return DaoUtil.convertDataList( | ||
81 | + entityViewRepository.findByTenantIdAndEntityId( | ||
82 | + fromTimeUUID(tenantId), | ||
83 | + fromTimeUUID(entityId), | ||
84 | + Objects.toString(pageLink.getTextSearch(), ""), | ||
85 | + pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()), | ||
86 | + new PageRequest(0, pageLink.getLimit()))); | ||
87 | + } | ||
88 | + | ||
89 | + @Override | ||
90 | + public List<EntityView> findEntityViewsByTenantIdAndCustomerId(UUID tenantId, | ||
91 | + UUID customerId, | ||
92 | + TextPageLink pageLink) { | ||
93 | + return DaoUtil.convertDataList( | ||
94 | + entityViewRepository.findByTenantIdAndCustomerId( | ||
95 | + fromTimeUUID(tenantId), | ||
96 | + fromTimeUUID(customerId), | ||
97 | + Objects.toString(pageLink, ""), | ||
98 | + pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()), | ||
99 | + new PageRequest(0, pageLink.getLimit()) | ||
100 | + )); | ||
101 | + } | ||
102 | + | ||
103 | + @Override | ||
104 | + public List<EntityView> findEntityViewsByTenantIdAndCustomerIdAndEntityId(UUID tenantId, | ||
105 | + UUID customerId, | ||
106 | + UUID entityId, | ||
107 | + TextPageLink pageLink) { | ||
108 | + return DaoUtil.convertDataList( | ||
109 | + entityViewRepository.findByTenantIdAndCustomerIdAndEntityId( | ||
110 | + fromTimeUUID(tenantId), | ||
111 | + fromTimeUUID(customerId), | ||
112 | + fromTimeUUID(entityId), | ||
113 | + Objects.toString(pageLink, ""), | ||
114 | + pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()), | ||
115 | + new PageRequest(0, pageLink.getLimit()) | ||
116 | + )); | ||
117 | + } | ||
118 | +} |
@@ -638,3 +638,45 @@ CREATE TABLE IF NOT EXISTS thingsboard.rule_node ( | @@ -638,3 +638,45 @@ CREATE TABLE IF NOT EXISTS thingsboard.rule_node ( | ||
638 | additional_info text, | 638 | additional_info text, |
639 | PRIMARY KEY (id) | 639 | PRIMARY KEY (id) |
640 | ); | 640 | ); |
641 | + | ||
642 | +CREATE TABLE IF NOT EXISTS thingsboard.entity_views ( | ||
643 | + id timeuuid, | ||
644 | + entity_id timeuuid, | ||
645 | + tenant_id timeuuid, | ||
646 | + customer_id timeuuid, | ||
647 | + name text, | ||
648 | + keys text, | ||
649 | + ts_begin bigint, | ||
650 | + ts_end bigint, | ||
651 | + search_text text, | ||
652 | + additional_info text, | ||
653 | + PRIMARY KEY (id, entity_id, tenant_id, customer_id) | ||
654 | +); | ||
655 | + | ||
656 | +CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_name AS | ||
657 | + SELECT * | ||
658 | + from thingsboard.entity_views | ||
659 | + WHERE entity_id IS NOT NULL AND tenant_id IS NOT NULL AND customer_id IS NOT NULL AND keys IS NOT NULL AND ts_begin IS NOT NULL AND ts_end IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL | ||
660 | + PRIMARY KEY (tenant_id, name, id, entity_id, customer_id) | ||
661 | + WITH CLUSTERING ORDER BY (name ASC, id DESC, entity_id DESC, customer_id DESC); | ||
662 | + | ||
663 | +CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_entity AS | ||
664 | + SELECT * | ||
665 | + from thingsboard.entity_views | ||
666 | + WHERE entity_id IS NOT NULL AND tenant_id IS NOT NULL AND customer_id IS NOT NULL AND keys IS NOT NULL AND ts_begin IS NOT NULL AND ts_end IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL | ||
667 | + PRIMARY KEY (tenant_id, entity_id, id, customer_id, name) | ||
668 | + WITH CLUSTERING ORDER BY (entity_id ASC, customer_id ASC, id DESC, name DESC); | ||
669 | + | ||
670 | +CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer AS | ||
671 | + SELECT * | ||
672 | + from thingsboard.entity_views | ||
673 | + WHERE entity_id IS NOT NULL AND tenant_id IS NOT NULL AND customer_id IS NOT NULL AND keys IS NOT NULL AND ts_begin IS NOT NULL AND ts_end IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL | ||
674 | + PRIMARY KEY (tenant_id, customer_id, id, entity_id, name) | ||
675 | + WITH CLUSTERING ORDER BY (customer_id ASC, id DESC, entity_id DESC, name DESC); | ||
676 | + | ||
677 | +CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer_and_entity AS | ||
678 | + SELECT * | ||
679 | + from thingsboard.entity_views | ||
680 | + WHERE entity_id IS NOT NULL AND tenant_id IS NOT NULL AND customer_id IS NOT NULL AND keys IS NOT NULL AND ts_begin IS NOT NULL AND ts_end IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL | ||
681 | + PRIMARY KEY (tenant_id, customer_id, entity_id, id, name) | ||
682 | + WITH CLUSTERING ORDER BY (customer_id ASC, entity_id DESC, id DESC, name DESC); |
@@ -251,3 +251,17 @@ CREATE TABLE IF NOT EXISTS rule_node ( | @@ -251,3 +251,17 @@ CREATE TABLE IF NOT EXISTS rule_node ( | ||
251 | debug_mode boolean, | 251 | debug_mode boolean, |
252 | search_text varchar(255) | 252 | search_text varchar(255) |
253 | ); | 253 | ); |
254 | + | ||
255 | +CREATE TABLE IF NOT EXISTS entity_views ( | ||
256 | + id varchar(31) NOT NULL CONSTRAINT entity_view_pkey PRIMARY KEY, | ||
257 | + entity_id varchar(31), | ||
258 | + entity_type varchar(255), | ||
259 | + tenant_id varchar(31), | ||
260 | + customer_id varchar(31), | ||
261 | + name varchar(255), | ||
262 | + keys varchar(255), | ||
263 | + ts_begin varchar(255), | ||
264 | + ts_end varchar(255), | ||
265 | + search_text varchar(255), | ||
266 | + additional_info varchar | ||
267 | +); |
@@ -18,4 +18,5 @@ DROP TABLE IF EXISTS user_credentials; | @@ -18,4 +18,5 @@ DROP TABLE IF EXISTS user_credentials; | ||
18 | DROP TABLE IF EXISTS widget_type; | 18 | DROP TABLE IF EXISTS widget_type; |
19 | DROP TABLE IF EXISTS widgets_bundle; | 19 | DROP TABLE IF EXISTS widgets_bundle; |
20 | DROP TABLE IF EXISTS rule_node; | 20 | DROP TABLE IF EXISTS rule_node; |
21 | -DROP TABLE IF EXISTS rule_chain; | ||
21 | +DROP TABLE IF EXISTS rule_chain; | ||
22 | +DROP TABLE IF EXISTS entity_views; |