Improved transport cache invalidation for device updates

This commit is contained in:
Andrii Shvaika 2020-11-24 12:11:29 +02:00
parent 63406b010f
commit 529608e60f
7 changed files with 61 additions and 46 deletions

View File

@ -72,6 +72,7 @@ import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
@ -701,12 +702,12 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
} }
@Override @Override
public void onProfileUpdate(DeviceProfile deviceProfile) { public void onDeviceProfileUpdate(TransportProtos.SessionInfoProto sessionInfo, DeviceProfile deviceProfile) {
deviceSessionCtx.onProfileUpdate(deviceProfile); deviceSessionCtx.onDeviceProfileUpdate(sessionInfo, deviceProfile);
} }
@Override @Override
public void onDeviceProfileUpdate(Device device, TransportProtos.SessionInfoProto sessionInfo) { public void onDeviceUpdate(TransportProtos.SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt) {
deviceSessionCtx.onDeviceProfileUpdate(device, sessionInfo); deviceSessionCtx.onDeviceUpdate(sessionInfo, device, deviceProfileOpt);
} }
} }

View File

@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportC
import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration;
import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration;
import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.transport.mqtt.MqttTransportContext; import org.thingsboard.server.transport.mqtt.MqttTransportContext;
import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor; import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor;
import org.thingsboard.server.transport.mqtt.util.MqttTopicFilter; import org.thingsboard.server.transport.mqtt.util.MqttTopicFilter;
@ -108,8 +109,8 @@ public class DeviceSessionCtx extends MqttDeviceAwareSessionContext {
} }
@Override @Override
public void onProfileUpdate(DeviceProfile deviceProfile) { public void onDeviceProfileUpdate(TransportProtos.SessionInfoProto sessionInfo, DeviceProfile deviceProfile) {
super.onProfileUpdate(deviceProfile); super.onDeviceProfileUpdate(sessionInfo, deviceProfile);
updateTopicFilters(deviceProfile); updateTopicFilters(deviceProfile);
} }

View File

@ -24,6 +24,8 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeResponse
import org.thingsboard.server.gen.transport.TransportProtos.SessionCloseNotificationProto; import org.thingsboard.server.gen.transport.TransportProtos.SessionCloseNotificationProto;
import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcRequestMsg;
import java.util.Optional;
/** /**
* Created by ashvayka on 04.10.18. * Created by ashvayka on 04.10.18.
*/ */
@ -39,9 +41,9 @@ public interface SessionMsgListener {
void onToServerRpcResponse(ToServerRpcResponseMsg toServerResponse); void onToServerRpcResponse(ToServerRpcResponseMsg toServerResponse);
default void onProfileUpdate(DeviceProfile deviceProfile) { default void onDeviceProfileUpdate(TransportProtos.SessionInfoProto newSessionInfo, DeviceProfile deviceProfile) {
} }
default void onDeviceProfileUpdate(Device device, TransportProtos.SessionInfoProto sessionInfo) { default void onDeviceUpdate(TransportProtos.SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt) {
} }
} }

View File

@ -672,9 +672,17 @@ public class DefaultTransportService implements TransportService {
long deviceProfileIdMSB = deviceProfile.getId().getId().getMostSignificantBits(); long deviceProfileIdMSB = deviceProfile.getId().getId().getMostSignificantBits();
long deviceProfileIdLSB = deviceProfile.getId().getId().getLeastSignificantBits(); long deviceProfileIdLSB = deviceProfile.getId().getId().getLeastSignificantBits();
sessions.forEach((id, md) -> { sessions.forEach((id, md) -> {
//TODO: if transport types are different - we should close the session.
if (md.getSessionInfo().getDeviceProfileIdMSB() == deviceProfileIdMSB if (md.getSessionInfo().getDeviceProfileIdMSB() == deviceProfileIdMSB
&& md.getSessionInfo().getDeviceProfileIdLSB() == deviceProfileIdLSB) { && md.getSessionInfo().getDeviceProfileIdLSB() == deviceProfileIdLSB) {
transportCallbackExecutor.submit(() -> md.getListener().onProfileUpdate(deviceProfile)); TransportProtos.SessionInfoProto newSessionInfo = TransportProtos.SessionInfoProto.newBuilder()
.mergeFrom(md.getSessionInfo())
.setDeviceProfileIdMSB(deviceProfileIdMSB)
.setDeviceProfileIdLSB(deviceProfileIdLSB)
.setDeviceType(deviceProfile.getName())
.build();
md.setSessionInfo(newSessionInfo);
transportCallbackExecutor.submit(() -> md.getListener().onDeviceProfileUpdate(newSessionInfo, deviceProfile));
} }
}); });
} }
@ -684,28 +692,27 @@ public class DefaultTransportService implements TransportService {
long deviceIdLSB = device.getId().getId().getLeastSignificantBits(); long deviceIdLSB = device.getId().getId().getLeastSignificantBits();
long deviceProfileIdMSB = device.getDeviceProfileId().getId().getMostSignificantBits(); long deviceProfileIdMSB = device.getDeviceProfileId().getId().getMostSignificantBits();
long deviceProfileIdLSB = device.getDeviceProfileId().getId().getLeastSignificantBits(); long deviceProfileIdLSB = device.getDeviceProfileId().getId().getLeastSignificantBits();
for (Map.Entry<UUID, SessionMetaData> entry : sessions.entrySet()) { sessions.forEach((id, md) -> {
SessionMetaData md = entry.getValue(); if ((md.getSessionInfo().getDeviceIdMSB() == deviceIdMSB && md.getSessionInfo().getDeviceIdLSB() == deviceIdLSB)) {
if ((md.getSessionInfo().getDeviceIdMSB() == deviceIdMSB DeviceProfile newDeviceProfile;
&& md.getSessionInfo().getDeviceIdLSB() == deviceIdLSB) if (md.getSessionInfo().getDeviceProfileIdMSB() != deviceProfileIdMSB
&& (md.getSessionInfo().getDeviceProfileIdMSB() != deviceProfileIdMSB && md.getSessionInfo().getDeviceProfileIdLSB() != deviceProfileIdLSB) {
&& md.getSessionInfo().getDeviceProfileIdLSB() != deviceProfileIdLSB)) { //TODO: if transport types are different - we should close the session.
updateSessionMetadata(device, entry, md); newDeviceProfile = deviceProfileCache.get(new DeviceProfileId(new UUID(deviceProfileIdMSB, deviceProfileIdLSB)));
} else {
newDeviceProfile = null;
} }
}
}
private void updateSessionMetadata(Device device, Map.Entry<UUID, SessionMetaData> entry, SessionMetaData md) {
TransportProtos.SessionInfoProto newSessionInfo = TransportProtos.SessionInfoProto.newBuilder() TransportProtos.SessionInfoProto newSessionInfo = TransportProtos.SessionInfoProto.newBuilder()
.mergeFrom(md.getSessionInfo()) .mergeFrom(md.getSessionInfo())
.setDeviceProfileIdMSB(device.getDeviceProfileId().getId().getMostSignificantBits()) .setDeviceProfileIdMSB(deviceProfileIdMSB)
.setDeviceProfileIdLSB(device.getDeviceProfileId().getId().getLeastSignificantBits()) .setDeviceProfileIdLSB(deviceProfileIdLSB)
.setDeviceName(device.getName())
.setDeviceType(device.getType()) .setDeviceType(device.getType())
.build(); .build();
SessionMetaData newSessionMetaData = new SessionMetaData(newSessionInfo, md.getSessionType(), md.getListener()); md.setSessionInfo(newSessionInfo);
entry.setValue(newSessionMetaData); transportCallbackExecutor.submit(() -> md.getListener().onDeviceUpdate(newSessionInfo, device, Optional.ofNullable(newDeviceProfile)));
transportCallbackExecutor.submit(() -> newSessionMetaData.getListener().onDeviceProfileUpdate(device, }
newSessionMetaData.getSessionInfo())); });
} }
protected UUID toSessionId(TransportProtos.SessionInfoProto sessionInfo) { protected UUID toSessionId(TransportProtos.SessionInfoProto sessionInfo) {

View File

@ -27,22 +27,17 @@ import java.util.concurrent.ScheduledFuture;
@Data @Data
class SessionMetaData { class SessionMetaData {
private final TransportProtos.SessionInfoProto sessionInfo; private volatile TransportProtos.SessionInfoProto sessionInfo;
private final TransportProtos.SessionType sessionType; private final TransportProtos.SessionType sessionType;
private final SessionMsgListener listener; private final SessionMsgListener listener;
private ScheduledFuture scheduledFuture; private volatile ScheduledFuture scheduledFuture;
private volatile long lastActivityTime; private volatile long lastActivityTime;
private volatile long lastReportedActivityTime; private volatile long lastReportedActivityTime;
private volatile boolean subscribedToAttributes; private volatile boolean subscribedToAttributes;
private volatile boolean subscribedToRPC; private volatile boolean subscribedToRPC;
SessionMetaData( SessionMetaData(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.SessionType sessionType, SessionMsgListener listener) {
TransportProtos.SessionInfoProto sessionInfo,
TransportProtos.SessionType sessionType,
SessionMsgListener listener
) {
this.sessionInfo = sessionInfo; this.sessionInfo = sessionInfo;
this.sessionType = sessionType; this.sessionType = sessionType;
this.listener = listener; this.listener = listener;
@ -54,11 +49,15 @@ class SessionMetaData {
this.lastActivityTime = System.currentTimeMillis(); this.lastActivityTime = System.currentTimeMillis();
} }
void setScheduledFuture(ScheduledFuture scheduledFuture) { this.scheduledFuture = scheduledFuture; } void setScheduledFuture(ScheduledFuture scheduledFuture) {
this.scheduledFuture = scheduledFuture;
}
public ScheduledFuture getScheduledFuture() { public ScheduledFuture getScheduledFuture() {
return scheduledFuture; return scheduledFuture;
} }
public boolean hasScheduledFuture() { return null != this.scheduledFuture; } public boolean hasScheduledFuture() {
return null != this.scheduledFuture;
}
} }

View File

@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.transport.auth.TransportDeviceInfo; import org.thingsboard.server.common.transport.auth.TransportDeviceInfo;
import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
/** /**
@ -58,16 +59,19 @@ public abstract class DeviceAwareSessionContext implements SessionContext {
} }
@Override @Override
public void onProfileUpdate(DeviceProfile deviceProfile) { public void onDeviceProfileUpdate(TransportProtos.SessionInfoProto sessionInfo, DeviceProfile deviceProfile) {
this.sessionInfo = sessionInfo;
this.deviceProfile = deviceProfile; this.deviceProfile = deviceProfile;
this.deviceInfo.setDeviceType(deviceProfile.getName()); this.deviceInfo.setDeviceType(deviceProfile.getName());
this.sessionInfo = TransportProtos.SessionInfoProto.newBuilder().mergeFrom(sessionInfo).setDeviceType(deviceProfile.getName()).build();
} }
public void onDeviceProfileUpdate(Device device, TransportProtos.SessionInfoProto sessionInfo) { @Override
public void onDeviceUpdate(TransportProtos.SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt) {
this.sessionInfo = sessionInfo;
this.deviceInfo.setDeviceProfileId(device.getDeviceProfileId()); this.deviceInfo.setDeviceProfileId(device.getDeviceProfileId());
this.deviceInfo.setDeviceType(device.getType()); this.deviceInfo.setDeviceType(device.getType());
this.sessionInfo = sessionInfo; deviceProfileOpt.ifPresent(profile -> this.deviceProfile = profile);
} }
public boolean isConnected() { public boolean isConnected() {

View File

@ -19,6 +19,7 @@ import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
public interface SessionContext { public interface SessionContext {
@ -27,7 +28,7 @@ public interface SessionContext {
int nextMsgId(); int nextMsgId();
void onProfileUpdate(DeviceProfile deviceProfile); void onDeviceProfileUpdate(TransportProtos.SessionInfoProto sessionInfo, DeviceProfile deviceProfile);
void onDeviceProfileUpdate(Device device, TransportProtos.SessionInfoProto sessionInfo); void onDeviceUpdate(TransportProtos.SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt);
} }