commit
						feeee23fa0
					
				@ -865,6 +865,8 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void notifyTransportAboutClosedSessionMaxSessionsLimit(UUID sessionId, SessionInfoMetaData sessionMd) {
 | 
			
		||||
        attributeSubscriptions.remove(sessionId);
 | 
			
		||||
        rpcSubscriptions.remove(sessionId);
 | 
			
		||||
        notifyTransportAboutClosedSession(sessionId, sessionMd, TransportSessionCloseReason.MAX_CONCURRENT_SESSIONS_LIMIT_REACHED);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,7 @@ import org.thingsboard.server.dao.service.DataValidator;
 | 
			
		||||
import org.thingsboard.server.gen.edge.v1.DashboardUpdateMsg;
 | 
			
		||||
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor;
 | 
			
		||||
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
@Slf4j
 | 
			
		||||
@ -40,54 +41,63 @@ public abstract class BaseDashboardProcessor extends BaseEdgeProcessor {
 | 
			
		||||
        if (dashboard == null) {
 | 
			
		||||
            throw new RuntimeException("[{" + tenantId + "}] dashboardUpdateMsg {" + dashboardUpdateMsg + "} cannot be converted to dashboard");
 | 
			
		||||
        }
 | 
			
		||||
        Set<ShortCustomerInfo> assignedCustomers = null;
 | 
			
		||||
        Set<ShortCustomerInfo> newAssignedCustomers = new HashSet<>(dashboard.getAssignedCustomers());
 | 
			
		||||
        Dashboard dashboardById = edgeCtx.getDashboardService().findDashboardById(tenantId, dashboardId);
 | 
			
		||||
        if (dashboardById == null) {
 | 
			
		||||
            created = true;
 | 
			
		||||
            dashboard.setId(null);
 | 
			
		||||
            dashboard.setAssignedCustomers(null);
 | 
			
		||||
        } else {
 | 
			
		||||
            dashboard.setId(dashboardId);
 | 
			
		||||
            assignedCustomers = filterNonExistingCustomers(tenantId, dashboardById.getAssignedCustomers());
 | 
			
		||||
            dashboard.setAssignedCustomers(dashboardById.getAssignedCustomers());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        dashboardValidator.validate(dashboard, Dashboard::getTenantId);
 | 
			
		||||
        if (created) {
 | 
			
		||||
            dashboard.setId(dashboardId);
 | 
			
		||||
        }
 | 
			
		||||
        Set<ShortCustomerInfo> msgAssignedCustomers = filterNonExistingCustomers(tenantId, dashboard.getAssignedCustomers());
 | 
			
		||||
        if (msgAssignedCustomers != null) {
 | 
			
		||||
            if (assignedCustomers == null) {
 | 
			
		||||
                assignedCustomers = msgAssignedCustomers;
 | 
			
		||||
            } else {
 | 
			
		||||
                assignedCustomers.addAll(msgAssignedCustomers);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        dashboard.setAssignedCustomers(assignedCustomers);
 | 
			
		||||
 | 
			
		||||
        Dashboard savedDashboard = edgeCtx.getDashboardService().saveDashboard(dashboard, false);
 | 
			
		||||
        if (msgAssignedCustomers != null && !msgAssignedCustomers.isEmpty()) {
 | 
			
		||||
            for (ShortCustomerInfo assignedCustomer : msgAssignedCustomers) {
 | 
			
		||||
                if (assignedCustomer.getCustomerId().equals(customerId)) {
 | 
			
		||||
                    edgeCtx.getDashboardService().assignDashboardToCustomer(tenantId, savedDashboard.getId(), assignedCustomer.getCustomerId());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            unassignCustomersFromDashboard(tenantId, savedDashboard, customerId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        updateDashboardAssignments(tenantId, dashboardById, savedDashboard, newAssignedCustomers);
 | 
			
		||||
 | 
			
		||||
        return created;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void unassignCustomersFromDashboard(TenantId tenantId, Dashboard dashboard, CustomerId customerId) {
 | 
			
		||||
        if (dashboard.getAssignedCustomers() != null && !dashboard.getAssignedCustomers().isEmpty()) {
 | 
			
		||||
            for (ShortCustomerInfo assignedCustomer : dashboard.getAssignedCustomers()) {
 | 
			
		||||
                if (assignedCustomer.getCustomerId().equals(customerId)) {
 | 
			
		||||
                    edgeCtx.getDashboardService().unassignDashboardFromCustomer(tenantId, dashboard.getId(), assignedCustomer.getCustomerId());
 | 
			
		||||
    private void updateDashboardAssignments(TenantId tenantId, Dashboard dashboardById, Dashboard savedDashboard, Set<ShortCustomerInfo> newAssignedCustomers) {
 | 
			
		||||
        Set<ShortCustomerInfo> currentAssignedCustomers = new HashSet<>();
 | 
			
		||||
        if (dashboardById != null) {
 | 
			
		||||
            if (dashboardById.getAssignedCustomers() != null) {
 | 
			
		||||
                currentAssignedCustomers.addAll(dashboardById.getAssignedCustomers());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        newAssignedCustomers = filterNonExistingCustomers(tenantId, currentAssignedCustomers, newAssignedCustomers);
 | 
			
		||||
 | 
			
		||||
        Set<CustomerId> addedCustomerIds = new HashSet<>();
 | 
			
		||||
        Set<CustomerId> removedCustomerIds = new HashSet<>();
 | 
			
		||||
        for (ShortCustomerInfo newAssignedCustomer : newAssignedCustomers) {
 | 
			
		||||
            if (!savedDashboard.isAssignedToCustomer(newAssignedCustomer.getCustomerId())) {
 | 
			
		||||
                addedCustomerIds.add(newAssignedCustomer.getCustomerId());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (ShortCustomerInfo currentAssignedCustomer : currentAssignedCustomers) {
 | 
			
		||||
            if (!newAssignedCustomers.contains(currentAssignedCustomer)) {
 | 
			
		||||
                removedCustomerIds.add(currentAssignedCustomer.getCustomerId());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (CustomerId customerIdToAdd : addedCustomerIds) {
 | 
			
		||||
            edgeCtx.getDashboardService().assignDashboardToCustomer(tenantId, savedDashboard.getId(), customerIdToAdd);
 | 
			
		||||
        }
 | 
			
		||||
        for (CustomerId customerIdToRemove : removedCustomerIds) {
 | 
			
		||||
            edgeCtx.getDashboardService().unassignDashboardFromCustomer(tenantId, savedDashboard.getId(), customerIdToRemove);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected abstract Dashboard constructDashboardFromUpdateMsg(TenantId tenantId, DashboardId dashboardId, DashboardUpdateMsg dashboardUpdateMsg);
 | 
			
		||||
 | 
			
		||||
    protected abstract Set<ShortCustomerInfo> filterNonExistingCustomers(TenantId tenantId, Set<ShortCustomerInfo> assignedCustomers);
 | 
			
		||||
    protected abstract Set<ShortCustomerInfo> filterNonExistingCustomers(TenantId tenantId, Set<ShortCustomerInfo> currentAssignedCustomers, Set<ShortCustomerInfo> newAssignedCustomers);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -128,9 +128,9 @@ public abstract class DashboardEdgeProcessor extends BaseDashboardProcessor impl
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected Set<ShortCustomerInfo> filterNonExistingCustomers(TenantId tenantId, Set<ShortCustomerInfo> assignedCustomers) {
 | 
			
		||||
        // do nothing on cloud
 | 
			
		||||
        return assignedCustomers;
 | 
			
		||||
    protected Set<ShortCustomerInfo> filterNonExistingCustomers(TenantId tenantId, Set<ShortCustomerInfo> currentAssignedCustomers, Set<ShortCustomerInfo> newAssignedCustomers) {
 | 
			
		||||
        newAssignedCustomers.addAll(currentAssignedCustomers);
 | 
			
		||||
        return newAssignedCustomers;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,7 @@ import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.gen.edge.v1.DashboardUpdateMsg;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
@Component
 | 
			
		||||
@ -44,7 +45,7 @@ public class DashboardEdgeProcessorV1 extends DashboardEdgeProcessor {
 | 
			
		||||
        Set<ShortCustomerInfo> assignedCustomers;
 | 
			
		||||
        if (dashboardUpdateMsg.hasAssignedCustomers()) {
 | 
			
		||||
            assignedCustomers = JacksonUtil.fromString(dashboardUpdateMsg.getAssignedCustomers(), new TypeReference<>() {});
 | 
			
		||||
            assignedCustomers = filterNonExistingCustomers(tenantId, assignedCustomers);
 | 
			
		||||
            assignedCustomers = filterNonExistingCustomers(tenantId, new HashSet<>(), assignedCustomers);
 | 
			
		||||
            dashboard.setAssignedCustomers(assignedCustomers);
 | 
			
		||||
        }
 | 
			
		||||
        dashboard.setMobileOrder(dashboardUpdateMsg.hasMobileOrder() ? dashboardUpdateMsg.getMobileOrder() : null);
 | 
			
		||||
 | 
			
		||||
@ -53,6 +53,9 @@ public abstract class BaseResourceProcessor extends BaseEdgeProcessor {
 | 
			
		||||
            }
 | 
			
		||||
            String resourceKey = resource.getResourceKey();
 | 
			
		||||
            ResourceType resourceType = resource.getResourceType();
 | 
			
		||||
            if (!created && !resourceType.isUpdatable()) {
 | 
			
		||||
                resource.setData(null);
 | 
			
		||||
            }
 | 
			
		||||
            PageDataIterable<TbResource> resourcesIterable = new PageDataIterable<>(
 | 
			
		||||
                    link -> edgeCtx.getResourceService().findTenantResourcesByResourceTypeAndPageLink(tenantId, resourceType, link), 1024);
 | 
			
		||||
            for (TbResource tbResource : resourcesIterable) {
 | 
			
		||||
 | 
			
		||||
@ -115,8 +115,9 @@ public class DefaultTbRuleEngineRpcService implements TbRuleEngineDeviceRpcServi
 | 
			
		||||
        ToDeviceRpcRequest request = new ToDeviceRpcRequest(src.getRequestUUID(), src.getTenantId(), src.getDeviceId(),
 | 
			
		||||
                src.isOneway(), src.getExpirationTime(), new ToDeviceRpcRequestBody(src.getMethod(), src.getBody()), src.isPersisted(), src.getRetries(), src.getAdditionalInfo());
 | 
			
		||||
        forwardRpcRequestToDeviceActor(request, response -> {
 | 
			
		||||
            if (src.isRestApiCall()) {
 | 
			
		||||
                sendRpcResponseToTbCore(src.getOriginServiceId(), response);
 | 
			
		||||
            String originServiceId = src.getOriginServiceId();
 | 
			
		||||
            if (src.isRestApiCall() && originServiceId != null) {
 | 
			
		||||
                sendRpcResponseToTbCore(originServiceId, response);
 | 
			
		||||
            }
 | 
			
		||||
            consumer.accept(RuleEngineDeviceRpcResponse.builder()
 | 
			
		||||
                    .deviceId(src.getDeviceId())
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@
 | 
			
		||||
package org.thingsboard.server.edge;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.core.type.TypeReference;
 | 
			
		||||
import com.google.common.collect.Sets;
 | 
			
		||||
import com.google.protobuf.AbstractMessage;
 | 
			
		||||
import org.junit.Assert;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
@ -175,7 +176,11 @@ public class DashboardEdgeTest extends AbstractEdgeTest {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testSendDashboardToCloud() throws Exception {
 | 
			
		||||
        Dashboard dashboard = buildDashboardForUplinkMsg();
 | 
			
		||||
        Customer customer = new Customer();
 | 
			
		||||
        customer.setTitle("Edge Customer");
 | 
			
		||||
        Customer savedCustomer = doPost("/api/customer", customer, Customer.class);
 | 
			
		||||
 | 
			
		||||
        Dashboard dashboard = buildDashboardForUplinkMsg(savedCustomer);
 | 
			
		||||
 | 
			
		||||
        UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder();
 | 
			
		||||
        DashboardUpdateMsg.Builder dashboardUpdateMsgBuilder = DashboardUpdateMsg.newBuilder();
 | 
			
		||||
@ -196,6 +201,11 @@ public class DashboardEdgeTest extends AbstractEdgeTest {
 | 
			
		||||
        Dashboard foundDashboard = doGet("/api/dashboard/" + dashboard.getUuidId(), Dashboard.class);
 | 
			
		||||
        Assert.assertNotNull(foundDashboard);
 | 
			
		||||
        Assert.assertEquals("Edge Test Dashboard", foundDashboard.getName());
 | 
			
		||||
 | 
			
		||||
        PageData<DashboardInfo> pageData = doGetTypedWithPageLink("/api/customer/" + savedCustomer.getId().toString() + "/dashboards?",
 | 
			
		||||
                new TypeReference<>() {}, new PageLink(100));
 | 
			
		||||
        Assert.assertEquals(1, pageData.getData().size());
 | 
			
		||||
        Assert.assertEquals("Edge Test Dashboard", pageData.getData().get(0).getTitle());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
@ -242,11 +252,12 @@ public class DashboardEdgeTest extends AbstractEdgeTest {
 | 
			
		||||
        return savedDashboard;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Dashboard buildDashboardForUplinkMsg() {
 | 
			
		||||
    private Dashboard buildDashboardForUplinkMsg(Customer savedCustomer) {
 | 
			
		||||
        Dashboard dashboard = new Dashboard();
 | 
			
		||||
        dashboard.setId(new DashboardId(UUID.randomUUID()));
 | 
			
		||||
        dashboard.setTenantId(tenantId);
 | 
			
		||||
        dashboard.setTitle("Edge Test Dashboard");
 | 
			
		||||
        dashboard.setAssignedCustomers(Sets.newHashSet(new ShortCustomerInfo(savedCustomer.getId(), savedCustomer.getTitle(), savedCustomer.isPublic())));
 | 
			
		||||
        return dashboard;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@ package org.thingsboard.server.edge;
 | 
			
		||||
 | 
			
		||||
import com.datastax.oss.driver.api.core.uuid.Uuids;
 | 
			
		||||
import com.google.protobuf.AbstractMessage;
 | 
			
		||||
import com.google.protobuf.InvalidProtocolBufferException;
 | 
			
		||||
import org.junit.Assert;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.thingsboard.common.util.JacksonUtil;
 | 
			
		||||
@ -98,30 +99,23 @@ public class ResourceEdgeTest extends AbstractEdgeTest {
 | 
			
		||||
    public void testSendResourceToCloud() throws Exception {
 | 
			
		||||
        TbResource tbResource = createTbResource();
 | 
			
		||||
        UUID uuid = Uuids.timeBased();
 | 
			
		||||
        UplinkMsg uplinkMsg = getUplinkMsg(uuid, tbResource, UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE);
 | 
			
		||||
 | 
			
		||||
        UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder();
 | 
			
		||||
        ResourceUpdateMsg.Builder resourceUpdateMsgBuilder = ResourceUpdateMsg.newBuilder();
 | 
			
		||||
        resourceUpdateMsgBuilder.setIdMSB(uuid.getMostSignificantBits());
 | 
			
		||||
        resourceUpdateMsgBuilder.setIdLSB(uuid.getLeastSignificantBits());
 | 
			
		||||
        resourceUpdateMsgBuilder.setEntity(JacksonUtil.toString(tbResource));
 | 
			
		||||
        resourceUpdateMsgBuilder.setMsgType(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE);
 | 
			
		||||
        testAutoGeneratedCodeByProtobuf(resourceUpdateMsgBuilder);
 | 
			
		||||
        uplinkMsgBuilder.addResourceUpdateMsg(resourceUpdateMsgBuilder.build());
 | 
			
		||||
        checkResourceOnCloud(uplinkMsg, uuid, tbResource.getTitle());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder);
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testUpdateResourceTitleOnCloud() throws Exception {
 | 
			
		||||
        TbResource tbResource = createTbResource();
 | 
			
		||||
        UUID uuid = Uuids.timeBased();
 | 
			
		||||
        UplinkMsg uplinkMsg = getUplinkMsg(uuid, tbResource, UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE);
 | 
			
		||||
 | 
			
		||||
        edgeImitator.expectResponsesAmount(1);
 | 
			
		||||
        edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build());
 | 
			
		||||
        checkResourceOnCloud(uplinkMsg, uuid, tbResource.getTitle());
 | 
			
		||||
 | 
			
		||||
        Assert.assertTrue(edgeImitator.waitForResponses());
 | 
			
		||||
        tbResource.setTitle("Updated Edge Test Resource");
 | 
			
		||||
        UplinkMsg updatedUplinkMsg = getUplinkMsg(uuid, tbResource, UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE);
 | 
			
		||||
 | 
			
		||||
        UplinkResponseMsg latestResponseMsg = edgeImitator.getLatestResponseMsg();
 | 
			
		||||
        Assert.assertTrue(latestResponseMsg.getSuccess());
 | 
			
		||||
 | 
			
		||||
        TbResource tb = doGet("/api/resource/" + uuid, TbResource.class);
 | 
			
		||||
        Assert.assertNotNull(tb);
 | 
			
		||||
        Assert.assertEquals("Edge Test Resource", tb.getName());
 | 
			
		||||
        Assert.assertEquals(TEST_DATA, tb.getEncodedData());
 | 
			
		||||
        checkResourceOnCloud(updatedUplinkMsg, uuid, tbResource.getTitle());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
@ -134,21 +128,12 @@ public class ResourceEdgeTest extends AbstractEdgeTest {
 | 
			
		||||
 | 
			
		||||
        UUID uuid = Uuids.timeBased();
 | 
			
		||||
 | 
			
		||||
        UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder();
 | 
			
		||||
        ResourceUpdateMsg.Builder resourceUpdateMsgBuilder = ResourceUpdateMsg.newBuilder();
 | 
			
		||||
        resourceUpdateMsgBuilder.setIdMSB(uuid.getMostSignificantBits());
 | 
			
		||||
        resourceUpdateMsgBuilder.setIdLSB(uuid.getLeastSignificantBits());
 | 
			
		||||
        resourceUpdateMsgBuilder.setEntity(JacksonUtil.toString(resource));
 | 
			
		||||
        resourceUpdateMsgBuilder.setMsgType(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE);
 | 
			
		||||
        testAutoGeneratedCodeByProtobuf(resourceUpdateMsgBuilder);
 | 
			
		||||
        uplinkMsgBuilder.addResourceUpdateMsg(resourceUpdateMsgBuilder.build());
 | 
			
		||||
 | 
			
		||||
        testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder);
 | 
			
		||||
        UplinkMsg uplinkMsg = getUplinkMsg(uuid, resource, UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE);
 | 
			
		||||
 | 
			
		||||
        edgeImitator.expectResponsesAmount(1);
 | 
			
		||||
        edgeImitator.expectMessageAmount(1);
 | 
			
		||||
 | 
			
		||||
        edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build());
 | 
			
		||||
        edgeImitator.sendUplinkMsg(uplinkMsg);
 | 
			
		||||
 | 
			
		||||
        Assert.assertTrue(edgeImitator.waitForResponses());
 | 
			
		||||
        Assert.assertTrue(edgeImitator.waitForMessages());
 | 
			
		||||
@ -177,4 +162,35 @@ public class ResourceEdgeTest extends AbstractEdgeTest {
 | 
			
		||||
        tbResource.setEncodedData(TEST_DATA);
 | 
			
		||||
        return tbResource;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private UplinkMsg getUplinkMsg(UUID uuid, TbResource tbResource, UpdateMsgType updateMsgType) throws InvalidProtocolBufferException {
 | 
			
		||||
        UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder();
 | 
			
		||||
        ResourceUpdateMsg.Builder resourceUpdateMsgBuilder = ResourceUpdateMsg.newBuilder();
 | 
			
		||||
        resourceUpdateMsgBuilder.setIdMSB(uuid.getMostSignificantBits());
 | 
			
		||||
        resourceUpdateMsgBuilder.setIdLSB(uuid.getLeastSignificantBits());
 | 
			
		||||
        resourceUpdateMsgBuilder.setEntity(JacksonUtil.toString(tbResource));
 | 
			
		||||
        resourceUpdateMsgBuilder.setMsgType(updateMsgType);
 | 
			
		||||
        testAutoGeneratedCodeByProtobuf(resourceUpdateMsgBuilder);
 | 
			
		||||
        uplinkMsgBuilder.addResourceUpdateMsg(resourceUpdateMsgBuilder.build());
 | 
			
		||||
 | 
			
		||||
        testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder);
 | 
			
		||||
 | 
			
		||||
        return uplinkMsgBuilder.build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void checkResourceOnCloud(UplinkMsg uplinkMsg, UUID uuid, String resourceTitle) throws Exception {
 | 
			
		||||
        edgeImitator.expectResponsesAmount(1);
 | 
			
		||||
        edgeImitator.sendUplinkMsg(uplinkMsg);
 | 
			
		||||
 | 
			
		||||
        Assert.assertTrue(edgeImitator.waitForResponses());
 | 
			
		||||
 | 
			
		||||
        UplinkResponseMsg latestResponseMsg = edgeImitator.getLatestResponseMsg();
 | 
			
		||||
        Assert.assertTrue(latestResponseMsg.getSuccess());
 | 
			
		||||
 | 
			
		||||
        TbResource tb = doGet("/api/resource/" + uuid, TbResource.class);
 | 
			
		||||
        Assert.assertNotNull(tb);
 | 
			
		||||
        Assert.assertEquals(resourceTitle, tb.getName());
 | 
			
		||||
        Assert.assertEquals(TEST_DATA, tb.getEncodedData());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -963,7 +963,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
 | 
			
		||||
                unSubResults.add((short) MqttReasonCodes.UnsubAck.NO_SUBSCRIPTION_EXISTED.byteValue());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!activityReported) {
 | 
			
		||||
        if (!activityReported && !deviceSessionCtx.isProvisionOnly()) {
 | 
			
		||||
            transportService.recordActivity(deviceSessionCtx.getSessionInfo());
 | 
			
		||||
        }
 | 
			
		||||
        ctx.writeAndFlush(createUnSubAckMessage(mqttMsg.variableHeader().messageId(), unSubResults));
 | 
			
		||||
 | 
			
		||||
@ -735,7 +735,11 @@ public class DefaultTransportService extends TransportActivityManager implements
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void recordActivityInternal(TransportProtos.SessionInfoProto sessionInfo) {
 | 
			
		||||
        if (sessionInfo != null) {
 | 
			
		||||
            onActivity(toSessionId(sessionInfo), sessionInfo, getCurrentTimeMillis());
 | 
			
		||||
        } else {
 | 
			
		||||
            log.warn("Session info is missing, unable to record activity");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,7 @@
 | 
			
		||||
          [class.!hidden]="isEdit || isDetailsPage">
 | 
			
		||||
    {{'common.open-details-page' | translate }}
 | 
			
		||||
  </button>
 | 
			
		||||
  <button mat-raised-button color="primary" class="xs:flex-1"
 | 
			
		||||
  <button mat-raised-button color="primary"
 | 
			
		||||
          [disabled]="(isLoading$ | async)"
 | 
			
		||||
          (click)="onEntityAction($event, 'delete')"
 | 
			
		||||
          [class.!hidden]="hideDelete() || isEdit">
 | 
			
		||||
 | 
			
		||||
@ -22,13 +22,13 @@
 | 
			
		||||
          [class.!hidden]="isEdit || isDetailsPage">
 | 
			
		||||
    {{'common.open-details-page' | translate }}
 | 
			
		||||
  </button>
 | 
			
		||||
  <button mat-raised-button color="primary" class="xs:flex-1"
 | 
			
		||||
  <button mat-raised-button color="primary"
 | 
			
		||||
          [disabled]="(isLoading$ | async)"
 | 
			
		||||
          (click)="onEntityAction($event, 'downloadResource')"
 | 
			
		||||
          [class.!hidden]="isEdit">
 | 
			
		||||
    {{ 'javascript.download' | translate }}
 | 
			
		||||
  </button>
 | 
			
		||||
  <button mat-raised-button color="primary" class="xs:flex-1"
 | 
			
		||||
  <button mat-raised-button color="primary"
 | 
			
		||||
          [disabled]="(isLoading$ | async)"
 | 
			
		||||
          (click)="onEntityAction($event, 'delete')"
 | 
			
		||||
          [class.!hidden]="hideDelete() || isEdit">
 | 
			
		||||
 | 
			
		||||
@ -22,13 +22,13 @@
 | 
			
		||||
          [class.!hidden]="isEdit || isDetailsPage">
 | 
			
		||||
    {{'common.open-details-page' | translate }}
 | 
			
		||||
  </button>
 | 
			
		||||
  <button mat-raised-button color="primary" class="xs:flex-1"
 | 
			
		||||
  <button mat-raised-button color="primary"
 | 
			
		||||
          [disabled]="(isLoading$ | async)"
 | 
			
		||||
          (click)="onEntityAction($event, 'downloadResource')"
 | 
			
		||||
          [class.!hidden]="isEdit">
 | 
			
		||||
    {{ 'resource.download' | translate }}
 | 
			
		||||
  </button>
 | 
			
		||||
  <button mat-raised-button color="primary" class="xs:flex-1"
 | 
			
		||||
  <button mat-raised-button color="primary"
 | 
			
		||||
          [disabled]="(isLoading$ | async)"
 | 
			
		||||
          (click)="onEntityAction($event, 'delete')"
 | 
			
		||||
          [class.!hidden]="hideDelete() || isEdit">
 | 
			
		||||
 | 
			
		||||
@ -58,7 +58,7 @@
 | 
			
		||||
          [class.!hidden]="isEdit || deviceScope !== 'edge'">
 | 
			
		||||
    {{ 'edge.unassign-from-edge' | translate }}
 | 
			
		||||
  </button>
 | 
			
		||||
  <button mat-raised-button color="primary" class="xs:flex-1"
 | 
			
		||||
  <button mat-raised-button color="primary"
 | 
			
		||||
          [disabled]="(isLoading$ | async)"
 | 
			
		||||
          (click)="onEntityAction($event, 'delete')"
 | 
			
		||||
          [class.!hidden]="hideDelete() || isEdit">
 | 
			
		||||
 | 
			
		||||
@ -70,7 +70,7 @@
 | 
			
		||||
          [class.!hidden]="isEdit || edgeScope !== 'tenant'">
 | 
			
		||||
    {{'edge.manage-rulechains' | translate }}
 | 
			
		||||
  </button>
 | 
			
		||||
  <button mat-raised-button color="primary" class="xs:flex-1"
 | 
			
		||||
  <button mat-raised-button color="primary"
 | 
			
		||||
          [disabled]="(isLoading$ | async)"
 | 
			
		||||
          (click)="onEntityAction($event, 'delete')"
 | 
			
		||||
          [class.!hidden]="hideDelete() || isEdit">
 | 
			
		||||
 | 
			
		||||
@ -16,19 +16,19 @@
 | 
			
		||||
 | 
			
		||||
-->
 | 
			
		||||
<div class="tb-details-buttons xs:flex xs:flex-col">
 | 
			
		||||
  <button mat-raised-button color="primary" class="xs:flex-1"
 | 
			
		||||
  <button mat-raised-button color="primary"
 | 
			
		||||
          [disabled]="(isLoading$ | async)"
 | 
			
		||||
          (click)="onEntityAction($event, 'open')"
 | 
			
		||||
          [class.!hidden]="isEdit || isDetailsPage">
 | 
			
		||||
    {{'common.open-details-page' | translate }}
 | 
			
		||||
  </button>
 | 
			
		||||
  <button mat-raised-button color="primary" class="xs:flex-1"
 | 
			
		||||
  <button mat-raised-button color="primary"
 | 
			
		||||
          [disabled]="(isLoading$ | async) || !(entity?.hasData && !entity?.url)"
 | 
			
		||||
          (click)="onEntityAction($event, 'uploadPackage')"
 | 
			
		||||
          [class.!hidden]="isEdit">
 | 
			
		||||
    {{ 'ota-update.download' | translate }}
 | 
			
		||||
  </button>
 | 
			
		||||
  <button mat-raised-button color="primary" class="xs:flex-1"
 | 
			
		||||
  <button mat-raised-button color="primary"
 | 
			
		||||
          [disabled]="(isLoading$ | async)"
 | 
			
		||||
          (click)="onEntityAction($event, 'delete')"
 | 
			
		||||
          [class.!hidden]="hideDelete() || isEdit">
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user