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,55 +39,54 @@ CREATE TABLE IF NOT EXISTS thingsboard.entity_views (
39 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_name AS 39 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_name AS
40 SELECT * 40 SELECT *
41 from thingsboard.entity_views 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 SELECT * 51 SELECT *
55 from thingsboard.entity_views 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 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer AS 72 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer AS
68 SELECT * 73 SELECT *
69 from thingsboard.entity_views 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 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer_and_entity AS 83 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer_and_entity AS
82 SELECT * 84 SELECT *
83 from thingsboard.entity_views 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,32 +15,28 @@
15 */ 15 */
16 package org.thingsboard.server.controller; 16 package org.thingsboard.server.controller;
17 17
18 -import com.google.common.util.concurrent.ListenableFuture;  
19 import org.springframework.http.HttpStatus; 18 import org.springframework.http.HttpStatus;
20 import org.springframework.security.access.prepost.PreAuthorize; 19 import org.springframework.security.access.prepost.PreAuthorize;
21 import org.springframework.web.bind.annotation.*; 20 import org.springframework.web.bind.annotation.*;
22 import org.thingsboard.server.common.data.Customer; 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 import org.thingsboard.server.common.data.EntityType; 22 import org.thingsboard.server.common.data.EntityType;
26 import org.thingsboard.server.common.data.EntityView; 23 import org.thingsboard.server.common.data.EntityView;
27 import org.thingsboard.server.common.data.audit.ActionType; 24 import org.thingsboard.server.common.data.audit.ActionType;
28 import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery; 25 import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
29 import org.thingsboard.server.common.data.exception.ThingsboardException; 26 import org.thingsboard.server.common.data.exception.ThingsboardException;
30 import org.thingsboard.server.common.data.id.CustomerId; 27 import org.thingsboard.server.common.data.id.CustomerId;
31 -import org.thingsboard.server.common.data.id.DeviceId;  
32 import org.thingsboard.server.common.data.id.EntityViewId; 28 import org.thingsboard.server.common.data.id.EntityViewId;
33 import org.thingsboard.server.common.data.id.TenantId; 29 import org.thingsboard.server.common.data.id.TenantId;
34 import org.thingsboard.server.common.data.page.TextPageData; 30 import org.thingsboard.server.common.data.page.TextPageData;
35 import org.thingsboard.server.common.data.page.TextPageLink; 31 import org.thingsboard.server.common.data.page.TextPageLink;
36 import org.thingsboard.server.dao.exception.IncorrectParameterException; 32 import org.thingsboard.server.dao.exception.IncorrectParameterException;
37 import org.thingsboard.server.dao.model.ModelConstants; 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 import java.util.List; 35 import java.util.List;
42 import java.util.stream.Collectors; 36 import java.util.stream.Collectors;
43 37
  38 +import static org.thingsboard.server.controller.CustomerController.CUSTOMER_ID;
  39 +
44 /** 40 /**
45 * Created by Victor Basanets on 8/28/2017. 41 * Created by Victor Basanets on 8/28/2017.
46 */ 42 */
@@ -109,9 +105,9 @@ public class EntityViewController extends BaseController { @@ -109,9 +105,9 @@ public class EntityViewController extends BaseController {
109 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 105 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
110 @RequestMapping(value = "/customer/{customerId}/entityView/{entityViewId}", method = RequestMethod.POST) 106 @RequestMapping(value = "/customer/{customerId}/entityView/{entityViewId}", method = RequestMethod.POST)
111 @ResponseBody 107 @ResponseBody
112 - public EntityView assignEntityViewToCustomer(@PathVariable("customerId") String strCustomerId, 108 + public EntityView assignEntityViewToCustomer(@PathVariable(CUSTOMER_ID) String strCustomerId,
113 @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { 109 @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException {
114 - checkParameter("customerId", strCustomerId); 110 + checkParameter(CUSTOMER_ID, strCustomerId);
115 checkParameter(ENTITY_VIEW_ID, strEntityViewId); 111 checkParameter(ENTITY_VIEW_ID, strEntityViewId);
116 try { 112 try {
117 CustomerId customerId = new CustomerId(toUUID(strCustomerId)); 113 CustomerId customerId = new CustomerId(toUUID(strCustomerId));
@@ -298,6 +298,9 @@ caffeine: @@ -298,6 +298,9 @@ caffeine:
298 assets: 298 assets:
299 timeToLiveInMinutes: 1440 299 timeToLiveInMinutes: 1440
300 maxSize: 100000 300 maxSize: 100000
  301 + entityViews:
  302 + timeToLiveInMinutes: 1440
  303 + maxSize: 100000
301 304
302 redis: 305 redis:
303 # standalone or cluster 306 # standalone or cluster
@@ -15,25 +15,31 @@ @@ -15,25 +15,31 @@
15 */ 15 */
16 package org.thingsboard.server.controller; 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 import org.junit.After; 21 import org.junit.After;
19 import org.junit.Assert; 22 import org.junit.Assert;
20 import org.junit.Before; 23 import org.junit.Before;
21 import org.junit.Test; 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 import org.thingsboard.server.common.data.objects.AttributesEntityView; 27 import org.thingsboard.server.common.data.objects.AttributesEntityView;
27 import org.thingsboard.server.common.data.objects.TelemetryEntityView; 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 import org.thingsboard.server.common.data.security.Authority; 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 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 37 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
33 import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; 38 import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
34 39
35 public abstract class BaseEntityViewControllerTest extends AbstractControllerTest { 40 public abstract class BaseEntityViewControllerTest extends AbstractControllerTest {
36 41
  42 + private IdComparator<EntityView> idComparator;
37 private Tenant savedTenant; 43 private Tenant savedTenant;
38 private User tenantAdmin; 44 private User tenantAdmin;
39 private Device testDevice; 45 private Device testDevice;
@@ -43,10 +49,9 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @@ -43,10 +49,9 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
43 public void beforeTest() throws Exception { 49 public void beforeTest() throws Exception {
44 loginSysAdmin(); 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 Assert.assertNotNull(savedTenant); 55 Assert.assertNotNull(savedTenant);
51 56
52 tenantAdmin = new User(); 57 tenantAdmin = new User();
@@ -62,13 +67,14 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @@ -62,13 +67,14 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
62 device.setName("Test device"); 67 device.setName("Test device");
63 device.setType("default"); 68 device.setType("default");
64 testDevice = doPost("/api/device", device, Device.class); 69 testDevice = doPost("/api/device", device, Device.class);
65 -  
66 obj = new TelemetryEntityView( 70 obj = new TelemetryEntityView(
67 Arrays.asList("109L", "209L"), 71 Arrays.asList("109L", "209L"),
68 new AttributesEntityView( 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 @After 80 @After
@@ -81,24 +87,15 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @@ -81,24 +87,15 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
81 87
82 @Test 88 @Test
83 public void testFindEntityViewById() throws Exception { 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 Assert.assertNotNull(foundView); 92 Assert.assertNotNull(foundView);
91 Assert.assertEquals(savedView, foundView); 93 Assert.assertEquals(savedView, foundView);
92 } 94 }
93 95
94 @Test 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 Assert.assertNotNull(savedView); 100 Assert.assertNotNull(savedView);
104 Assert.assertNotNull(savedView.getId()); 101 Assert.assertNotNull(savedView.getId());
@@ -109,26 +106,253 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes @@ -109,26 +106,253 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
109 Assert.assertEquals(savedView.getName(), savedView.getName()); 106 Assert.assertEquals(savedView.getName(), savedView.getName());
110 107
111 savedView.setName("New test entity view"); 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 Assert.assertEquals(foundEntityView.getName(), savedView.getName()); 112 Assert.assertEquals(foundEntityView.getName(), savedView.getName());
118 } 113 }
119 114
120 @Test 115 @Test
121 public void testDeleteEntityView() throws Exception { 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 .andExpect(status().isOk()); 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 .andExpect(status().isNotFound()); 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,49 +67,75 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit
67 67
68 @Override 68 @Override
69 public List<EntityView> findEntityViewByTenantId(UUID tenantId, TextPageLink pageLink) { 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 List<EntityViewEntity> entityViewEntities = 71 List<EntityViewEntity> entityViewEntities =
72 findPageWithTextSearch(ENTITY_VIEW_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, 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 return DaoUtil.convertDataList(entityViewEntities); 76 return DaoUtil.convertDataList(entityViewEntities);
77 } 77 }
78 78
79 @Override 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 @Override 87 @Override
89 public List<EntityView> findEntityViewByTenantIdAndEntityId(UUID tenantId, UUID entityId, TextPageLink pageLink) { 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 pageLink); 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 return DaoUtil.convertDataList(entityViewEntities); 97 return DaoUtil.convertDataList(entityViewEntities);
98 } 98 }
99 99
100 @Override 100 @Override
101 public List<EntityView> findEntityViewsByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TextPageLink pageLink) { 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 @Override 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 @Override 133 @Override
111 public ListenableFuture<List<EntityView>> findEntityViewsByTenantIdAndEntityIdAsync(UUID tenantId, UUID entityId) { 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,17 +21,18 @@ import com.google.common.util.concurrent.ListenableFuture;
21 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
22 import org.apache.commons.lang3.StringUtils; 22 import org.apache.commons.lang3.StringUtils;
23 import org.springframework.beans.factory.annotation.Autowired; 23 import org.springframework.beans.factory.annotation.Autowired;
  24 +import org.springframework.cache.Cache;
24 import org.springframework.cache.CacheManager; 25 import org.springframework.cache.CacheManager;
  26 +import org.springframework.cache.annotation.CacheEvict;
  27 +import org.springframework.cache.annotation.Cacheable;
25 import org.springframework.stereotype.Service; 28 import org.springframework.stereotype.Service;
26 import org.thingsboard.server.common.data.Customer; 29 import org.thingsboard.server.common.data.Customer;
27 import org.thingsboard.server.common.data.DataConstants; 30 import org.thingsboard.server.common.data.DataConstants;
28 -import org.thingsboard.server.common.data.Device;  
29 import org.thingsboard.server.common.data.EntityType; 31 import org.thingsboard.server.common.data.EntityType;
30 import org.thingsboard.server.common.data.EntityView; 32 import org.thingsboard.server.common.data.EntityView;
31 import org.thingsboard.server.common.data.Tenant; 33 import org.thingsboard.server.common.data.Tenant;
32 import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery; 34 import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
33 import org.thingsboard.server.common.data.id.CustomerId; 35 import org.thingsboard.server.common.data.id.CustomerId;
34 -import org.thingsboard.server.common.data.id.DeviceId;  
35 import org.thingsboard.server.common.data.id.EntityId; 36 import org.thingsboard.server.common.data.id.EntityId;
36 import org.thingsboard.server.common.data.id.EntityViewId; 37 import org.thingsboard.server.common.data.id.EntityViewId;
37 import org.thingsboard.server.common.data.id.TenantId; 38 import org.thingsboard.server.common.data.id.TenantId;
@@ -50,14 +51,14 @@ import org.thingsboard.server.dao.tenant.TenantDao; @@ -50,14 +51,14 @@ import org.thingsboard.server.dao.tenant.TenantDao;
50 51
51 import javax.annotation.Nullable; 52 import javax.annotation.Nullable;
52 import java.util.ArrayList; 53 import java.util.ArrayList;
  54 +import java.util.Arrays;
53 import java.util.Collection; 55 import java.util.Collection;
54 import java.util.List; 56 import java.util.List;
55 import java.util.stream.Collectors; 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 import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; 60 import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
59 import static org.thingsboard.server.dao.service.Validator.validateId; 61 import static org.thingsboard.server.dao.service.Validator.validateId;
60 -import static org.thingsboard.server.dao.service.Validator.validateIds;  
61 import static org.thingsboard.server.dao.service.Validator.validatePageLink; 62 import static org.thingsboard.server.dao.service.Validator.validatePageLink;
62 import static org.thingsboard.server.dao.service.Validator.validateString; 63 import static org.thingsboard.server.dao.service.Validator.validateString;
63 64
@@ -88,7 +89,6 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -88,7 +89,6 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
88 @Autowired 89 @Autowired
89 private CacheManager cacheManager; 90 private CacheManager cacheManager;
90 91
91 -// @Cacheable(cacheNames = ENTITY_VIEW_CACHE)  
92 @Override 92 @Override
93 public EntityView findEntityViewById(EntityViewId entityViewId) { 93 public EntityView findEntityViewById(EntityViewId entityViewId) {
94 log.trace("Executing findEntityViewById [{}]", entityViewId); 94 log.trace("Executing findEntityViewById [{}]", entityViewId);
@@ -96,6 +96,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -96,6 +96,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
96 return entityViewDao.findById(entityViewId.getId()); 96 return entityViewDao.findById(entityViewId.getId());
97 } 97 }
98 98
  99 + @Cacheable(cacheNames = ENTITY_VIEW_CACHE, key = "{#tenantId, #name}")
99 @Override 100 @Override
100 public EntityView findEntityViewByTenantIdAndName(TenantId tenantId, String name) { 101 public EntityView findEntityViewByTenantIdAndName(TenantId tenantId, String name) {
101 log.trace("Executing findEntityViewByTenantIdAndName [{}][{}]", tenantId, name); 102 log.trace("Executing findEntityViewByTenantIdAndName [{}][{}]", tenantId, name);
@@ -104,7 +105,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -104,7 +105,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
104 .orElse(null); 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 @Override 109 @Override
109 public EntityView saveEntityView(EntityView entityView) { 110 public EntityView saveEntityView(EntityView entityView) {
110 log.trace("Executing save entity view [{}]", entityView); 111 log.trace("Executing save entity view [{}]", entityView);
@@ -168,14 +169,11 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -168,14 +169,11 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
168 @Override 169 @Override
169 public void deleteEntityView(EntityViewId entityViewId) { 170 public void deleteEntityView(EntityViewId entityViewId) {
170 log.trace("Executing deleteEntityView [{}]", entityViewId); 171 log.trace("Executing deleteEntityView [{}]", entityViewId);
171 -// Cache cache = cacheManager.getCache(ENTITY_VIEW_CACHE); 172 + Cache cache = cacheManager.getCache(ENTITY_VIEW_CACHE);
172 validateId(entityViewId, INCORRECT_ENTITY_VIEW_ID + entityViewId); 173 validateId(entityViewId, INCORRECT_ENTITY_VIEW_ID + entityViewId);
173 deleteEntityRelations(entityViewId); 174 deleteEntityRelations(entityViewId);
174 EntityView entityView = entityViewDao.findById(entityViewId.getId()); 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 entityViewDao.removeById(entityViewId.getId()); 177 entityViewDao.removeById(entityViewId.getId());
180 } 178 }
181 179
@@ -188,7 +186,6 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -188,7 +186,6 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
188 return new TextPageData<>(entityViews, pageLink); 186 return new TextPageData<>(entityViews, pageLink);
189 } 187 }
190 188
191 -// @Cacheable(cacheNames = ENTITY_VIEW_CACHE)  
192 @Override 189 @Override
193 public TextPageData<EntityView> findEntityViewByTenantIdAndEntityId(TenantId tenantId, EntityId entityId, 190 public TextPageData<EntityView> findEntityViewByTenantIdAndEntityId(TenantId tenantId, EntityId entityId,
194 TextPageLink pageLink) { 191 TextPageLink pageLink) {
@@ -228,7 +225,6 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -228,7 +225,6 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
228 return new TextPageData<>(entityViews, pageLink); 225 return new TextPageData<>(entityViews, pageLink);
229 } 226 }
230 227
231 -// @Cacheable(cacheNames = ENTITY_VIEW_CACHE, key = "{#tenantId, #customerId, #entityId, #pageLink}")  
232 @Override 228 @Override
233 public TextPageData<EntityView> findEntityViewsByTenantIdAndCustomerIdAndEntityId(TenantId tenantId, 229 public TextPageData<EntityView> findEntityViewsByTenantIdAndCustomerIdAndEntityId(TenantId tenantId,
234 CustomerId customerId, 230 CustomerId customerId,
@@ -312,9 +308,6 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -312,9 +308,6 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
312 308
313 @Override 309 @Override
314 protected void validateDataImpl(EntityView entityView) { 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 if (StringUtils.isEmpty(entityView.getName())) { 311 if (StringUtils.isEmpty(entityView.getName())) {
319 throw new DataValidationException("Entity view name should be specified!"); 312 throw new DataValidationException("Entity view name should be specified!");
320 } 313 }
@@ -45,7 +45,6 @@ public class ModelConstants { @@ -45,7 +45,6 @@ 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";*/  
49 48
50 public static final String ENTITY_TYPE_COLUMN = ENTITY_TYPE_PROPERTY; 49 public static final String ENTITY_TYPE_COLUMN = ENTITY_TYPE_PROPERTY;
51 public static final String ENTITY_ID_COLUMN = "entity_id"; 50 public static final String ENTITY_ID_COLUMN = "entity_id";
@@ -53,7 +52,6 @@ public class ModelConstants { @@ -53,7 +52,6 @@ public class ModelConstants {
53 public static final String ATTRIBUTE_KEY_COLUMN = "attribute_key"; 52 public static final String ATTRIBUTE_KEY_COLUMN = "attribute_key";
54 public static final String LAST_UPDATE_TS_COLUMN = "last_update_ts"; 53 public static final String LAST_UPDATE_TS_COLUMN = "last_update_ts";
55 54
56 -  
57 /** 55 /**
58 * Cassandra user constants. 56 * Cassandra user constants.
59 */ 57 */
@@ -148,18 +146,19 @@ public class ModelConstants { @@ -148,18 +146,19 @@ public class ModelConstants {
148 * Cassandra entityView constants. 146 * Cassandra entityView constants.
149 */ 147 */
150 public static final String ENTITY_VIEW_TABLE_FAMILY_NAME = "entity_views"; 148 public static final String ENTITY_VIEW_TABLE_FAMILY_NAME = "entity_views";
151 - public static final String ENTITY_VIEW_FAMILY_NAME = "entity-view";  
152 public static final String ENTITY_VIEW_ENTITY_ID_PROPERTY = ENTITY_ID_COLUMN; 149 public static final String ENTITY_VIEW_ENTITY_ID_PROPERTY = ENTITY_ID_COLUMN;
153 public static final String ENTITY_VIEW_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; 150 public static final String ENTITY_VIEW_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY;
154 public static final String ENTITY_VIEW_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY; 151 public static final String ENTITY_VIEW_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY;
155 public static final String ENTITY_VIEW_NAME_PROPERTY = DEVICE_NAME_PROPERTY; 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 public static final String ENTITY_VIEW_KEYS_PROPERTY = "keys"; 155 public static final String ENTITY_VIEW_KEYS_PROPERTY = "keys";
159 public static final String ENTITY_VIEW_START_TS_PROPERTY = "start_ts"; 156 public static final String ENTITY_VIEW_START_TS_PROPERTY = "start_ts";
160 public static final String ENTITY_VIEW_END_TS_PROPERTY = "end_ts"; 157 public static final String ENTITY_VIEW_END_TS_PROPERTY = "end_ts";
161 public static final String ENTITY_VIEW_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; 158 public static final String ENTITY_VIEW_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY;
162 public static final String ENTITY_VIEW_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "entity_view_by_tenant_and_search_text"; 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 * Cassandra audit log constants. 164 * Cassandra audit log constants.
@@ -165,35 +165,55 @@ CREATE TABLE IF NOT EXISTS thingsboard.device ( @@ -165,35 +165,55 @@ CREATE TABLE IF NOT EXISTS thingsboard.device (
165 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_tenant_and_name AS 165 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_tenant_and_name AS
166 SELECT * 166 SELECT *
167 from thingsboard.device 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 PRIMARY KEY ( tenant_id, name, id, customer_id, type) 173 PRIMARY KEY ( tenant_id, name, id, customer_id, type)
170 WITH CLUSTERING ORDER BY ( name ASC, id DESC, customer_id DESC); 174 WITH CLUSTERING ORDER BY ( name ASC, id DESC, customer_id DESC);
171 175
172 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_tenant_and_search_text AS 176 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_tenant_and_search_text AS
173 SELECT * 177 SELECT *
174 from thingsboard.device 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 PRIMARY KEY ( tenant_id, search_text, id, customer_id, type) 184 PRIMARY KEY ( tenant_id, search_text, id, customer_id, type)
177 WITH CLUSTERING ORDER BY ( search_text ASC, id DESC, customer_id DESC); 185 WITH CLUSTERING ORDER BY ( search_text ASC, id DESC, customer_id DESC);
178 186
179 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_tenant_by_type_and_search_text AS 187 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_tenant_by_type_and_search_text AS
180 SELECT * 188 SELECT *
181 from thingsboard.device 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 PRIMARY KEY ( tenant_id, type, search_text, id, customer_id) 195 PRIMARY KEY ( tenant_id, type, search_text, id, customer_id)
184 WITH CLUSTERING ORDER BY ( type ASC, search_text ASC, id DESC, customer_id DESC); 196 WITH CLUSTERING ORDER BY ( type ASC, search_text ASC, id DESC, customer_id DESC);
185 197
186 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_customer_and_search_text AS 198 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_customer_and_search_text AS
187 SELECT * 199 SELECT *
188 from thingsboard.device 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 PRIMARY KEY ( customer_id, tenant_id, search_text, id, type ) 206 PRIMARY KEY ( customer_id, tenant_id, search_text, id, type )
191 WITH CLUSTERING ORDER BY ( tenant_id DESC, search_text ASC, id DESC ); 207 WITH CLUSTERING ORDER BY ( tenant_id DESC, search_text ASC, id DESC );
192 208
193 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_customer_by_type_and_search_text AS 209 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_customer_by_type_and_search_text AS
194 SELECT * 210 SELECT *
195 from thingsboard.device 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 PRIMARY KEY ( customer_id, tenant_id, type, search_text, id ) 217 PRIMARY KEY ( customer_id, tenant_id, type, search_text, id )
198 WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC ); 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,33 +671,60 @@ CREATE TABLE IF NOT EXISTS thingsboard.entity_views (
651 end_ts bigint, 671 end_ts bigint,
652 search_text text, 672 search_text text,
653 additional_info text, 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 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_name AS 677 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_name AS
658 SELECT * 678 SELECT *
659 from thingsboard.entity_views 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 SELECT * 700 SELECT *
666 from thingsboard.entity_views 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 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer AS 710 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer AS
672 SELECT * 711 SELECT *
673 from thingsboard.entity_views 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 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer_and_entity AS 721 CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer_and_entity AS
679 SELECT * 722 SELECT *
680 from thingsboard.entity_views 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);