Merge branch 'master' of github.com:thingsboard/thingsboard into develop/3.0

This commit is contained in:
Igor Kulikov 2020-04-29 11:43:10 +03:00
commit d3cbfdce27

View File

@ -54,6 +54,8 @@ import java.util.Set;
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;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/** /**
* Created by ashvayka on 19.01.17. * Created by ashvayka on 19.01.17.
@ -69,7 +71,9 @@ public class GatewaySessionHandler {
private final TransportService transportService; private final TransportService transportService;
private final DeviceInfoProto gateway; private final DeviceInfoProto gateway;
private final UUID sessionId; private final UUID sessionId;
private final Map<String, GatewayDeviceSessionCtx> devices; private final Lock deviceCreationLock = new ReentrantLock();
private final ConcurrentMap<String, GatewayDeviceSessionCtx> devices;
private final ConcurrentMap<String, SettableFuture<GatewayDeviceSessionCtx>> deviceFutures;
private final ConcurrentMap<MqttTopicMatcher, Integer> mqttQoSMap; private final ConcurrentMap<MqttTopicMatcher, Integer> mqttQoSMap;
private final ChannelHandlerContext channel; private final ChannelHandlerContext channel;
private final DeviceSessionCtx deviceSessionCtx; private final DeviceSessionCtx deviceSessionCtx;
@ -81,6 +85,7 @@ public class GatewaySessionHandler {
this.gateway = deviceSessionCtx.getDeviceInfo(); this.gateway = deviceSessionCtx.getDeviceInfo();
this.sessionId = sessionId; this.sessionId = sessionId;
this.devices = new ConcurrentHashMap<>(); this.devices = new ConcurrentHashMap<>();
this.deviceFutures = new ConcurrentHashMap<>();
this.mqttQoSMap = deviceSessionCtx.getMqttQoSMap(); this.mqttQoSMap = deviceSessionCtx.getMqttQoSMap();
this.channel = deviceSessionCtx.getChannel(); this.channel = deviceSessionCtx.getChannel();
} }
@ -106,9 +111,30 @@ public class GatewaySessionHandler {
} }
private ListenableFuture<GatewayDeviceSessionCtx> onDeviceConnect(String deviceName, String deviceType) { private ListenableFuture<GatewayDeviceSessionCtx> onDeviceConnect(String deviceName, String deviceType) {
SettableFuture<GatewayDeviceSessionCtx> future = SettableFuture.create();
GatewayDeviceSessionCtx result = devices.get(deviceName); GatewayDeviceSessionCtx result = devices.get(deviceName);
if (result == null) { if (result == null) {
deviceCreationLock.lock();
try {
result = devices.get(deviceName);
if (result == null) {
return getDeviceCreationFuture(deviceName, deviceType);
} else {
return toCompletedFuture(result);
}
} finally {
deviceCreationLock.unlock();
}
} else {
return toCompletedFuture(result);
}
}
private ListenableFuture<GatewayDeviceSessionCtx> getDeviceCreationFuture(String deviceName, String deviceType) {
SettableFuture<GatewayDeviceSessionCtx> future = deviceFutures.get(deviceName);
if (future == null) {
final SettableFuture<GatewayDeviceSessionCtx> futureToSet = SettableFuture.create();
deviceFutures.put(deviceName, futureToSet);
try {
transportService.process(GetOrCreateDeviceFromGatewayRequestMsg.newBuilder() transportService.process(GetOrCreateDeviceFromGatewayRequestMsg.newBuilder()
.setDeviceName(deviceName) .setDeviceName(deviceName)
.setDeviceType(deviceType) .setDeviceType(deviceType)
@ -125,18 +151,30 @@ public class GatewaySessionHandler {
transportService.process(deviceSessionInfo, TransportProtos.SubscribeToRPCMsg.getDefaultInstance(), null); transportService.process(deviceSessionInfo, TransportProtos.SubscribeToRPCMsg.getDefaultInstance(), null);
transportService.process(deviceSessionInfo, TransportProtos.SubscribeToAttributeUpdatesMsg.getDefaultInstance(), null); transportService.process(deviceSessionInfo, TransportProtos.SubscribeToAttributeUpdatesMsg.getDefaultInstance(), null);
} }
future.set(devices.get(deviceName)); futureToSet.set(devices.get(deviceName));
deviceFutures.remove(deviceName);
} }
@Override @Override
public void onError(Throwable e) { public void onError(Throwable e) {
log.warn("[{}] Failed to process device connect command: {}", sessionId, deviceName, e); log.warn("[{}] Failed to process device connect command: {}", sessionId, deviceName, e);
future.setException(e); futureToSet.setException(e);
deviceFutures.remove(deviceName);
} }
}); });
} else { return futureToSet;
future.set(result); } catch (Throwable e) {
deviceFutures.remove(deviceName);
throw e;
} }
} else {
return future;
}
}
private ListenableFuture<GatewayDeviceSessionCtx> toCompletedFuture(GatewayDeviceSessionCtx result) {
SettableFuture<GatewayDeviceSessionCtx> future = SettableFuture.create();
future.set(result);
return future; return future;
} }