lwm2m: fix bug2: TbLwM2mStoreFactory.class "NetworkConfig must not be null"

This commit is contained in:
nick 2024-01-18 18:15:39 +02:00
parent 92353e2820
commit abb907b342
3 changed files with 37 additions and 25 deletions

View File

@ -18,6 +18,7 @@ package org.thingsboard.server.transport.lwm2m.server.store;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import org.eclipse.californium.core.coap.Token; import org.eclipse.californium.core.coap.Token;
import org.eclipse.californium.core.network.RandomTokenGenerator;
import org.eclipse.californium.core.network.TokenGenerator; import org.eclipse.californium.core.network.TokenGenerator;
import org.eclipse.californium.core.network.TokenGenerator.Scope; import org.eclipse.californium.core.network.TokenGenerator.Scope;
import org.eclipse.leshan.core.Destroyable; import org.eclipse.leshan.core.Destroyable;
@ -42,6 +43,7 @@ import org.eclipse.leshan.server.registration.UpdatedRegistration;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
import org.thingsboard.server.transport.lwm2m.server.LwM2mVersionedModelProvider; import org.thingsboard.server.transport.lwm2m.server.LwM2mVersionedModelProvider;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -87,25 +89,27 @@ public class TbInMemoryRegistrationStore implements RegistrationStore, Startable
private boolean started = false; private boolean started = false;
private final long cleanPeriod; // in seconds private final long cleanPeriod; // in seconds
private final TokenGenerator tokenGenerator; private final LwM2MTransportServerConfig config;
private final LwM2mVersionedModelProvider modelProvider; private final LwM2mVersionedModelProvider modelProvider;
private TokenGenerator tokenGenerator;
public TbInMemoryRegistrationStore() { public TbInMemoryRegistrationStore() {
this(null, 2, null); // default clean period : 2s this(null, 2, null); // default clean period : 2s
} }
public TbInMemoryRegistrationStore(TokenGenerator tokenGenerator, long cleanPeriodInSec, LwM2mVersionedModelProvider modelProvider) { public TbInMemoryRegistrationStore(LwM2MTransportServerConfig config, long cleanPeriodInSec, LwM2mVersionedModelProvider modelProvider) {
this(tokenGenerator, Executors.newScheduledThreadPool(1, this(config, Executors.newScheduledThreadPool(1,
new NamedThreadFactory(String.format("TbInMemoryRegistrationStore Cleaner (%ds)", cleanPeriodInSec))), new NamedThreadFactory(String.format("TbInMemoryRegistrationStore Cleaner (%ds)", cleanPeriodInSec))),
cleanPeriodInSec, modelProvider); cleanPeriodInSec, modelProvider);
} }
public TbInMemoryRegistrationStore(TokenGenerator tokenGenerator, ScheduledExecutorService schedExecutor, long cleanPeriodInSec, LwM2mVersionedModelProvider modelProvider) { public TbInMemoryRegistrationStore(LwM2MTransportServerConfig config, ScheduledExecutorService schedExecutor, long cleanPeriodInSec, LwM2mVersionedModelProvider modelProvider) {
this.schedExecutor = schedExecutor; this.schedExecutor = schedExecutor;
this.cleanPeriod = cleanPeriodInSec; this.cleanPeriod = cleanPeriodInSec;
this.modelProvider = modelProvider; this.modelProvider = modelProvider;
this.tokenGenerator = tokenGenerator; this.config = config;
} }
/* *************** Leshan Registration API **************** */ /* *************** Leshan Registration API **************** */
@ -271,7 +275,7 @@ public class TbInMemoryRegistrationStore implements RegistrationStore, Startable
((CompositeObservation)observation).getPaths().forEach(path -> { ((CompositeObservation)observation).getPaths().forEach(path -> {
if (validateObserveResource(path, registrationId)) { if (validateObserveResource(path, registrationId)) {
String serializedObs = createSerializedSingleObservation(nodeSerObs, path.toString()); String serializedObs = createSerializedSingleObservation(nodeSerObs, path.toString());
Observation singleObservation = createSingleObservation(registrationId, path, ct, ctx, serializedObs, tokenGenerator); Observation singleObservation = createSingleObservation(registrationId, path, ct, ctx, serializedObs, getTokenGenerator());
updateSingleObservation(registrationId, (SingleObservation) singleObservation, addIfAbsent, removed); updateSingleObservation(registrationId, (SingleObservation) singleObservation, addIfAbsent, removed);
// cancel existing observations for the same path and registration id. // cancel existing observations for the same path and registration id.
cancelObservation (singleObservation, registrationId, removed); cancelObservation (singleObservation, registrationId, removed);
@ -359,6 +363,13 @@ public class TbInMemoryRegistrationStore implements RegistrationStore, Startable
return result.get(); return result.get();
} }
private TokenGenerator getTokenGenerator(){
if (this.tokenGenerator == null) {
this.tokenGenerator = new RandomTokenGenerator(config.getCoapConfig());
}
return this.tokenGenerator;
}
public static SingleObservation createSingleObservation(String registrationId, LwM2mPath target, ContentFormat ct, public static SingleObservation createSingleObservation(String registrationId, LwM2mPath target, ContentFormat ct,
Map<String, String> ctx, String serializedObservation, TokenGenerator tokenGenerator) { Map<String, String> ctx, String serializedObservation, TokenGenerator tokenGenerator) {
Token token = tokenGenerator.createToken(Scope.SHORT_TERM); Token token = tokenGenerator.createToken(Scope.SHORT_TERM);

View File

@ -18,6 +18,7 @@ package org.thingsboard.server.transport.lwm2m.server.store;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.core.coap.Token; import org.eclipse.californium.core.coap.Token;
import org.eclipse.californium.core.network.RandomTokenGenerator;
import org.eclipse.californium.core.network.TokenGenerator; import org.eclipse.californium.core.network.TokenGenerator;
import org.eclipse.californium.core.network.serialization.UdpDataParser; import org.eclipse.californium.core.network.serialization.UdpDataParser;
import org.eclipse.californium.core.network.serialization.UdpDataSerializer; import org.eclipse.californium.core.network.serialization.UdpDataSerializer;
@ -53,6 +54,7 @@ import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.ScanOptions;
import org.springframework.integration.redis.util.RedisLockRegistry; import org.springframework.integration.redis.util.RedisLockRegistry;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
import org.thingsboard.server.transport.lwm2m.server.LwM2mVersionedModelProvider; import org.thingsboard.server.transport.lwm2m.server.LwM2mVersionedModelProvider;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -118,21 +120,22 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab
private final RedisLockRegistry redisLock; private final RedisLockRegistry redisLock;
private final TokenGenerator tokenGenerator; private final LwM2MTransportServerConfig config;
private TokenGenerator tokenGenerator;
private final LwM2mVersionedModelProvider modelProvider; private final LwM2mVersionedModelProvider modelProvider;
public TbLwM2mRedisRegistrationStore(TokenGenerator tokenGenerator,RedisConnectionFactory connectionFactory, LwM2mVersionedModelProvider modelProvider) { public TbLwM2mRedisRegistrationStore(LwM2MTransportServerConfig config, RedisConnectionFactory connectionFactory, LwM2mVersionedModelProvider modelProvider) {
this(tokenGenerator, connectionFactory, DEFAULT_CLEAN_PERIOD, DEFAULT_GRACE_PERIOD, DEFAULT_CLEAN_LIMIT, modelProvider); // default clean period 60s this(config, connectionFactory, DEFAULT_CLEAN_PERIOD, DEFAULT_GRACE_PERIOD, DEFAULT_CLEAN_LIMIT, modelProvider); // default clean period 60s
} }
public TbLwM2mRedisRegistrationStore(TokenGenerator tokenGenerator, RedisConnectionFactory connectionFactory, long cleanPeriodInSec, long lifetimeGracePeriodInSec, int cleanLimit, LwM2mVersionedModelProvider modelProvider) { public TbLwM2mRedisRegistrationStore(LwM2MTransportServerConfig config, RedisConnectionFactory connectionFactory, long cleanPeriodInSec, long lifetimeGracePeriodInSec, int cleanLimit, LwM2mVersionedModelProvider modelProvider) {
this(tokenGenerator, connectionFactory, Executors.newScheduledThreadPool(1, this(config, connectionFactory, Executors.newScheduledThreadPool(1,
new NamedThreadFactory(String.format("RedisRegistrationStore Cleaner (%ds)", cleanPeriodInSec))), new NamedThreadFactory(String.format("RedisRegistrationStore Cleaner (%ds)", cleanPeriodInSec))),
cleanPeriodInSec, lifetimeGracePeriodInSec, cleanLimit, modelProvider); cleanPeriodInSec, lifetimeGracePeriodInSec, cleanLimit, modelProvider);
} }
public TbLwM2mRedisRegistrationStore(TokenGenerator tokenGenerator,RedisConnectionFactory connectionFactory, ScheduledExecutorService schedExecutor, long cleanPeriodInSec, public TbLwM2mRedisRegistrationStore(LwM2MTransportServerConfig config, RedisConnectionFactory connectionFactory, ScheduledExecutorService schedExecutor, long cleanPeriodInSec,
long lifetimeGracePeriodInSec, int cleanLimit, LwM2mVersionedModelProvider modelProvider) { long lifetimeGracePeriodInSec, int cleanLimit, LwM2mVersionedModelProvider modelProvider) {
this.connectionFactory = connectionFactory; this.connectionFactory = connectionFactory;
this.schedExecutor = schedExecutor; this.schedExecutor = schedExecutor;
@ -140,7 +143,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab
this.cleanLimit = cleanLimit; this.cleanLimit = cleanLimit;
this.gracePeriod = lifetimeGracePeriodInSec; this.gracePeriod = lifetimeGracePeriodInSec;
this.redisLock = new RedisLockRegistry(connectionFactory, "Registration"); this.redisLock = new RedisLockRegistry(connectionFactory, "Registration");
this.tokenGenerator = tokenGenerator; this.config = config;
this.modelProvider = modelProvider; this.modelProvider = modelProvider;
} }
@ -508,7 +511,7 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab
((CompositeObservation)observation).getPaths().forEach(path -> { ((CompositeObservation)observation).getPaths().forEach(path -> {
if (validateObserveResource(path, registrationId)) { if (validateObserveResource(path, registrationId)) {
String serializedObs = createSerializedSingleObservation(nodeSerObs, path.toString()); String serializedObs = createSerializedSingleObservation(nodeSerObs, path.toString());
SingleObservation singleObservation = createSingleObservation(registrationId, path, ct, ctx, serializedObs, tokenGenerator); SingleObservation singleObservation = createSingleObservation(registrationId, path, ct, ctx, serializedObs, getTokenGenerator());
updateSingleObservation(registrationId, singleObservation, addIfAbsent, removed, connection); updateSingleObservation(registrationId, singleObservation, addIfAbsent, removed, connection);
// cancel existing observations for the same path and registration id. // cancel existing observations for the same path and registration id.
cancelObservation (singleObservation, registrationId, removed, connection); cancelObservation (singleObservation, registrationId, removed, connection);
@ -706,6 +709,13 @@ public class TbLwM2mRedisRegistrationStore implements RegistrationStore, Startab
/* *************** Observation utility functions **************** */ /* *************** Observation utility functions **************** */
private TokenGenerator getTokenGenerator(){
if (this.tokenGenerator == null) {
this.tokenGenerator = new RandomTokenGenerator(config.getCoapConfig());
}
return this.tokenGenerator;
}
private void unsafeRemoveObservation(RedisConnection connection, String registrationId, byte[] observationId) { private void unsafeRemoveObservation(RedisConnection connection, String registrationId, byte[] observationId) {
if (connection.commands().del(toKey(OBS_TKN, observationId)) > 0L) { if (connection.commands().del(toKey(OBS_TKN, observationId)) > 0L) {
connection.listCommands().lRem(toKey(OBS_TKNS_REGID_IDX, registrationId), 0, observationId); connection.listCommands().lRem(toKey(OBS_TKNS_REGID_IDX, registrationId), 0, observationId);

View File

@ -17,10 +17,8 @@ package org.thingsboard.server.transport.lwm2m.server.store;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.core.network.RandomTokenGenerator;
import org.eclipse.leshan.server.registration.RegistrationStore; import org.eclipse.leshan.server.registration.RegistrationStore;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.cache.TBRedisCacheConfiguration; import org.thingsboard.server.cache.TBRedisCacheConfiguration;
@ -38,22 +36,15 @@ import java.util.Optional;
public class TbLwM2mStoreFactory { public class TbLwM2mStoreFactory {
private final Optional<TBRedisCacheConfiguration> redisConfiguration; private final Optional<TBRedisCacheConfiguration> redisConfiguration;
@Lazy
private final LwM2MTransportServerConfig config; private final LwM2MTransportServerConfig config;
private final LwM2mCredentialsSecurityInfoValidator validator; private final LwM2mCredentialsSecurityInfoValidator validator;
private final LwM2mVersionedModelProvider modelProvider; private final LwM2mVersionedModelProvider modelProvider;
@Bean @Bean
private RegistrationStore registrationStore() { private RegistrationStore registrationStore() {
if (config == null || config.getCoapConfig() == null) {
log.error("For the test: CoapConfig is null!");
} else {
log.info("For the test: CoapConfig: is ok!");
}
return redisConfiguration.isPresent() ? return redisConfiguration.isPresent() ?
new TbLwM2mRedisRegistrationStore(new RandomTokenGenerator(config.getCoapConfig()), getConnectionFactory(), modelProvider) : new TbLwM2mRedisRegistrationStore(config, getConnectionFactory(), modelProvider) :
new TbInMemoryRegistrationStore(new RandomTokenGenerator(config.getCoapConfig()), config.getCleanPeriodInSec(), modelProvider); new TbInMemoryRegistrationStore(config, config.getCleanPeriodInSec(), modelProvider);
} }
@Bean @Bean