Browse Source

Merge pull request #1053 from ViktorBasanets/master

Entity View server side
pull/1070/head
VoBa 8 years ago
committed by GitHub
parent
commit
b0b6ee06bd
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 92
      application/src/main/data/upgrade/2.1.1/schema_update.cql
  2. 31
      application/src/main/data/upgrade/2.1.1/schema_update.sql
  3. 26
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  4. 98
      application/src/main/java/org/thingsboard/server/controller/EntityViewController.java
  5. 7
      application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java
  6. 4
      application/src/main/java/org/thingsboard/server/service/install/DefaultDataUpdateService.java
  7. 9
      application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java
  8. 2
      application/src/main/resources/thingsboard.yml
  9. 134
      application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java
  10. 2
      application/src/test/java/org/thingsboard/server/controller/ControllerSqlTestSuite.java
  11. 24
      application/src/test/java/org/thingsboard/server/controller/nosql/EntityViewControllerNoSqlTest.java
  12. 31
      application/src/test/java/org/thingsboard/server/controller/sql/EntityViewControllerSqlTest.java
  13. 1
      common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java
  14. 2
      common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java
  15. 76
      common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java
  16. 2
      common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java
  17. 44
      common/data/src/main/java/org/thingsboard/server/common/data/id/EntityViewId.java
  18. 52
      common/data/src/main/java/org/thingsboard/server/common/data/objects/AttributesEntityView.java
  19. 48
      common/data/src/main/java/org/thingsboard/server/common/data/objects/TelemetryEntityView.java
  20. 88
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewDao.java
  21. 60
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java
  22. 276
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java
  23. 15
      dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
  24. 146
      dao/src/main/java/org/thingsboard/server/dao/model/nosql/EntityViewEntity.java
  25. 150
      dao/src/main/java/org/thingsboard/server/dao/model/sql/EntityViewEntity.java
  26. 81
      dao/src/main/java/org/thingsboard/server/dao/sql/entityview/EntityViewRepository.java
  27. 118
      dao/src/main/java/org/thingsboard/server/dao/sql/entityview/JpaEntityViewDao.java
  28. 42
      dao/src/main/resources/cassandra/schema.cql
  29. 14
      dao/src/main/resources/sql/schema.sql
  30. 3
      dao/src/test/resources/sql/drop-all-tables.sql

92
application/src/main/data/upgrade/2.1.1/schema_update.cql

@ -0,0 +1,92 @@
--
-- Copyright © 2016-2018 The Thingsboard Authors
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
DROP MATERIALIZED VIEW IF EXISTS thingsboard.entity_views_by_tenant_and_name;
DROP MATERIALIZED VIEW IF EXISTS thingsboard.entity_views_by_tenant_and_entity;
DROP MATERIALIZED VIEW IF EXISTS thingsboard.entity_views_by_tenant_and_customer;
DROP MATERIALIZED VIEW IF EXISTS thingsboard.entity_views_by_tenant_and_customer_and_entity;
DROP TABLE IF EXISTS thingsboard.entity_views;
CREATE TABLE IF NOT EXISTS thingsboard.entity_views (
id timeuuid,
entity_id timeuuid,
tenant_id timeuuid,
customer_id timeuuid,
name text,
keys text,
ts_begin bigint,
ts_end bigint,
search_text text,
additional_info text,
PRIMARY KEY (id, entity_id, tenant_id, customer_id)
);
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_name AS
SELECT *
from thingsboard.entity_views
WHERE entity_id IS NOT NULL
AND tenant_id IS NOT NULL
AND customer_id IS NOT NULL
AND keys IS NOT NULL
AND ts_begin IS NOT NULL
AND ts_end IS NOT NULL
AND name IS NOT NULL
AND id IS NOT NULL
PRIMARY KEY (tenant_id, name, id, entity_id, customer_id)
WITH CLUSTERING ORDER BY (name ASC, id DESC, entity_id DESC, customer_id DESC);
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_entity AS
SELECT *
from thingsboard.entity_views
WHERE entity_id IS NOT NULL
AND tenant_id IS NOT NULL
AND customer_id IS NOT NULL
AND keys IS NOT NULL
AND ts_begin IS NOT NULL
AND ts_end IS NOT NULL
AND name IS NOT NULL
AND id IS NOT NULL
PRIMARY KEY (tenant_id, entity_id, id, customer_id, name)
WITH CLUSTERING ORDER BY (entity_id ASC, customer_id ASC, id DESC, name DESC);
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer AS
SELECT *
from thingsboard.entity_views
WHERE entity_id IS NOT NULL
AND tenant_id IS NOT NULL
AND customer_id IS NOT NULL
AND keys IS NOT NULL
AND ts_begin IS NOT NULL
AND ts_end IS NOT NULL
AND name IS NOT NULL
AND id IS NOT NULL
PRIMARY KEY (tenant_id, customer_id, id, entity_id, name)
WITH CLUSTERING ORDER BY (customer_id ASC, id DESC, entity_id DESC, name DESC);
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer_and_entity AS
SELECT *
from thingsboard.entity_views
WHERE entity_id IS NOT NULL
AND tenant_id IS NOT NULL
AND customer_id IS NOT NULL
AND keys IS NOT NULL
AND ts_begin IS NOT NULL
AND ts_end IS NOT NULL
AND name IS NOT NULL
AND id IS NOT NULL
PRIMARY KEY (tenant_id, customer_id, entity_id, id, name)
WITH CLUSTERING ORDER BY (customer_id ASC, entity_id DESC, id DESC, name DESC);

31
application/src/main/data/upgrade/2.1.1/schema_update.sql

@ -0,0 +1,31 @@
--
-- Copyright © 2016-2018 The Thingsboard Authors
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
DROP TABLE IF EXISTS entity_views;
CREATE TABLE IF NOT EXISTS entity_views (
id varchar(31) NOT NULL CONSTRAINT entity_view_pkey PRIMARY KEY,
entity_id varchar(31),
entity_type varchar(255),
tenant_id varchar(31),
customer_id varchar(31),
name varchar(255),
keys varchar(255),
ts_begin varchar(255),
ts_end varchar(255),
search_text varchar(255),
additional_info varchar
);

26
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -56,6 +56,7 @@ import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.dashboard.DashboardService;
import org.thingsboard.server.dao.device.DeviceCredentialsService; import org.thingsboard.server.dao.device.DeviceCredentialsService;
import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.ModelConstants;
@ -139,6 +140,9 @@ public abstract class BaseController {
@Autowired @Autowired
protected DeviceStateService deviceStateService; protected DeviceStateService deviceStateService;
@Autowired
protected EntityViewService entityViewService;
@ExceptionHandler(ThingsboardException.class) @ExceptionHandler(ThingsboardException.class)
public void handleThingsboardException(ThingsboardException ex, HttpServletResponse response) { public void handleThingsboardException(ThingsboardException ex, HttpServletResponse response) {
errorResponseHandler.handle(ex, response); errorResponseHandler.handle(ex, response);
@ -313,6 +317,9 @@ public abstract class BaseController {
case USER: case USER:
checkUserId(new UserId(entityId.getId())); checkUserId(new UserId(entityId.getId()));
return; return;
case ENTITY_VIEW:
checkEntityView(entityViewService.findEntityViewById(new EntityViewId(entityId.getId())));
return;
default: default:
throw new IllegalArgumentException("Unsupported entity type: " + entityId.getEntityType()); throw new IllegalArgumentException("Unsupported entity type: " + entityId.getEntityType());
} }
@ -340,6 +347,25 @@ public abstract class BaseController {
} }
} }
protected EntityView checkEntityViewId(EntityViewId entityViewId) throws ThingsboardException {
try {
validateId(entityViewId, "Incorrect entityViewId " + entityViewId);
EntityView entityView = entityViewService.findEntityViewById(entityViewId);
checkEntityView(entityView);
return entityView;
} catch (Exception e) {
throw handleException(e, false);
}
}
protected void checkEntityView(EntityView entityView) throws ThingsboardException {
checkNotNull(entityView);
checkTenantId(entityView.getTenantId());
if (entityView.getCustomerId() != null && !entityView.getCustomerId().getId().equals(ModelConstants.NULL_UUID)) {
checkCustomerId(entityView.getCustomerId());
}
}
Asset checkAssetId(AssetId assetId) throws ThingsboardException { Asset checkAssetId(AssetId assetId) throws ThingsboardException {
try { try {
validateId(assetId, "Incorrect assetId " + assetId); validateId(assetId, "Incorrect assetId " + assetId);

98
application/src/main/java/org/thingsboard/server/controller/EntityViewController.java

@ -0,0 +1,98 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.controller;
import com.google.common.util.concurrent.ListenableFuture;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.service.security.model.SecurityUser;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Victor Basanets on 8/28/2017.
*/
@RestController
@RequestMapping("/api")
public class EntityViewController extends BaseController {
public static final String ENTITY_VIEW_ID = "entityViewId";
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/entity-view/{entityViewId}", method = RequestMethod.GET)
@ResponseBody
public EntityView getEntityViewById(@PathVariable(ENTITY_VIEW_ID) String strEntityViewId)
throws ThingsboardException {
checkParameter(ENTITY_VIEW_ID, strEntityViewId);
try {
EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId));
return checkEntityViewId(entityViewId);
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/entity-view", method = RequestMethod.POST)
@ResponseBody
public EntityView saveEntityView(@RequestBody EntityView entityView) throws ThingsboardException {
try {
entityView.setTenantId(getCurrentUser().getTenantId());
EntityView savedEntityView = checkNotNull(entityViewService.saveEntityView(entityView));
logEntityAction(savedEntityView.getId(), savedEntityView, null,
entityView.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
return savedEntityView;
} catch (Exception e) {
logEntityAction(emptyId(EntityType.ENTITY_VIEW), entityView, null,
entityView.getId() == null ? ActionType.ADDED : ActionType.UPDATED, e);
throw handleException(e);
}
}
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/entity-view/{entityViewId}", method = RequestMethod.DELETE)
@ResponseStatus(value = HttpStatus.OK)
public void deleteEntityView(@PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException {
checkParameter(ENTITY_VIEW_ID, strEntityViewId);
try {
EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId));
EntityView entityView = checkEntityViewId(entityViewId);
entityViewService.deleteEntityView(entityViewId);
logEntityAction(entityViewId, entityView, entityView.getCustomerId(),
ActionType.DELETED,null, strEntityViewId);
} catch (Exception e) {
logEntityAction(emptyId(EntityType.ENTITY_VIEW),
null,
null,
ActionType.DELETED, e, strEntityViewId);
throw handleException(e);
}
}
}

7
application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java

@ -88,6 +88,13 @@ public class ThingsboardInstallService {
dataUpdateService.updateData("1.4.0"); dataUpdateService.updateData("1.4.0");
case "2.0.0":
log.info("Upgrading ThingsBoard from version 2.0.0 to 2.1.1 ...");
databaseUpgradeService.upgradeDatabase("2.0.0");
dataUpdateService.updateData("2.0.0");
log.info("Updating system data..."); log.info("Updating system data...");
systemDataLoaderService.deleteSystemWidgetBundle("charts"); systemDataLoaderService.deleteSystemWidgetBundle("charts");

4
application/src/main/java/org/thingsboard/server/service/install/DefaultDataUpdateService.java

@ -49,6 +49,10 @@ public class DefaultDataUpdateService implements DataUpdateService {
log.info("Updating data from version 1.4.0 to 2.0.0 ..."); log.info("Updating data from version 1.4.0 to 2.0.0 ...");
tenantsDefaultRuleChainUpdater.updateEntities(null); tenantsDefaultRuleChainUpdater.updateEntities(null);
break; break;
case "2.0.0":
log.info("Updating data from version 2.0.0 to 2.1.1 ...");
tenantsDefaultRuleChainUpdater.updateEntities(null);
break;
default: default:
throw new RuntimeException("Unable to update data, unsupported fromVersion: " + fromVersion); throw new RuntimeException("Unable to update data, unsupported fromVersion: " + fromVersion);
} }

9
application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java

@ -107,6 +107,15 @@ public class SqlDatabaseUpgradeService implements DatabaseUpgradeService {
log.info("Schema updated."); log.info("Schema updated.");
} }
break; break;
case "2.0.0":
try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
log.info("Updating schema ...");
schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.1.1", SCHEMA_UPDATE_SQL);
loadSql(schemaUpdateFile, conn);
log.info("Schema updated.");
}
break;
default: default:
throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion);
} }

2
application/src/main/resources/thingsboard.yml

@ -359,7 +359,7 @@ spring:
password: "${SPRING_DATASOURCE_PASSWORD:}" password: "${SPRING_DATASOURCE_PASSWORD:}"
# PostgreSQL DAO Configuration # PostgreSQL DAO Configuration
#spring: # spring:
# data: # data:
# sql: # sql:
# repositories: # repositories:

134
application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java

@ -0,0 +1,134 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.controller;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.objects.AttributesEntityView;
import org.thingsboard.server.common.data.objects.TelemetryEntityView;
import org.thingsboard.server.common.data.security.Authority;
import java.util.Arrays;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
public abstract class BaseEntityViewControllerTest extends AbstractControllerTest {
private Tenant savedTenant;
private User tenantAdmin;
private Device testDevice;
private TelemetryEntityView obj;
@Before
public void beforeTest() throws Exception {
loginSysAdmin();
Tenant tenant = new Tenant();
tenant.setTitle("My tenant");
savedTenant = doPost("/api/tenant", tenant, Tenant.class);
Assert.assertNotNull(savedTenant);
tenantAdmin = new User();
tenantAdmin.setAuthority(Authority.TENANT_ADMIN);
tenantAdmin.setTenantId(savedTenant.getId());
tenantAdmin.setEmail("tenant2@thingsboard.org");
tenantAdmin.setFirstName("Joe");
tenantAdmin.setLastName("Downs");
tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1");
Device device = new Device();
device.setName("Test device");
device.setType("default");
testDevice = doPost("/api/device", device, Device.class);
obj = new TelemetryEntityView(
Arrays.asList("109L", "209L"),
new AttributesEntityView(
Arrays.asList("caKey1", "caKey2", "caKey3"),
Arrays.asList("saKey1", "saKey2", "saKey3", "saKey4"),
Arrays.asList("shKey1", "shKey2", "shKey3", "shKey4", "shKey5")));
}
@After
public void afterTest() throws Exception {
loginSysAdmin();
doDelete("/api/tenant/" + savedTenant.getId().getId().toString())
.andExpect(status().isOk());
}
@Test
public void testFindEntityViewById() throws Exception {
EntityView view = new EntityView();
view.setName("Test entity view");
view.setEntityId(testDevice.getId());
view.setKeys(new TelemetryEntityView(obj));
EntityView savedView = doPost("/api/entity-view", view, EntityView.class);
EntityView foundView = doGet("/api/entity-view/" + savedView.getId().getId().toString(), EntityView.class);
Assert.assertNotNull(foundView);
Assert.assertEquals(savedView, foundView);
}
@Test
public void testSaveEntityViewWithIdOfDevice() throws Exception {
EntityView view = new EntityView();
view.setEntityId(testDevice.getId());
view.setName("Test entity view");
view.setTenantId(savedTenant.getId());
view.setKeys(new TelemetryEntityView(obj));
EntityView savedView = doPost("/api/entity-view", view, EntityView.class);
Assert.assertNotNull(savedView);
Assert.assertNotNull(savedView.getId());
Assert.assertTrue(savedView.getCreatedTime() > 0);
Assert.assertEquals(savedTenant.getId(), savedView.getTenantId());
Assert.assertNotNull(savedView.getCustomerId());
Assert.assertEquals(NULL_UUID, savedView.getCustomerId().getId());
Assert.assertEquals(savedView.getName(), savedView.getName());
savedView.setName("New test entity view");
doPost("/api/entity-view", savedView, EntityView.class);
EntityView foundEntityView = doGet("/api/entity-view/"
+ savedView.getId().getId().toString(), EntityView.class);
Assert.assertEquals(foundEntityView.getName(), savedView.getName());
}
@Test
public void testDeleteEntityView() throws Exception {
EntityView view = new EntityView();
view.setName("Test entity view");
view.setEntityId(testDevice.getId());
view.setKeys(new TelemetryEntityView((TelemetryEntityView) obj));
EntityView savedView = doPost("/api/entity-view", view, EntityView.class);
doDelete("/api/entity-view/" + savedView.getId().getId().toString())
.andExpect(status().isOk());
doGet("/api/entity-view/" + savedView.getId().getId().toString())
.andExpect(status().isNotFound());
}
}

2
application/src/test/java/org/thingsboard/server/controller/ControllerSqlTestSuite.java

@ -24,7 +24,7 @@ import java.util.Arrays;
@RunWith(ClasspathSuite.class) @RunWith(ClasspathSuite.class)
@ClasspathSuite.ClassnameFilters({ @ClasspathSuite.ClassnameFilters({
"org.thingsboard.server.controller.sql.*SqlTest", "org.thingsboard.server.controller.sql.EntityViewControllerSqlTest",
}) })
public class ControllerSqlTestSuite { public class ControllerSqlTestSuite {

24
application/src/test/java/org/thingsboard/server/controller/nosql/EntityViewControllerNoSqlTest.java

@ -0,0 +1,24 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.controller.nosql;
import org.thingsboard.server.controller.BaseEntityViewControllerTest;
/**
* Created by Victor Basanets on 8/27/2017.
*/
public class EntityViewControllerNoSqlTest extends BaseEntityViewControllerTest {
}

31
application/src/test/java/org/thingsboard/server/controller/sql/EntityViewControllerSqlTest.java

@ -0,0 +1,31 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.controller.sql;
import org.junit.Assert;
import org.junit.Test;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.controller.BaseEntityViewControllerTest;
import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.Arrays;
/**
* Created by Victor Basanets on 8/27/2017.
*/
@DaoSqlTest
public class EntityViewControllerSqlTest extends BaseEntityViewControllerTest {
}

1
common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java

@ -20,4 +20,5 @@ public class CacheConstants {
public static final String RELATIONS_CACHE = "relations"; public static final String RELATIONS_CACHE = "relations";
public static final String DEVICE_CACHE = "devices"; public static final String DEVICE_CACHE = "devices";
public static final String ASSET_CACHE = "assets"; public static final String ASSET_CACHE = "assets";
public static final String ENTITY_VIEW_CACHE = "entityViews";
} }

2
common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java

@ -19,5 +19,5 @@ package org.thingsboard.server.common.data;
* @author Andrew Shvayka * @author Andrew Shvayka
*/ */
public enum EntityType { public enum EntityType {
TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE; TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW
} }

76
common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java

@ -0,0 +1,76 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data;
import lombok.*;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.objects.TelemetryEntityView;
/**
* Created by Victor Basanets on 8/27/2017.
*/
@Data
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class EntityView extends SearchTextBasedWithAdditionalInfo<EntityViewId>
implements HasName, HasTenantId, HasCustomerId {
private static final long serialVersionUID = 5582010124562018986L;
private EntityId entityId;
private TenantId tenantId;
private CustomerId customerId;
private String name;
private TelemetryEntityView keys;
private Long tsBegin;
private Long tsEnd;
public EntityView() {
super();
}
public EntityView(EntityViewId id) {
super(id);
}
public EntityView(EntityView entityView) {
super(entityView);
}
@Override
public String getSearchText() {
return getName() /*What the ...*/;
}
@Override
public CustomerId getCustomerId() {
return customerId;
}
@Override
public String getName() {
return name;
}
@Override
public TenantId getTenantId() {
return tenantId;
}
}

2
common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java

@ -57,6 +57,8 @@ public class EntityIdFactory {
return new RuleChainId(uuid); return new RuleChainId(uuid);
case RULE_NODE: case RULE_NODE:
return new RuleNodeId(uuid); return new RuleNodeId(uuid);
case ENTITY_VIEW:
return new EntityViewId(uuid);
} }
throw new IllegalArgumentException("EntityType " + type + " is not supported!"); throw new IllegalArgumentException("EntityType " + type + " is not supported!");
} }

44
common/data/src/main/java/org/thingsboard/server/common/data/id/EntityViewId.java

@ -0,0 +1,44 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.id;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.thingsboard.server.common.data.EntityType;
import java.util.UUID;
/**
* Created by Victor Basanets on 8/27/2017.
*/
public class EntityViewId extends UUIDBased implements EntityId {
private static final long serialVersionUID = 1L;
@JsonCreator
public EntityViewId(@JsonProperty("id") UUID id) {
super(id);
}
public static EntityViewId fromString(String entityViewID) {
return new EntityViewId(UUID.fromString(entityViewID));
}
@Override
public EntityType getEntityType() {
return EntityType.ENTITY_VIEW;
}
}

52
common/data/src/main/java/org/thingsboard/server/common/data/objects/AttributesEntityView.java

@ -0,0 +1,52 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.objects;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Victor Basanets on 9/05/2017.
*/
@Data
@NoArgsConstructor
public class AttributesEntityView {
private List<String> cs = new ArrayList<>();
private List<String> ss = new ArrayList<>();
private List<String> sh = new ArrayList<>();
public AttributesEntityView(List<String> cs,
List<String> ss,
List<String> sh) {
this.cs = new ArrayList<>(cs);
this.ss = new ArrayList<>(ss);
this.sh = new ArrayList<>(sh);
}
public AttributesEntityView(AttributesEntityView obj) {
this(obj.getCs(), obj.getSs(), obj.getSh());
}
@Override
public String toString() {
return "{cs=" + cs + ", ss=" + ss + ", sh=" + sh + '}';
}
}

48
common/data/src/main/java/org/thingsboard/server/common/data/objects/TelemetryEntityView.java

@ -0,0 +1,48 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.objects;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Victor Basanets on 9/05/2017.
*/
@Data
@NoArgsConstructor
public class TelemetryEntityView {
private List<String> timeseries;
private AttributesEntityView attributes;
public TelemetryEntityView(List<String> timeseries, AttributesEntityView attributes) {
this.timeseries = new ArrayList<>(timeseries);
this.attributes = attributes;
}
public TelemetryEntityView(TelemetryEntityView obj) {
this(obj.getTimeseries(), obj.getAttributes());
}
@Override
public String toString() {
return "{timeseries=" + timeseries + ", attributes=" + attributes + '}';
}
}

88
dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewDao.java

@ -0,0 +1,88 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.entityview;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.dao.Dao;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
/**
* Created by Victor Basanets on 8/28/2017.
*/
public interface EntityViewDao extends Dao<EntityView> {
/**
* Find entity views by tenantId and page link.
*
* @param tenantId the tenantId
* @param pageLink the page link
* @return the list of entity view objects
*/
List<EntityView> findEntityViewByTenantId(UUID tenantId, TextPageLink pageLink);
/**
* Find entity views by tenantId and entity view name.
*
* @param tenantId the tenantId
* @param name the entity view name
* @return the optional entity view object
*/
Optional<EntityView> findEntityViewByTenantIdAndName(UUID tenantId, String name);
/**
* Find entity views by tenantId, entityId and page link.
*
* @param tenantId the tenantId
* @param entityId the entityId
* @param pageLink the page link
* @return the list of entity view objects
*/
List<EntityView> findEntityViewByTenantIdAndEntityId(UUID tenantId,
UUID entityId,
TextPageLink pageLink);
/**
* Find entity views by tenantId, customerId and page link.
*
* @param tenantId the tenantId
* @param customerId the customerId
* @param pageLink the page link
* @return the list of entity view objects
*/
List<EntityView> findEntityViewsByTenantIdAndCustomerId(UUID tenantId,
UUID customerId,
TextPageLink pageLink);
/**
* Find entity views by tenantId, customerId, entityId and page link.
*
* @param tenantId the tenantId
* @param customerId the customerId
* @param entityId the entityId
* @param pageLink the page link
* @return the list of entity view objects
*/
List<EntityView> findEntityViewsByTenantIdAndCustomerIdAndEntityId(UUID tenantId,
UUID customerId,
UUID entityId,
TextPageLink pageLink);
}

60
dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java

@ -0,0 +1,60 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.entityview;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
/**
* Created by Victor Basanets on 8/27/2017.
*/
public interface EntityViewService {
EntityView findEntityViewById(EntityViewId entityViewId);
EntityView findEntityViewByTenantIdAndName(TenantId tenantId, String name);
EntityView saveEntityView(EntityView entityView);
EntityView assignEntityViewToCustomer(EntityViewId entityViewId, CustomerId customerId);
EntityView unassignEntityViewFromCustomer(EntityViewId entityViewId);
void deleteEntityView(EntityViewId entityViewId);
TextPageData<EntityView> findEntityViewByTenantId(TenantId tenantId, TextPageLink pageLink);
TextPageData<EntityView> findEntityViewByTenantIdAndEntityId(TenantId tenantId, EntityId entityId,
TextPageLink pageLink);
void deleteEntityViewByTenantId(TenantId tenantId);
TextPageData<EntityView> findEntityViewsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId,
TextPageLink pageLink);
TextPageData<EntityView> findEntityViewsByTenantIdAndCustomerIdAndEntityId(TenantId tenantId,
CustomerId customerId,
EntityId entityId,
TextPageLink pageLink);
void unassignCustomerEntityViews(TenantId tenantId, CustomerId customerId);
}

276
dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java

@ -0,0 +1,276 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.entityview;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.dao.customer.CustomerDao;
import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.service.PaginatedRemover;
import org.thingsboard.server.dao.tenant.TenantDao;
import java.util.ArrayList;
import java.util.List;
import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID;
import static org.thingsboard.server.dao.service.Validator.validateId;
import static org.thingsboard.server.dao.service.Validator.validatePageLink;
import static org.thingsboard.server.dao.service.Validator.validateString;
/**
* Created by Victor Basanets on 8/28/2017.
*/
@Service
@Slf4j
public class EntityViewServiceImpl extends AbstractEntityService
implements EntityViewService {
public static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";
public static final String INCORRECT_PAGE_LINK = "Incorrect page link ";
public static final String INCORRECT_CUSTOMER_ID = "Incorrect customerId ";
public static final String INCORRECT_ENTITY_VIEW_ID = "Incorrect entityViewId ";
@Autowired
private EntityViewDao entityViewDao;
@Autowired
private TenantDao tenantDao;
@Autowired
private CustomerDao customerDao;
@Override
public EntityView findEntityViewById(EntityViewId entityViewId) {
log.trace("Executing findEntityViewById [{}]", entityViewId);
validateId(entityViewId, INCORRECT_ENTITY_VIEW_ID + entityViewId);
return entityViewDao.findById(entityViewId.getId());
}
@Override
public EntityView findEntityViewByTenantIdAndName(TenantId tenantId, String name) {
log.trace("Executing findEntityViewByTenantIdAndName [{}][{}]", tenantId, name);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
return entityViewDao.findEntityViewByTenantIdAndName(tenantId.getId(), name)
.orElse(null);
}
@Override
public EntityView saveEntityView(EntityView entityView) {
log.trace("Executing save entity view [{}]", entityView);
entityViewValidator.validate(entityView);
return entityViewDao.save(entityView);
}
@Override
public EntityView assignEntityViewToCustomer(EntityViewId entityViewId, CustomerId customerId) {
EntityView entityView = findEntityViewById(entityViewId);
entityView.setCustomerId(customerId);
return saveEntityView(entityView);
}
@Override
public EntityView unassignEntityViewFromCustomer(EntityViewId entityViewId) {
EntityView entityView = findEntityViewById(entityViewId);
entityView.setCustomerId(null);
return saveEntityView(entityView);
}
@Override
public void deleteEntityView(EntityViewId entityViewId) {
log.trace("Executing deleteEntityView [{}]", entityViewId);
validateId(entityViewId, INCORRECT_ENTITY_VIEW_ID + entityViewId);
deleteEntityRelations(entityViewId);
EntityView entityView = entityViewDao.findById(entityViewId.getId());
List<Object> list = new ArrayList<>();
list.add(entityView.getTenantId());
list.add(entityView.getName());
entityViewDao.removeById(entityViewId.getId());
}
@Override
public TextPageData<EntityView> findEntityViewByTenantId(TenantId tenantId, TextPageLink pageLink) {
log.trace("Executing findEntityViewByTenantId, tenantId [{}], pageLink [{}]", tenantId, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink);
List<EntityView> entityViews = entityViewDao.findEntityViewByTenantId(tenantId.getId(), pageLink);
return new TextPageData<>(entityViews, pageLink);
}
@Override
public TextPageData<EntityView> findEntityViewByTenantIdAndEntityId(TenantId tenantId, EntityId entityId,
TextPageLink pageLink) {
log.trace("Executing findEntityViewByTenantIdAndType, tenantId [{}], entityId [{}], pageLink [{}]",
tenantId, entityId, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validateString(entityId.toString(), "Incorrect entityId " + entityId.toString());
validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink);
List<EntityView> entityViews = entityViewDao.findEntityViewByTenantIdAndEntityId(tenantId.getId(),
entityId.getId(), pageLink);
return new TextPageData<>(entityViews, pageLink);
}
@Override
public void deleteEntityViewByTenantId(TenantId tenantId) {
log.trace("Executing deleteEntityViewByTenantId, tenantId [{}]", tenantId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
tenantEntityViewRemover.removeEntities(tenantId);
}
@Override
public TextPageData<EntityView> findEntityViewsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId,
TextPageLink pageLink) {
log.trace("Executing findEntityViewByTenantIdAndCustomerId, tenantId [{}], customerId [{}]," +
" pageLink [{}]", tenantId, customerId, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validateId(customerId, INCORRECT_CUSTOMER_ID + customerId);
validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink);
List<EntityView> entityViews = entityViewDao.findEntityViewsByTenantIdAndCustomerId(tenantId.getId(),
customerId.getId(), pageLink);
return new TextPageData<>(entityViews, pageLink);
}
@Override
public TextPageData<EntityView> findEntityViewsByTenantIdAndCustomerIdAndEntityId(TenantId tenantId,
CustomerId customerId,
EntityId entityId,
TextPageLink pageLink) {
log.trace("Executing findEntityViewsByTenantIdAndCustomerIdAndType, tenantId [{}], customerId [{}]," +
" entityId [{}], pageLink [{}]", tenantId, customerId, entityId, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validateId(customerId, INCORRECT_CUSTOMER_ID + customerId);
validateString(entityId.toString(), "Incorrect entityId " + entityId.toString());
validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink);
List<EntityView> entityViews = entityViewDao.findEntityViewsByTenantIdAndCustomerIdAndEntityId(
tenantId.getId(), customerId.getId(), entityId.getId(), pageLink);
return new TextPageData<>(entityViews, pageLink);
}
@Override
public void unassignCustomerEntityViews(TenantId tenantId, CustomerId customerId) {
log.trace("Executing unassignCustomerEntityViews, tenantId [{}], customerId [{}]", tenantId, customerId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validateId(customerId, INCORRECT_CUSTOMER_ID + customerId);
new CustomerEntityViewsUnAssigner(tenantId).removeEntities(customerId);
}
private DataValidator<EntityView> entityViewValidator =
new DataValidator<EntityView>() {
@Override
protected void validateCreate(EntityView entityView) {
entityViewDao.findEntityViewByTenantIdAndName(entityView.getTenantId().getId(), entityView.getName())
.ifPresent( e -> {
throw new DataValidationException("Entity view with such name already exists!");
});
}
@Override
protected void validateUpdate(EntityView entityView) {
entityViewDao.findEntityViewByTenantIdAndName(entityView.getTenantId().getId(), entityView.getName())
.ifPresent( e -> {
if (!e.getUuidId().equals(entityView.getUuidId())) {
throw new DataValidationException("Entity view with such name already exists!");
}
});
}
@Override
protected void validateDataImpl(EntityView entityView) {
if (StringUtils.isEmpty(entityView.getKeys().toString())) {
throw new DataValidationException("Entity view type should be specified!");
}
if (StringUtils.isEmpty(entityView.getName())) {
throw new DataValidationException("Entity view name should be specified!");
}
if (entityView.getTenantId() == null) {
throw new DataValidationException("Entity view should be assigned to tenant!");
} else {
Tenant tenant = tenantDao.findById(entityView.getTenantId().getId());
if (tenant == null) {
throw new DataValidationException("Entity view is referencing to non-existent tenant!");
}
}
if (entityView.getCustomerId() == null) {
entityView.setCustomerId(new CustomerId(NULL_UUID));
} else if (!entityView.getCustomerId().getId().equals(NULL_UUID)) {
Customer customer = customerDao.findById(entityView.getCustomerId().getId());
if (customer == null) {
throw new DataValidationException("Can't assign entity view to non-existent customer!");
}
if (!customer.getTenantId().getId().equals(entityView.getTenantId().getId())) {
throw new DataValidationException("Can't assign entity view to customer from different tenant!");
}
}
}
};
private PaginatedRemover<TenantId, EntityView> tenantEntityViewRemover =
new PaginatedRemover<TenantId, EntityView>() {
@Override
protected List<EntityView> findEntities(TenantId id, TextPageLink pageLink) {
return entityViewDao.findEntityViewByTenantId(id.getId(), pageLink);
}
@Override
protected void removeEntity(EntityView entity) {
deleteEntityView(new EntityViewId(entity.getUuidId()));
}
};
private class CustomerEntityViewsUnAssigner extends PaginatedRemover<CustomerId, EntityView> {
private TenantId tenantId;
CustomerEntityViewsUnAssigner(TenantId tenantId) {
this.tenantId = tenantId;
}
@Override
protected List<EntityView> findEntities(CustomerId id, TextPageLink pageLink) {
return entityViewDao.findEntityViewsByTenantIdAndCustomerId(tenantId.getId(), id.getId(), pageLink);
}
@Override
protected void removeEntity(EntityView entity) {
unassignEntityViewFromCustomer(new EntityViewId(entity.getUuidId()));
}
}
}

15
dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java

@ -45,6 +45,7 @@ public class ModelConstants {
public static final String SEARCH_TEXT_PROPERTY = "search_text"; public static final String SEARCH_TEXT_PROPERTY = "search_text";
public static final String ADDITIONAL_INFO_PROPERTY = "additional_info"; public static final String ADDITIONAL_INFO_PROPERTY = "additional_info";
public static final String ENTITY_TYPE_PROPERTY = "entity_type"; public static final String ENTITY_TYPE_PROPERTY = "entity_type";
/*public static final String ENTITY_VIEW_ID_PROPERTY = "entity_view_id";*/
public static final String ENTITY_TYPE_COLUMN = ENTITY_TYPE_PROPERTY; public static final String ENTITY_TYPE_COLUMN = ENTITY_TYPE_PROPERTY;
public static final String ENTITY_ID_COLUMN = "entity_id"; public static final String ENTITY_ID_COLUMN = "entity_id";
@ -143,6 +144,20 @@ public class ModelConstants {
public static final String DEVICE_BY_TENANT_AND_NAME_VIEW_NAME = "device_by_tenant_and_name"; public static final String DEVICE_BY_TENANT_AND_NAME_VIEW_NAME = "device_by_tenant_and_name";
public static final String DEVICE_TYPES_BY_TENANT_VIEW_NAME = "device_types_by_tenant"; public static final String DEVICE_TYPES_BY_TENANT_VIEW_NAME = "device_types_by_tenant";
/**
* Cassandra entityView constants.
*/
public static final String ENTITY_VIEW_TABLE_FAMILY_NAME = "entity_views";
public static final String ENTITY_VIEW_ENTITY_ID_PROPERTY = ENTITY_ID_COLUMN;
public static final String ENTITY_VIEW_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY;
public static final String ENTITY_VIEW_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY;
public static final String ENTITY_VIEW_NAME_PROPERTY = DEVICE_NAME_PROPERTY;
public static final String ENTITY_VIEW_TYPE_PROPERTY = "type_entity";
public static final String ENTITY_VIEW_KEYS_PROPERTY = "keys";
public static final String ENTITY_VIEW_TS_BEGIN_PROPERTY = "ts_begin";
public static final String ENTITY_VIEW_TS_END_PROPERTY = "ts_end";
public static final String ENTITY_VIEW_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY;
/** /**
* Cassandra audit log constants. * Cassandra audit log constants.
*/ */

146
dao/src/main/java/org/thingsboard/server/dao/model/nosql/EntityViewEntity.java

@ -0,0 +1,146 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.model.nosql;
import com.datastax.driver.core.utils.UUIDs;
import com.datastax.driver.mapping.annotations.PartitionKey;
import com.datastax.driver.mapping.annotations.Table;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.Type;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.objects.TelemetryEntityView;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import javax.persistence.Column;
import java.io.IOException;
import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_VIEW_TABLE_FAMILY_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY;
/**
* Created by Victor Basanets on 8/31/2017.
*/
@Data
@Table(name = ENTITY_VIEW_TABLE_FAMILY_NAME)
@EqualsAndHashCode
@ToString
public class EntityViewEntity implements SearchTextEntity<EntityView> {
@PartitionKey(value = 0)
@Column(name = ID_PROPERTY)
private UUID id;
@PartitionKey(value = 1)
@Column(name = ModelConstants.ENTITY_VIEW_ENTITY_ID_PROPERTY)
private UUID entityId;
@PartitionKey(value = 2)
@Column(name = ModelConstants.ENTITY_VIEW_TENANT_ID_PROPERTY)
private UUID tenantId;
@PartitionKey(value = 3)
@Column(name = ModelConstants.ENTITY_VIEW_CUSTOMER_ID_PROPERTY)
private UUID customerId;
@Column(name = ModelConstants.ENTITY_VIEW_NAME_PROPERTY)
private String name;
@Type(type = "json")
@Column(name = ModelConstants.ENTITY_VIEW_KEYS_PROPERTY)
private JsonNode keys;
@Column(name = ModelConstants.ENTITY_VIEW_TS_BEGIN_PROPERTY)
private String tsBegin;
@Column(name = ModelConstants.ENTITY_VIEW_TS_END_PROPERTY)
private String tsEnd;
@Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
private String searchText;
@Type(type = "json")
@Column(name = ModelConstants.ENTITY_VIEW_ADDITIONAL_INFO_PROPERTY)
private JsonNode additionalInfo;
public EntityViewEntity() {
super();
}
public EntityViewEntity(EntityView entityView) {
if (entityView.getId() != null) {
this.id = entityView.getId().getId();
}
if (entityView.getEntityId() != null) {
this.entityId = entityView.getEntityId().getId();
}
if (entityView.getTenantId() != null) {
this.tenantId = entityView.getTenantId().getId();
}
if (entityView.getCustomerId() != null) {
this.customerId = entityView.getCustomerId().getId();
}
this.name = entityView.getName();
// try {
// this.keys = entityView.getKeys();
// } catch (IOException e) {
// e.printStackTrace();
// }
this.tsBegin = entityView.getTsBegin() != null ? String.valueOf(entityView.getTsBegin()) : "0";
this.tsEnd = entityView.getTsEnd() != null ? String.valueOf(entityView.getTsEnd()) : "0";
this.searchText = entityView.getSearchText();
this.additionalInfo = entityView.getAdditionalInfo();
}
@Override
public String getSearchTextSource() {
return name;
}
@Override
public EntityView toData() {
EntityView entityView = new EntityView(new EntityViewId(id));
entityView.setCreatedTime(UUIDs.unixTimestamp(id));
if (entityId != null) {
entityView.setEntityId(new DeviceId(entityId));
}
if (tenantId != null) {
entityView.setTenantId(new TenantId(tenantId));
}
if (customerId != null) {
entityView.setCustomerId(new CustomerId(customerId));
}
entityView.setName(name);
// try {
// entityView.setKeys((TelemetryEntityView) entityView.getKeys().toObject(keys));
// } catch (IOException e) {
// e.printStackTrace();
// }
entityView.setTsBegin(Long.parseLong(tsBegin));
entityView.setTsEnd(Long.parseLong(tsEnd));
entityView.setAdditionalInfo(additionalInfo);
return entityView;
}
}

150
dao/src/main/java/org/thingsboard/server/dao/model/sql/EntityViewEntity.java

@ -0,0 +1,150 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.model.sql;
import com.datastax.driver.core.utils.UUIDs;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.id.*;
import org.thingsboard.server.common.data.objects.TelemetryEntityView;
import org.thingsboard.server.dao.model.BaseSqlEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import org.thingsboard.server.dao.util.mapping.JsonStringType;
import javax.persistence.*;
import java.io.IOException;
import static org.thingsboard.server.dao.model.ModelConstants.AUDIT_LOG_ENTITY_TYPE_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_TYPE_PROPERTY;
/**
* Created by Victor Basanets on 8/30/2017.
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = ModelConstants.ENTITY_VIEW_TABLE_FAMILY_NAME)
public class EntityViewEntity extends BaseSqlEntity<EntityView> implements SearchTextEntity<EntityView> {
@Column(name = ModelConstants.ENTITY_VIEW_ENTITY_ID_PROPERTY)
private String entityId;
@Enumerated(EnumType.STRING)
@Column(name = ENTITY_TYPE_PROPERTY)
private EntityType entityType;
@Column(name = ModelConstants.ENTITY_VIEW_TENANT_ID_PROPERTY)
private String tenantId;
@Column(name = ModelConstants.ENTITY_VIEW_CUSTOMER_ID_PROPERTY)
private String customerId;
@Column(name = ModelConstants.ENTITY_VIEW_NAME_PROPERTY)
private String name;
@Column(name = ModelConstants.ENTITY_VIEW_KEYS_PROPERTY)
private String keys;
@Column(name = ModelConstants.ENTITY_VIEW_TS_BEGIN_PROPERTY)
private String tsBegin;
@Column(name = ModelConstants.ENTITY_VIEW_TS_END_PROPERTY)
private String tsEnd;
@Column(name = ModelConstants.SEARCH_TEXT_PROPERTY)
private String searchText;
@Type(type = "json")
@Column(name = ModelConstants.ENTITY_VIEW_ADDITIONAL_INFO_PROPERTY)
private JsonNode additionalInfo;
private static final ObjectMapper mapper = new ObjectMapper();
public EntityViewEntity() {
super();
}
public EntityViewEntity(EntityView entityView) {
if (entityView.getId() != null) {
this.setId(entityView.getId().getId());
}
if (entityView.getEntityId() != null) {
this.entityId = toString(entityView.getEntityId().getId());
this.entityType = entityView.getEntityId().getEntityType();
}
if (entityView.getTenantId() != null) {
this.tenantId = toString(entityView.getTenantId().getId());
}
if (entityView.getCustomerId() != null) {
this.customerId = toString(entityView.getCustomerId().getId());
}
this.name = entityView.getName();
try {
this.keys = mapper.writeValueAsString(entityView.getKeys());
} catch (IOException e) {
e.printStackTrace();
}
this.tsBegin = entityView.getTsBegin() != null ? String.valueOf(entityView.getTsBegin()) : "0";
this.tsEnd = entityView.getTsEnd() != null ? String.valueOf(entityView.getTsEnd()) : "0";
this.searchText = entityView.getSearchText();
this.additionalInfo = entityView.getAdditionalInfo();
}
@Override
public String getSearchTextSource() {
return name;
}
@Override
public void setSearchText(String searchText) {
this.searchText = searchText;
}
@Override
public EntityView toData() {
EntityView entityView = new EntityView(new EntityViewId(getId()));
entityView.setCreatedTime(UUIDs.unixTimestamp(getId()));
if (entityId != null) {
entityView.setEntityId(EntityIdFactory.getByTypeAndId(entityType.name(), toUUID(entityId).toString()));
}
if (tenantId != null) {
entityView.setTenantId(new TenantId(toUUID(tenantId)));
}
if (customerId != null) {
entityView.setCustomerId(new CustomerId(toUUID(customerId)));
}
entityView.setName(name);
try {
entityView.setKeys(mapper.readValue(keys, TelemetryEntityView.class));
} catch (IOException e) {
e.printStackTrace();
}
entityView.setTsBegin(Long.parseLong(tsBegin));
entityView.setTsEnd(Long.parseLong(tsEnd));
entityView.setAdditionalInfo(additionalInfo);
return entityView;
}
}

81
dao/src/main/java/org/thingsboard/server/dao/sql/entityview/EntityViewRepository.java

@ -0,0 +1,81 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.sql.entityview;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.dao.model.sql.EntityViewEntity;
import org.thingsboard.server.dao.util.SqlDao;
import java.util.List;
/**
* Created by Victor Basanets on 8/31/2017.
*/
@SqlDao
public interface EntityViewRepository extends CrudRepository<EntityViewEntity, String> {
@Query("SELECT e FROM EntityViewEntity e WHERE e.tenantId = :tenantId " +
"AND LOWER(e.searchText) LIKE LOWER(CONCAT(:textSearch, '%')) " +
"AND e.id > :idOffset ORDER BY e.id")
List<EntityViewEntity> findByTenantId(@Param("tenantId") String tenantId,
@Param("textSearch") String textSearch,
@Param("idOffset") String idOffset,
Pageable pageable);
@Query("SELECT e FROM EntityViewEntity e WHERE e.tenantId = :tenantId " +
"AND e.entityId = :entityId " +
"AND LOWER(e.searchText) LIKE LOWER(CONCAT(:textSearch, '%')) " +
"AND e.id > :idOffset ORDER BY e.id")
List<EntityViewEntity> findByTenantIdAndEntityId(@Param("tenantId") String tenantId,
@Param("entityId") String entityId,
@Param("textSearch") String textSearch,
@Param("idOffset") String idOffset,
Pageable pageable);
@Query("SELECT e FROM EntityViewEntity e WHERE e.tenantId = :tenantId " +
"AND e.customerId = :customerId " +
"AND LOWER(e.searchText) LIKE LOWER(CONCAT(:searchText, '%')) " +
"AND e.id > :idOffset ORDER BY e.id")
List<EntityViewEntity> findByTenantIdAndCustomerId(@Param("tenantId") String tenantId,
@Param("customerId") String customerId,
@Param("searchText") String searchText,
@Param("idOffset") String idOffset,
Pageable pageable);
@Query("SELECT e FROM EntityViewEntity e WHERE e.tenantId = :tenantId " +
"AND e.customerId = :customerId " +
"AND e.entityId = :entityId " +
"AND LOWER(e.searchText) LIKE LOWER(CONCAT(:textSearch, '%')) " +
"AND e.id > :idOffset ORDER BY e.id")
List<EntityViewEntity> findByTenantIdAndCustomerIdAndEntityId(@Param("tenantId") String tenantId,
@Param("customerId") String customerId,
@Param("entityId") String entityId,
@Param("textSearch") String textSearch,
@Param("idOffset") String idOffset,
Pageable pageable);
EntityViewEntity findByTenantIdAndName(String tenantId, String name);
List<EntityViewEntity> findAllByTenantIdAndCustomerIdAndIdIn(String tenantId,
String customerId,
List<String> entityViewsIds);
List<EntityViewEntity> findAllByTenantIdAndIdIn(String tenantId, List<String> entityViewsIds);
}

118
dao/src/main/java/org/thingsboard/server/dao/sql/entityview/JpaEntityViewDao.java

@ -0,0 +1,118 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.sql.entityview;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.entityview.EntityViewDao;
import org.thingsboard.server.dao.model.sql.EntityViewEntity;
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
import org.thingsboard.server.dao.util.SqlDao;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import static org.thingsboard.server.common.data.UUIDConverter.fromTimeUUID;
import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID_STR;
/**
* Created by Victor Basanets on 8/31/2017.
*/
@Component
@SqlDao
public class JpaEntityViewDao extends JpaAbstractSearchTextDao<EntityViewEntity, EntityView>
implements EntityViewDao {
@Autowired
EntityViewRepository entityViewRepository;
@Override
protected Class<EntityViewEntity> getEntityClass() {
return EntityViewEntity.class;
}
@Override
protected CrudRepository<EntityViewEntity, String> getCrudRepository() {
return entityViewRepository;
}
@Override
public List<EntityView> findEntityViewByTenantId(UUID tenantId, TextPageLink pageLink) {
return DaoUtil.convertDataList(
entityViewRepository.findByTenantId(
fromTimeUUID(tenantId),
Objects.toString(pageLink.getTextSearch(), ""),
pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()),
new PageRequest(0, pageLink.getLimit())));
}
@Override
public Optional<EntityView> findEntityViewByTenantIdAndName(UUID tenantId, String name) {
return Optional.ofNullable(
DaoUtil.getData(entityViewRepository.findByTenantIdAndName(fromTimeUUID(tenantId), name)));
}
@Override
public List<EntityView> findEntityViewByTenantIdAndEntityId(UUID tenantId,
UUID entityId,
TextPageLink pageLink) {
return DaoUtil.convertDataList(
entityViewRepository.findByTenantIdAndEntityId(
fromTimeUUID(tenantId),
fromTimeUUID(entityId),
Objects.toString(pageLink.getTextSearch(), ""),
pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()),
new PageRequest(0, pageLink.getLimit())));
}
@Override
public List<EntityView> findEntityViewsByTenantIdAndCustomerId(UUID tenantId,
UUID customerId,
TextPageLink pageLink) {
return DaoUtil.convertDataList(
entityViewRepository.findByTenantIdAndCustomerId(
fromTimeUUID(tenantId),
fromTimeUUID(customerId),
Objects.toString(pageLink, ""),
pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()),
new PageRequest(0, pageLink.getLimit())
));
}
@Override
public List<EntityView> findEntityViewsByTenantIdAndCustomerIdAndEntityId(UUID tenantId,
UUID customerId,
UUID entityId,
TextPageLink pageLink) {
return DaoUtil.convertDataList(
entityViewRepository.findByTenantIdAndCustomerIdAndEntityId(
fromTimeUUID(tenantId),
fromTimeUUID(customerId),
fromTimeUUID(entityId),
Objects.toString(pageLink, ""),
pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()),
new PageRequest(0, pageLink.getLimit())
));
}
}

42
dao/src/main/resources/cassandra/schema.cql

@ -638,3 +638,45 @@ CREATE TABLE IF NOT EXISTS thingsboard.rule_node (
additional_info text, additional_info text,
PRIMARY KEY (id) PRIMARY KEY (id)
); );
CREATE TABLE IF NOT EXISTS thingsboard.entity_views (
id timeuuid,
entity_id timeuuid,
tenant_id timeuuid,
customer_id timeuuid,
name text,
keys text,
ts_begin bigint,
ts_end bigint,
search_text text,
additional_info text,
PRIMARY KEY (id, entity_id, tenant_id, customer_id)
);
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_name AS
SELECT *
from thingsboard.entity_views
WHERE entity_id IS NOT NULL AND tenant_id IS NOT NULL AND customer_id IS NOT NULL AND keys IS NOT NULL AND ts_begin IS NOT NULL AND ts_end IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL
PRIMARY KEY (tenant_id, name, id, entity_id, customer_id)
WITH CLUSTERING ORDER BY (name ASC, id DESC, entity_id DESC, customer_id DESC);
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_entity AS
SELECT *
from thingsboard.entity_views
WHERE entity_id IS NOT NULL AND tenant_id IS NOT NULL AND customer_id IS NOT NULL AND keys IS NOT NULL AND ts_begin IS NOT NULL AND ts_end IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL
PRIMARY KEY (tenant_id, entity_id, id, customer_id, name)
WITH CLUSTERING ORDER BY (entity_id ASC, customer_id ASC, id DESC, name DESC);
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer AS
SELECT *
from thingsboard.entity_views
WHERE entity_id IS NOT NULL AND tenant_id IS NOT NULL AND customer_id IS NOT NULL AND keys IS NOT NULL AND ts_begin IS NOT NULL AND ts_end IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL
PRIMARY KEY (tenant_id, customer_id, id, entity_id, name)
WITH CLUSTERING ORDER BY (customer_id ASC, id DESC, entity_id DESC, name DESC);
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_customer_and_entity AS
SELECT *
from thingsboard.entity_views
WHERE entity_id IS NOT NULL AND tenant_id IS NOT NULL AND customer_id IS NOT NULL AND keys IS NOT NULL AND ts_begin IS NOT NULL AND ts_end IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL
PRIMARY KEY (tenant_id, customer_id, entity_id, id, name)
WITH CLUSTERING ORDER BY (customer_id ASC, entity_id DESC, id DESC, name DESC);

14
dao/src/main/resources/sql/schema.sql

@ -251,3 +251,17 @@ CREATE TABLE IF NOT EXISTS rule_node (
debug_mode boolean, debug_mode boolean,
search_text varchar(255) search_text varchar(255)
); );
CREATE TABLE IF NOT EXISTS entity_views (
id varchar(31) NOT NULL CONSTRAINT entity_view_pkey PRIMARY KEY,
entity_id varchar(31),
entity_type varchar(255),
tenant_id varchar(31),
customer_id varchar(31),
name varchar(255),
keys varchar(255),
ts_begin varchar(255),
ts_end varchar(255),
search_text varchar(255),
additional_info varchar
);

3
dao/src/test/resources/sql/drop-all-tables.sql

@ -18,4 +18,5 @@ DROP TABLE IF EXISTS user_credentials;
DROP TABLE IF EXISTS widget_type; DROP TABLE IF EXISTS widget_type;
DROP TABLE IF EXISTS widgets_bundle; DROP TABLE IF EXISTS widgets_bundle;
DROP TABLE IF EXISTS rule_node; DROP TABLE IF EXISTS rule_node;
DROP TABLE IF EXISTS rule_chain; DROP TABLE IF EXISTS rule_chain;
DROP TABLE IF EXISTS entity_views;
Loading…
Cancel
Save