Commit 4b67d428d71c7870ea245185c5f297a206e782e0

Authored by Andrew Shvayka
Committed by GitHub
2 parents 30c0f42f 47361b01

Merge pull request #189 from volodymyr-babak/fix/device-name-type-cache-fix

Added deviceType and deviceName update.
Showing 22 changed files with 88 additions and 49 deletions
  1 +-Xmx4096m -Xms1024m
\ No newline at end of file
... ...
... ... @@ -28,6 +28,7 @@ import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
28 28 import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
29 29 import org.thingsboard.server.extensions.api.device.DeviceAttributesEventNotificationMsg;
30 30 import org.thingsboard.server.extensions.api.device.DeviceCredentialsUpdateNotificationMsg;
  31 +import org.thingsboard.server.extensions.api.device.DeviceNameOrTypeUpdateMsg;
31 32 import org.thingsboard.server.extensions.api.device.ToDeviceActorNotificationMsg;
32 33 import org.thingsboard.server.extensions.api.plugins.msg.*;
33 34
... ... @@ -60,7 +61,9 @@ public class DeviceActor extends ContextAwareActor {
60 61 } else if (msg instanceof ToDeviceRpcRequestPluginMsg) {
61 62 processor.processRpcRequest(context(), (ToDeviceRpcRequestPluginMsg) msg);
62 63 } else if (msg instanceof DeviceCredentialsUpdateNotificationMsg){
63   - processor.processCredentialsUpdate(context(), (DeviceCredentialsUpdateNotificationMsg) msg);
  64 + processor.processCredentialsUpdate();
  65 + } else if (msg instanceof DeviceNameOrTypeUpdateMsg){
  66 + processor.processNameOrTypeUpdate((DeviceNameOrTypeUpdateMsg) msg);
64 67 }
65 68 } else if (msg instanceof TimeoutMsg) {
66 69 processor.processTimeout(context(), (TimeoutMsg) msg);
... ...
... ... @@ -37,10 +37,7 @@ import org.thingsboard.server.common.msg.session.FromDeviceMsg;
37 37 import org.thingsboard.server.common.msg.session.MsgType;
38 38 import org.thingsboard.server.common.msg.session.SessionType;
39 39 import org.thingsboard.server.common.msg.session.ToDeviceMsg;
40   -import org.thingsboard.server.extensions.api.device.DeviceAttributes;
41   -import org.thingsboard.server.extensions.api.device.DeviceAttributesEventNotificationMsg;
42   -import org.thingsboard.server.extensions.api.device.DeviceCredentialsUpdateNotificationMsg;
43   -import org.thingsboard.server.extensions.api.device.DeviceMetaData;
  40 +import org.thingsboard.server.extensions.api.device.*;
44 41 import org.thingsboard.server.extensions.api.plugins.msg.FromDeviceRpcResponse;
45 42 import org.thingsboard.server.extensions.api.plugins.msg.RpcError;
46 43 import org.thingsboard.server.extensions.api.plugins.msg.TimeoutIntMsg;
... ... @@ -372,11 +369,16 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
372 369 }
373 370 }
374 371
375   - public void processCredentialsUpdate(ActorContext context, DeviceCredentialsUpdateNotificationMsg msg) {
  372 + public void processCredentialsUpdate() {
376 373 sessions.forEach((k, v) -> {
377 374 sendMsgToSessionActor(new BasicToDeviceSessionActorMsg(new SessionCloseNotification(), k), v.getServer());
378 375 });
379 376 attributeSubscriptions.clear();
380 377 rpcSubscriptions.clear();
381 378 }
  379 +
  380 + public void processNameOrTypeUpdate(DeviceNameOrTypeUpdateMsg msg) {
  381 + this.deviceName = msg.getDeviceName();
  382 + this.deviceType = msg.getDeviceType();
  383 + }
382 384 }
... ...
... ... @@ -31,4 +31,6 @@ public interface ActorService extends SessionMsgProcessor, WebSocketMsgProcessor
31 31 void onRuleStateChange(TenantId tenantId, RuleId ruleId, ComponentLifecycleEvent state);
32 32
33 33 void onCredentialsUpdate(TenantId tenantId, DeviceId deviceId);
  34 +
  35 + void onDeviceNameOrTypeUpdate(TenantId tenantId, DeviceId deviceId, String deviceName, String deviceType);
34 36 }
... ...
... ... @@ -20,8 +20,6 @@ import akka.actor.ActorSystem;
20 20 import akka.actor.Props;
21 21 import akka.actor.Terminated;
22 22 import lombok.extern.slf4j.Slf4j;
23   -import org.slf4j.Logger;
24   -import org.slf4j.LoggerFactory;
25 23 import org.springframework.beans.factory.annotation.Autowired;
26 24 import org.springframework.stereotype.Service;
27 25 import org.thingsboard.server.actors.ActorSystemContext;
... ... @@ -42,13 +40,13 @@ import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
42 40 import org.thingsboard.server.common.msg.cluster.ServerAddress;
43 41 import org.thingsboard.server.common.msg.cluster.ToAllNodesMsg;
44 42 import org.thingsboard.server.common.msg.core.ToDeviceSessionActorMsg;
  43 +import org.thingsboard.server.extensions.api.device.DeviceNameOrTypeUpdateMsg;
45 44 import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
46 45 import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
47 46 import org.thingsboard.server.extensions.api.device.DeviceCredentialsUpdateNotificationMsg;
48 47 import org.thingsboard.server.extensions.api.device.ToDeviceActorNotificationMsg;
49 48 import org.thingsboard.server.extensions.api.plugins.msg.ToPluginActorMsg;
50 49 import org.thingsboard.server.extensions.api.plugins.rest.PluginRestMsg;
51   -import org.thingsboard.server.extensions.api.plugins.rpc.PluginRpcMsg;
52 50 import org.thingsboard.server.extensions.api.plugins.ws.msg.PluginWebsocketMsg;
53 51 import org.thingsboard.server.service.cluster.discovery.DiscoveryService;
54 52 import org.thingsboard.server.service.cluster.discovery.ServerInstance;
... ... @@ -238,6 +236,18 @@ public class DefaultActorService implements ActorService {
238 236 }
239 237 }
240 238
  239 + @Override
  240 + public void onDeviceNameOrTypeUpdate(TenantId tenantId, DeviceId deviceId, String deviceName, String deviceType) {
  241 + log.trace("[{}] Processing onDeviceNameOrTypeUpdate event, deviceName: {}, deviceType: {}", deviceId, deviceName, deviceType);
  242 + DeviceNameOrTypeUpdateMsg msg = new DeviceNameOrTypeUpdateMsg(tenantId, deviceId, deviceName, deviceType);
  243 + Optional<ServerAddress> address = actorContext.getRoutingService().resolveById(deviceId);
  244 + if (address.isPresent()) {
  245 + rpcService.tell(address.get(), msg);
  246 + } else {
  247 + onMsg(msg);
  248 + }
  249 + }
  250 +
241 251 public void broadcast(ToAllNodesMsg msg) {
242 252 rpcService.broadcast(msg);
243 253 appActor.tell(msg, ActorRef.noSender());
... ...
... ... @@ -61,7 +61,14 @@ public class DeviceController extends BaseController {
61 61 public Device saveDevice(@RequestBody Device device) throws ThingsboardException {
62 62 try {
63 63 device.setTenantId(getCurrentUser().getTenantId());
64   - return checkNotNull(deviceService.saveDevice(device));
  64 + Device savedDevice = checkNotNull(deviceService.saveDevice(device));
  65 + actorService
  66 + .onDeviceNameOrTypeUpdate(
  67 + savedDevice.getTenantId(),
  68 + savedDevice.getId(),
  69 + savedDevice.getName(),
  70 + savedDevice.getType());
  71 + return savedDevice;
65 72 } catch (Exception e) {
66 73 throw handleException(e);
67 74 }
... ... @@ -174,7 +181,7 @@ public class DeviceController extends BaseController {
174 181 try {
175 182 TenantId tenantId = getCurrentUser().getTenantId();
176 183 TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
177   - if (type != null && type.trim().length()>0) {
  184 + if (type != null && type.trim().length() > 0) {
178 185 return checkNotNull(deviceService.findDevicesByTenantIdAndType(tenantId, type, pageLink));
179 186 } else {
180 187 return checkNotNull(deviceService.findDevicesByTenantId(tenantId, pageLink));
... ... @@ -213,7 +220,7 @@ public class DeviceController extends BaseController {
213 220 CustomerId customerId = new CustomerId(toUUID(strCustomerId));
214 221 checkCustomerId(customerId);
215 222 TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
216   - if (type != null && type.trim().length()>0) {
  223 + if (type != null && type.trim().length() > 0) {
217 224 return checkNotNull(deviceService.findDevicesByTenantIdAndCustomerIdAndType(tenantId, customerId, type, pageLink));
218 225 } else {
219 226 return checkNotNull(deviceService.findDevicesByTenantIdAndCustomerId(tenantId, customerId, pageLink));
... ...
... ... @@ -105,9 +105,11 @@ coap:
105 105 adaptor: "${COAP_ADAPTOR_NAME:JsonCoapAdaptor}"
106 106 timeout: "${COAP_TIMEOUT:10000}"
107 107
  108 +database:
  109 + type: "${DATABASE_TYPE:cassandra}" # cassandra OR postgres
  110 +
108 111 # Cassandra driver configuration parameters
109 112 cassandra:
110   - enabled: "${CASSANDRA_ENABLED:false}"
111 113 # Thingsboard cluster name
112 114 cluster_name: "${CASSANDRA_CLUSTER_NAME:Thingsboard Cluster}"
113 115 # Thingsboard keyspace name
... ... @@ -202,7 +204,7 @@ updates:
202 204 # Enable/disable updates checking.
203 205 enabled: "${UPDATES_ENABLED:true}"
204 206
205   - # spring CORS configuration
  207 +# spring CORS configuration
206 208 spring.mvc.cors:
207 209 mappings:
208 210 # Intercept path
... ... @@ -225,8 +227,6 @@ spring.mvc.cors:
225 227 allow-credentials: "true"
226 228
227 229 # SQL DAO Configuration
228   -sql:
229   - enabled: "${SQL_ENABLED:true}"
230 230
231 231 spring:
232 232 data:
... ...
... ... @@ -34,6 +34,6 @@ public class ControllerTestSuite {
34 34 Arrays.asList(
35 35 new ClassPathCQLDataSet("cassandra/schema.cql", false, false),
36 36 new ClassPathCQLDataSet("cassandra/system-data.cql", false, false),
37   - new ClassPathCQLDataSet("system-test.cql", false, false)),
  37 + new ClassPathCQLDataSet("cassandra/system-test.cql", false, false)),
38 38 "cassandra-test.yaml", 30000l);
39 39 }
... ...
... ... @@ -18,19 +18,15 @@ package org.thingsboard.server.dao.sql;
18 18 import com.datastax.driver.core.utils.UUIDs;
19 19 import com.google.common.collect.Lists;
20 20 import com.google.common.util.concurrent.ListenableFuture;
21   -import com.google.common.util.concurrent.ListeningExecutorService;
22   -import com.google.common.util.concurrent.MoreExecutors;
23 21 import lombok.extern.slf4j.Slf4j;
24 22 import org.springframework.data.repository.CrudRepository;
25 23 import org.springframework.transaction.annotation.Transactional;
26 24 import org.thingsboard.server.dao.Dao;
27 25 import org.thingsboard.server.dao.DaoUtil;
28 26 import org.thingsboard.server.dao.model.BaseEntity;
29   -import org.thingsboard.server.dao.model.SearchTextEntity;
30 27
31 28 import java.util.List;
32 29 import java.util.UUID;
33   -import java.util.concurrent.Executors;
34 30
35 31 import static org.springframework.transaction.annotation.Propagation.REQUIRES_NEW;
36 32
... ... @@ -46,9 +42,7 @@ public abstract class JpaAbstractDao<E extends BaseEntity<D>, D>
46 42
47 43 protected abstract CrudRepository<E, UUID> getCrudRepository();
48 44
49   - protected boolean isSearchTextDao() {
50   - return false;
51   - }
  45 + protected void setSearchText(E entity) {}
52 46
53 47 @Override
54 48 @Transactional(propagation = REQUIRES_NEW)
... ... @@ -60,9 +54,7 @@ public abstract class JpaAbstractDao<E extends BaseEntity<D>, D>
60 54 log.error("Can't create entity for domain object {}", domain, e);
61 55 throw new IllegalArgumentException("Can't create entity for domain object {" + domain + "}", e);
62 56 }
63   - if (isSearchTextDao()) {
64   - ((SearchTextEntity) entity).setSearchText(((SearchTextEntity) entity).getSearchTextSource().toLowerCase());
65   - }
  57 + setSearchText(entity);
66 58 log.debug("Saving entity {}", entity);
67 59 if (entity.getId() == null) {
68 60 entity.setId(UUIDs.timeBased());
... ...
... ... @@ -16,6 +16,7 @@
16 16 package org.thingsboard.server.dao.sql;
17 17
18 18 import org.thingsboard.server.dao.model.BaseEntity;
  19 +import org.thingsboard.server.dao.model.SearchTextEntity;
19 20
20 21 /**
21 22 * Created by Valerii Sosliuk on 5/6/2017.
... ... @@ -23,7 +24,7 @@ import org.thingsboard.server.dao.model.BaseEntity;
23 24 public abstract class JpaAbstractSearchTextDao <E extends BaseEntity<D>, D> extends JpaAbstractDao<E, D> {
24 25
25 26 @Override
26   - protected boolean isSearchTextDao() {
27   - return true;
  27 + protected void setSearchText(E entity) {
  28 + ((SearchTextEntity) entity).setSearchText(((SearchTextEntity) entity).getSearchTextSource().toLowerCase());
28 29 }
29 30 }
... ...
... ... @@ -16,16 +16,14 @@
16 16 package org.thingsboard.server.dao.sql.user;
17 17
18 18 import org.springframework.beans.factory.annotation.Autowired;
19   -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
20 19 import org.springframework.data.repository.CrudRepository;
21 20 import org.springframework.stereotype.Component;
22   -import org.thingsboard.server.common.data.User;
23 21 import org.thingsboard.server.common.data.security.UserCredentials;
24 22 import org.thingsboard.server.dao.DaoUtil;
25   -import org.thingsboard.server.dao.model.ModelConstants;
26 23 import org.thingsboard.server.dao.model.sql.UserCredentialsEntity;
27 24 import org.thingsboard.server.dao.sql.JpaAbstractDao;
28 25 import org.thingsboard.server.dao.user.UserCredentialsDao;
  26 +import org.thingsboard.server.dao.util.SqlDao;
29 27
30 28 import java.util.UUID;
31 29
... ... @@ -33,7 +31,7 @@ import java.util.UUID;
33 31 * Created by Valerii Sosliuk on 4/22/2017.
34 32 */
35 33 @Component
36   -@ConditionalOnProperty(prefix="sql", value="enabled",havingValue = "true", matchIfMissing = false)
  34 +@SqlDao
37 35 public class JpaUserCredentialsDao extends JpaAbstractDao<UserCredentialsEntity, UserCredentials> implements UserCredentialsDao {
38 36
39 37 @Autowired
... ...
... ... @@ -15,16 +15,16 @@
15 15 */
16 16 package org.thingsboard.server.dao.sql.user;
17 17
18   -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
19 18 import org.springframework.data.repository.CrudRepository;
20 19 import org.thingsboard.server.dao.model.sql.UserCredentialsEntity;
  20 +import org.thingsboard.server.dao.util.SqlDao;
21 21
22 22 import java.util.UUID;
23 23
24 24 /**
25 25 * Created by Valerii Sosliuk on 4/22/2017.
26 26 */
27   -@ConditionalOnProperty(prefix="sql", value="enabled",havingValue = "true", matchIfMissing = false)
  27 +@SqlDao
28 28 public interface UserCredentialsRepository extends CrudRepository<UserCredentialsEntity, UUID> {
29 29
30 30 UserCredentialsEntity findByUserId(UUID userId);
... ...
... ... @@ -17,6 +17,6 @@ package org.thingsboard.server.dao.util;
17 17
18 18 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
19 19
20   -@ConditionalOnProperty(prefix = "cassandra", value = "enabled", havingValue = "true")
  20 +@ConditionalOnProperty(prefix = "database", value = "type", havingValue = "cassandra")
21 21 public @interface NoSqlDao {
22 22 }
... ...
... ... @@ -17,6 +17,6 @@ package org.thingsboard.server.dao.util;
17 17
18 18 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
19 19
20   -@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true")
  20 +@ConditionalOnProperty(prefix = "database", value = "type", havingValue = "postgres")
21 21 public @interface SqlDao {
22 22 }
... ...
... ... @@ -24,8 +24,7 @@ import java.util.Arrays;
24 24
25 25 @RunWith(ClasspathSuite.class)
26 26 @ClassnameFilters({
27   -// "org.thingsboard.server.dao.sql.alarm.",
28   - "org.thingsboard.server.dao.sql.*Test",
  27 + "org.thingsboard.server.dao.sql.*Test"
29 28 })
30 29 public class JpaDaoTestSuite {
31 30
... ...
... ... @@ -34,7 +34,7 @@ public class NoSqlDaoServiceTestSuite {
34 34 new CustomCassandraCQLUnit(
35 35 Arrays.asList(new ClassPathCQLDataSet("cassandra/schema.cql", false, false),
36 36 new ClassPathCQLDataSet("cassandra/system-data.cql", false, false),
37   - new ClassPathCQLDataSet("system-test.cql", false, false)),
  37 + new ClassPathCQLDataSet("cassandra/system-test.cql", false, false)),
38 38 "cassandra-test.yaml", 30000L);
39 39
40 40 }
... ...
... ... @@ -30,7 +30,7 @@ public class SqlDaoServiceTestSuite {
30 30
31 31 @ClassRule
32 32 public static CustomPostgresUnit postgresUnit = new CustomPostgresUnit(
33   - Arrays.asList("postgres/schema.sql", "postgres/system-data.sql", "system-test.sql"),
  33 + Arrays.asList("postgres/schema.sql", "postgres/system-data.sql", "postgres/system-test.sql"),
34 34 "postgres-embedded-test.properties");
35 35
36 36 }
... ...
dao/src/test/resources/cassandra/system-test.cql renamed from dao/src/test/resources/system-test.cql
1   -sql.enabled=false
2   -cassandra.enabled=true
\ No newline at end of file
  1 +database.type=cassandra
\ No newline at end of file
... ...
dao/src/test/resources/postgres/system-test.sql renamed from dao/src/test/resources/system-test.sql
1   -cassandra.enabled=false
2   -sql.enabled=true
  1 +database.type=postgres
3 2
4 3 spring.jpa.show-sql=false
5 4 spring.jpa.hibernate.ddl-auto=validate
... ... @@ -7,7 +6,3 @@ spring.jpa.hibernate.ddl-auto=validate
7 6 spring.datasource.url=jdbc:postgresql://localhost:5433/thingsboard-test
8 7 spring.datasource.username=postgres
9 8 spring.datasource.password=postgres
10   -
11   -#spring.datasource.url=jdbc:h2:mem:test;MODE=PostgreSQL
12   -#spring.datasource.schema=classpath:postgres/schema.sql
13   -#spring.datasource.data=classpath:postgres/system-data.sql;classpath:system-test.sql
\ No newline at end of file
... ...
  1 +/**
  2 + * Copyright © 2016-2017 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.extensions.api.device;
  17 +
  18 +import lombok.AllArgsConstructor;
  19 +import lombok.Data;
  20 +import org.thingsboard.server.common.data.id.DeviceId;
  21 +import org.thingsboard.server.common.data.id.TenantId;
  22 +
  23 +@Data
  24 +@AllArgsConstructor
  25 +public class DeviceNameOrTypeUpdateMsg implements ToDeviceActorNotificationMsg {
  26 + private final TenantId tenantId;
  27 + private final DeviceId deviceId;
  28 + private final String deviceName;
  29 + private final String deviceType;
  30 +}
... ...