Fetch LwM2M device profile when restart
This commit is contained in:
commit
4bf8ef1806
@ -78,7 +78,7 @@ public class LwM2MTransportServerConfig implements LwM2MSecureServerConfig {
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Value("${transport.lwm2m.security.key_store:}")
|
@Value("${transport.lwm2m.security.key_store:}")
|
||||||
private String keyStorePathFile;
|
private String keyStoreFilePath;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@ -141,14 +141,27 @@ public class LwM2MTransportServerConfig implements LwM2MSecureServerConfig {
|
|||||||
public void init() {
|
public void init() {
|
||||||
URI uri = null;
|
URI uri = null;
|
||||||
try {
|
try {
|
||||||
uri = Resources.getResource(keyStorePathFile).toURI();
|
InputStream keyStoreInputStream;
|
||||||
log.info("URI: {}", uri);
|
File keyStoreFile = new File(keyStoreFilePath);
|
||||||
File keyStoreFile = new File(uri);
|
if (keyStoreFile.exists()) {
|
||||||
InputStream inKeyStore = new FileInputStream(keyStoreFile);
|
log.info("Reading key store from file {}", keyStoreFilePath);
|
||||||
|
keyStoreInputStream = new FileInputStream(keyStoreFile);
|
||||||
|
} else {
|
||||||
|
InputStream classPathStream = this.getClass().getClassLoader().getResourceAsStream(keyStoreFilePath);
|
||||||
|
if (classPathStream != null) {
|
||||||
|
log.info("Reading key store from class path {}", keyStoreFilePath);
|
||||||
|
keyStoreInputStream = classPathStream;
|
||||||
|
} else {
|
||||||
|
uri = Resources.getResource(keyStoreFilePath).toURI();
|
||||||
|
log.info("Reading key store from URI {}", keyStoreFilePath);
|
||||||
|
keyStoreInputStream = new FileInputStream(new File(uri));
|
||||||
|
}
|
||||||
|
}
|
||||||
keyStoreValue = KeyStore.getInstance(keyStoreType);
|
keyStoreValue = KeyStore.getInstance(keyStoreType);
|
||||||
keyStoreValue.load(inKeyStore, keyStorePassword == null ? null : keyStorePassword.toCharArray());
|
keyStoreValue.load(keyStoreInputStream, keyStorePassword == null ? null : keyStorePassword.toCharArray());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.info("Unable to lookup LwM2M keystore. Reason: {}, {}" , uri, e.getMessage());
|
log.info("Unable to lookup LwM2M keystore. Reason: {}, {}", uri, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,8 @@ import org.eclipse.leshan.server.registration.Registration;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.thingsboard.server.common.data.DeviceProfile;
|
import org.thingsboard.server.common.data.DeviceProfile;
|
||||||
import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
|
import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
|
||||||
|
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
||||||
|
import org.thingsboard.server.common.transport.TransportDeviceProfileCache;
|
||||||
import org.thingsboard.server.common.transport.TransportService;
|
import org.thingsboard.server.common.transport.TransportService;
|
||||||
import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse;
|
import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos;
|
import org.thingsboard.server.gen.transport.TransportProtos;
|
||||||
@ -61,6 +63,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
|
|||||||
private final TbMainSecurityStore securityStore;
|
private final TbMainSecurityStore securityStore;
|
||||||
private final TbLwM2MClientStore clientStore;
|
private final TbLwM2MClientStore clientStore;
|
||||||
private final LwM2MSessionManager sessionManager;
|
private final LwM2MSessionManager sessionManager;
|
||||||
|
private final TransportDeviceProfileCache deviceProfileCache;
|
||||||
private final Map<String, LwM2mClient> lwM2mClientsByEndpoint = new ConcurrentHashMap<>();
|
private final Map<String, LwM2mClient> lwM2mClientsByEndpoint = new ConcurrentHashMap<>();
|
||||||
private final Map<String, LwM2mClient> lwM2mClientsByRegistrationId = new ConcurrentHashMap<>();
|
private final Map<String, LwM2mClient> lwM2mClientsByRegistrationId = new ConcurrentHashMap<>();
|
||||||
private final Map<UUID, Lwm2mDeviceProfileTransportConfiguration> profiles = new ConcurrentHashMap<>();
|
private final Map<UUID, Lwm2mDeviceProfileTransportConfiguration> profiles = new ConcurrentHashMap<>();
|
||||||
@ -231,12 +234,26 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Lwm2mDeviceProfileTransportConfiguration getProfile(UUID profileId) {
|
public Lwm2mDeviceProfileTransportConfiguration getProfile(UUID profileId) {
|
||||||
return profiles.get(profileId);
|
return doGetAndCache(profileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Lwm2mDeviceProfileTransportConfiguration getProfile(Registration registration) {
|
public Lwm2mDeviceProfileTransportConfiguration getProfile(Registration registration) {
|
||||||
return profiles.get(getClientByEndpoint(registration.getEndpoint()).getProfileId());
|
UUID profileId = getClientByEndpoint(registration.getEndpoint()).getProfileId();
|
||||||
|
Lwm2mDeviceProfileTransportConfiguration result = doGetAndCache(profileId);
|
||||||
|
if (result == null) {
|
||||||
|
log.debug("[{}] Fetching profile [{}]", registration.getEndpoint(), profileId);
|
||||||
|
DeviceProfile deviceProfile = deviceProfileCache.get(new DeviceProfileId(profileId));
|
||||||
|
if (deviceProfile != null) {
|
||||||
|
profileUpdate(deviceProfile);
|
||||||
|
result = doGetAndCache(profileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Lwm2mDeviceProfileTransportConfiguration doGetAndCache(UUID profileId) {
|
||||||
|
return profiles.get(profileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -46,7 +46,7 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore {
|
|||||||
lock = redisLock.obtain(toLockKey(endpoint));
|
lock = redisLock.obtain(toLockKey(endpoint));
|
||||||
lock.lock();
|
lock.lock();
|
||||||
byte[] data = connection.get((SEC_EP + endpoint).getBytes());
|
byte[] data = connection.get((SEC_EP + endpoint).getBytes());
|
||||||
if (data == null) {
|
if (data == null || data.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return ((TbLwM2MSecurityInfo) serializer.asObject(data)).getSecurityInfo();
|
return ((TbLwM2MSecurityInfo) serializer.asObject(data)).getSecurityInfo();
|
||||||
@ -69,7 +69,7 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore {
|
|||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
byte[] data = connection.get((SEC_EP + new String(ep)).getBytes());
|
byte[] data = connection.get((SEC_EP + new String(ep)).getBytes());
|
||||||
if (data == null) {
|
if (data == null || data.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return ((TbLwM2MSecurityInfo) serializer.asObject(data)).getSecurityInfo();
|
return ((TbLwM2MSecurityInfo) serializer.asObject(data)).getSecurityInfo();
|
||||||
@ -122,7 +122,11 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore {
|
|||||||
lock = redisLock.obtain(endpoint);
|
lock = redisLock.obtain(endpoint);
|
||||||
lock.lock();
|
lock.lock();
|
||||||
byte[] data = connection.get((SEC_EP + endpoint).getBytes());
|
byte[] data = connection.get((SEC_EP + endpoint).getBytes());
|
||||||
return (TbLwM2MSecurityInfo) serializer.asObject(data);
|
if (data != null && data.length > 0) {
|
||||||
|
return (TbLwM2MSecurityInfo) serializer.asObject(data);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (lock != null) {
|
if (lock != null) {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
@ -137,7 +141,7 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore {
|
|||||||
lock = redisLock.obtain(endpoint);
|
lock = redisLock.obtain(endpoint);
|
||||||
lock.lock();
|
lock.lock();
|
||||||
byte[] data = connection.get((SEC_EP + endpoint).getBytes());
|
byte[] data = connection.get((SEC_EP + endpoint).getBytes());
|
||||||
if (data != null) {
|
if (data != null && data.length > 0) {
|
||||||
SecurityInfo info = ((TbLwM2MSecurityInfo) serializer.asObject(data)).getSecurityInfo();
|
SecurityInfo info = ((TbLwM2MSecurityInfo) serializer.asObject(data)).getSecurityInfo();
|
||||||
if (info != null && info.getIdentity() != null) {
|
if (info != null && info.getIdentity() != null) {
|
||||||
connection.hDel(PSKID_SEC.getBytes(), info.getIdentity().getBytes());
|
connection.hDel(PSKID_SEC.getBytes(), info.getIdentity().getBytes());
|
||||||
|
|||||||
@ -321,20 +321,28 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onDeviceProfileUpdate(SessionInfoProto sessionInfo, DeviceProfile deviceProfile) {
|
public void onDeviceProfileUpdate(SessionInfoProto sessionInfo, DeviceProfile deviceProfile) {
|
||||||
List<LwM2mClient> clients = clientContext.getLwM2mClients()
|
try {
|
||||||
.stream().filter(e -> e.getProfileId().equals(deviceProfile.getUuidId())).collect(Collectors.toList());
|
List<LwM2mClient> clients = clientContext.getLwM2mClients()
|
||||||
clients.forEach(client -> client.onDeviceProfileUpdate(deviceProfile));
|
.stream().filter(e -> e.getProfileId() != null)
|
||||||
if (clients.size() > 0) {
|
.filter(e -> e.getProfileId().equals(deviceProfile.getUuidId())).collect(Collectors.toList());
|
||||||
this.onDeviceProfileUpdate(clients, deviceProfile);
|
clients.forEach(client -> client.onDeviceProfileUpdate(deviceProfile));
|
||||||
|
if (clients.size() > 0) {
|
||||||
|
this.onDeviceProfileUpdate(clients, deviceProfile);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("[{}] failed to update profile: {}", deviceProfile.getId(), deviceProfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDeviceUpdate(SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt) {
|
public void onDeviceUpdate(SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt) {
|
||||||
//TODO: check, maybe device has multiple sessions/registrations? Is this possible according to the standard.
|
try {
|
||||||
LwM2mClient client = clientContext.getClientByDeviceId(device.getUuidId());
|
LwM2mClient client = clientContext.getClientByDeviceId(device.getUuidId());
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
this.onDeviceUpdate(client, device, deviceProfileOpt);
|
this.onDeviceUpdate(client, device, deviceProfileOpt);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("[{}] failed to update device: {}", device.getId(), device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -210,7 +210,6 @@ public class DefaultTransportService implements TransportService {
|
|||||||
}
|
}
|
||||||
records.forEach(record -> {
|
records.forEach(record -> {
|
||||||
try {
|
try {
|
||||||
log.info("[{}] SessionIdMSB, [{}] SessionIdLSB, records", record.getValue().getSessionIdMSB(), record.getValue().getSessionIdLSB());
|
|
||||||
processToTransportMsg(record.getValue());
|
processToTransportMsg(record.getValue());
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
log.warn("Failed to process the notification.", e);
|
log.warn("Failed to process the notification.", e);
|
||||||
@ -771,6 +770,7 @@ public class DefaultTransportService implements TransportService {
|
|||||||
UUID sessionId = new UUID(toSessionMsg.getSessionIdMSB(), toSessionMsg.getSessionIdLSB());
|
UUID sessionId = new UUID(toSessionMsg.getSessionIdMSB(), toSessionMsg.getSessionIdLSB());
|
||||||
SessionMetaData md = sessions.get(sessionId);
|
SessionMetaData md = sessions.get(sessionId);
|
||||||
if (md != null) {
|
if (md != null) {
|
||||||
|
log.trace("[{}] Processing notification: {}", sessionId, toSessionMsg);
|
||||||
SessionMsgListener listener = md.getListener();
|
SessionMsgListener listener = md.getListener();
|
||||||
transportCallbackExecutor.submit(() -> {
|
transportCallbackExecutor.submit(() -> {
|
||||||
if (toSessionMsg.hasGetAttributesResponse()) {
|
if (toSessionMsg.hasGetAttributesResponse()) {
|
||||||
@ -798,12 +798,14 @@ public class DefaultTransportService implements TransportService {
|
|||||||
deregisterSession(md.getSessionInfo());
|
deregisterSession(md.getSessionInfo());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
log.trace("Processing broadcast notification: {}", toSessionMsg);
|
||||||
if (toSessionMsg.hasEntityUpdateMsg()) {
|
if (toSessionMsg.hasEntityUpdateMsg()) {
|
||||||
TransportProtos.EntityUpdateMsg msg = toSessionMsg.getEntityUpdateMsg();
|
TransportProtos.EntityUpdateMsg msg = toSessionMsg.getEntityUpdateMsg();
|
||||||
EntityType entityType = EntityType.valueOf(msg.getEntityType());
|
EntityType entityType = EntityType.valueOf(msg.getEntityType());
|
||||||
if (EntityType.DEVICE_PROFILE.equals(entityType)) {
|
if (EntityType.DEVICE_PROFILE.equals(entityType)) {
|
||||||
DeviceProfile deviceProfile = deviceProfileCache.put(msg.getData());
|
DeviceProfile deviceProfile = deviceProfileCache.put(msg.getData());
|
||||||
if (deviceProfile != null) {
|
if (deviceProfile != null) {
|
||||||
|
log.info("On device profile update: {}", deviceProfile);
|
||||||
onProfileUpdate(deviceProfile);
|
onProfileUpdate(deviceProfile);
|
||||||
}
|
}
|
||||||
} else if (EntityType.TENANT_PROFILE.equals(entityType)) {
|
} else if (EntityType.TENANT_PROFILE.equals(entityType)) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user