Commit a2a89033b41eae660c5479fa739a22eb00fcf07d

Authored by VoBa
Committed by GitHub
2 parents 3b0d7204 1e6bd551

Merge pull request #1080 from ViktorBasanets/master

Was done second fixed
... ... @@ -39,55 +39,54 @@ CREATE TABLE IF NOT EXISTS thingsboard.entity_views (
39 39 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_name AS
40 40 SELECT *
41 41 from thingsboard.entity_views
42   - WHERE entity_id IS NOT NULL
43   - AND tenant_id IS NOT NULL
44   - AND customer_id IS NOT NULL
45   - AND keys IS NOT NULL
46   - AND start_ts IS NOT NULL
47   - AND end_ts IS NOT NULL
48   - AND name IS NOT NULL
49   - AND id IS NOT NULL
50   - PRIMARY KEY (tenant_id, name, id, entity_id, customer_id)
51   - WITH CLUSTERING ORDER BY (name ASC, id DESC, entity_id DESC, customer_id DESC);
  42 + WHERE tenant_id IS NOT NULL
  43 + AND entity_id IS NOT NULL
  44 + AND customer_id IS NOT NULL
  45 + AND name IS NOT NULL
  46 + AND id IS NOT NULL
  47 + PRIMARY KEY (tenant_id, name, id, customer_id, entity_id)
  48 + WITH CLUSTERING ORDER BY (name ASC, id DESC, customer_id DESC);
52 49
53   -CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_entity AS
  50 +CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_view_by_tenant_and_search_text AS
54 51 SELECT *
55 52 from thingsboard.entity_views
56   - WHERE entity_id IS NOT NULL
57   - AND tenant_id IS NOT NULL
58   - AND customer_id IS NOT NULL
59   - AND keys IS NOT NULL
60   - AND start_ts IS NOT NULL
61   - AND end_ts IS NOT NULL
62   - AND name IS NOT NULL
63   - AND id IS NOT NULL
64   - PRIMARY KEY (tenant_id, entity_id, id, customer_id, name)
65   - WITH CLUSTERING ORDER BY (entity_id ASC, customer_id ASC, id DESC, name DESC);
  53 + WHERE tenant_id IS NOT NULL
  54 + AND entity_id IS NOT NULL
  55 + AND customer_id IS NOT NULL
  56 + AND search_text IS NOT NULL
  57 + AND id IS NOT NULL
  58 + PRIMARY KEY (tenant_id, search_text, id, customer_id, entity_id)
  59 + WITH CLUSTERING ORDER BY (search_text ASC, id DESC, customer_id DESC);
  60 +
  61 +CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_view_by_tenant_and_entity AS
  62 + SELECT *
  63 + from thingsboard.entity_views
  64 + WHERE tenant_id IS NOT NULL
  65 + AND customer_id IS NOT NULL
  66 + AND entity_id IS NOT NULL
  67 + AND search_text IS NOT NULL
  68 + AND id IS NOT NULL
  69 + PRIMARY KEY (tenant_id, entity_id, search_text, id, customer_id)
  70 + WITH CLUSTERING ORDER BY (entity_id ASC, search_text ASC, id DESC, customer_id DESC);
66 71
67 72 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer AS
68 73 SELECT *
69 74 from thingsboard.entity_views
70   - WHERE entity_id IS NOT NULL
71   - AND tenant_id IS NOT NULL
72   - AND customer_id IS NOT NULL
73   - AND keys IS NOT NULL
74   - AND start_ts IS NOT NULL
75   - AND end_ts IS NOT NULL
76   - AND name IS NOT NULL
77   - AND id IS NOT NULL
78   - PRIMARY KEY (tenant_id, customer_id, id, entity_id, name)
79   - WITH CLUSTERING ORDER BY (customer_id ASC, id DESC, entity_id DESC, name DESC);
  75 + WHERE tenant_id IS NOT NULL
  76 + AND customer_id IS NOT NULL
  77 + AND entity_id IS NOT NULL
  78 + AND search_text IS NOT NULL
  79 + AND id IS NOT NULL
  80 + PRIMARY KEY (tenant_id, customer_id, search_text, id, entity_id)
  81 + WITH CLUSTERING ORDER BY (customer_id DESC, search_text ASC, id DESC);
80 82
81 83 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer_and_entity AS
82 84 SELECT *
83 85 from thingsboard.entity_views
84   - WHERE entity_id IS NOT NULL
85   - AND tenant_id IS NOT NULL
86   - AND customer_id IS NOT NULL
87   - AND keys IS NOT NULL
88   - AND start_ts IS NOT NULL
89   - AND end_ts IS NOT NULL
90   - AND name IS NOT NULL
91   - AND id IS NOT NULL
92   - PRIMARY KEY (tenant_id, customer_id, entity_id, id, name)
93   - WITH CLUSTERING ORDER BY (customer_id ASC, entity_id DESC, id DESC, name DESC);
  86 + WHERE tenant_id IS NOT NULL
  87 + AND customer_id IS NOT NULL
  88 + AND entity_id IS NOT NULL
  89 + AND search_text IS NOT NULL
  90 + AND id IS NOT NULL
  91 + PRIMARY KEY (tenant_id, customer_id, entity_id, search_text, id)
  92 + WITH CLUSTERING ORDER BY (customer_id DESC, entity_id ASC, search_text ASC, id DESC);
... ...
... ... @@ -15,32 +15,28 @@
15 15 */
16 16 package org.thingsboard.server.controller;
17 17
18   -import com.google.common.util.concurrent.ListenableFuture;
19 18 import org.springframework.http.HttpStatus;
20 19 import org.springframework.security.access.prepost.PreAuthorize;
21 20 import org.springframework.web.bind.annotation.*;
22 21 import org.thingsboard.server.common.data.Customer;
23   -import org.thingsboard.server.common.data.Device;
24   -import org.thingsboard.server.common.data.EntitySubtype;
25 22 import org.thingsboard.server.common.data.EntityType;
26 23 import org.thingsboard.server.common.data.EntityView;
27 24 import org.thingsboard.server.common.data.audit.ActionType;
28 25 import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
29 26 import org.thingsboard.server.common.data.exception.ThingsboardException;
30 27 import org.thingsboard.server.common.data.id.CustomerId;
31   -import org.thingsboard.server.common.data.id.DeviceId;
32 28 import org.thingsboard.server.common.data.id.EntityViewId;
33 29 import org.thingsboard.server.common.data.id.TenantId;
34 30 import org.thingsboard.server.common.data.page.TextPageData;
35 31 import org.thingsboard.server.common.data.page.TextPageLink;
36 32 import org.thingsboard.server.dao.exception.IncorrectParameterException;
37 33 import org.thingsboard.server.dao.model.ModelConstants;
38   -import org.thingsboard.server.service.security.model.SecurityUser;
39 34
40   -import java.util.ArrayList;
41 35 import java.util.List;
42 36 import java.util.stream.Collectors;
43 37
  38 +import static org.thingsboard.server.controller.CustomerController.CUSTOMER_ID;
  39 +
44 40 /**
45 41 * Created by Victor Basanets on 8/28/2017.
46 42 */
... ... @@ -109,9 +105,9 @@ public class EntityViewController extends BaseController {
109 105 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
110 106 @RequestMapping(value = "/customer/{customerId}/entityView/{entityViewId}", method = RequestMethod.POST)
111 107 @ResponseBody
112   - public EntityView assignEntityViewToCustomer(@PathVariable("customerId") String strCustomerId,
  108 + public EntityView assignEntityViewToCustomer(@PathVariable(CUSTOMER_ID) String strCustomerId,
113 109 @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException {
114   - checkParameter("customerId", strCustomerId);
  110 + checkParameter(CUSTOMER_ID, strCustomerId);
115 111 checkParameter(ENTITY_VIEW_ID, strEntityViewId);
116 112 try {
117 113 CustomerId customerId = new CustomerId(toUUID(strCustomerId));
... ...
... ... @@ -298,6 +298,9 @@ caffeine:
298 298 assets:
299 299 timeToLiveInMinutes: 1440
300 300 maxSize: 100000
  301 + entityViews:
  302 + timeToLiveInMinutes: 1440
  303 + maxSize: 100000
301 304
302 305 redis:
303 306 # standalone or cluster
... ...
... ... @@ -15,25 +15,31 @@
15 15 */
16 16 package org.thingsboard.server.controller;
17 17
  18 +import com.datastax.driver.core.utils.UUIDs;
  19 +import com.fasterxml.jackson.core.type.TypeReference;
  20 +import org.apache.commons.lang3.RandomStringUtils;
18 21 import org.junit.After;
19 22 import org.junit.Assert;
20 23 import org.junit.Before;
21 24 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;
  25 +import org.thingsboard.server.common.data.*;
  26 +import org.thingsboard.server.common.data.id.CustomerId;
26 27 import org.thingsboard.server.common.data.objects.AttributesEntityView;
27 28 import org.thingsboard.server.common.data.objects.TelemetryEntityView;
  29 +import org.thingsboard.server.common.data.page.TextPageData;
  30 +import org.thingsboard.server.common.data.page.TextPageLink;
28 31 import org.thingsboard.server.common.data.security.Authority;
  32 +import org.thingsboard.server.dao.model.ModelConstants;
29 33
30   -import java.util.Arrays;
  34 +import java.util.*;
31 35
  36 +import static org.hamcrest.Matchers.containsString;
32 37 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
33 38 import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
34 39
35 40 public abstract class BaseEntityViewControllerTest extends AbstractControllerTest {
36 41
  42 + private IdComparator<EntityView> idComparator;
37 43 private Tenant savedTenant;
38 44 private User tenantAdmin;
39 45 private Device testDevice;
... ... @@ -43,10 +49,9 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
43 49 public void beforeTest() throws Exception {
44 50 loginSysAdmin();
45 51
46   - Tenant tenant = new Tenant();
47   - tenant.setTitle("My tenant");
48   - savedTenant = doPost("/api/tenant", tenant, Tenant.class);
  52 + idComparator = new IdComparator<>();
49 53
  54 + savedTenant = doPost("/api/tenant", getNewTenant("My tenant"), Tenant.class);
50 55 Assert.assertNotNull(savedTenant);
51 56
52 57 tenantAdmin = new User();
... ... @@ -62,13 +67,14 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
62 67 device.setName("Test device");
63 68 device.setType("default");
64 69 testDevice = doPost("/api/device", device, Device.class);
65   -
66 70 obj = new TelemetryEntityView(
67 71 Arrays.asList("109L", "209L"),
68 72 new AttributesEntityView(
69   - Arrays.asList("caKey1", "caKey2", "caKey3"),
70   - Arrays.asList("saKey1", "saKey2", "saKey3", "saKey4"),
71   - Arrays.asList("shKey1", "shKey2", "shKey3", "shKey4", "shKey5")));
  73 + Arrays.asList("caKey1", "caKey2"),
  74 + Arrays.asList("saKey1", "saKey2", "saKey3"),
  75 + Arrays.asList("shKey1", "shKey2", "shKey3", "shKey4")
  76 + )
  77 + );
72 78 }
73 79
74 80 @After
... ... @@ -81,24 +87,15 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
81 87
82 88 @Test
83 89 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 + EntityView savedView = doPost("/api/entityView", getNewEntityView("Test entity view"), EntityView.class);
  91 + EntityView foundView = doGet("/api/entityView/" + savedView.getId().getId().toString(), EntityView.class);
90 92 Assert.assertNotNull(foundView);
91 93 Assert.assertEquals(savedView, foundView);
92 94 }
93 95
94 96 @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);
  97 + public void testSaveEntityView() throws Exception {
  98 + EntityView savedView = doPost("/api/entityView", getNewEntityView("Test entity view"), EntityView.class);
102 99
103 100 Assert.assertNotNull(savedView);
104 101 Assert.assertNotNull(savedView.getId());
... ... @@ -109,26 +106,253 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
109 106 Assert.assertEquals(savedView.getName(), savedView.getName());
110 107
111 108 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);
  109 + doPost("/api/entityView", savedView, EntityView.class);
  110 + EntityView foundEntityView = doGet("/api/entityView/" + savedView.getId().getId().toString(), EntityView.class);
116 111
117 112 Assert.assertEquals(foundEntityView.getName(), savedView.getName());
118 113 }
119 114
120 115 @Test
121 116 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);
  117 + EntityView view = getNewEntityView("Test entity view");
  118 + Customer customer = doPost("/api/customer", getNewCustomer("My customer"), Customer.class);
  119 + view.setCustomerId(customer.getId());
  120 + EntityView savedView = doPost("/api/entityView", view, EntityView.class);
127 121
128   - doDelete("/api/entity-view/" + savedView.getId().getId().toString())
  122 + doDelete("/api/entityView/" + savedView.getId().getId().toString())
129 123 .andExpect(status().isOk());
130 124
131   - doGet("/api/entity-view/" + savedView.getId().getId().toString())
  125 + doGet("/api/entityView/" + savedView.getId().getId().toString())
  126 + .andExpect(status().isNotFound());
  127 + }
  128 +
  129 + @Test
  130 + public void testSaveEntityViewWithEmptyName() throws Exception {
  131 + doPost("/api/entityView", new EntityView())
  132 + .andExpect(status().isBadRequest())
  133 + .andExpect(statusReason(containsString("Entity view name should be specified!")));
  134 + }
  135 +
  136 + @Test
  137 + public void testAssignAndUnAssignedEntityViewToCustomer() throws Exception {
  138 + EntityView view = getNewEntityView("Test entity view");
  139 + Customer savedCustomer = doPost("/api/customer", getNewCustomer("My customer"), Customer.class);
  140 + view.setCustomerId(savedCustomer.getId());
  141 + EntityView savedView = doPost("/api/entityView", view, EntityView.class);
  142 +
  143 + EntityView assignedView = doPost(
  144 + "/api/customer/" + savedCustomer.getId().getId().toString() + "/entityView/" + savedView.getId().getId().toString(),
  145 + EntityView.class);
  146 + Assert.assertEquals(savedCustomer.getId(), assignedView.getCustomerId());
  147 +
  148 + EntityView foundView = doGet("/api/entityView/" + savedView.getId().getId().toString(), EntityView.class);
  149 + Assert.assertEquals(savedCustomer.getId(), foundView.getCustomerId());
  150 +
  151 + EntityView unAssignedView = doDelete("/api/customer/entityView/" + savedView.getId().getId().toString(), EntityView.class);
  152 + Assert.assertEquals(ModelConstants.NULL_UUID, unAssignedView.getCustomerId().getId());
  153 +
  154 + foundView = doGet("/api/entityView/" + savedView.getId().getId().toString(), EntityView.class);
  155 + Assert.assertEquals(ModelConstants.NULL_UUID, foundView.getCustomerId().getId());
  156 + }
  157 +
  158 + @Test
  159 + public void testAssignEntityViewToNonExistentCustomer() throws Exception {
  160 + EntityView savedView = doPost("/api/entityView", getNewEntityView("Test entity view"), EntityView.class);
  161 + doPost("/api/customer/" + UUIDs.timeBased().toString() + "/device/" + savedView.getId().getId().toString())
132 162 .andExpect(status().isNotFound());
133 163 }
  164 +
  165 + @Test
  166 + public void testAssignEntityViewToCustomerFromDifferentTenant() throws Exception {
  167 + loginSysAdmin();
  168 +
  169 + Tenant tenant2 = getNewTenant("Different tenant");
  170 + Tenant savedTenant2 = doPost("/api/tenant", tenant2, Tenant.class);
  171 + Assert.assertNotNull(savedTenant2);
  172 +
  173 + User tenantAdmin2 = new User();
  174 + tenantAdmin2.setAuthority(Authority.TENANT_ADMIN);
  175 + tenantAdmin2.setTenantId(savedTenant2.getId());
  176 + tenantAdmin2.setEmail("tenant3@thingsboard.org");
  177 + tenantAdmin2.setFirstName("Joe");
  178 + tenantAdmin2.setLastName("Downs");
  179 + createUserAndLogin(tenantAdmin2, "testPassword1");
  180 +
  181 + Customer customer = getNewCustomer("Different customer");
  182 + Customer savedCustomer = doPost("/api/customer", customer, Customer.class);
  183 +
  184 + login(tenantAdmin.getEmail(), "testPassword1");
  185 +
  186 + EntityView view = getNewEntityView("Test entity view");
  187 + EntityView savedView = doPost("/api/entityView", view, EntityView.class);
  188 +
  189 + doPost("/api/customer/" + savedCustomer.getId().getId().toString() + "/entityView/" + savedView.getId().getId().toString())
  190 + .andExpect(status().isForbidden());
  191 +
  192 + loginSysAdmin();
  193 +
  194 + doDelete("/api/tenant/" + savedTenant2.getId().getId().toString())
  195 + .andExpect(status().isOk());
  196 + }
  197 +
  198 + @Test
  199 + public void testGetCustomerEntityViews() throws Exception {
  200 + CustomerId customerId = doPost("/api/customer", getNewCustomer("Test customer"), Customer.class).getId();
  201 + String urlTemplate = "/api/customer/" + customerId.getId().toString() + "/entityViews?";
  202 +
  203 + List<EntityView> views = new ArrayList<>();
  204 + for (int i = 0; i < 128; i++) {
  205 + views.add(doPost("/api/customer/" + customerId.getId().toString() + "/entityView/"
  206 + + getNewEntityView("Test entity view " + i).getId().getId().toString(), EntityView.class));
  207 + }
  208 +
  209 + List<EntityView> loadedViews = loadListOf(new TextPageLink(23), urlTemplate);
  210 +
  211 + Collections.sort(views, idComparator);
  212 + Collections.sort(loadedViews, idComparator);
  213 +
  214 + Assert.assertEquals(views, loadedViews);
  215 + }
  216 +
  217 + @Test
  218 + public void testGetCustomerEntityViewsByName() throws Exception {
  219 + CustomerId customerId = doPost("/api/customer", getNewCustomer("Test customer"), Customer.class).getId();
  220 + String urlTemplate = "/api/customer/" + customerId.getId().toString() + "/entityViews?";
  221 +
  222 + String name1 = "Entity view name1";
  223 + List<EntityView> namesOfView1 = fillListOf(125, name1, "/api/customer/" + customerId.getId().toString()
  224 + + "/entityView/");
  225 + List<EntityView> loadedNamesOfView1 = loadListOf(new TextPageLink(15, name1), urlTemplate);
  226 + Collections.sort(namesOfView1, idComparator);
  227 + Collections.sort(loadedNamesOfView1, idComparator);
  228 + Assert.assertEquals(namesOfView1, loadedNamesOfView1);
  229 +
  230 + String name2 = "Entity view name2";
  231 + List<EntityView> NamesOfView2 = fillListOf(143, name2, "/api/customer/" + customerId.getId().toString()
  232 + + "/entityView/");
  233 + List<EntityView> loadedNamesOfView2 = loadListOf(new TextPageLink(4, name2), urlTemplate);
  234 + Collections.sort(NamesOfView2, idComparator);
  235 + Collections.sort(loadedNamesOfView2, idComparator);
  236 + Assert.assertEquals(NamesOfView2, loadedNamesOfView2);
  237 +
  238 + for (EntityView view : loadedNamesOfView1) {
  239 + doDelete("/api/customer/entityView/" + view.getId().getId().toString()).andExpect(status().isOk());
  240 + }
  241 + TextPageData<EntityView> pageData = doGetTypedWithPageLink(urlTemplate,
  242 + new TypeReference<TextPageData<EntityView>>(){}, new TextPageLink(4, name1));
  243 + Assert.assertFalse(pageData.hasNext());
  244 + Assert.assertEquals(0, pageData.getData().size());
  245 +
  246 + for (EntityView view : loadedNamesOfView2) {
  247 + doDelete("/api/customer/entityView/" + view.getId().getId().toString()).andExpect(status().isOk());
  248 + }
  249 + pageData = doGetTypedWithPageLink(urlTemplate, new TypeReference<TextPageData<EntityView>>(){},
  250 + new TextPageLink(4, name2));
  251 + Assert.assertFalse(pageData.hasNext());
  252 + Assert.assertEquals(0, pageData.getData().size());
  253 + }
  254 +
  255 + @Test
  256 + public void testGetTenantEntityViews() throws Exception {
  257 +
  258 + List<EntityView> views = new ArrayList<>();
  259 + for (int i = 0; i < 178; i++) {
  260 + views.add(doPost("/api/entityView/", getNewEntityView("Test entity view" + i), EntityView.class));
  261 + }
  262 + List<EntityView> loadedViews = loadListOf(new TextPageLink(23), "/api/tenant/entityViews?");
  263 +
  264 + Collections.sort(views, idComparator);
  265 + Collections.sort(loadedViews, idComparator);
  266 +
  267 + Assert.assertEquals(views, loadedViews);
  268 + }
  269 +
  270 + @Test
  271 + public void testGetTenantEntityViewsByName() throws Exception {
  272 + String name1 = "Entity view name1";
  273 + List<EntityView> namesOfView1 = fillListOf(143, name1);
  274 + List<EntityView> loadedNamesOfView1 = loadListOf(new TextPageLink(15, name1), "/api/tenant/entityViews?");
  275 + Collections.sort(namesOfView1, idComparator);
  276 + Collections.sort(loadedNamesOfView1, idComparator);
  277 + Assert.assertEquals(namesOfView1, loadedNamesOfView1);
  278 +
  279 + String name2 = "Entity view name2";
  280 + List<EntityView> NamesOfView2 = fillListOf(75, name2);
  281 + List<EntityView> loadedNamesOfView2 = loadListOf(new TextPageLink(4, name2), "/api/tenant/entityViews?");
  282 + Collections.sort(NamesOfView2, idComparator);
  283 + Collections.sort(loadedNamesOfView2, idComparator);
  284 + Assert.assertEquals(NamesOfView2, loadedNamesOfView2);
  285 +
  286 + for (EntityView view : loadedNamesOfView1) {
  287 + doDelete("/api/entityView/" + view.getId().getId().toString()).andExpect(status().isOk());
  288 + }
  289 + TextPageData<EntityView> pageData = doGetTypedWithPageLink("/api/tenant/entityViews?",
  290 + new TypeReference<TextPageData<EntityView>>(){}, new TextPageLink(4, name1));
  291 + Assert.assertFalse(pageData.hasNext());
  292 + Assert.assertEquals(0, pageData.getData().size());
  293 +
  294 + for (EntityView view : loadedNamesOfView2) {
  295 + doDelete("/api/entityView/" + view.getId().getId().toString()).andExpect(status().isOk());
  296 + }
  297 + pageData = doGetTypedWithPageLink("/api/tenant/entityViews?", new TypeReference<TextPageData<EntityView>>(){},
  298 + new TextPageLink(4, name2));
  299 + Assert.assertFalse(pageData.hasNext());
  300 + Assert.assertEquals(0, pageData.getData().size());
  301 + }
  302 +
  303 + private EntityView getNewEntityView(String name) throws Exception {
  304 + EntityView view = new EntityView();
  305 + view.setEntityId(testDevice.getId());
  306 + view.setTenantId(savedTenant.getId());
  307 + view.setName(name);
  308 + view.setKeys(new TelemetryEntityView(obj));
  309 + return doPost("/api/entityView", view, EntityView.class);
  310 + }
  311 +
  312 + private Customer getNewCustomer(String title) {
  313 + Customer customer = new Customer();
  314 + customer.setTitle(title);
  315 + return customer;
  316 + }
  317 +
  318 + private Tenant getNewTenant(String title) {
  319 + Tenant tenant = new Tenant();
  320 + tenant.setTitle(title);
  321 + return tenant;
  322 + }
  323 +
  324 + private List<EntityView> fillListOf(int limit, String partOfName, String urlTemplate) throws Exception {
  325 + List<EntityView> views = new ArrayList<>();
  326 + for (EntityView view : fillListOf(limit, partOfName)) {
  327 + views.add(doPost(urlTemplate + view.getId().getId().toString(), EntityView.class));
  328 + }
  329 + return views;
  330 + }
  331 +
  332 + private List<EntityView> fillListOf(int limit, String partOfName) throws Exception {
  333 + List<EntityView> viewNames = new ArrayList<>();
  334 + for (int i = 0; i < limit; i++) {
  335 + String fullName = partOfName + ' ' + RandomStringUtils.randomAlphanumeric(15);
  336 + fullName = i % 2 == 0 ? fullName.toLowerCase() : fullName.toUpperCase();
  337 + EntityView view = getNewEntityView(fullName);
  338 + Customer customer = getNewCustomer("Test customer " + String.valueOf(Math.random()));
  339 + view.setCustomerId(doPost("/api/customer", customer, Customer.class).getId());
  340 + viewNames.add(doPost("/api/entityView", view, EntityView.class));
  341 + }
  342 + return viewNames;
  343 + }
  344 +
  345 + private List<EntityView> loadListOf(TextPageLink pageLink, String urlTemplate) throws Exception {
  346 + List<EntityView> loadedItems = new ArrayList<>();
  347 + TextPageData<EntityView> pageData;
  348 + do {
  349 + pageData = doGetTypedWithPageLink(urlTemplate, new TypeReference<TextPageData<EntityView>>(){}, pageLink);
  350 + loadedItems.addAll(pageData.getData());
  351 + if (pageData.hasNext()) {
  352 + pageLink = pageData.getNextPageLink();
  353 + }
  354 + } while (pageData.hasNext());
  355 +
  356 + return loadedItems;
  357 + }
134 358 }
... ...
... ... @@ -67,49 +67,75 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit
67 67
68 68 @Override
69 69 public List<EntityView> findEntityViewByTenantId(UUID tenantId, TextPageLink pageLink) {
70   - log.debug("Try to find entity-views by tenantId [{}] and pageLink [{}]", tenantId, pageLink);
  70 + log.debug("Try to find entity views by tenantId [{}] and pageLink [{}]", tenantId, pageLink);
71 71 List<EntityViewEntity> entityViewEntities =
72 72 findPageWithTextSearch(ENTITY_VIEW_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
73   - Collections.singletonList(eq(ENTITY_VIEW_TENANT_ID_PROPERTY, tenantId)), pageLink);
74   -
75   - log.trace("Found entity-views [{}] by tenantId [{}] and pageLink [{}]", entityViewEntities, tenantId, pageLink);
  73 + Collections.singletonList(eq(TENANT_ID_PROPERTY, tenantId)), pageLink);
  74 + log.trace("Found entity views [{}] by tenantId [{}] and pageLink [{}]",
  75 + entityViewEntities, tenantId, pageLink);
76 76 return DaoUtil.convertDataList(entityViewEntities);
77 77 }
78 78
79 79 @Override
80   - public Optional<EntityView> findEntityViewByTenantIdAndName(UUID tenantId, String entityViewName) {
81   - return Optional.ofNullable(DaoUtil.getData(
82   - findOneByStatement(select().from(ENTITY_VIEW_TENANT_AND_NAME_VIEW_NAME).where()
83   - .and(eq(ENTITY_VIEW_TENANT_ID_PROPERTY, tenantId))
84   - .and(eq(ENTITY_VIEW_NAME_PROPERTY, entityViewName))))
85   - );
  80 + public Optional<EntityView> findEntityViewByTenantIdAndName(UUID tenantId, String name) {
  81 + Select.Where query = select().from(ENTITY_VIEW_BY_TENANT_AND_NAME).where();
  82 + query.and(eq(ENTITY_VIEW_TENANT_ID_PROPERTY, tenantId));
  83 + query.and(eq(ENTITY_VIEW_NAME_PROPERTY, name));
  84 + return Optional.ofNullable(DaoUtil.getData(findOneByStatement(query)));
86 85 }
87 86
88 87 @Override
89 88 public List<EntityView> findEntityViewByTenantIdAndEntityId(UUID tenantId, UUID entityId, TextPageLink pageLink) {
90   - log.debug("Try to find entity-views by tenantId [{}], entityId[{}] and pageLink [{}]", tenantId, entityId, pageLink);
91   - List<EntityViewEntity> entityViewEntities = findPageWithTextSearch(DEVICE_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
92   - Arrays.asList(eq(DEVICE_CUSTOMER_ID_PROPERTY, entityId),
93   - eq(DEVICE_TENANT_ID_PROPERTY, tenantId)),
  89 + log.debug("Try to find entity views by tenantId [{}], entityId [{}] and pageLink [{}]",
  90 + tenantId, entityId, pageLink);
  91 + List<EntityViewEntity> entityViewEntities = findPageWithTextSearch(
  92 + ENTITY_VIEW_BY_TENANT_AND_ENTITY_AND_SEARCH_TEXT,
  93 + Arrays.asList(eq(CUSTOMER_ID_PROPERTY, entityId), eq(TENANT_ID_PROPERTY, tenantId)),
94 94 pageLink);
95   -
96   - log.trace("Found entity-views [{}] by tenantId [{}], entityId [{}] and pageLink [{}]", entityViewEntities, tenantId, entityId, pageLink);
  95 + log.trace("Found entity views [{}] by tenantId [{}], entityId [{}] and pageLink [{}]",
  96 + entityViewEntities, tenantId, entityId, pageLink);
97 97 return DaoUtil.convertDataList(entityViewEntities);
98 98 }
99 99
100 100 @Override
101 101 public List<EntityView> findEntityViewsByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TextPageLink pageLink) {
102   - return null;
  102 + log.debug("Try to find entity views by tenantId [{}], customerId[{}] and pageLink [{}]",
  103 + tenantId, customerId, pageLink);
  104 + List<EntityViewEntity> entityViewEntities = findPageWithTextSearch(
  105 + ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_AND_SEARCH_TEXT,
  106 + Arrays.asList(eq(CUSTOMER_ID_PROPERTY, customerId), eq(TENANT_ID_PROPERTY, tenantId)),
  107 + pageLink);
  108 + log.trace("Found find entity views [{}] by tenantId [{}], customerId [{}] and pageLink [{}]",
  109 + entityViewEntities, tenantId, customerId, pageLink);
  110 + return DaoUtil.convertDataList(entityViewEntities);
103 111 }
104 112
105 113 @Override
106   - public List<EntityView> findEntityViewsByTenantIdAndCustomerIdAndEntityId(UUID tenantId, UUID customerId, UUID entityId, TextPageLink pageLink) {
107   - return null;
  114 + public List<EntityView> findEntityViewsByTenantIdAndCustomerIdAndEntityId(UUID tenantId,
  115 + UUID customerId,
  116 + UUID entityId,
  117 + TextPageLink pageLink) {
  118 +
  119 + log.debug("Try to find entity views by tenantId [{}], customerId [{}], entityId [{}] and pageLink [{}]",
  120 + tenantId, customerId, entityId, pageLink);
  121 + List<EntityViewEntity> entityViewEntities = findPageWithTextSearch(
  122 + ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_AND_ENTITY_AND_SEARCH_TEXT,
  123 + Arrays.asList(
  124 + eq(TENANT_ID_PROPERTY, tenantId),
  125 + eq(CUSTOMER_ID_PROPERTY, customerId),
  126 + eq(ENTITY_ID_COLUMN, entityId)),
  127 + pageLink);
  128 + log.trace("Found devices [{}] by tenantId [{}], customerId [{}], entityId [{}] and pageLink [{}]",
  129 + entityViewEntities, tenantId, customerId, entityId, pageLink);
  130 + return DaoUtil.convertDataList(entityViewEntities);
108 131 }
109 132
110 133 @Override
111 134 public ListenableFuture<List<EntityView>> findEntityViewsByTenantIdAndEntityIdAsync(UUID tenantId, UUID entityId) {
112   - // TODO: implement this
113   - return null;
  135 + log.debug("Try to find entity views by tenantId [{}] and entityId [{}]", tenantId, entityId);
  136 + Select.Where query = select().from(getColumnFamilyName()).where();
  137 + query.and(eq(TENANT_ID_PROPERTY, tenantId));
  138 + query.and(eq(ENTITY_ID_COLUMN, entityId));
  139 + return findListByStatementAsync(query);
114 140 }
115 141 }
... ...
... ... @@ -21,17 +21,18 @@ import com.google.common.util.concurrent.ListenableFuture;
21 21 import lombok.extern.slf4j.Slf4j;
22 22 import org.apache.commons.lang3.StringUtils;
23 23 import org.springframework.beans.factory.annotation.Autowired;
  24 +import org.springframework.cache.Cache;
24 25 import org.springframework.cache.CacheManager;
  26 +import org.springframework.cache.annotation.CacheEvict;
  27 +import org.springframework.cache.annotation.Cacheable;
25 28 import org.springframework.stereotype.Service;
26 29 import org.thingsboard.server.common.data.Customer;
27 30 import org.thingsboard.server.common.data.DataConstants;
28   -import org.thingsboard.server.common.data.Device;
29 31 import org.thingsboard.server.common.data.EntityType;
30 32 import org.thingsboard.server.common.data.EntityView;
31 33 import org.thingsboard.server.common.data.Tenant;
32 34 import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
33 35 import org.thingsboard.server.common.data.id.CustomerId;
34   -import org.thingsboard.server.common.data.id.DeviceId;
35 36 import org.thingsboard.server.common.data.id.EntityId;
36 37 import org.thingsboard.server.common.data.id.EntityViewId;
37 38 import org.thingsboard.server.common.data.id.TenantId;
... ... @@ -50,14 +51,14 @@ import org.thingsboard.server.dao.tenant.TenantDao;
50 51
51 52 import javax.annotation.Nullable;
52 53 import java.util.ArrayList;
  54 +import java.util.Arrays;
53 55 import java.util.Collection;
54 56 import java.util.List;
55 57 import java.util.stream.Collectors;
56 58
57   -import static org.thingsboard.server.dao.DaoUtil.toUUIDs;
  59 +import static org.thingsboard.server.common.data.CacheConstants.ENTITY_VIEW_CACHE;
58 60 import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
59 61 import static org.thingsboard.server.dao.service.Validator.validateId;
60   -import static org.thingsboard.server.dao.service.Validator.validateIds;
61 62 import static org.thingsboard.server.dao.service.Validator.validatePageLink;
62 63 import static org.thingsboard.server.dao.service.Validator.validateString;
63 64
... ... @@ -88,7 +89,6 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
88 89 @Autowired
89 90 private CacheManager cacheManager;
90 91
91   -// @Cacheable(cacheNames = ENTITY_VIEW_CACHE)
92 92 @Override
93 93 public EntityView findEntityViewById(EntityViewId entityViewId) {
94 94 log.trace("Executing findEntityViewById [{}]", entityViewId);
... ... @@ -96,6 +96,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
96 96 return entityViewDao.findById(entityViewId.getId());
97 97 }
98 98
  99 + @Cacheable(cacheNames = ENTITY_VIEW_CACHE, key = "{#tenantId, #name}")
99 100 @Override
100 101 public EntityView findEntityViewByTenantIdAndName(TenantId tenantId, String name) {
101 102 log.trace("Executing findEntityViewByTenantIdAndName [{}][{}]", tenantId, name);
... ... @@ -104,7 +105,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
104 105 .orElse(null);
105 106 }
106 107
107   -// @CachePut(cacheNames = ENTITY_VIEW_CACHE)
  108 + @CacheEvict(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityView.tenantId, #entityView.name}")
108 109 @Override
109 110 public EntityView saveEntityView(EntityView entityView) {
110 111 log.trace("Executing save entity view [{}]", entityView);
... ... @@ -168,14 +169,11 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
168 169 @Override
169 170 public void deleteEntityView(EntityViewId entityViewId) {
170 171 log.trace("Executing deleteEntityView [{}]", entityViewId);
171   -// Cache cache = cacheManager.getCache(ENTITY_VIEW_CACHE);
  172 + Cache cache = cacheManager.getCache(ENTITY_VIEW_CACHE);
172 173 validateId(entityViewId, INCORRECT_ENTITY_VIEW_ID + entityViewId);
173 174 deleteEntityRelations(entityViewId);
174 175 EntityView entityView = entityViewDao.findById(entityViewId.getId());
175   -// List<Object> list = new ArrayList<>();
176   -// list.add(entityView.getTenantId());
177   -// list.add(entityView.getName());
178   -// cache.evict(list);
  176 + cache.evict(Arrays.asList(entityView.getTenantId(), entityView.getName()));
179 177 entityViewDao.removeById(entityViewId.getId());
180 178 }
181 179
... ... @@ -188,7 +186,6 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
188 186 return new TextPageData<>(entityViews, pageLink);
189 187 }
190 188
191   -// @Cacheable(cacheNames = ENTITY_VIEW_CACHE)
192 189 @Override
193 190 public TextPageData<EntityView> findEntityViewByTenantIdAndEntityId(TenantId tenantId, EntityId entityId,
194 191 TextPageLink pageLink) {
... ... @@ -228,7 +225,6 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
228 225 return new TextPageData<>(entityViews, pageLink);
229 226 }
230 227
231   -// @Cacheable(cacheNames = ENTITY_VIEW_CACHE, key = "{#tenantId, #customerId, #entityId, #pageLink}")
232 228 @Override
233 229 public TextPageData<EntityView> findEntityViewsByTenantIdAndCustomerIdAndEntityId(TenantId tenantId,
234 230 CustomerId customerId,
... ... @@ -312,9 +308,6 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
312 308
313 309 @Override
314 310 protected void validateDataImpl(EntityView entityView) {
315   - if (StringUtils.isEmpty(entityView.getKeys().toString())) {
316   - throw new DataValidationException("Entity view type should be specified!");
317   - }
318 311 if (StringUtils.isEmpty(entityView.getName())) {
319 312 throw new DataValidationException("Entity view name should be specified!");
320 313 }
... ...
... ... @@ -45,7 +45,6 @@ public class ModelConstants {
45 45 public static final String SEARCH_TEXT_PROPERTY = "search_text";
46 46 public static final String ADDITIONAL_INFO_PROPERTY = "additional_info";
47 47 public static final String ENTITY_TYPE_PROPERTY = "entity_type";
48   - /*public static final String ENTITY_VIEW_ID_PROPERTY = "entity_view_id";*/
49 48
50 49 public static final String ENTITY_TYPE_COLUMN = ENTITY_TYPE_PROPERTY;
51 50 public static final String ENTITY_ID_COLUMN = "entity_id";
... ... @@ -53,7 +52,6 @@ public class ModelConstants {
53 52 public static final String ATTRIBUTE_KEY_COLUMN = "attribute_key";
54 53 public static final String LAST_UPDATE_TS_COLUMN = "last_update_ts";
55 54
56   -
57 55 /**
58 56 * Cassandra user constants.
59 57 */
... ... @@ -148,18 +146,19 @@ public class ModelConstants {
148 146 * Cassandra entityView constants.
149 147 */
150 148 public static final String ENTITY_VIEW_TABLE_FAMILY_NAME = "entity_views";
151   - public static final String ENTITY_VIEW_FAMILY_NAME = "entity-view";
152 149 public static final String ENTITY_VIEW_ENTITY_ID_PROPERTY = ENTITY_ID_COLUMN;
153 150 public static final String ENTITY_VIEW_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY;
154 151 public static final String ENTITY_VIEW_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY;
155 152 public static final String ENTITY_VIEW_NAME_PROPERTY = DEVICE_NAME_PROPERTY;
156   - public static final String ENTITY_VIEW_TYPE_PROPERTY = DEVICE_TYPE_PROPERTY;
157   - public static final String ENTITY_VIEW_TENANT_AND_NAME_VIEW_NAME = "entity_view_by_tenant_and_name";
  153 + public static final String ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_AND_ENTITY_AND_SEARCH_TEXT = "entity_views_by_tenant_and_customer_and_entity";
  154 + public static final String ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_AND_SEARCH_TEXT = "entity_views_by_tenant_and_customer";
158 155 public static final String ENTITY_VIEW_KEYS_PROPERTY = "keys";
159 156 public static final String ENTITY_VIEW_START_TS_PROPERTY = "start_ts";
160 157 public static final String ENTITY_VIEW_END_TS_PROPERTY = "end_ts";
161 158 public static final String ENTITY_VIEW_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY;
162 159 public static final String ENTITY_VIEW_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "entity_view_by_tenant_and_search_text";
  160 + public static final String ENTITY_VIEW_BY_TENANT_AND_NAME = "entity_views_by_tenant_and_name";
  161 + public static final String ENTITY_VIEW_BY_TENANT_AND_ENTITY_AND_SEARCH_TEXT = "entity_view_by_tenant_and_entity";
163 162
164 163 /**
165 164 * Cassandra audit log constants.
... ...
... ... @@ -165,35 +165,55 @@ CREATE TABLE IF NOT EXISTS thingsboard.device (
165 165 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_tenant_and_name AS
166 166 SELECT *
167 167 from thingsboard.device
168   - WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL
  168 + WHERE tenant_id IS NOT NULL
  169 + AND customer_id IS NOT NULL
  170 + AND type IS NOT NULL
  171 + AND name IS NOT NULL
  172 + AND id IS NOT NULL
169 173 PRIMARY KEY ( tenant_id, name, id, customer_id, type)
170 174 WITH CLUSTERING ORDER BY ( name ASC, id DESC, customer_id DESC);
171 175
172 176 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_tenant_and_search_text AS
173 177 SELECT *
174 178 from thingsboard.device
175   - WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL
  179 + WHERE tenant_id IS NOT NULL
  180 + AND customer_id IS NOT NULL
  181 + AND type IS NOT NULL
  182 + AND search_text IS NOT NULL
  183 + AND id IS NOT NULL
176 184 PRIMARY KEY ( tenant_id, search_text, id, customer_id, type)
177 185 WITH CLUSTERING ORDER BY ( search_text ASC, id DESC, customer_id DESC);
178 186
179 187 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_tenant_by_type_and_search_text AS
180 188 SELECT *
181 189 from thingsboard.device
182   - WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL
  190 + WHERE tenant_id IS NOT NULL
  191 + AND customer_id IS NOT NULL
  192 + AND type IS NOT NULL
  193 + AND search_text IS NOT NULL
  194 + AND id IS NOT NULL
183 195 PRIMARY KEY ( tenant_id, type, search_text, id, customer_id)
184 196 WITH CLUSTERING ORDER BY ( type ASC, search_text ASC, id DESC, customer_id DESC);
185 197
186 198 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_customer_and_search_text AS
187 199 SELECT *
188 200 from thingsboard.device
189   - WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL
  201 + WHERE tenant_id IS NOT NULL
  202 + AND customer_id IS NOT NULL
  203 + AND type IS NOT NULL
  204 + AND search_text IS NOT NULL
  205 + AND id IS NOT NULL
190 206 PRIMARY KEY ( customer_id, tenant_id, search_text, id, type )
191 207 WITH CLUSTERING ORDER BY ( tenant_id DESC, search_text ASC, id DESC );
192 208
193 209 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_customer_by_type_and_search_text AS
194 210 SELECT *
195 211 from thingsboard.device
196   - WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL
  212 + WHERE tenant_id IS NOT NULL
  213 + AND customer_id IS NOT NULL
  214 + AND type IS NOT NULL
  215 + AND search_text IS NOT NULL
  216 + AND id IS NOT NULL
197 217 PRIMARY KEY ( customer_id, tenant_id, type, search_text, id )
198 218 WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC );
199 219
... ... @@ -651,33 +671,60 @@ CREATE TABLE IF NOT EXISTS thingsboard.entity_views (
651 671 end_ts bigint,
652 672 search_text text,
653 673 additional_info text,
654   - PRIMARY KEY (id, tenant_id, customer_id)
  674 + PRIMARY KEY (id, entity_id, tenant_id, customer_id)
655 675 );
656 676
657 677 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_name AS
658 678 SELECT *
659 679 from thingsboard.entity_views
660   - WHERE entity_id IS NOT NULL AND tenant_id IS NOT NULL AND customer_id IS NOT NULL AND keys IS NOT NULL AND start_ts IS NOT NULL AND end_ts IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL
661   - PRIMARY KEY (tenant_id, name, id, entity_id, customer_id)
662   - WITH CLUSTERING ORDER BY (name ASC, id DESC, entity_id DESC, customer_id DESC);
663   -
664   -CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_entity AS
  680 + WHERE tenant_id IS NOT NULL
  681 + AND entity_id IS NOT NULL
  682 + AND customer_id IS NOT NULL
  683 + AND name IS NOT NULL
  684 + AND id IS NOT NULL
  685 + PRIMARY KEY (tenant_id, name, id, customer_id, entity_id)
  686 + WITH CLUSTERING ORDER BY (name ASC, id DESC, customer_id DESC);
  687 +
  688 +CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_view_by_tenant_and_search_text AS
  689 + SELECT *
  690 + from thingsboard.entity_views
  691 + WHERE tenant_id IS NOT NULL
  692 + AND entity_id IS NOT NULL
  693 + AND customer_id IS NOT NULL
  694 + AND search_text IS NOT NULL
  695 + AND id IS NOT NULL
  696 + PRIMARY KEY (tenant_id, search_text, id, customer_id, entity_id)
  697 + WITH CLUSTERING ORDER BY (search_text ASC, id DESC, customer_id DESC);
  698 +
  699 +CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_view_by_tenant_and_entity AS
665 700 SELECT *
666 701 from thingsboard.entity_views
667   - WHERE entity_id IS NOT NULL AND tenant_id IS NOT NULL AND customer_id IS NOT NULL AND keys IS NOT NULL AND start_ts IS NOT NULL AND end_ts IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL
668   - PRIMARY KEY (tenant_id, entity_id, id, customer_id, name)
669   - WITH CLUSTERING ORDER BY (entity_id ASC, customer_id ASC, id DESC, name DESC);
  702 + WHERE tenant_id IS NOT NULL
  703 + AND customer_id IS NOT NULL
  704 + AND entity_id IS NOT NULL
  705 + AND search_text IS NOT NULL
  706 + AND id IS NOT NULL
  707 + PRIMARY KEY (tenant_id, entity_id, search_text, id, customer_id)
  708 + WITH CLUSTERING ORDER BY (entity_id ASC, search_text ASC, id DESC, customer_id DESC);
670 709
671 710 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer AS
672 711 SELECT *
673 712 from thingsboard.entity_views
674   - WHERE entity_id IS NOT NULL AND tenant_id IS NOT NULL AND customer_id IS NOT NULL AND keys IS NOT NULL AND start_ts IS NOT NULL AND end_ts IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL
675   - PRIMARY KEY (tenant_id, customer_id, id, entity_id, name)
676   - WITH CLUSTERING ORDER BY (customer_id ASC, id DESC, entity_id DESC, name DESC);
  713 + WHERE tenant_id IS NOT NULL
  714 + AND customer_id IS NOT NULL
  715 + AND entity_id IS NOT NULL
  716 + AND search_text IS NOT NULL
  717 + AND id IS NOT NULL
  718 + PRIMARY KEY (tenant_id, customer_id, search_text, id, entity_id)
  719 + WITH CLUSTERING ORDER BY (customer_id DESC, search_text ASC, id DESC);
677 720
678 721 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer_and_entity AS
679 722 SELECT *
680 723 from thingsboard.entity_views
681   - WHERE entity_id IS NOT NULL AND tenant_id IS NOT NULL AND customer_id IS NOT NULL AND keys IS NOT NULL AND start_ts IS NOT NULL AND end_ts IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL
682   - PRIMARY KEY (tenant_id, customer_id, entity_id, id, name)
683   - WITH CLUSTERING ORDER BY (customer_id ASC, entity_id DESC, id DESC, name DESC);
  724 + WHERE tenant_id IS NOT NULL
  725 + AND customer_id IS NOT NULL
  726 + AND entity_id IS NOT NULL
  727 + AND search_text IS NOT NULL
  728 + AND id IS NOT NULL
  729 + PRIMARY KEY (tenant_id, customer_id, entity_id, search_text, id)
  730 + WITH CLUSTERING ORDER BY (customer_id DESC, entity_id ASC, search_text ASC, id DESC);
... ...