Merge branch 'master' into feature/TB-65
This commit is contained in:
		
						commit
						e11dc50a7f
					
				
							
								
								
									
										1
									
								
								.mvn/jvm.config
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.mvn/jvm.config
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
-Xmx4096m -Xms1024m
 | 
			
		||||
@ -28,6 +28,7 @@ import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
 | 
			
		||||
import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceAttributesEventNotificationMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceCredentialsUpdateNotificationMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceNameOrTypeUpdateMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.ToDeviceActorNotificationMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.plugins.msg.*;
 | 
			
		||||
 | 
			
		||||
@ -60,7 +61,9 @@ public class DeviceActor extends ContextAwareActor {
 | 
			
		||||
            } else if (msg instanceof ToDeviceRpcRequestPluginMsg) {
 | 
			
		||||
                processor.processRpcRequest(context(), (ToDeviceRpcRequestPluginMsg) msg);
 | 
			
		||||
            } else if (msg instanceof DeviceCredentialsUpdateNotificationMsg){
 | 
			
		||||
                processor.processCredentialsUpdate(context(), (DeviceCredentialsUpdateNotificationMsg) msg);
 | 
			
		||||
                processor.processCredentialsUpdate();
 | 
			
		||||
            } else if (msg instanceof DeviceNameOrTypeUpdateMsg){
 | 
			
		||||
                processor.processNameOrTypeUpdate((DeviceNameOrTypeUpdateMsg) msg);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (msg instanceof TimeoutMsg) {
 | 
			
		||||
            processor.processTimeout(context(), (TimeoutMsg) msg);
 | 
			
		||||
 | 
			
		||||
@ -37,10 +37,7 @@ import org.thingsboard.server.common.msg.session.FromDeviceMsg;
 | 
			
		||||
import org.thingsboard.server.common.msg.session.MsgType;
 | 
			
		||||
import org.thingsboard.server.common.msg.session.SessionType;
 | 
			
		||||
import org.thingsboard.server.common.msg.session.ToDeviceMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceAttributes;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceAttributesEventNotificationMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceCredentialsUpdateNotificationMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceMetaData;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.*;
 | 
			
		||||
import org.thingsboard.server.extensions.api.plugins.msg.FromDeviceRpcResponse;
 | 
			
		||||
import org.thingsboard.server.extensions.api.plugins.msg.RpcError;
 | 
			
		||||
import org.thingsboard.server.extensions.api.plugins.msg.TimeoutIntMsg;
 | 
			
		||||
@ -372,11 +369,16 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void processCredentialsUpdate(ActorContext context, DeviceCredentialsUpdateNotificationMsg msg) {
 | 
			
		||||
    public void processCredentialsUpdate() {
 | 
			
		||||
        sessions.forEach((k, v) -> {
 | 
			
		||||
            sendMsgToSessionActor(new BasicToDeviceSessionActorMsg(new SessionCloseNotification(), k), v.getServer());
 | 
			
		||||
        });
 | 
			
		||||
        attributeSubscriptions.clear();
 | 
			
		||||
        rpcSubscriptions.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void processNameOrTypeUpdate(DeviceNameOrTypeUpdateMsg msg) {
 | 
			
		||||
        this.deviceName = msg.getDeviceName();
 | 
			
		||||
        this.deviceType = msg.getDeviceType();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -31,4 +31,6 @@ public interface ActorService extends SessionMsgProcessor, WebSocketMsgProcessor
 | 
			
		||||
    void onRuleStateChange(TenantId tenantId, RuleId ruleId, ComponentLifecycleEvent state);
 | 
			
		||||
 | 
			
		||||
    void onCredentialsUpdate(TenantId tenantId, DeviceId deviceId);
 | 
			
		||||
 | 
			
		||||
    void onDeviceNameOrTypeUpdate(TenantId tenantId, DeviceId deviceId, String deviceName, String deviceType);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -20,8 +20,6 @@ import akka.actor.ActorSystem;
 | 
			
		||||
import akka.actor.Props;
 | 
			
		||||
import akka.actor.Terminated;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.thingsboard.server.actors.ActorSystemContext;
 | 
			
		||||
@ -42,13 +40,13 @@ import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
 | 
			
		||||
import org.thingsboard.server.common.msg.cluster.ServerAddress;
 | 
			
		||||
import org.thingsboard.server.common.msg.cluster.ToAllNodesMsg;
 | 
			
		||||
import org.thingsboard.server.common.msg.core.ToDeviceSessionActorMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceNameOrTypeUpdateMsg;
 | 
			
		||||
import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
 | 
			
		||||
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.DeviceCredentialsUpdateNotificationMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.device.ToDeviceActorNotificationMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.plugins.msg.ToPluginActorMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.plugins.rest.PluginRestMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.plugins.rpc.PluginRpcMsg;
 | 
			
		||||
import org.thingsboard.server.extensions.api.plugins.ws.msg.PluginWebsocketMsg;
 | 
			
		||||
import org.thingsboard.server.service.cluster.discovery.DiscoveryService;
 | 
			
		||||
import org.thingsboard.server.service.cluster.discovery.ServerInstance;
 | 
			
		||||
@ -238,6 +236,18 @@ public class DefaultActorService implements ActorService {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onDeviceNameOrTypeUpdate(TenantId tenantId, DeviceId deviceId, String deviceName, String deviceType) {
 | 
			
		||||
        log.trace("[{}] Processing onDeviceNameOrTypeUpdate event, deviceName: {}, deviceType: {}", deviceId, deviceName, deviceType);
 | 
			
		||||
        DeviceNameOrTypeUpdateMsg msg = new DeviceNameOrTypeUpdateMsg(tenantId, deviceId, deviceName, deviceType);
 | 
			
		||||
        Optional<ServerAddress> address = actorContext.getRoutingService().resolveById(deviceId);
 | 
			
		||||
        if (address.isPresent()) {
 | 
			
		||||
            rpcService.tell(address.get(), msg);
 | 
			
		||||
        } else {
 | 
			
		||||
            onMsg(msg);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void broadcast(ToAllNodesMsg msg) {
 | 
			
		||||
        rpcService.broadcast(msg);
 | 
			
		||||
        appActor.tell(msg, ActorRef.noSender());
 | 
			
		||||
 | 
			
		||||
@ -61,7 +61,14 @@ public class DeviceController extends BaseController {
 | 
			
		||||
    public Device saveDevice(@RequestBody Device device) throws ThingsboardException {
 | 
			
		||||
        try {
 | 
			
		||||
            device.setTenantId(getCurrentUser().getTenantId());
 | 
			
		||||
            return checkNotNull(deviceService.saveDevice(device));
 | 
			
		||||
            Device savedDevice = checkNotNull(deviceService.saveDevice(device));
 | 
			
		||||
            actorService
 | 
			
		||||
                    .onDeviceNameOrTypeUpdate(
 | 
			
		||||
                            savedDevice.getTenantId(),
 | 
			
		||||
                            savedDevice.getId(),
 | 
			
		||||
                            savedDevice.getName(),
 | 
			
		||||
                            savedDevice.getType());
 | 
			
		||||
            return savedDevice;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            throw handleException(e);
 | 
			
		||||
        }
 | 
			
		||||
@ -174,7 +181,7 @@ public class DeviceController extends BaseController {
 | 
			
		||||
        try {
 | 
			
		||||
            TenantId tenantId = getCurrentUser().getTenantId();
 | 
			
		||||
            TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
 | 
			
		||||
            if (type != null && type.trim().length()>0) {
 | 
			
		||||
            if (type != null && type.trim().length() > 0) {
 | 
			
		||||
                return checkNotNull(deviceService.findDevicesByTenantIdAndType(tenantId, type, pageLink));
 | 
			
		||||
            } else {
 | 
			
		||||
                return checkNotNull(deviceService.findDevicesByTenantId(tenantId, pageLink));
 | 
			
		||||
@ -213,7 +220,7 @@ public class DeviceController extends BaseController {
 | 
			
		||||
            CustomerId customerId = new CustomerId(toUUID(strCustomerId));
 | 
			
		||||
            checkCustomerId(customerId);
 | 
			
		||||
            TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
 | 
			
		||||
            if (type != null && type.trim().length()>0) {
 | 
			
		||||
            if (type != null && type.trim().length() > 0) {
 | 
			
		||||
                return checkNotNull(deviceService.findDevicesByTenantIdAndCustomerIdAndType(tenantId, customerId, type, pageLink));
 | 
			
		||||
            } else {
 | 
			
		||||
                return checkNotNull(deviceService.findDevicesByTenantIdAndCustomerId(tenantId, customerId, pageLink));
 | 
			
		||||
 | 
			
		||||
@ -105,9 +105,11 @@ coap:
 | 
			
		||||
  adaptor:  "${COAP_ADAPTOR_NAME:JsonCoapAdaptor}"
 | 
			
		||||
  timeout: "${COAP_TIMEOUT:10000}"
 | 
			
		||||
 | 
			
		||||
database:
 | 
			
		||||
  type: "${DATABASE_TYPE:cassandra}" # cassandra OR postgres
 | 
			
		||||
 | 
			
		||||
# Cassandra driver configuration parameters
 | 
			
		||||
cassandra:
 | 
			
		||||
  enabled: "${CASSANDRA_ENABLED:false}"
 | 
			
		||||
  # Thingsboard cluster name
 | 
			
		||||
  cluster_name: "${CASSANDRA_CLUSTER_NAME:Thingsboard Cluster}"
 | 
			
		||||
  # Thingsboard keyspace name
 | 
			
		||||
@ -200,7 +202,7 @@ updates:
 | 
			
		||||
  # Enable/disable updates checking.
 | 
			
		||||
  enabled: "${UPDATES_ENABLED:true}"
 | 
			
		||||
  
 | 
			
		||||
  # spring CORS configuration
 | 
			
		||||
# spring CORS configuration
 | 
			
		||||
spring.mvc.cors:
 | 
			
		||||
   mappings:
 | 
			
		||||
     # Intercept path
 | 
			
		||||
@ -223,8 +225,6 @@ spring.mvc.cors:
 | 
			
		||||
         allow-credentials: "true"
 | 
			
		||||
         
 | 
			
		||||
# SQL DAO Configuration
 | 
			
		||||
sql:
 | 
			
		||||
  enabled: "${SQL_ENABLED:true}"
 | 
			
		||||
 | 
			
		||||
spring:
 | 
			
		||||
  data:
 | 
			
		||||
 | 
			
		||||
@ -34,6 +34,6 @@ public class ControllerTestSuite {
 | 
			
		||||
                    Arrays.asList(
 | 
			
		||||
                            new ClassPathCQLDataSet("cassandra/schema.cql", false, false),
 | 
			
		||||
                            new ClassPathCQLDataSet("cassandra/system-data.cql", false, false),
 | 
			
		||||
                            new ClassPathCQLDataSet("system-test.cql", false, false)),
 | 
			
		||||
                            new ClassPathCQLDataSet("cassandra/system-test.cql", false, false)),
 | 
			
		||||
                    "cassandra-test.yaml", 30000l);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -18,19 +18,15 @@ package org.thingsboard.server.dao.sql;
 | 
			
		||||
import com.datastax.driver.core.utils.UUIDs;
 | 
			
		||||
import com.google.common.collect.Lists;
 | 
			
		||||
import com.google.common.util.concurrent.ListenableFuture;
 | 
			
		||||
import com.google.common.util.concurrent.ListeningExecutorService;
 | 
			
		||||
import com.google.common.util.concurrent.MoreExecutors;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.data.repository.CrudRepository;
 | 
			
		||||
import org.springframework.transaction.annotation.Transactional;
 | 
			
		||||
import org.thingsboard.server.dao.Dao;
 | 
			
		||||
import org.thingsboard.server.dao.DaoUtil;
 | 
			
		||||
import org.thingsboard.server.dao.model.BaseEntity;
 | 
			
		||||
import org.thingsboard.server.dao.model.SearchTextEntity;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import java.util.concurrent.Executors;
 | 
			
		||||
 | 
			
		||||
import static org.springframework.transaction.annotation.Propagation.REQUIRES_NEW;
 | 
			
		||||
 | 
			
		||||
@ -46,9 +42,7 @@ public abstract class JpaAbstractDao<E extends BaseEntity<D>, D>
 | 
			
		||||
 | 
			
		||||
    protected abstract CrudRepository<E, UUID> getCrudRepository();
 | 
			
		||||
 | 
			
		||||
    protected boolean isSearchTextDao() {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    protected void setSearchText(E entity) {}
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @Transactional(propagation = REQUIRES_NEW)
 | 
			
		||||
@ -60,9 +54,7 @@ public abstract class JpaAbstractDao<E extends BaseEntity<D>, D>
 | 
			
		||||
            log.error("Can't create entity for domain object {}", domain, e);
 | 
			
		||||
            throw new IllegalArgumentException("Can't create entity for domain object {" + domain + "}", e);
 | 
			
		||||
        }
 | 
			
		||||
        if (isSearchTextDao()) {
 | 
			
		||||
            ((SearchTextEntity) entity).setSearchText(((SearchTextEntity) entity).getSearchTextSource().toLowerCase());
 | 
			
		||||
        }
 | 
			
		||||
        setSearchText(entity);
 | 
			
		||||
        log.debug("Saving entity {}", entity);
 | 
			
		||||
        if (entity.getId() == null) {
 | 
			
		||||
            entity.setId(UUIDs.timeBased());
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@
 | 
			
		||||
package org.thingsboard.server.dao.sql;
 | 
			
		||||
 | 
			
		||||
import org.thingsboard.server.dao.model.BaseEntity;
 | 
			
		||||
import org.thingsboard.server.dao.model.SearchTextEntity;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Valerii Sosliuk on 5/6/2017.
 | 
			
		||||
@ -23,7 +24,7 @@ import org.thingsboard.server.dao.model.BaseEntity;
 | 
			
		||||
public abstract class JpaAbstractSearchTextDao <E extends BaseEntity<D>, D> extends JpaAbstractDao<E, D> {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected boolean isSearchTextDao() {
 | 
			
		||||
        return true;
 | 
			
		||||
    protected void setSearchText(E entity) {
 | 
			
		||||
        ((SearchTextEntity) entity).setSearchText(((SearchTextEntity) entity).getSearchTextSource().toLowerCase());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -16,16 +16,14 @@
 | 
			
		||||
package org.thingsboard.server.dao.sql.user;
 | 
			
		||||
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 | 
			
		||||
import org.springframework.data.repository.CrudRepository;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
import org.thingsboard.server.common.data.User;
 | 
			
		||||
import org.thingsboard.server.common.data.security.UserCredentials;
 | 
			
		||||
import org.thingsboard.server.dao.DaoUtil;
 | 
			
		||||
import org.thingsboard.server.dao.model.ModelConstants;
 | 
			
		||||
import org.thingsboard.server.dao.model.sql.UserCredentialsEntity;
 | 
			
		||||
import org.thingsboard.server.dao.sql.JpaAbstractDao;
 | 
			
		||||
import org.thingsboard.server.dao.user.UserCredentialsDao;
 | 
			
		||||
import org.thingsboard.server.dao.util.SqlDao;
 | 
			
		||||
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
@ -33,7 +31,7 @@ import java.util.UUID;
 | 
			
		||||
 * Created by Valerii Sosliuk on 4/22/2017.
 | 
			
		||||
 */
 | 
			
		||||
@Component
 | 
			
		||||
@ConditionalOnProperty(prefix="sql", value="enabled",havingValue = "true", matchIfMissing = false)
 | 
			
		||||
@SqlDao
 | 
			
		||||
public class JpaUserCredentialsDao extends JpaAbstractDao<UserCredentialsEntity, UserCredentials> implements UserCredentialsDao {
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
 | 
			
		||||
@ -15,16 +15,16 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.dao.sql.user;
 | 
			
		||||
 | 
			
		||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 | 
			
		||||
import org.springframework.data.repository.CrudRepository;
 | 
			
		||||
import org.thingsboard.server.dao.model.sql.UserCredentialsEntity;
 | 
			
		||||
import org.thingsboard.server.dao.util.SqlDao;
 | 
			
		||||
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Valerii Sosliuk on 4/22/2017.
 | 
			
		||||
 */
 | 
			
		||||
@ConditionalOnProperty(prefix="sql", value="enabled",havingValue = "true", matchIfMissing = false)
 | 
			
		||||
@SqlDao
 | 
			
		||||
public interface UserCredentialsRepository extends CrudRepository<UserCredentialsEntity, UUID> {
 | 
			
		||||
 | 
			
		||||
    UserCredentialsEntity findByUserId(UUID userId);
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,6 @@ package org.thingsboard.server.dao.util;
 | 
			
		||||
 | 
			
		||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 | 
			
		||||
 | 
			
		||||
@ConditionalOnProperty(prefix = "cassandra", value = "enabled", havingValue = "true")
 | 
			
		||||
@ConditionalOnProperty(prefix = "database", value = "type", havingValue = "cassandra")
 | 
			
		||||
public @interface NoSqlDao {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,6 @@ package org.thingsboard.server.dao.util;
 | 
			
		||||
 | 
			
		||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 | 
			
		||||
 | 
			
		||||
@ConditionalOnProperty(prefix = "sql", value = "enabled", havingValue = "true")
 | 
			
		||||
@ConditionalOnProperty(prefix = "database", value = "type", havingValue = "postgres")
 | 
			
		||||
public @interface SqlDao {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -24,8 +24,7 @@ import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
@RunWith(ClasspathSuite.class)
 | 
			
		||||
@ClassnameFilters({
 | 
			
		||||
//        "org.thingsboard.server.dao.sql.alarm.",
 | 
			
		||||
        "org.thingsboard.server.dao.sql.*Test",
 | 
			
		||||
        "org.thingsboard.server.dao.sql.*Test"
 | 
			
		||||
})
 | 
			
		||||
public class JpaDaoTestSuite {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -34,7 +34,7 @@ public class NoSqlDaoServiceTestSuite {
 | 
			
		||||
            new CustomCassandraCQLUnit(
 | 
			
		||||
                    Arrays.asList(new ClassPathCQLDataSet("cassandra/schema.cql", false, false),
 | 
			
		||||
                            new ClassPathCQLDataSet("cassandra/system-data.cql", false, false),
 | 
			
		||||
                            new ClassPathCQLDataSet("system-test.cql", false, false)),
 | 
			
		||||
                            new ClassPathCQLDataSet("cassandra/system-test.cql", false, false)),
 | 
			
		||||
                    "cassandra-test.yaml", 30000L);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -30,7 +30,7 @@ public class SqlDaoServiceTestSuite {
 | 
			
		||||
 | 
			
		||||
    @ClassRule
 | 
			
		||||
    public static CustomPostgresUnit postgresUnit = new CustomPostgresUnit(
 | 
			
		||||
            Arrays.asList("postgres/schema.sql", "postgres/system-data.sql", "system-test.sql"),
 | 
			
		||||
            Arrays.asList("postgres/schema.sql", "postgres/system-data.sql", "postgres/system-test.sql"),
 | 
			
		||||
            "postgres-embedded-test.properties");
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,2 +1 @@
 | 
			
		||||
sql.enabled=false
 | 
			
		||||
cassandra.enabled=true
 | 
			
		||||
database.type=cassandra
 | 
			
		||||
@ -1,5 +1,4 @@
 | 
			
		||||
cassandra.enabled=false
 | 
			
		||||
sql.enabled=true
 | 
			
		||||
database.type=postgres
 | 
			
		||||
 | 
			
		||||
spring.jpa.show-sql=false
 | 
			
		||||
spring.jpa.hibernate.ddl-auto=validate
 | 
			
		||||
@ -7,7 +6,3 @@ spring.jpa.hibernate.ddl-auto=validate
 | 
			
		||||
spring.datasource.url=jdbc:postgresql://localhost:5433/thingsboard-test
 | 
			
		||||
spring.datasource.username=postgres
 | 
			
		||||
spring.datasource.password=postgres
 | 
			
		||||
 | 
			
		||||
#spring.datasource.url=jdbc:h2:mem:test;MODE=PostgreSQL
 | 
			
		||||
#spring.datasource.schema=classpath:postgres/schema.sql
 | 
			
		||||
#spring.datasource.data=classpath:postgres/system-data.sql;classpath:system-test.sql
 | 
			
		||||
@ -0,0 +1,30 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2017 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.extensions.api.device;
 | 
			
		||||
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import org.thingsboard.server.common.data.id.DeviceId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
 | 
			
		||||
@Data
 | 
			
		||||
@AllArgsConstructor
 | 
			
		||||
public class DeviceNameOrTypeUpdateMsg implements ToDeviceActorNotificationMsg {
 | 
			
		||||
    private final TenantId tenantId;
 | 
			
		||||
    private final DeviceId deviceId;
 | 
			
		||||
    private final String deviceName;
 | 
			
		||||
    private final String deviceType;
 | 
			
		||||
}
 | 
			
		||||
@ -892,10 +892,10 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getRelatedEntities(rootEntityId, entityType, entitySubTypes, maxLevel, keys, typeTranslatePrefix) {
 | 
			
		||||
    function getRelatedEntities(rootEntityId, entityType, entitySubTypes, maxLevel, keys, typeTranslatePrefix, relationType) {
 | 
			
		||||
        var deferred = $q.defer();
 | 
			
		||||
 | 
			
		||||
        var entitySearchQuery = constructRelatedEntitiesSearchQuery(rootEntityId, entityType, entitySubTypes, maxLevel);
 | 
			
		||||
        var entitySearchQuery = constructRelatedEntitiesSearchQuery(rootEntityId, entityType, entitySubTypes, maxLevel, relationType);
 | 
			
		||||
        if (!entitySearchQuery) {
 | 
			
		||||
            deferred.reject();
 | 
			
		||||
        } else {
 | 
			
		||||
@ -930,12 +930,12 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
 | 
			
		||||
        return deferred.promise;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function saveRelatedEntity(relatedEntity, parentEntityId, keys) {
 | 
			
		||||
    function saveRelatedEntity(relatedEntity, parentEntityId, keys, relation) {
 | 
			
		||||
        var deferred = $q.defer();
 | 
			
		||||
        if (relatedEntity.id.id) {
 | 
			
		||||
            updateRelatedEntity(relatedEntity, keys, deferred);
 | 
			
		||||
            updateRelatedEntity(relatedEntity, keys, deferred, relation);
 | 
			
		||||
        } else {
 | 
			
		||||
            addRelatedEntity(relatedEntity, parentEntityId, keys, deferred);
 | 
			
		||||
            addRelatedEntity(relatedEntity, parentEntityId, keys, deferred, relation);
 | 
			
		||||
        }
 | 
			
		||||
        return deferred.promise;
 | 
			
		||||
    }
 | 
			
		||||
@ -1073,7 +1073,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function addRelatedEntity(relatedEntity, parentEntityId, keys, deferred) {
 | 
			
		||||
    function addRelatedEntity(relatedEntity, parentEntityId, keys, deferred, relation) {
 | 
			
		||||
        var entity = {};
 | 
			
		||||
        entity.id = relatedEntity.id;
 | 
			
		||||
        entity.name = relatedEntity.name;
 | 
			
		||||
@ -1081,14 +1081,18 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
 | 
			
		||||
        saveEntityPromise(entity).then(
 | 
			
		||||
            function success(entity) {
 | 
			
		||||
                relatedEntity.id = entity.id;
 | 
			
		||||
                var relation = {
 | 
			
		||||
                    from: parentEntityId,
 | 
			
		||||
                    to: relatedEntity.id,
 | 
			
		||||
                    type: types.entityRelationType.contains
 | 
			
		||||
                };
 | 
			
		||||
                if (!relation) {
 | 
			
		||||
                    relation = {
 | 
			
		||||
                        from: parentEntityId,
 | 
			
		||||
                        to: relatedEntity.id,
 | 
			
		||||
                        type: types.entityRelationType.contains
 | 
			
		||||
                    };
 | 
			
		||||
                } else {
 | 
			
		||||
                    relation.to = relatedEntity.id;
 | 
			
		||||
                }
 | 
			
		||||
                entityRelationService.saveRelation(relation).then(
 | 
			
		||||
                    function success() {
 | 
			
		||||
                        updateEntity(entity, relatedEntity, keys, deferred);
 | 
			
		||||
                        updateEntity(entity, relatedEntity, keys, deferred, relation);
 | 
			
		||||
                    },
 | 
			
		||||
                    function fail() {
 | 
			
		||||
                        deferred.reject();
 | 
			
		||||
@ -1101,10 +1105,22 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function updateRelatedEntity(relatedEntity, keys, deferred) {
 | 
			
		||||
    function updateRelatedEntity(relatedEntity, keys, deferred, relation) {
 | 
			
		||||
        getEntityPromise(relatedEntity.id.entityType, relatedEntity.id.id, {ignoreLoading: true}).then(
 | 
			
		||||
            function success(entity) {
 | 
			
		||||
                updateEntity(entity, relatedEntity, keys, deferred);
 | 
			
		||||
                if (relation) {
 | 
			
		||||
                    relation.to = relatedEntity.id;
 | 
			
		||||
                    entityRelationService.saveRelation(relation).then(
 | 
			
		||||
                        function success() {
 | 
			
		||||
                            updateEntity(entity, relatedEntity, keys, deferred);
 | 
			
		||||
                        },
 | 
			
		||||
                        function fail() {
 | 
			
		||||
                            deferred.reject();
 | 
			
		||||
                        }
 | 
			
		||||
                    );
 | 
			
		||||
                } else {
 | 
			
		||||
                    updateEntity(entity, relatedEntity, keys, deferred);
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            function fail() {
 | 
			
		||||
                deferred.reject();
 | 
			
		||||
@ -1146,7 +1162,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
 | 
			
		||||
            );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function constructRelatedEntitiesSearchQuery(rootEntityId, entityType, entitySubTypes, maxLevel) {
 | 
			
		||||
    function constructRelatedEntitiesSearchQuery(rootEntityId, entityType, entitySubTypes, maxLevel, relationType) {
 | 
			
		||||
 | 
			
		||||
        var searchQuery = {
 | 
			
		||||
            parameters: {
 | 
			
		||||
@ -1154,8 +1170,11 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
 | 
			
		||||
                rootType: rootEntityId.entityType,
 | 
			
		||||
                direction: types.entitySearchDirection.from
 | 
			
		||||
            },
 | 
			
		||||
            relationType: types.entityRelationType.contains
 | 
			
		||||
            relationType: relationType
 | 
			
		||||
        };
 | 
			
		||||
        if (!relationType) {
 | 
			
		||||
            searchQuery.relationType = types.entityRelationType.contains;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (maxLevel) {
 | 
			
		||||
            searchQuery.parameters.maxLevel = maxLevel;
 | 
			
		||||
 | 
			
		||||
@ -125,7 +125,7 @@
 | 
			
		||||
        </md-table-container>
 | 
			
		||||
        <md-table-pagination md-limit="vm.query.limit" md-limit-options="[5, 10, 15]"
 | 
			
		||||
                             md-page="vm.query.page" md-total="{{vm.relationsCount}}"
 | 
			
		||||
                             md-on-paginate="onPaginate" md-page-select>
 | 
			
		||||
                             md-on-paginate="vm.onPaginate" md-page-select>
 | 
			
		||||
        </md-table-pagination>
 | 
			
		||||
    </div>
 | 
			
		||||
</md-content>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user