Showing
11 changed files
with
423 additions
and
398 deletions
... | ... | @@ -32,7 +32,7 @@ import org.springframework.stereotype.Service; |
32 | 32 | import org.thingsboard.server.gen.transport.TransportProtos; |
33 | 33 | import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; |
34 | 34 | import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; |
35 | -import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; | |
35 | +import org.thingsboard.server.transport.lwm2m.secure.EndpointSecurityInfo; | |
36 | 36 | import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener; |
37 | 37 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext; |
38 | 38 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper; |
... | ... | @@ -72,7 +72,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { |
72 | 72 | |
73 | 73 | @Override |
74 | 74 | public List<SecurityInfo> getAllByEndpoint(String endPoint) { |
75 | - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(endPoint, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP); | |
75 | + EndpointSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(endPoint, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP); | |
76 | 76 | if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { |
77 | 77 | /* add value to store from BootstrapJson */ |
78 | 78 | this.setBootstrapConfigScurityInfo(store); |
... | ... | @@ -96,7 +96,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { |
96 | 96 | |
97 | 97 | @Override |
98 | 98 | public SecurityInfo getByIdentity(String identity) { |
99 | - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP); | |
99 | + EndpointSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(identity, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP); | |
100 | 100 | if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { |
101 | 101 | /* add value to store from BootstrapJson */ |
102 | 102 | this.setBootstrapConfigScurityInfo(store); |
... | ... | @@ -113,7 +113,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { |
113 | 113 | return null; |
114 | 114 | } |
115 | 115 | |
116 | - private void setBootstrapConfigScurityInfo(ReadResultSecurityStore store) { | |
116 | + private void setBootstrapConfigScurityInfo(EndpointSecurityInfo store) { | |
117 | 117 | /* BootstrapConfig */ |
118 | 118 | LwM2MBootstrapConfig lwM2MBootstrapConfig = this.getParametersBootstrap(store); |
119 | 119 | if (lwM2MBootstrapConfig != null) { |
... | ... | @@ -150,7 +150,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { |
150 | 150 | } |
151 | 151 | } |
152 | 152 | |
153 | - private LwM2MBootstrapConfig getParametersBootstrap(ReadResultSecurityStore store) { | |
153 | + private LwM2MBootstrapConfig getParametersBootstrap(EndpointSecurityInfo store) { | |
154 | 154 | try { |
155 | 155 | JsonObject bootstrapJsonCredential = store.getBootstrapJsonCredential(); |
156 | 156 | if (bootstrapJsonCredential != null) { | ... | ... |
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/EndpointSecurityInfo.java
renamed from
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/ReadResultSecurityStore.java
... | ... | @@ -25,7 +25,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCreden |
25 | 25 | import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.DEFAULT_MODE; |
26 | 26 | |
27 | 27 | @Data |
28 | -public class ReadResultSecurityStore { | |
28 | +public class EndpointSecurityInfo { | |
29 | 29 | private ValidateDeviceCredentialsResponseMsg msg; |
30 | 30 | private SecurityInfo securityInfo; |
31 | 31 | private int securityMode = DEFAULT_MODE.code; | ... | ... |
... | ... | @@ -52,15 +52,10 @@ public class LwM2mCredentialsSecurityInfoValidator { |
52 | 52 | private final LwM2mTransportContext context; |
53 | 53 | private final LwM2MTransportServerConfig config; |
54 | 54 | |
55 | - /** | |
56 | - * Request to thingsboard Response from thingsboard ValidateDeviceLwM2MCredentials | |
57 | - * @param endpoint - | |
58 | - * @param keyValue - | |
59 | - * @return ValidateDeviceCredentialsResponseMsg and SecurityInfo | |
60 | - */ | |
61 | - public ReadResultSecurityStore createAndValidateCredentialsSecurityInfo(String endpoint, LwM2mTransportUtil.LwM2mTypeServer keyValue) { | |
55 | + | |
56 | + public EndpointSecurityInfo getEndpointSecurityInfo(String endpoint, LwM2mTransportUtil.LwM2mTypeServer keyValue) { | |
62 | 57 | CountDownLatch latch = new CountDownLatch(1); |
63 | - final ReadResultSecurityStore[] resultSecurityStore = new ReadResultSecurityStore[1]; | |
58 | + final EndpointSecurityInfo[] resultSecurityStore = new EndpointSecurityInfo[1]; | |
64 | 59 | context.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(endpoint).build(), |
65 | 60 | new TransportServiceCallback<>() { |
66 | 61 | @Override |
... | ... | @@ -90,27 +85,27 @@ public class LwM2mCredentialsSecurityInfoValidator { |
90 | 85 | |
91 | 86 | /** |
92 | 87 | * Create new SecurityInfo |
93 | - * @param endPoint - | |
88 | + * @param endpoint - | |
94 | 89 | * @param jsonStr - |
95 | 90 | * @param keyValue - |
96 | 91 | * @return SecurityInfo |
97 | 92 | */ |
98 | - private ReadResultSecurityStore createSecurityInfo(String endPoint, String jsonStr, LwM2mTransportUtil.LwM2mTypeServer keyValue) { | |
99 | - ReadResultSecurityStore result = new ReadResultSecurityStore(); | |
93 | + private EndpointSecurityInfo createSecurityInfo(String endpoint, String jsonStr, LwM2mTransportUtil.LwM2mTypeServer keyValue) { | |
94 | + EndpointSecurityInfo result = new EndpointSecurityInfo(); | |
100 | 95 | JsonObject objectMsg = LwM2mTransportUtil.validateJson(jsonStr); |
101 | 96 | if (objectMsg != null && !objectMsg.isJsonNull()) { |
102 | 97 | JsonObject object = (objectMsg.has(keyValue.type) && !objectMsg.get(keyValue.type).isJsonNull()) ? objectMsg.get(keyValue.type).getAsJsonObject() : null; |
103 | 98 | /** |
104 | 99 | * Only PSK |
105 | 100 | */ |
106 | - String endPointPsk = (objectMsg.has("client") | |
101 | + String endpointPsk = (objectMsg.has("client") | |
107 | 102 | && objectMsg.get("client").getAsJsonObject().has("endpoint") |
108 | 103 | && objectMsg.get("client").getAsJsonObject().get("endpoint").isJsonPrimitive()) ? objectMsg.get("client").getAsJsonObject().get("endpoint").getAsString() : null; |
109 | - endPoint = (endPointPsk == null || endPointPsk.isEmpty()) ? endPoint : endPointPsk; | |
104 | + endpoint = (endpointPsk == null || endpointPsk.isEmpty()) ? endpoint : endpointPsk; | |
110 | 105 | if (object != null && !object.isJsonNull()) { |
111 | 106 | if (keyValue.equals(LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP)) { |
112 | 107 | result.setBootstrapJsonCredential(object); |
113 | - result.setEndPoint(endPoint); | |
108 | + result.setEndPoint(endpoint); | |
114 | 109 | result.setSecurityMode(LwM2MSecurityMode.fromSecurityMode(object.get("bootstrapServer").getAsJsonObject().get("securityMode").getAsString().toLowerCase()).code); |
115 | 110 | } else { |
116 | 111 | LwM2MSecurityMode lwM2MSecurityMode = LwM2MSecurityMode.fromSecurityMode(object.get("securityConfigClientMode").getAsString().toLowerCase()); |
... | ... | @@ -119,13 +114,13 @@ public class LwM2mCredentialsSecurityInfoValidator { |
119 | 114 | createClientSecurityInfoNoSec(result); |
120 | 115 | break; |
121 | 116 | case PSK: |
122 | - createClientSecurityInfoPSK(result, endPoint, object); | |
117 | + createClientSecurityInfoPSK(result, endpoint, object); | |
123 | 118 | break; |
124 | 119 | case RPK: |
125 | - createClientSecurityInfoRPK(result, endPoint, object); | |
120 | + createClientSecurityInfoRPK(result, endpoint, object); | |
126 | 121 | break; |
127 | 122 | case X509: |
128 | - createClientSecurityInfoX509(result, endPoint); | |
123 | + createClientSecurityInfoX509(result, endpoint); | |
129 | 124 | break; |
130 | 125 | default: |
131 | 126 | break; |
... | ... | @@ -136,20 +131,20 @@ public class LwM2mCredentialsSecurityInfoValidator { |
136 | 131 | return result; |
137 | 132 | } |
138 | 133 | |
139 | - private void createClientSecurityInfoNoSec(ReadResultSecurityStore result) { | |
134 | + private void createClientSecurityInfoNoSec(EndpointSecurityInfo result) { | |
140 | 135 | result.setSecurityInfo(null); |
141 | 136 | result.setSecurityMode(NO_SEC.code); |
142 | 137 | } |
143 | 138 | |
144 | - private void createClientSecurityInfoPSK(ReadResultSecurityStore result, String endPoint, JsonObject object) { | |
139 | + private void createClientSecurityInfoPSK(EndpointSecurityInfo result, String endpoint, JsonObject object) { | |
145 | 140 | /** PSK Deserialization */ |
146 | 141 | String identity = (object.has("identity") && object.get("identity").isJsonPrimitive()) ? object.get("identity").getAsString() : null; |
147 | 142 | if (identity != null && !identity.isEmpty()) { |
148 | 143 | try { |
149 | 144 | byte[] key = (object.has("key") && object.get("key").isJsonPrimitive()) ? Hex.decodeHex(object.get("key").getAsString().toCharArray()) : null; |
150 | 145 | if (key != null && key.length > 0) { |
151 | - if (endPoint != null && !endPoint.isEmpty()) { | |
152 | - result.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(endPoint, identity, key)); | |
146 | + if (endpoint != null && !endpoint.isEmpty()) { | |
147 | + result.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(endpoint, identity, key)); | |
153 | 148 | result.setSecurityMode(PSK.code); |
154 | 149 | } |
155 | 150 | } |
... | ... | @@ -161,7 +156,7 @@ public class LwM2mCredentialsSecurityInfoValidator { |
161 | 156 | } |
162 | 157 | } |
163 | 158 | |
164 | - private void createClientSecurityInfoRPK(ReadResultSecurityStore result, String endpoint, JsonObject object) { | |
159 | + private void createClientSecurityInfoRPK(EndpointSecurityInfo result, String endpoint, JsonObject object) { | |
165 | 160 | try { |
166 | 161 | if (object.has("key") && object.get("key").isJsonPrimitive()) { |
167 | 162 | byte[] rpkkey = Hex.decodeHex(object.get("key").getAsString().toLowerCase().toCharArray()); |
... | ... | @@ -176,7 +171,7 @@ public class LwM2mCredentialsSecurityInfoValidator { |
176 | 171 | } |
177 | 172 | } |
178 | 173 | |
179 | - private void createClientSecurityInfoX509(ReadResultSecurityStore result, String endpoint) { | |
174 | + private void createClientSecurityInfoX509(EndpointSecurityInfo result, String endpoint) { | |
180 | 175 | result.setSecurityInfo(SecurityInfo.newX509CertInfo(endpoint)); |
181 | 176 | result.setSecurityMode(X509.code); |
182 | 177 | } | ... | ... |
... | ... | @@ -32,11 +32,11 @@ import org.eclipse.leshan.core.observation.Observation; |
32 | 32 | import org.eclipse.leshan.core.request.ContentFormat; |
33 | 33 | import org.eclipse.leshan.core.request.WriteRequest; |
34 | 34 | import org.eclipse.leshan.core.response.ReadResponse; |
35 | -import org.eclipse.leshan.core.util.NamedThreadFactory; | |
36 | 35 | import org.eclipse.leshan.server.registration.Registration; |
37 | 36 | import org.springframework.context.annotation.Lazy; |
38 | 37 | import org.springframework.stereotype.Service; |
39 | 38 | import org.thingsboard.common.util.JacksonUtil; |
39 | +import org.thingsboard.common.util.ThingsBoardExecutors; | |
40 | 40 | import org.thingsboard.server.cache.firmware.FirmwareDataCache; |
41 | 41 | import org.thingsboard.server.common.data.Device; |
42 | 42 | import org.thingsboard.server.common.data.DeviceProfile; |
... | ... | @@ -66,8 +66,8 @@ import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; |
66 | 66 | import javax.annotation.PostConstruct; |
67 | 67 | import java.util.ArrayList; |
68 | 68 | import java.util.Collection; |
69 | +import java.util.Collections; | |
69 | 70 | import java.util.HashSet; |
70 | -import java.util.LinkedHashSet; | |
71 | 71 | import java.util.List; |
72 | 72 | import java.util.Map; |
73 | 73 | import java.util.Optional; |
... | ... | @@ -77,7 +77,6 @@ import java.util.UUID; |
77 | 77 | import java.util.concurrent.ConcurrentHashMap; |
78 | 78 | import java.util.concurrent.ConcurrentMap; |
79 | 79 | import java.util.concurrent.ExecutorService; |
80 | -import java.util.concurrent.Executors; | |
81 | 80 | import java.util.concurrent.TimeUnit; |
82 | 81 | import java.util.stream.Collectors; |
83 | 82 | |
... | ... | @@ -85,6 +84,7 @@ import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST; |
85 | 84 | import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; |
86 | 85 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY; |
87 | 86 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; |
87 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper.getValueFromKvProto; | |
88 | 88 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.CLIENT_NOT_AUTHORIZED; |
89 | 89 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.DEVICE_ATTRIBUTES_REQUEST; |
90 | 90 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FR_OBJECT_ID; |
... | ... | @@ -103,7 +103,6 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.L |
103 | 103 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES; |
104 | 104 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE; |
105 | 105 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_UPDATE; |
106 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SERVICE_CHANNEL; | |
107 | 106 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertJsonArrayToSet; |
108 | 107 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromIdVerToObjectId; |
109 | 108 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer; |
... | ... | @@ -115,9 +114,9 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.v |
115 | 114 | @TbLwM2mTransportComponent |
116 | 115 | public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler { |
117 | 116 | |
118 | - private ExecutorService executorRegistered; | |
119 | - private ExecutorService executorUpdateRegistered; | |
120 | - private ExecutorService executorUnRegistered; | |
117 | + private ExecutorService registrationExecutor; | |
118 | + private ExecutorService updateRegistrationExecutor; | |
119 | + private ExecutorService unregistrationExecutor; | |
121 | 120 | private LwM2mValueConverterImpl converter; |
122 | 121 | |
123 | 122 | private final TransportService transportService; |
... | ... | @@ -126,18 +125,18 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
126 | 125 | private final FirmwareDataCache firmwareDataCache; |
127 | 126 | private final LwM2mTransportServerHelper helper; |
128 | 127 | private final LwM2MJsonAdaptor adaptor; |
129 | - private final LwM2mClientContext lwM2mClientContext; | |
128 | + private final LwM2mClientContext clientContext; | |
130 | 129 | private final LwM2mTransportRequest lwM2mTransportRequest; |
131 | 130 | |
132 | 131 | public DefaultLwM2MTransportMsgHandler(TransportService transportService, LwM2MTransportServerConfig config, LwM2mTransportServerHelper helper, |
133 | - LwM2mClientContext lwM2mClientContext, | |
132 | + LwM2mClientContext clientContext, | |
134 | 133 | @Lazy LwM2mTransportRequest lwM2mTransportRequest, |
135 | 134 | FirmwareDataCache firmwareDataCache, |
136 | 135 | LwM2mTransportContext context, LwM2MJsonAdaptor adaptor) { |
137 | 136 | this.transportService = transportService; |
138 | 137 | this.config = config; |
139 | 138 | this.helper = helper; |
140 | - this.lwM2mClientContext = lwM2mClientContext; | |
139 | + this.clientContext = clientContext; | |
141 | 140 | this.lwM2mTransportRequest = lwM2mTransportRequest; |
142 | 141 | this.firmwareDataCache = firmwareDataCache; |
143 | 142 | this.context = context; |
... | ... | @@ -146,13 +145,10 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
146 | 145 | |
147 | 146 | @PostConstruct |
148 | 147 | public void init() { |
149 | - this.context.getScheduler().scheduleAtFixedRate(this::checkInactivityAndReportActivity, new Random().nextInt((int) config.getSessionReportTimeout()), config.getSessionReportTimeout(), TimeUnit.MILLISECONDS); | |
150 | - this.executorRegistered = Executors.newFixedThreadPool(this.config.getRegisteredPoolSize(), | |
151 | - new NamedThreadFactory(String.format("LwM2M %s channel registered", SERVICE_CHANNEL))); | |
152 | - this.executorUpdateRegistered = Executors.newFixedThreadPool(this.config.getUpdateRegisteredPoolSize(), | |
153 | - new NamedThreadFactory(String.format("LwM2M %s channel update registered", SERVICE_CHANNEL))); | |
154 | - this.executorUnRegistered = Executors.newFixedThreadPool(this.config.getUnRegisteredPoolSize(), | |
155 | - new NamedThreadFactory(String.format("LwM2M %s channel un registered", SERVICE_CHANNEL))); | |
148 | + this.context.getScheduler().scheduleAtFixedRate(this::reportActivity, new Random().nextInt((int) config.getSessionReportTimeout()), config.getSessionReportTimeout(), TimeUnit.MILLISECONDS); | |
149 | + this.registrationExecutor = ThingsBoardExecutors.newWorkStealingPool(this.config.getRegisteredPoolSize(), "LwM2M registration"); | |
150 | + this.updateRegistrationExecutor = ThingsBoardExecutors.newWorkStealingPool(this.config.getUpdateRegisteredPoolSize(), "LwM2M update registration"); | |
151 | + this.unregistrationExecutor = ThingsBoardExecutors.newWorkStealingPool(this.config.getUnRegisteredPoolSize(), "LwM2M unregistration"); | |
156 | 152 | this.converter = LwM2mValueConverterImpl.getInstance(); |
157 | 153 | } |
158 | 154 | |
... | ... | @@ -171,14 +167,13 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
171 | 167 | * @param previousObservations - may be null |
172 | 168 | */ |
173 | 169 | public void onRegistered(Registration registration, Collection<Observation> previousObservations) { |
174 | - executorRegistered.submit(() -> { | |
170 | + registrationExecutor.submit(() -> { | |
175 | 171 | try { |
176 | 172 | log.warn("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId()); |
177 | - LwM2mClient lwM2MClient = this.lwM2mClientContext.updateInSessionsLwM2MClient(registration); | |
173 | + LwM2mClient lwM2MClient = this.clientContext.registerOrUpdate(registration); | |
178 | 174 | if (lwM2MClient != null) { |
179 | - SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration); | |
175 | + SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); | |
180 | 176 | if (sessionInfo != null) { |
181 | - this.initLwM2mClient(lwM2MClient, sessionInfo); | |
182 | 177 | transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo)); |
183 | 178 | transportService.process(sessionInfo, DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN), null); |
184 | 179 | transportService.process(sessionInfo, TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build(), null); |
... | ... | @@ -204,24 +199,18 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
204 | 199 | * @param registration - Registration LwM2M Client |
205 | 200 | */ |
206 | 201 | public void updatedReg(Registration registration) { |
207 | - executorUpdateRegistered.submit(() -> { | |
202 | + updateRegistrationExecutor.submit(() -> { | |
208 | 203 | try { |
209 | - SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration); | |
210 | - if (sessionInfo != null) { | |
211 | - this.checkInactivity(sessionInfo); | |
212 | - LwM2mClient lwM2MClient = this.lwM2mClientContext.getLwM2MClient(sessionInfo); | |
213 | - if (lwM2MClient.getDeviceId() == null && lwM2MClient.getProfileId() == null) { | |
214 | - initLwM2mClient(lwM2MClient, sessionInfo); | |
215 | - } else { | |
216 | - if (registration.getBindingMode().useQueueMode()) { | |
217 | - LwM2mQueuedRequest request; | |
218 | - while ((request = lwM2MClient.getQueuedRequests().poll()) != null) { | |
219 | - request.send(); | |
220 | - } | |
204 | + LwM2mClient client = clientContext.getOrRegister(registration); | |
205 | + if (client != null && client.getSession() != null) { | |
206 | + SessionInfoProto sessionInfo = client.getSession(); | |
207 | + this.reportActivityAndRegister(sessionInfo); | |
208 | + if (registration.getBindingMode().useQueueMode()) { | |
209 | + LwM2mQueuedRequest request; | |
210 | + while ((request = client.getQueuedRequests().poll()) != null) { | |
211 | + request.send(); | |
221 | 212 | } |
222 | 213 | } |
223 | - | |
224 | - log.info("Client: [{}] updatedReg [{}] name [{}] profile ", registration.getId(), registration.getEndpoint(), sessionInfo.getDeviceType()); | |
225 | 214 | } else { |
226 | 215 | log.error("Client: [{}] updatedReg [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null); |
227 | 216 | } |
... | ... | @@ -237,7 +226,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
237 | 226 | * !!! Warn: if have not finishing unReg, then this operation will be finished on next Client`s connect |
238 | 227 | */ |
239 | 228 | public void unReg(Registration registration, Collection<Observation> observations) { |
240 | - executorUnRegistered.submit(() -> { | |
229 | + unregistrationExecutor.submit(() -> { | |
241 | 230 | try { |
242 | 231 | this.setCancelObservations(registration); |
243 | 232 | this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client unRegistration", registration.getId()); |
... | ... | @@ -248,22 +237,12 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
248 | 237 | }); |
249 | 238 | } |
250 | 239 | |
251 | - private void initLwM2mClient(LwM2mClient lwM2MClient, SessionInfoProto sessionInfo) { | |
252 | - lwM2MClient.setDeviceId(new UUID(sessionInfo.getDeviceIdMSB(), sessionInfo.getDeviceIdLSB())); | |
253 | - lwM2MClient.setProfileId(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB())); | |
254 | - lwM2MClient.setDeviceName(sessionInfo.getDeviceName()); | |
255 | - lwM2MClient.setDeviceProfileName(sessionInfo.getDeviceType()); | |
256 | - } | |
257 | - | |
258 | 240 | private void closeClientSession(Registration registration) { |
259 | - SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration); | |
241 | + SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(registration); | |
260 | 242 | if (sessionInfo != null) { |
261 | 243 | transportService.deregisterSession(sessionInfo); |
262 | 244 | this.doCloseSession(sessionInfo); |
263 | - lwM2mClientContext.delRemoveSessionAndListener(registration.getId()); | |
264 | - if (lwM2mClientContext.getProfiles().size() > 0) { | |
265 | - this.syncSessionsAndProfiles(); | |
266 | - } | |
245 | + clientContext.removeClientByRegistrationId(registration.getId()); | |
267 | 246 | log.info("Client close session: [{}] unReg [{}] name [{}] profile ", registration.getId(), registration.getEndpoint(), sessionInfo.getDeviceType()); |
268 | 247 | } else { |
269 | 248 | log.error("Client close session: [{}] unReg [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null); |
... | ... | @@ -331,12 +310,12 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
331 | 310 | */ |
332 | 311 | @Override |
333 | 312 | public void onAttributeUpdate(AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo) { |
334 | - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); | |
313 | + LwM2mClient lwM2MClient = clientContext.getClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); | |
335 | 314 | if (msg.getSharedUpdatedCount() > 0) { |
336 | 315 | msg.getSharedUpdatedList().forEach(tsKvProto -> { |
337 | 316 | String pathName = tsKvProto.getKv().getKey(); |
338 | 317 | String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName); |
339 | - Object valueNew = LwM2mTransportServerHelper.getValueFromKvProto(tsKvProto.getKv()); | |
318 | + Object valueNew = getValueFromKvProto(tsKvProto.getKv()); | |
340 | 319 | //TODO: react on change of the firmware name. |
341 | 320 | if (FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName) && !valueNew.equals(lwM2MClient.getFrUpdate().getCurrentFwVersion())) { |
342 | 321 | this.getInfoFirmwareUpdate(lwM2MClient); |
... | ... | @@ -363,7 +342,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
363 | 342 | } else if (msg.getSharedDeletedCount() > 0) { |
364 | 343 | msg.getSharedUpdatedList().forEach(tsKvProto -> { |
365 | 344 | String pathName = tsKvProto.getKv().getKey(); |
366 | - Object valueNew = LwM2mTransportServerHelper.getValueFromKvProto(tsKvProto.getKv()); | |
345 | + Object valueNew = getValueFromKvProto(tsKvProto.getKv()); | |
367 | 346 | if (FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName) && !valueNew.equals(lwM2MClient.getFrUpdate().getCurrentFwVersion())) { |
368 | 347 | lwM2MClient.getFrUpdate().setCurrentFwVersion((String) valueNew); |
369 | 348 | } |
... | ... | @@ -378,45 +357,34 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
378 | 357 | */ |
379 | 358 | @Override |
380 | 359 | public void onDeviceProfileUpdate(SessionInfoProto sessionInfo, DeviceProfile deviceProfile) { |
381 | - Set<String> registrationIds = lwM2mClientContext.getLwM2mClients().entrySet() | |
382 | - .stream() | |
383 | - .filter(e -> e.getValue().getProfileId().equals(deviceProfile.getUuidId())) | |
384 | - .map(Map.Entry::getKey).sorted().collect(Collectors.toCollection(LinkedHashSet::new)); | |
360 | + Set<LwM2mClient> clients = clientContext.getLwM2mClients() | |
361 | + .stream().filter(e -> e.getProfileId().equals(deviceProfile.getUuidId())).collect(Collectors.toSet()); | |
362 | + clients.forEach(client -> client.onDeviceProfileUpdate(deviceProfile)); | |
363 | + Set<String> registrationIds = clients.stream().map(LwM2mClient::getRegistration).map(Registration::getId).collect(Collectors.toSet()); | |
385 | 364 | if (registrationIds.size() > 0) { |
386 | - this.onDeviceUpdateChangeProfile(registrationIds, deviceProfile); | |
365 | + this.onDeviceProfileUpdate(registrationIds, deviceProfile); | |
387 | 366 | } |
388 | 367 | } |
389 | 368 | |
390 | - /** | |
391 | - * @param sessionInfo - | |
392 | - * @param device - | |
393 | - * @param deviceProfileOpt - | |
394 | - */ | |
395 | 369 | @Override |
396 | 370 | public void onDeviceUpdate(SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt) { |
397 | - Optional<String> registrationIdOpt = lwM2mClientContext.getLwM2mClients().entrySet().stream() | |
398 | - .filter(e -> device.getUuidId().equals(e.getValue().getDeviceId())) | |
399 | - .map(Map.Entry::getKey) | |
400 | - .findFirst(); | |
401 | - registrationIdOpt.ifPresent(registrationId -> this.onDeviceUpdateLwM2MClient(registrationId, device, deviceProfileOpt)); | |
371 | + //TODO: check, maybe device has multiple sessions/registrations? Is this possible according to the standard. | |
372 | + LwM2mClient client = clientContext.getClientByDeviceId(device.getUuidId()); | |
373 | + if (client != null) { | |
374 | + this.onDeviceUpdate(client, device, deviceProfileOpt); | |
375 | + } | |
402 | 376 | } |
403 | 377 | |
404 | - /** | |
405 | - * @param resourceUpdateMsgOpt - | |
406 | - */ | |
407 | 378 | @Override |
408 | 379 | public void onResourceUpdate(Optional<TransportProtos.ResourceUpdateMsg> resourceUpdateMsgOpt) { |
409 | 380 | String idVer = resourceUpdateMsgOpt.get().getResourceKey(); |
410 | - lwM2mClientContext.getLwM2mClients().values().stream().forEach(e -> e.updateResourceModel(idVer, this.config.getModelProvider())); | |
381 | + clientContext.getLwM2mClients().forEach(e -> e.updateResourceModel(idVer, this.config.getModelProvider())); | |
411 | 382 | } |
412 | 383 | |
413 | - /** | |
414 | - * @param resourceDeleteMsgOpt - | |
415 | - */ | |
416 | 384 | @Override |
417 | 385 | public void onResourceDelete(Optional<TransportProtos.ResourceDeleteMsg> resourceDeleteMsgOpt) { |
418 | 386 | String pathIdVer = resourceDeleteMsgOpt.get().getResourceKey(); |
419 | - lwM2mClientContext.getLwM2mClients().values().stream().forEach(e -> e.deleteResources(pathIdVer, this.config.getModelProvider())); | |
387 | + clientContext.getLwM2mClients().forEach(e -> e.deleteResources(pathIdVer, this.config.getModelProvider())); | |
420 | 388 | } |
421 | 389 | |
422 | 390 | @Override |
... | ... | @@ -424,9 +392,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
424 | 392 | Lwm2mClientRpcRequest lwm2mClientRpcRequest = null; |
425 | 393 | try { |
426 | 394 | log.info("[{}] toDeviceRpcRequest", toDeviceRequest); |
427 | - Registration registration = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).getRegistration(); | |
395 | + Registration registration = clientContext.getClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).getRegistration(); | |
428 | 396 | lwm2mClientRpcRequest = this.getDeviceRpcRequest(toDeviceRequest, sessionInfo, registration); |
429 | - if (lwm2mClientRpcRequest != null && lwm2mClientRpcRequest.getErrorMsg() != null) { | |
397 | + if (lwm2mClientRpcRequest.getErrorMsg() != null) { | |
430 | 398 | lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); |
431 | 399 | this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); |
432 | 400 | } else { |
... | ... | @@ -446,13 +414,6 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
446 | 414 | } |
447 | 415 | } |
448 | 416 | |
449 | - /** | |
450 | - * @param toDeviceRequest - | |
451 | - * @param sessionInfo - | |
452 | - * @param registration - | |
453 | - * @return | |
454 | - * @throws IllegalArgumentException | |
455 | - */ | |
456 | 417 | private Lwm2mClientRpcRequest getDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest, |
457 | 418 | SessionInfoProto sessionInfo, Registration registration) throws IllegalArgumentException { |
458 | 419 | Lwm2mClientRpcRequest lwm2mClientRpcRequest = new Lwm2mClientRpcRequest(); |
... | ... | @@ -590,35 +551,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
590 | 551 | } |
591 | 552 | |
592 | 553 | /** |
593 | - * This method is used to sync with sessions | |
594 | - * Removes a profile if not used in sessions | |
595 | - */ | |
596 | - private void syncSessionsAndProfiles() { | |
597 | - Map<UUID, LwM2mClientProfile> profilesClone = lwM2mClientContext.getProfiles().entrySet() | |
598 | - .stream() | |
599 | - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); | |
600 | - profilesClone.forEach((k, v) -> { | |
601 | - String registrationId = lwM2mClientContext.getLwM2mClients().entrySet() | |
602 | - .stream() | |
603 | - .filter(e -> e.getValue().getProfileId().equals(k)) | |
604 | - .findFirst() | |
605 | - .map(Map.Entry::getKey) // return the key of the matching entry if found | |
606 | - .orElse(""); | |
607 | - if (registrationId.isEmpty()) { | |
608 | - lwM2mClientContext.getProfiles().remove(k); | |
609 | - } | |
610 | - }); | |
611 | - } | |
612 | - | |
613 | - /** | |
614 | - * @param logMsg - text msg | |
554 | + * @param logMsg - text msg | |
615 | 555 | * @param registrationId - Id of Registration LwM2M Client |
616 | 556 | */ |
617 | 557 | @Override |
618 | 558 | public void sendLogsToThingsboard(String logMsg, String registrationId) { |
619 | - SessionInfoProto sessionInfo = this.getValidateSessionInfo(registrationId); | |
559 | + SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(registrationId); | |
620 | 560 | if (logMsg != null && sessionInfo != null) { |
621 | - if(logMsg.length() > 1024){ | |
561 | + if (logMsg.length() > 1024) { | |
622 | 562 | logMsg = logMsg.substring(0, 1024); |
623 | 563 | } |
624 | 564 | this.helper.sendParametersOnThingsboardTelemetry(this.helper.getKvLogyToThingsboard(logMsg), sessionInfo); |
... | ... | @@ -638,8 +578,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
638 | 578 | * @param lwM2MClient - object with All parameters off client |
639 | 579 | */ |
640 | 580 | private void initLwM2mFromClientValue(Registration registration, LwM2mClient lwM2MClient) { |
641 | - LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration); | |
642 | - Set<String> clientObjects = lwM2mClientContext.getSupportedIdVerInClient(registration); | |
581 | + LwM2mClientProfile lwM2MClientProfile = clientContext.getProfile(registration); | |
582 | + Set<String> clientObjects = clientContext.getSupportedIdVerInClient(registration); | |
643 | 583 | if (clientObjects != null && clientObjects.size() > 0) { |
644 | 584 | if (LWM2M_STRATEGY_2 == LwM2mTransportUtil.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) { |
645 | 585 | // #2 |
... | ... | @@ -693,7 +633,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
693 | 633 | * @param path - resource |
694 | 634 | */ |
695 | 635 | private void updateResourcesValue(Registration registration, LwM2mResource lwM2mResource, String path) { |
696 | - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); | |
636 | + LwM2mClient lwM2MClient = clientContext.getOrRegister(registration); | |
697 | 637 | if (lwM2MClient.saveResourceValue(path, lwM2mResource, this.config |
698 | 638 | .getModelProvider())) { |
699 | 639 | if (FR_PATH_RESOURCE_VER_ID.equals(convertPathFromIdVerToObjectId(path)) && |
... | ... | @@ -730,7 +670,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
730 | 670 | private void updateAttrTelemetry(Registration registration, Set<String> paths) { |
731 | 671 | try { |
732 | 672 | ResultsAddKeyValueProto results = getParametersFromProfile(registration, paths); |
733 | - SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration); | |
673 | + SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(registration); | |
734 | 674 | if (results != null && sessionInfo != null) { |
735 | 675 | if (results.getResultAttributes().size() > 0) { |
736 | 676 | this.helper.sendParametersOnThingsboardAttribute(results.getResultAttributes(), sessionInfo); |
... | ... | @@ -752,7 +692,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
752 | 692 | */ |
753 | 693 | private void initReadAttrTelemetryObserveToClient(Registration registration, LwM2mClient lwM2MClient, |
754 | 694 | LwM2mTypeOper typeOper, Set<String> clientObjects) { |
755 | - LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration); | |
695 | + LwM2mClientProfile lwM2MClientProfile = clientContext.getProfile(registration); | |
756 | 696 | Set<String> result = null; |
757 | 697 | ConcurrentHashMap<String, Object> params = null; |
758 | 698 | if (READ.equals(typeOper)) { |
... | ... | @@ -784,8 +724,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
784 | 724 | lwM2MClient.getPendingReadRequests().addAll(pathSend); |
785 | 725 | ConcurrentHashMap<String, Object> finalParams = params; |
786 | 726 | pathSend.forEach(target -> { |
787 | - lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, ContentFormat.TLV.getName(), | |
788 | - finalParams != null ? finalParams.get(target) : null, this.config.getTimeout(), null); | |
727 | + lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, ContentFormat.TLV.getName(), | |
728 | + finalParams != null ? finalParams.get(target) : null, this.config.getTimeout(), null); | |
789 | 729 | }); |
790 | 730 | if (OBSERVE.equals(typeOper)) { |
791 | 731 | lwM2MClient.initReadValue(this, null); |
... | ... | @@ -801,23 +741,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
801 | 741 | return pathAttributes; |
802 | 742 | } |
803 | 743 | |
804 | - /** | |
805 | - * Update parameters device in LwM2MClient | |
806 | - * If new deviceProfile != old deviceProfile => update deviceProfile | |
807 | - * | |
808 | - * @param registrationId - | |
809 | - * @param device - | |
810 | - */ | |
811 | - private void onDeviceUpdateLwM2MClient(String registrationId, Device device, Optional<DeviceProfile> deviceProfileOpt) { | |
812 | - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClients().get(registrationId); | |
813 | - lwM2MClient.setDeviceName(device.getName()); | |
814 | - if (!lwM2MClient.getProfileId().equals(device.getDeviceProfileId().getId())) { | |
815 | - Set<String> registrationIds = new HashSet<>(); | |
816 | - registrationIds.add(registrationId); | |
817 | - deviceProfileOpt.ifPresent(deviceProfile -> this.onDeviceUpdateChangeProfile(registrationIds, deviceProfile)); | |
818 | - } | |
819 | - | |
820 | - lwM2MClient.setProfileId(device.getDeviceProfileId().getId()); | |
744 | + private void onDeviceUpdate(LwM2mClient lwM2MClient, Device device, Optional<DeviceProfile> deviceProfileOpt) { | |
745 | + deviceProfileOpt.ifPresent(deviceProfile -> this.onDeviceProfileUpdate(Collections.singleton(lwM2MClient.getRegistration().getId()), deviceProfile)); | |
746 | + lwM2MClient.onDeviceUpdate(device, deviceProfileOpt); | |
821 | 747 | } |
822 | 748 | |
823 | 749 | /** |
... | ... | @@ -830,7 +756,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
830 | 756 | private ResultsAddKeyValueProto getParametersFromProfile(Registration registration, Set<String> path) { |
831 | 757 | if (path != null && path.size() > 0) { |
832 | 758 | ResultsAddKeyValueProto results = new ResultsAddKeyValueProto(); |
833 | - LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration); | |
759 | + LwM2mClientProfile lwM2MClientProfile = clientContext.getProfile(registration); | |
834 | 760 | List<TransportProtos.KeyValueProto> resultAttributes = new ArrayList<>(); |
835 | 761 | lwM2MClientProfile.getPostAttributeProfile().forEach(pathIdVer -> { |
836 | 762 | if (path.contains(pathIdVer.getAsString())) { |
... | ... | @@ -861,8 +787,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
861 | 787 | } |
862 | 788 | |
863 | 789 | private TransportProtos.KeyValueProto getKvToThingsboard(String pathIdVer, Registration registration) { |
864 | - LwM2mClient lwM2MClient = this.lwM2mClientContext.getLwM2mClientWithReg(null, registration.getId()); | |
865 | - JsonObject names = lwM2mClientContext.getProfiles().get(lwM2MClient.getProfileId()).getPostKeyNameProfile(); | |
790 | + LwM2mClient lwM2MClient = this.clientContext.getClientByRegistrationId(registration.getId()); | |
791 | + JsonObject names = clientContext.getProfiles().get(lwM2MClient.getProfileId()).getPostKeyNameProfile(); | |
866 | 792 | if (names != null && names.has(pathIdVer)) { |
867 | 793 | String resourceName = names.get(pathIdVer).getAsString(); |
868 | 794 | if (resourceName != null && !resourceName.isEmpty()) { |
... | ... | @@ -960,9 +886,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
960 | 886 | * @param registrationIds - |
961 | 887 | * @param deviceProfile - |
962 | 888 | */ |
963 | - private void onDeviceUpdateChangeProfile(Set<String> registrationIds, DeviceProfile deviceProfile) { | |
964 | - LwM2mClientProfile lwM2MClientProfileOld = lwM2mClientContext.getProfiles().get(deviceProfile.getUuidId()).clone(); | |
965 | - if (lwM2mClientContext.addUpdateProfileParameters(deviceProfile)) { | |
889 | + private void onDeviceProfileUpdate(Set<String> registrationIds, DeviceProfile deviceProfile) { | |
890 | + LwM2mClientProfile lwM2MClientProfileOld = clientContext.getProfiles().get(deviceProfile.getUuidId()).clone(); | |
891 | + if (clientContext.toClientProfile(deviceProfile) != null) { | |
966 | 892 | // #1 |
967 | 893 | JsonArray attributeOld = lwM2MClientProfileOld.getPostAttributeProfile(); |
968 | 894 | Set<String> attributeSetOld = convertJsonArrayToSet(attributeOld); |
... | ... | @@ -972,7 +898,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
972 | 898 | JsonObject keyNameOld = lwM2MClientProfileOld.getPostKeyNameProfile(); |
973 | 899 | JsonObject attributeLwm2mOld = lwM2MClientProfileOld.getPostAttributeLwm2mProfile(); |
974 | 900 | |
975 | - LwM2mClientProfile lwM2MClientProfileNew = lwM2mClientContext.getProfiles().get(deviceProfile.getUuidId()); | |
901 | + LwM2mClientProfile lwM2MClientProfileNew = clientContext.getProfiles().get(deviceProfile.getUuidId()); | |
976 | 902 | JsonArray attributeNew = lwM2MClientProfileNew.getPostAttributeProfile(); |
977 | 903 | Set<String> attributeSetNew = convertJsonArrayToSet(attributeNew); |
978 | 904 | JsonArray telemetryNew = lwM2MClientProfileNew.getPostTelemetryProfile(); |
... | ... | @@ -1018,7 +944,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
1018 | 944 | if (sendAttrToThingsboard.getPathPostParametersAdd().size() > 0) { |
1019 | 945 | // update value in Resources |
1020 | 946 | registrationIds.forEach(registrationId -> { |
1021 | - Registration registration = lwM2mClientContext.getRegistration(registrationId); | |
947 | + Registration registration = clientContext.getRegistration(registrationId); | |
1022 | 948 | this.readObserveFromProfile(registration, sendAttrToThingsboard.getPathPostParametersAdd(), READ); |
1023 | 949 | // send attr/telemetry to tingsboard for new path |
1024 | 950 | this.updateAttrTelemetry(registration, sendAttrToThingsboard.getPathPostParametersAdd()); |
... | ... | @@ -1046,7 +972,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
1046 | 972 | ResultsAnalyzerParameters postObserveAnalyzer = this.getAnalyzerParameters(sendObserveToClientOld.getPathPostParametersAdd(), sendObserveToClientNew.getPathPostParametersAdd()); |
1047 | 973 | // send Request observe to Client |
1048 | 974 | registrationIds.forEach(registrationId -> { |
1049 | - Registration registration = lwM2mClientContext.getRegistration(registrationId); | |
975 | + Registration registration = clientContext.getRegistration(registrationId); | |
1050 | 976 | if (postObserveAnalyzer.getPathPostParametersAdd().size() > 0) { |
1051 | 977 | this.readObserveFromProfile(registration, postObserveAnalyzer.getPathPostParametersAdd(), OBSERVE); |
1052 | 978 | } |
... | ... | @@ -1151,8 +1077,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
1151 | 1077 | // #6.2 |
1152 | 1078 | if (analyzerParameters.getPathPostParametersAdd().size() > 0) { |
1153 | 1079 | registrationIds.forEach(registrationId -> { |
1154 | - Registration registration = this.lwM2mClientContext.getRegistration(registrationId); | |
1155 | - Set<String> clientObjects = lwM2mClientContext.getSupportedIdVerInClient(registration); | |
1080 | + Registration registration = this.clientContext.getRegistration(registrationId); | |
1081 | + Set<String> clientObjects = clientContext.getSupportedIdVerInClient(registration); | |
1156 | 1082 | Set<String> pathSend = analyzerParameters.getPathPostParametersAdd().stream().filter(target -> clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1])) |
1157 | 1083 | .collect(Collectors.toUnmodifiableSet()); |
1158 | 1084 | if (!pathSend.isEmpty()) { |
... | ... | @@ -1165,8 +1091,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
1165 | 1091 | // #6.2 |
1166 | 1092 | if (analyzerParameters.getPathPostParametersDel().size() > 0) { |
1167 | 1093 | registrationIds.forEach(registrationId -> { |
1168 | - Registration registration = this.lwM2mClientContext.getRegistration(registrationId); | |
1169 | - Set<String> clientObjects = lwM2mClientContext.getSupportedIdVerInClient(registration); | |
1094 | + Registration registration = this.clientContext.getRegistration(registrationId); | |
1095 | + Set<String> clientObjects = clientContext.getSupportedIdVerInClient(registration); | |
1170 | 1096 | Set<String> pathSend = analyzerParameters.getPathPostParametersDel().stream().filter(target -> clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1])) |
1171 | 1097 | .collect(Collectors.toUnmodifiableSet()); |
1172 | 1098 | if (!pathSend.isEmpty()) { |
... | ... | @@ -1184,7 +1110,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
1184 | 1110 | } |
1185 | 1111 | |
1186 | 1112 | private void cancelObserveFromProfile(Registration registration, Set<String> paramAnallyzer) { |
1187 | - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); | |
1113 | + LwM2mClient lwM2MClient = clientContext.getOrRegister(registration); | |
1188 | 1114 | paramAnallyzer.forEach(pathIdVer -> { |
1189 | 1115 | if (this.getResourceValueFromLwM2MClient(lwM2MClient, pathIdVer) != null) { |
1190 | 1116 | lwM2mTransportRequest.sendAllRequest(registration, pathIdVer, OBSERVE_CANCEL, null, |
... | ... | @@ -1224,8 +1150,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
1224 | 1150 | * @return - |
1225 | 1151 | */ |
1226 | 1152 | private String getPresentPathIntoProfile(TransportProtos.SessionInfoProto sessionInfo, String name) { |
1227 | - LwM2mClientProfile profile = lwM2mClientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB())); | |
1228 | - LwM2mClient lwM2mClient = lwM2mClientContext.getLwM2MClient(sessionInfo); | |
1153 | + LwM2mClientProfile profile = clientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB())); | |
1154 | + LwM2mClient lwM2mClient = clientContext.getClient(sessionInfo); | |
1229 | 1155 | return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream() |
1230 | 1156 | .filter(e -> e.getValue().getAsString().equals(name) && validateResourceInModel(lwM2mClient, e.getKey(), false)).findFirst().map(Map.Entry::getKey) |
1231 | 1157 | .orElse(null); |
... | ... | @@ -1244,7 +1170,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
1244 | 1170 | try { |
1245 | 1171 | List<TransportProtos.TsKvProto> tsKvProtos = attributesResponse.getSharedAttributeListList(); |
1246 | 1172 | |
1247 | - this.updateAttriuteFromThingsboard(tsKvProtos, sessionInfo); | |
1173 | + this.updateAttributeFromThingsboard(tsKvProtos, sessionInfo); | |
1248 | 1174 | } catch (Exception e) { |
1249 | 1175 | log.error(String.valueOf(e)); |
1250 | 1176 | } |
... | ... | @@ -1260,8 +1186,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
1260 | 1186 | * @param tsKvProtos |
1261 | 1187 | * @param sessionInfo |
1262 | 1188 | */ |
1263 | - public void updateAttriuteFromThingsboard(List<TransportProtos.TsKvProto> tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) { | |
1264 | - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2MClient(sessionInfo); | |
1189 | + public void updateAttributeFromThingsboard(List<TransportProtos.TsKvProto> tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) { | |
1190 | + LwM2mClient lwM2MClient = clientContext.getClient(sessionInfo); | |
1265 | 1191 | tsKvProtos.forEach(tsKvProto -> { |
1266 | 1192 | String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, tsKvProto.getKv().getKey()); |
1267 | 1193 | if (pathIdVer != null) { |
... | ... | @@ -1276,7 +1202,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
1276 | 1202 | // #2.1 |
1277 | 1203 | lwM2MClient.getDelayedRequests().forEach((pathIdVer, tsKvProto) -> { |
1278 | 1204 | this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer), |
1279 | - this.helper.getValueFromKvProto(tsKvProto.getKv()), pathIdVer); | |
1205 | + getValueFromKvProto(tsKvProto.getKv()), pathIdVer); | |
1280 | 1206 | }); |
1281 | 1207 | } |
1282 | 1208 | |
... | ... | @@ -1284,30 +1210,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
1284 | 1210 | * @param lwM2MClient - |
1285 | 1211 | * @return SessionInfoProto - |
1286 | 1212 | */ |
1287 | - private SessionInfoProto getNewSessionInfoProto(LwM2mClient lwM2MClient) { | |
1213 | + private SessionInfoProto getSessionInfoOrCloseSession(LwM2mClient lwM2MClient) { | |
1288 | 1214 | if (lwM2MClient != null) { |
1289 | - TransportProtos.ValidateDeviceCredentialsResponseMsg msg = lwM2MClient.getCredentialsResponse(); | |
1290 | - if (msg == null) { | |
1291 | - log.error("[{}] [{}]", lwM2MClient.getEndpoint(), CLIENT_NOT_AUTHORIZED); | |
1215 | + SessionInfoProto sessionInfoProto = lwM2MClient.getSession(); | |
1216 | + if (sessionInfoProto == null) { | |
1217 | + log.info("[{}] [{}]", lwM2MClient.getEndpoint(), CLIENT_NOT_AUTHORIZED); | |
1292 | 1218 | this.closeClientSession(lwM2MClient.getRegistration()); |
1293 | - return null; | |
1294 | - } else { | |
1295 | - return SessionInfoProto.newBuilder() | |
1296 | - .setNodeId(this.context.getNodeId()) | |
1297 | - .setSessionIdMSB(lwM2MClient.getSessionId().getMostSignificantBits()) | |
1298 | - .setSessionIdLSB(lwM2MClient.getSessionId().getLeastSignificantBits()) | |
1299 | - .setDeviceIdMSB(msg.getDeviceInfo().getDeviceIdMSB()) | |
1300 | - .setDeviceIdLSB(msg.getDeviceInfo().getDeviceIdLSB()) | |
1301 | - .setTenantIdMSB(msg.getDeviceInfo().getTenantIdMSB()) | |
1302 | - .setTenantIdLSB(msg.getDeviceInfo().getTenantIdLSB()) | |
1303 | - .setCustomerIdMSB(msg.getDeviceInfo().getCustomerIdMSB()) | |
1304 | - .setCustomerIdLSB(msg.getDeviceInfo().getCustomerIdLSB()) | |
1305 | - .setDeviceName(msg.getDeviceInfo().getDeviceName()) | |
1306 | - .setDeviceType(msg.getDeviceInfo().getDeviceType()) | |
1307 | - .setDeviceProfileIdLSB(msg.getDeviceInfo().getDeviceProfileIdLSB()) | |
1308 | - .setDeviceProfileIdMSB(msg.getDeviceInfo().getDeviceProfileIdMSB()) | |
1309 | - .build(); | |
1310 | 1219 | } |
1220 | + return sessionInfoProto; | |
1311 | 1221 | } |
1312 | 1222 | return null; |
1313 | 1223 | } |
... | ... | @@ -1316,18 +1226,16 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
1316 | 1226 | * @param registration - Registration LwM2M Client |
1317 | 1227 | * @return - sessionInfo after access connect client |
1318 | 1228 | */ |
1319 | - private SessionInfoProto getValidateSessionInfo(Registration registration) { | |
1320 | - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); | |
1321 | - return getNewSessionInfoProto(lwM2MClient); | |
1229 | + private SessionInfoProto getSessionInfoOrCloseSession(Registration registration) { | |
1230 | + return getSessionInfoOrCloseSession(clientContext.getOrRegister(registration)); | |
1322 | 1231 | } |
1323 | 1232 | |
1324 | 1233 | /** |
1325 | 1234 | * @param registrationId - |
1326 | 1235 | * @return - |
1327 | 1236 | */ |
1328 | - private SessionInfoProto getValidateSessionInfo(String registrationId) { | |
1329 | - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(null, registrationId); | |
1330 | - return lwM2MClient != null ? this.getNewSessionInfoProto(lwM2MClient) : null; | |
1237 | + private SessionInfoProto getSessionInfoOrCloseSession(String registrationId) { | |
1238 | + return getSessionInfoOrCloseSession(clientContext.getClientByRegistrationId(registrationId)); | |
1331 | 1239 | } |
1332 | 1240 | |
1333 | 1241 | /** |
... | ... | @@ -1335,14 +1243,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
1335 | 1243 | * |
1336 | 1244 | * @param sessionInfo - |
1337 | 1245 | */ |
1338 | - private void checkInactivity(SessionInfoProto sessionInfo) { | |
1339 | - if (transportService.reportActivity(sessionInfo) == null) { | |
1246 | + private void reportActivityAndRegister(SessionInfoProto sessionInfo) { | |
1247 | + if (sessionInfo != null && transportService.reportActivity(sessionInfo) == null) { | |
1340 | 1248 | transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo)); |
1341 | 1249 | } |
1342 | 1250 | } |
1343 | 1251 | |
1344 | - private void checkInactivityAndReportActivity() { | |
1345 | - lwM2mClientContext.getLwM2mClients().forEach((key, value) -> this.checkInactivity(this.getValidateSessionInfo(key))); | |
1252 | + private void reportActivity() { | |
1253 | + clientContext.getLwM2mClients().forEach(client -> reportActivityAndRegister(client.getSession())); | |
1346 | 1254 | } |
1347 | 1255 | |
1348 | 1256 | /** |
... | ... | @@ -1356,7 +1264,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
1356 | 1264 | * @param lwM2MClient - LwM2M Client |
1357 | 1265 | */ |
1358 | 1266 | public void putDelayedUpdateResourcesThingsboard(LwM2mClient lwM2MClient) { |
1359 | - SessionInfoProto sessionInfo = this.getValidateSessionInfo(lwM2MClient.getRegistration()); | |
1267 | + SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); | |
1360 | 1268 | if (sessionInfo != null) { |
1361 | 1269 | //#1.1 |
1362 | 1270 | ConcurrentMap<String, String> keyNamesMap = this.getNamesFromProfileForSharedAttributes(lwM2MClient); |
... | ... | @@ -1374,7 +1282,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
1374 | 1282 | } |
1375 | 1283 | |
1376 | 1284 | public void getInfoFirmwareUpdate(LwM2mClient lwM2MClient) { |
1377 | - SessionInfoProto sessionInfo = this.getValidateSessionInfo(lwM2MClient.getRegistration()); | |
1285 | + SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); | |
1378 | 1286 | if (sessionInfo != null) { |
1379 | 1287 | TransportProtos.GetFirmwareRequestMsg getFirmwareRequestMsg = TransportProtos.GetFirmwareRequestMsg.newBuilder() |
1380 | 1288 | .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) |
... | ... | @@ -1415,7 +1323,6 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
1415 | 1323 | } |
1416 | 1324 | |
1417 | 1325 | /** |
1418 | - * | |
1419 | 1326 | * @param lwM2MClient - |
1420 | 1327 | */ |
1421 | 1328 | public void updateFirmwareClient(LwM2mClient lwM2MClient) { |
... | ... | @@ -1441,7 +1348,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler |
1441 | 1348 | */ |
1442 | 1349 | private ConcurrentMap<String, String> getNamesFromProfileForSharedAttributes(LwM2mClient lwM2MClient) { |
1443 | 1350 | |
1444 | - LwM2mClientProfile profile = lwM2mClientContext.getProfile(lwM2MClient.getProfileId()); | |
1351 | + LwM2mClientProfile profile = clientContext.getProfile(lwM2MClient.getProfileId()); | |
1445 | 1352 | return new Gson().fromJson(profile.getPostKeyNameProfile().toString(), |
1446 | 1353 | new TypeToken<ConcurrentHashMap<String, String>>() { |
1447 | 1354 | }.getType()); | ... | ... |
... | ... | @@ -115,7 +115,7 @@ public class LwM2mTransportRequest { |
115 | 115 | String target = convertPathFromIdVerToObjectId(targetIdVer); |
116 | 116 | DownlinkRequest request = null; |
117 | 117 | ContentFormat contentFormat = contentFormatName != null ? ContentFormat.fromName(contentFormatName.toUpperCase()) : ContentFormat.DEFAULT; |
118 | - LwM2mClient lwM2MClient = this.lwM2mClientContext.getLwM2mClientWithReg(registration, null); | |
118 | + LwM2mClient lwM2MClient = this.lwM2mClientContext.getOrRegister(registration); | |
119 | 119 | LwM2mPath resultIds = target != null ? new LwM2mPath(target) : null; |
120 | 120 | if (!OBSERVE_READ_ALL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0 && lwM2MClient != null) { |
121 | 121 | if (lwM2MClient.isValidObjectVersion(targetIdVer)) { | ... | ... |
... | ... | @@ -183,7 +183,6 @@ public class LwM2mTransportUtil { |
183 | 183 | } |
184 | 184 | |
185 | 185 | public static final String EVENT_AWAKE = "AWAKE"; |
186 | - public static final String SERVICE_CHANNEL = "SERVICE"; | |
187 | 186 | public static final String RESPONSE_CHANNEL = "RESP"; |
188 | 187 | |
189 | 188 | public static boolean equalsResourceValue(Object valueOld, Object valueNew, ResourceModel.Type type, LwM2mPath resourcePath) throws CodecException { |
... | ... | @@ -249,7 +248,7 @@ public class LwM2mTransportUtil { |
249 | 248 | * "/3_1.0/0": {"gt": 17}, |
250 | 249 | * "/3_1.0/0/9": {"pmax": 45}, "/3_1.2": {ver": "3_1.2"}} |
251 | 250 | */ |
252 | - public static LwM2mClientProfile getLwM2MClientProfileFromThingsboard(DeviceProfile deviceProfile) { | |
251 | + public static LwM2mClientProfile toLwM2MClientProfile(DeviceProfile deviceProfile) { | |
253 | 252 | if (deviceProfile != null && ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties().size() > 0) { |
254 | 253 | Object profile = ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties(); |
255 | 254 | try { | ... | ... |
... | ... | @@ -16,6 +16,8 @@ |
16 | 16 | package org.thingsboard.server.transport.lwm2m.server.client; |
17 | 17 | |
18 | 18 | import lombok.Data; |
19 | +import lombok.Getter; | |
20 | +import lombok.Setter; | |
19 | 21 | import lombok.extern.slf4j.Slf4j; |
20 | 22 | import org.eclipse.leshan.core.model.ResourceModel; |
21 | 23 | import org.eclipse.leshan.core.node.LwM2mPath; |
... | ... | @@ -24,7 +26,11 @@ import org.eclipse.leshan.core.node.LwM2mSingleResource; |
24 | 26 | import org.eclipse.leshan.server.model.LwM2mModelProvider; |
25 | 27 | import org.eclipse.leshan.server.registration.Registration; |
26 | 28 | import org.eclipse.leshan.server.security.SecurityInfo; |
29 | +import org.thingsboard.server.common.data.Device; | |
30 | +import org.thingsboard.server.common.data.DeviceProfile; | |
27 | 31 | import org.thingsboard.server.gen.transport.TransportProtos; |
32 | +import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; | |
33 | +import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; | |
28 | 34 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg; |
29 | 35 | import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2MTransportMsgHandler; |
30 | 36 | import org.thingsboard.server.transport.lwm2m.server.LwM2mQueuedRequest; |
... | ... | @@ -33,6 +39,7 @@ import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; |
33 | 39 | import java.util.Collection; |
34 | 40 | import java.util.List; |
35 | 41 | import java.util.Map; |
42 | +import java.util.Optional; | |
36 | 43 | import java.util.Queue; |
37 | 44 | import java.util.Set; |
38 | 45 | import java.util.UUID; |
... | ... | @@ -47,31 +54,52 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.c |
47 | 54 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.getVerFromPathIdVerOrId; |
48 | 55 | |
49 | 56 | @Slf4j |
50 | -@Data | |
51 | 57 | public class LwM2mClient implements Cloneable { |
58 | + @Getter | |
52 | 59 | private String deviceName; |
60 | + @Getter | |
53 | 61 | private String deviceProfileName; |
62 | + @Getter | |
54 | 63 | private String endpoint; |
64 | + @Getter | |
55 | 65 | private String identity; |
66 | + @Getter | |
56 | 67 | private SecurityInfo securityInfo; |
68 | + @Getter | |
57 | 69 | private UUID deviceId; |
70 | + @Getter | |
58 | 71 | private UUID sessionId; |
72 | + @Getter | |
73 | + private SessionInfoProto session; | |
74 | + @Getter | |
59 | 75 | private UUID profileId; |
76 | + @Getter | |
77 | + @Setter | |
60 | 78 | private volatile LwM2mFirmwareUpdate frUpdate; |
79 | + @Getter | |
80 | + @Setter | |
61 | 81 | private Registration registration; |
82 | + | |
62 | 83 | private ValidateDeviceCredentialsResponseMsg credentialsResponse; |
84 | + @Getter | |
63 | 85 | private final Map<String, ResourceValue> resources; |
64 | - private final Map<String, TransportProtos.TsKvProto> delayedRequests; | |
86 | + @Getter | |
87 | + private final Map<String, TsKvProto> delayedRequests; | |
88 | + @Getter | |
65 | 89 | private final List<String> pendingReadRequests; |
90 | + @Getter | |
66 | 91 | private final Queue<LwM2mQueuedRequest> queuedRequests; |
92 | + @Getter | |
67 | 93 | private boolean init; |
94 | + @Getter | |
95 | + @Setter | |
68 | 96 | private volatile boolean updateFw; |
69 | 97 | |
70 | 98 | public Object clone() throws CloneNotSupportedException { |
71 | 99 | return super.clone(); |
72 | 100 | } |
73 | 101 | |
74 | - public LwM2mClient(String endpoint, String identity, SecurityInfo securityInfo, ValidateDeviceCredentialsResponseMsg credentialsResponse, UUID profileId, UUID sessionId) { | |
102 | + public LwM2mClient(String nodeId, String endpoint, String identity, SecurityInfo securityInfo, ValidateDeviceCredentialsResponseMsg credentialsResponse, UUID profileId, UUID sessionId) { | |
75 | 103 | this.endpoint = endpoint; |
76 | 104 | this.identity = identity; |
77 | 105 | this.securityInfo = securityInfo; |
... | ... | @@ -85,6 +113,56 @@ public class LwM2mClient implements Cloneable { |
85 | 113 | this.updateFw = false; |
86 | 114 | this.queuedRequests = new ConcurrentLinkedQueue<>(); |
87 | 115 | this.frUpdate = new LwM2mFirmwareUpdate(); |
116 | + if (this.credentialsResponse != null && this.credentialsResponse.hasDeviceInfo()) { | |
117 | + this.session = createSession(nodeId, sessionId, credentialsResponse); | |
118 | + this.deviceId = new UUID(session.getDeviceIdMSB(), session.getDeviceIdLSB()); | |
119 | + this.profileId = new UUID(session.getDeviceProfileIdMSB(), session.getDeviceProfileIdLSB()); | |
120 | + this.deviceName = session.getDeviceName(); | |
121 | + this.deviceProfileName = session.getDeviceType(); | |
122 | + } | |
123 | + } | |
124 | + | |
125 | + public void onDeviceUpdate(Device device, Optional<DeviceProfile> deviceProfileOpt) { | |
126 | + SessionInfoProto.Builder builder = SessionInfoProto.newBuilder().mergeFrom(session); | |
127 | + this.deviceId = device.getUuidId(); | |
128 | + this.deviceName = device.getName(); | |
129 | + builder.setDeviceIdMSB(deviceId.getMostSignificantBits()); | |
130 | + builder.setDeviceIdLSB(deviceId.getLeastSignificantBits()); | |
131 | + builder.setDeviceName(deviceName); | |
132 | + deviceProfileOpt.ifPresent(deviceProfile -> updateSession(deviceProfile, builder)); | |
133 | + this.session = builder.build(); | |
134 | + } | |
135 | + | |
136 | + public void onDeviceProfileUpdate(DeviceProfile deviceProfile) { | |
137 | + SessionInfoProto.Builder builder = SessionInfoProto.newBuilder().mergeFrom(session); | |
138 | + updateSession(deviceProfile, builder); | |
139 | + this.session = builder.build(); | |
140 | + } | |
141 | + | |
142 | + private void updateSession(DeviceProfile deviceProfile, SessionInfoProto.Builder builder) { | |
143 | + this.deviceProfileName = deviceProfile.getName(); | |
144 | + this.profileId = deviceProfile.getUuidId(); | |
145 | + builder.setDeviceProfileIdMSB(profileId.getMostSignificantBits()); | |
146 | + builder.setDeviceProfileIdLSB(profileId.getLeastSignificantBits()); | |
147 | + builder.setDeviceType(this.deviceProfileName); | |
148 | + } | |
149 | + | |
150 | + private SessionInfoProto createSession(String nodeId, UUID sessionId, ValidateDeviceCredentialsResponseMsg msg) { | |
151 | + return SessionInfoProto.newBuilder() | |
152 | + .setNodeId(nodeId) | |
153 | + .setSessionIdMSB(sessionId.getMostSignificantBits()) | |
154 | + .setSessionIdLSB(sessionId.getLeastSignificantBits()) | |
155 | + .setDeviceIdMSB(msg.getDeviceInfo().getDeviceIdMSB()) | |
156 | + .setDeviceIdLSB(msg.getDeviceInfo().getDeviceIdLSB()) | |
157 | + .setTenantIdMSB(msg.getDeviceInfo().getTenantIdMSB()) | |
158 | + .setTenantIdLSB(msg.getDeviceInfo().getTenantIdLSB()) | |
159 | + .setCustomerIdMSB(msg.getDeviceInfo().getCustomerIdMSB()) | |
160 | + .setCustomerIdLSB(msg.getDeviceInfo().getCustomerIdLSB()) | |
161 | + .setDeviceName(msg.getDeviceInfo().getDeviceName()) | |
162 | + .setDeviceType(msg.getDeviceInfo().getDeviceType()) | |
163 | + .setDeviceProfileIdLSB(msg.getDeviceInfo().getDeviceProfileIdLSB()) | |
164 | + .setDeviceProfileIdMSB(msg.getDeviceInfo().getDeviceProfileIdMSB()) | |
165 | + .build(); | |
88 | 166 | } |
89 | 167 | |
90 | 168 | public boolean saveResourceValue(String pathRez, LwM2mResource rez, LwM2mModelProvider modelProvider) { |
... | ... | @@ -123,7 +201,7 @@ public class LwM2mClient implements Cloneable { |
123 | 201 | return resources; |
124 | 202 | } |
125 | 203 | |
126 | - public boolean isValidObjectVersion (String path) { | |
204 | + public boolean isValidObjectVersion(String path) { | |
127 | 205 | LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(path)); |
128 | 206 | String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId()); |
129 | 207 | String verRez = getVerFromPathIdVerOrId(path); |
... | ... | @@ -131,8 +209,7 @@ public class LwM2mClient implements Cloneable { |
131 | 209 | } |
132 | 210 | |
133 | 211 | /** |
134 | - * | |
135 | - * @param pathIdVer == "3_1.0" | |
212 | + * @param pathIdVer == "3_1.0" | |
136 | 213 | * @param modelProvider - |
137 | 214 | */ |
138 | 215 | public void deleteResources(String pathIdVer, LwM2mModelProvider modelProvider) { |
... | ... | @@ -142,16 +219,14 @@ public class LwM2mClient implements Cloneable { |
142 | 219 | ResourceModel resourceModel = modelProvider.getObjectModel(registration).getResourceModel(pathIds.getObjectId(), pathIds.getResourceId()); |
143 | 220 | if (resourceModel != null) { |
144 | 221 | this.resources.get(pathRez).setResourceModel(resourceModel); |
145 | - } | |
146 | - else { | |
222 | + } else { | |
147 | 223 | this.resources.remove(pathRez); |
148 | 224 | } |
149 | 225 | }); |
150 | 226 | } |
151 | 227 | |
152 | 228 | /** |
153 | - * | |
154 | - * @param idVer - | |
229 | + * @param idVer - | |
155 | 230 | * @param modelProvider - |
156 | 231 | */ |
157 | 232 | public void updateResourceModel(String idVer, LwM2mModelProvider modelProvider) { |
... | ... | @@ -182,8 +257,5 @@ public class LwM2mClient implements Cloneable { |
182 | 257 | } |
183 | 258 | } |
184 | 259 | |
185 | - public LwM2mClient copy() { | |
186 | - return new LwM2mClient(this.endpoint, this.identity, this.securityInfo, this.credentialsResponse, this.profileId, this.sessionId); | |
187 | - } | |
188 | 260 | } |
189 | 261 | ... | ... |
... | ... | @@ -19,29 +19,32 @@ import org.eclipse.leshan.server.registration.Registration; |
19 | 19 | import org.thingsboard.server.common.data.DeviceProfile; |
20 | 20 | import org.thingsboard.server.gen.transport.TransportProtos; |
21 | 21 | |
22 | +import java.util.Collection; | |
22 | 23 | import java.util.Map; |
23 | 24 | import java.util.Set; |
24 | 25 | import java.util.UUID; |
25 | 26 | |
26 | 27 | public interface LwM2mClientContext { |
27 | 28 | |
28 | - void delRemoveSessionAndListener(String registrationId); | |
29 | + void removeClientByRegistrationId(String registrationId); | |
29 | 30 | |
30 | - LwM2mClient getLwM2MClient(String endPoint, String identity); | |
31 | + LwM2mClient getClientByEndpoint(String endpoint); | |
31 | 32 | |
32 | - LwM2mClient getLwM2MClient(TransportProtos.SessionInfoProto sessionInfo); | |
33 | + LwM2mClient getClientByRegistrationId(String registrationId); | |
33 | 34 | |
34 | - LwM2mClient getLwM2mClient(UUID sessionId); | |
35 | + LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo); | |
35 | 36 | |
36 | - LwM2mClient getLwM2mClientWithReg(Registration registration, String registrationId); | |
37 | + LwM2mClient getClient(UUID sessionId); | |
37 | 38 | |
38 | - LwM2mClient updateInSessionsLwM2MClient(Registration registration); | |
39 | + LwM2mClient getOrRegister(Registration registration); | |
39 | 40 | |
40 | - LwM2mClient addLwM2mClientToSession(String identity); | |
41 | + LwM2mClient registerOrUpdate(Registration registration); | |
42 | + | |
43 | + LwM2mClient fetchClientByEndpoint(String endpoint); | |
41 | 44 | |
42 | 45 | Registration getRegistration(String registrationId); |
43 | 46 | |
44 | - Map<String, LwM2mClient> getLwM2mClients(); | |
47 | + Collection<LwM2mClient> getLwM2mClients(); | |
45 | 48 | |
46 | 49 | Map<UUID, LwM2mClientProfile> getProfiles(); |
47 | 50 | |
... | ... | @@ -51,7 +54,9 @@ public interface LwM2mClientContext { |
51 | 54 | |
52 | 55 | Map<UUID, LwM2mClientProfile> setProfiles(Map<UUID, LwM2mClientProfile> profiles); |
53 | 56 | |
54 | - boolean addUpdateProfileParameters(DeviceProfile deviceProfile); | |
57 | + LwM2mClientProfile toClientProfile(DeviceProfile deviceProfile); | |
55 | 58 | |
56 | 59 | Set<String> getSupportedIdVerInClient(Registration registration); |
60 | + | |
61 | + LwM2mClient getClientByDeviceId(UUID deviceId); | |
57 | 62 | } | ... | ... |
... | ... | @@ -15,6 +15,7 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.transport.lwm2m.server.client; |
17 | 17 | |
18 | +import lombok.RequiredArgsConstructor; | |
18 | 19 | import org.eclipse.leshan.core.node.LwM2mPath; |
19 | 20 | import org.eclipse.leshan.server.registration.Registration; |
20 | 21 | import org.eclipse.leshan.server.security.EditableSecurityStore; |
... | ... | @@ -24,123 +25,121 @@ import org.thingsboard.server.gen.transport.TransportProtos; |
24 | 25 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
25 | 26 | import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; |
26 | 27 | import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; |
27 | -import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; | |
28 | +import org.thingsboard.server.transport.lwm2m.secure.EndpointSecurityInfo; | |
29 | +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext; | |
28 | 30 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; |
29 | 31 | |
30 | 32 | import java.util.Arrays; |
33 | +import java.util.Collection; | |
31 | 34 | import java.util.Map; |
35 | +import java.util.Optional; | |
32 | 36 | import java.util.Set; |
33 | 37 | import java.util.UUID; |
34 | 38 | import java.util.concurrent.ConcurrentHashMap; |
39 | +import java.util.stream.Collectors; | |
35 | 40 | |
36 | 41 | import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC; |
37 | 42 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer; |
38 | 43 | |
39 | 44 | @Service |
40 | 45 | @TbLwM2mTransportComponent |
46 | +@RequiredArgsConstructor | |
41 | 47 | public class LwM2mClientContextImpl implements LwM2mClientContext { |
42 | 48 | |
43 | - private static final boolean INFOS_ARE_COMPROMISED = false; | |
44 | - | |
45 | - private final Map<String /** registrationId */, LwM2mClient> lwM2mClients = new ConcurrentHashMap<>(); | |
46 | - private Map<UUID /** profileUUid */, LwM2mClientProfile> profiles = new ConcurrentHashMap<>(); | |
49 | + private final LwM2mTransportContext context; | |
50 | + private final Map<String, LwM2mClient> lwM2mClientsByEndpoint = new ConcurrentHashMap<>(); | |
51 | + private final Map<String, LwM2mClient> lwM2mClientsByRegistrationId = new ConcurrentHashMap<>(); | |
52 | + private Map<UUID, LwM2mClientProfile> profiles = new ConcurrentHashMap<>(); | |
47 | 53 | |
48 | 54 | private final LwM2mCredentialsSecurityInfoValidator lwM2MCredentialsSecurityInfoValidator; |
49 | 55 | |
50 | 56 | private final EditableSecurityStore securityStore; |
51 | 57 | |
52 | - public LwM2mClientContextImpl(LwM2mCredentialsSecurityInfoValidator lwM2MCredentialsSecurityInfoValidator, EditableSecurityStore securityStore) { | |
53 | - this.lwM2MCredentialsSecurityInfoValidator = lwM2MCredentialsSecurityInfoValidator; | |
54 | - this.securityStore = securityStore; | |
55 | - } | |
56 | - | |
57 | - public void delRemoveSessionAndListener(String registrationId) { | |
58 | - LwM2mClient lwM2MClient = this.lwM2mClients.get(registrationId); | |
59 | - if (lwM2MClient != null) { | |
60 | - this.securityStore.remove(lwM2MClient.getEndpoint(), INFOS_ARE_COMPROMISED); | |
61 | - this.lwM2mClients.remove(registrationId); | |
62 | - } | |
58 | + @Override | |
59 | + public LwM2mClient getClientByEndpoint(String endpoint) { | |
60 | + return lwM2mClientsByEndpoint.get(endpoint); | |
63 | 61 | } |
64 | 62 | |
65 | 63 | @Override |
66 | - public LwM2mClient getLwM2MClient(String endPoint, String identity) { | |
67 | - Map.Entry<String, LwM2mClient> modelClients = endPoint != null ? | |
68 | - this.lwM2mClients.entrySet().stream().filter(model -> endPoint.equals(model.getValue().getEndpoint())).findAny().orElse(null) : | |
69 | - this.lwM2mClients.entrySet().stream().filter(model -> identity.equals(model.getValue().getIdentity())).findAny().orElse(null); | |
70 | - return modelClients != null ? modelClients.getValue() : null; | |
64 | + public LwM2mClient getClientByRegistrationId(String registrationId) { | |
65 | + return lwM2mClientsByRegistrationId.get(registrationId); | |
71 | 66 | } |
72 | 67 | |
73 | 68 | @Override |
74 | - public LwM2mClient getLwM2MClient(TransportProtos.SessionInfoProto sessionInfo) { | |
75 | - return getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); | |
69 | + public LwM2mClient getOrRegister(Registration registration) { | |
70 | + if (registration == null) { | |
71 | + return null; | |
72 | + } | |
73 | + LwM2mClient client = lwM2mClientsByRegistrationId.get(registration.getId()); | |
74 | + if (client == null) { | |
75 | + client = lwM2mClientsByEndpoint.get(registration.getEndpoint()); | |
76 | + if (client == null) { | |
77 | + client = registerOrUpdate(registration); | |
78 | + } | |
79 | + } | |
80 | + return client; | |
76 | 81 | } |
77 | 82 | |
78 | 83 | @Override |
79 | - public LwM2mClient getLwM2mClient(UUID sessionId) { | |
80 | - return lwM2mClients.values().stream().filter(c -> c.getSessionId().equals(sessionId)).findAny().get(); | |
84 | + public LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo) { | |
85 | + return getClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); | |
81 | 86 | } |
82 | 87 | |
83 | 88 | @Override |
84 | - public LwM2mClient getLwM2mClientWithReg(Registration registration, String registrationId) { | |
85 | - LwM2mClient client = registrationId != null && this.lwM2mClients.containsKey(registrationId) ? | |
86 | - this.lwM2mClients.get(registrationId) : | |
87 | - registration !=null && this.lwM2mClients.containsKey(registration.getId()) ? | |
88 | - this.lwM2mClients.get(registration.getId()) : registration !=null && this.lwM2mClients.containsKey(registration) ? | |
89 | - this.lwM2mClients.get(registration.getEndpoint()) : null; | |
90 | - return client != null ? client : registration!= null ? updateInSessionsLwM2MClient(registration) : null; | |
89 | + public LwM2mClient getClient(UUID sessionId) { | |
90 | + //TODO: refactor this to search by sessionId efficiently. | |
91 | + return lwM2mClientsByEndpoint.values().stream().filter(c -> c.getSessionId().equals(sessionId)).findAny().get(); | |
91 | 92 | } |
92 | 93 | |
93 | 94 | @Override |
94 | - public LwM2mClient updateInSessionsLwM2MClient(Registration registration) { | |
95 | - if (this.lwM2mClients.get(registration.getEndpoint()) == null) { | |
96 | - this.addLwM2mClientToSession(registration.getEndpoint()); | |
95 | + public LwM2mClient registerOrUpdate(Registration registration) { | |
96 | + LwM2mClient lwM2MClient = lwM2mClientsByEndpoint.get(registration.getEndpoint()); | |
97 | + if (lwM2MClient == null) { | |
98 | + lwM2MClient = this.fetchClientByEndpoint(registration.getEndpoint()); | |
97 | 99 | } |
98 | - LwM2mClient lwM2MClient = lwM2mClients.get(registration.getEndpoint()); | |
99 | 100 | lwM2MClient.setRegistration(registration); |
100 | - this.lwM2mClients.remove(registration.getEndpoint()); | |
101 | - this.lwM2mClients.put(registration.getId(), lwM2MClient); | |
101 | +// TODO: this remove is probably redundant. We should remove it. | |
102 | +// this.lwM2mClientsByEndpoint.remove(registration.getEndpoint()); | |
103 | + this.lwM2mClientsByRegistrationId.put(registration.getId(), lwM2MClient); | |
102 | 104 | return lwM2MClient; |
103 | 105 | } |
104 | 106 | |
105 | 107 | public Registration getRegistration(String registrationId) { |
106 | - return this.lwM2mClients.get(registrationId).getRegistration(); | |
108 | + return this.lwM2mClientsByRegistrationId.get(registrationId).getRegistration(); | |
107 | 109 | } |
108 | 110 | |
109 | - /** | |
110 | - * Add new LwM2MClient to session | |
111 | - * | |
112 | - * @param identity- | |
113 | - * @return SecurityInfo. If error - SecurityInfoError | |
114 | - * and log: | |
115 | - * - FORBIDDEN - if there is no authorization | |
116 | - * - profileUuid - if the device does not have a profile | |
117 | - * - device - if the thingsboard does not have a device with a name equal to the identity | |
118 | - */ | |
119 | 111 | @Override |
120 | - public LwM2mClient addLwM2mClientToSession(String identity) { | |
121 | - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, LwM2mTransportUtil.LwM2mTypeServer.CLIENT); | |
122 | - if (store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { | |
123 | - UUID profileUuid = (store.getDeviceProfile() != null && addUpdateProfileParameters(store.getDeviceProfile())) ? store.getDeviceProfile().getUuidId() : null; | |
124 | - LwM2mClient client; | |
125 | - if (store.getSecurityInfo() != null && profileUuid != null) { | |
126 | - String endpoint = store.getSecurityInfo().getEndpoint(); | |
127 | - client = new LwM2mClient(endpoint, store.getSecurityInfo().getIdentity(), store.getSecurityInfo(), store.getMsg(), profileUuid, UUID.randomUUID()); | |
128 | - lwM2mClients.put(endpoint, client); | |
129 | - } else if (store.getSecurityMode() == NO_SEC.code && profileUuid != null) { | |
130 | - client = new LwM2mClient(identity, null, null, store.getMsg(), profileUuid, UUID.randomUUID()); | |
131 | - lwM2mClients.put(identity, client); | |
112 | + public LwM2mClient fetchClientByEndpoint(String endpoint) { | |
113 | + EndpointSecurityInfo securityInfo = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(endpoint, LwM2mTransportUtil.LwM2mTypeServer.CLIENT); | |
114 | + if (securityInfo.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { | |
115 | + if (securityInfo.getDeviceProfile() != null) { | |
116 | + toClientProfile(securityInfo.getDeviceProfile()); | |
117 | + UUID profileUuid = securityInfo.getDeviceProfile().getUuidId(); | |
118 | + LwM2mClient client; | |
119 | + if (securityInfo.getSecurityInfo() != null) { | |
120 | + client = new LwM2mClient(context.getNodeId(), securityInfo.getSecurityInfo().getEndpoint(), | |
121 | + securityInfo.getSecurityInfo().getIdentity(), securityInfo.getSecurityInfo(), | |
122 | + securityInfo.getMsg(), profileUuid, UUID.randomUUID()); | |
123 | + } else if (securityInfo.getSecurityMode() == NO_SEC.code) { | |
124 | + client = new LwM2mClient(context.getNodeId(), endpoint, | |
125 | + null, null, | |
126 | + securityInfo.getMsg(), profileUuid, UUID.randomUUID()); | |
127 | + } else { | |
128 | + throw new RuntimeException(String.format("Registration failed: device %s not found.", endpoint)); | |
129 | + } | |
130 | + lwM2mClientsByEndpoint.put(client.getEndpoint(), client); | |
131 | + return client; | |
132 | 132 | } else { |
133 | - throw new RuntimeException(String.format("Registration failed: FORBIDDEN/profileUuid/device %s , endpointId: %s [PSK]", profileUuid, identity)); | |
133 | + throw new RuntimeException(String.format("Registration failed: device %s not found.", endpoint)); | |
134 | 134 | } |
135 | - return client; | |
136 | 135 | } else { |
137 | - throw new RuntimeException(String.format("Registration failed: FORBIDDEN, endpointId: %s", identity)); | |
136 | + throw new RuntimeException(String.format("Registration failed: FORBIDDEN, endpointId: %s", endpoint)); | |
138 | 137 | } |
139 | 138 | } |
140 | 139 | |
141 | 140 | @Override |
142 | - public Map<String, LwM2mClient> getLwM2mClients() { | |
143 | - return lwM2mClients; | |
141 | + public Collection<LwM2mClient> getLwM2mClients() { | |
142 | + return lwM2mClientsByEndpoint.values(); | |
144 | 143 | } |
145 | 144 | |
146 | 145 | @Override |
... | ... | @@ -155,7 +154,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { |
155 | 154 | |
156 | 155 | @Override |
157 | 156 | public LwM2mClientProfile getProfile(Registration registration) { |
158 | - return this.getProfiles().get(getLwM2mClientWithReg(registration, null).getProfileId()); | |
157 | + return this.getProfiles().get(getOrRegister(registration).getProfileId()); | |
159 | 158 | } |
160 | 159 | |
161 | 160 | @Override |
... | ... | @@ -164,17 +163,18 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { |
164 | 163 | } |
165 | 164 | |
166 | 165 | @Override |
167 | - public boolean addUpdateProfileParameters(DeviceProfile deviceProfile) { | |
168 | - LwM2mClientProfile lwM2MClientProfile = LwM2mTransportUtil.getLwM2MClientProfileFromThingsboard(deviceProfile); | |
169 | - if (lwM2MClientProfile != null) { | |
166 | + public LwM2mClientProfile toClientProfile(DeviceProfile deviceProfile) { | |
167 | + LwM2mClientProfile lwM2MClientProfile = profiles.get(deviceProfile.getUuidId()); | |
168 | + if (lwM2MClientProfile == null) { | |
169 | + lwM2MClientProfile = LwM2mTransportUtil.toLwM2MClientProfile(deviceProfile); | |
170 | 170 | profiles.put(deviceProfile.getUuidId(), lwM2MClientProfile); |
171 | - return true; | |
172 | 171 | } |
173 | - return false; | |
172 | + return lwM2MClientProfile; | |
174 | 173 | } |
175 | 174 | |
176 | 175 | /** |
177 | 176 | * if isVer - ok or default ver=DEFAULT_LWM2M_VERSION |
177 | + * | |
178 | 178 | * @param registration - |
179 | 179 | * @return - all objectIdVer in client |
180 | 180 | */ |
... | ... | @@ -184,9 +184,31 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { |
184 | 184 | Arrays.stream(registration.getObjectLinks()).forEach(url -> { |
185 | 185 | LwM2mPath pathIds = new LwM2mPath(url.getUrl()); |
186 | 186 | if (!pathIds.isRoot()) { |
187 | - clientObjects.add(convertPathFromObjectIdToIdVer(url.getUrl(), registration)); | |
187 | + clientObjects.add(convertPathFromObjectIdToIdVer(url.getUrl(), registration)); | |
188 | 188 | } |
189 | 189 | }); |
190 | 190 | return (clientObjects.size() > 0) ? clientObjects : null; |
191 | 191 | } |
192 | + | |
193 | + @Override | |
194 | + public LwM2mClient getClientByDeviceId(UUID deviceId) { | |
195 | + return lwM2mClientsByRegistrationId.values().stream().filter(e -> deviceId.equals(e.getDeviceId())).findFirst().orElse(null); | |
196 | + } | |
197 | + | |
198 | + @Override | |
199 | + public void removeClientByRegistrationId(String registrationId) { | |
200 | + LwM2mClient lwM2MClient = this.lwM2mClientsByRegistrationId.get(registrationId); | |
201 | + if (lwM2MClient != null) { | |
202 | + this.securityStore.remove(lwM2MClient.getEndpoint(), false); | |
203 | + this.lwM2mClientsByEndpoint.remove(lwM2MClient.getEndpoint()); | |
204 | + this.lwM2mClientsByRegistrationId.remove(registrationId); | |
205 | + UUID profileId = lwM2MClient.getProfileId(); | |
206 | + if (profileId != null) { | |
207 | + Optional<LwM2mClient> otherClients = lwM2mClientsByRegistrationId.values().stream().filter(e -> e.getProfileId().equals(profileId)).findFirst(); | |
208 | + if (otherClients.isEmpty()) { | |
209 | + profiles.remove(profileId); | |
210 | + } | |
211 | + } | |
212 | + } | |
213 | + } | |
192 | 214 | } | ... | ... |
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mSecurityStore.java
renamed from
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mStoreConfiguration.java
... | ... | @@ -15,114 +15,80 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.transport.lwm2m.server.store; |
17 | 17 | |
18 | -import org.eclipse.leshan.server.californium.registration.CaliforniumRegistrationStore; | |
19 | -import org.eclipse.leshan.server.californium.registration.InMemoryRegistrationStore; | |
18 | +import lombok.extern.slf4j.Slf4j; | |
20 | 19 | import org.eclipse.leshan.server.security.EditableSecurityStore; |
21 | -import org.eclipse.leshan.server.security.InMemorySecurityStore; | |
22 | 20 | import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException; |
23 | 21 | import org.eclipse.leshan.server.security.SecurityInfo; |
24 | 22 | import org.eclipse.leshan.server.security.SecurityStoreListener; |
25 | -import org.springframework.beans.factory.annotation.Autowired; | |
26 | -import org.springframework.beans.factory.annotation.Value; | |
27 | -import org.springframework.context.annotation.Bean; | |
28 | -import org.springframework.context.annotation.Lazy; | |
29 | -import org.springframework.stereotype.Service; | |
30 | -import org.thingsboard.server.cache.TBRedisCacheConfiguration; | |
31 | -import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | |
32 | 23 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; |
33 | 24 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; |
34 | 25 | |
35 | 26 | import java.util.Collection; |
36 | -import java.util.Optional; | |
37 | 27 | |
38 | -@Service | |
39 | -@TbLwM2mTransportComponent | |
40 | -public class TbLwM2mStoreConfiguration { | |
28 | +@Slf4j | |
29 | +public class TbLwM2mSecurityStore implements EditableSecurityStore { | |
41 | 30 | |
42 | - @Autowired(required = false) | |
43 | - private Optional<TBRedisCacheConfiguration> redisConfiguration; | |
31 | + private final LwM2mClientContext clientContext; | |
32 | + private final EditableSecurityStore securityStore; | |
44 | 33 | |
45 | - @Autowired | |
46 | - @Lazy | |
47 | - private LwM2mClientContext clientContext; | |
48 | - | |
49 | - @Value("${transport.lwm2m.redis.enabled:false}") | |
50 | - private boolean useRedis; | |
51 | - | |
52 | - @Bean | |
53 | - private CaliforniumRegistrationStore registrationStore() { | |
54 | - return redisConfiguration.isPresent() && useRedis ? | |
55 | - new TbLwM2mRedisRegistrationStore(redisConfiguration.get().redisConnectionFactory()) : new InMemoryRegistrationStore(); | |
34 | + public TbLwM2mSecurityStore(LwM2mClientContext clientContext, EditableSecurityStore securityStore) { | |
35 | + this.clientContext = clientContext; | |
36 | + this.securityStore = securityStore; | |
56 | 37 | } |
57 | 38 | |
58 | - @Bean | |
59 | - private EditableSecurityStore securityStore() { | |
60 | - return new TbLwM2mSecurityStoreWrapper(redisConfiguration.isPresent() && useRedis ? | |
61 | - new TbLwM2mRedisSecurityStore(redisConfiguration.get().redisConnectionFactory()) : new InMemorySecurityStore()); | |
39 | + @Override | |
40 | + public Collection<SecurityInfo> getAll() { | |
41 | + return securityStore.getAll(); | |
62 | 42 | } |
63 | 43 | |
64 | - public class TbLwM2mSecurityStoreWrapper implements EditableSecurityStore { | |
65 | - | |
66 | - private final EditableSecurityStore securityStore; | |
67 | - | |
68 | - public TbLwM2mSecurityStoreWrapper(EditableSecurityStore securityStore) { | |
69 | - this.securityStore = securityStore; | |
70 | - } | |
71 | - | |
72 | - @Override | |
73 | - public Collection<SecurityInfo> getAll() { | |
74 | - return securityStore.getAll(); | |
75 | - } | |
76 | - | |
77 | - @Override | |
78 | - public SecurityInfo add(SecurityInfo info) throws NonUniqueSecurityInfoException { | |
79 | - return securityStore.add(info); | |
80 | - } | |
44 | + @Override | |
45 | + public SecurityInfo add(SecurityInfo info) throws NonUniqueSecurityInfoException { | |
46 | + return securityStore.add(info); | |
47 | + } | |
81 | 48 | |
82 | - @Override | |
83 | - public SecurityInfo remove(String endpoint, boolean infosAreCompromised) { | |
84 | - return securityStore.remove(endpoint, infosAreCompromised); | |
85 | - } | |
49 | + @Override | |
50 | + public SecurityInfo remove(String endpoint, boolean infosAreCompromised) { | |
51 | + return securityStore.remove(endpoint, infosAreCompromised); | |
52 | + } | |
86 | 53 | |
87 | - @Override | |
88 | - public void setListener(SecurityStoreListener listener) { | |
89 | - securityStore.setListener(listener); | |
90 | - } | |
54 | + @Override | |
55 | + public void setListener(SecurityStoreListener listener) { | |
56 | + securityStore.setListener(listener); | |
57 | + } | |
91 | 58 | |
92 | - @Override | |
93 | - public SecurityInfo getByEndpoint(String endPoint) { | |
94 | - SecurityInfo securityInfo = securityStore.getByEndpoint(endPoint); | |
95 | - if (securityInfo == null) { | |
96 | - LwM2mClient lwM2mClient = clientContext.getLwM2MClient(endPoint, null); | |
97 | - if (lwM2mClient != null && lwM2mClient.getRegistration() != null && !lwM2mClient.getRegistration().getIdentity().isSecure()){ | |
98 | - return null; | |
99 | - } | |
100 | - securityInfo = clientContext.addLwM2mClientToSession(endPoint).getSecurityInfo(); | |
101 | - try { | |
102 | - if (securityInfo != null) { | |
103 | - add(securityInfo); | |
104 | - } | |
105 | - } catch (NonUniqueSecurityInfoException e) { | |
106 | - e.printStackTrace(); | |
59 | + @Override | |
60 | + public SecurityInfo getByEndpoint(String endpoint) { | |
61 | + SecurityInfo securityInfo = securityStore.getByEndpoint(endpoint); | |
62 | + if (securityInfo == null) { | |
63 | + LwM2mClient lwM2mClient = clientContext.getClientByEndpoint(endpoint); | |
64 | + if (lwM2mClient != null && lwM2mClient.getRegistration() != null && !lwM2mClient.getRegistration().getIdentity().isSecure()) { | |
65 | + return null; | |
66 | + } | |
67 | + securityInfo = clientContext.fetchClientByEndpoint(endpoint).getSecurityInfo(); | |
68 | + try { | |
69 | + if (securityInfo != null) { | |
70 | + add(securityInfo); | |
107 | 71 | } |
72 | + } catch (NonUniqueSecurityInfoException e) { | |
73 | + log.warn("Failed to add security info: {}", securityInfo, e); | |
108 | 74 | } |
109 | - return securityInfo; | |
110 | 75 | } |
76 | + return securityInfo; | |
77 | + } | |
111 | 78 | |
112 | - @Override | |
113 | - public SecurityInfo getByIdentity(String pskIdentity) { | |
114 | - SecurityInfo securityInfo = securityStore.getByIdentity(pskIdentity); | |
115 | - if (securityInfo == null) { | |
116 | - securityInfo = clientContext.addLwM2mClientToSession(pskIdentity).getSecurityInfo(); | |
117 | - try { | |
118 | - if (securityInfo != null) { | |
119 | - add(securityInfo); | |
120 | - } | |
121 | - } catch (NonUniqueSecurityInfoException e) { | |
122 | - e.printStackTrace(); | |
79 | + @Override | |
80 | + public SecurityInfo getByIdentity(String pskIdentity) { | |
81 | + SecurityInfo securityInfo = securityStore.getByIdentity(pskIdentity); | |
82 | + if (securityInfo == null) { | |
83 | + securityInfo = clientContext.fetchClientByEndpoint(pskIdentity).getSecurityInfo(); | |
84 | + try { | |
85 | + if (securityInfo != null) { | |
86 | + add(securityInfo); | |
123 | 87 | } |
88 | + } catch (NonUniqueSecurityInfoException e) { | |
89 | + log.warn("Failed to add security info: {}", securityInfo, e); | |
124 | 90 | } |
125 | - return securityInfo; | |
126 | 91 | } |
92 | + return securityInfo; | |
127 | 93 | } |
128 | 94 | } | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2021 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +package org.thingsboard.server.transport.lwm2m.server.store; | |
17 | + | |
18 | +import org.eclipse.leshan.server.californium.registration.CaliforniumRegistrationStore; | |
19 | +import org.eclipse.leshan.server.californium.registration.InMemoryRegistrationStore; | |
20 | +import org.eclipse.leshan.server.security.EditableSecurityStore; | |
21 | +import org.eclipse.leshan.server.security.InMemorySecurityStore; | |
22 | +import org.springframework.beans.factory.annotation.Autowired; | |
23 | +import org.springframework.beans.factory.annotation.Value; | |
24 | +import org.springframework.context.annotation.Bean; | |
25 | +import org.springframework.context.annotation.Lazy; | |
26 | +import org.springframework.stereotype.Component; | |
27 | +import org.thingsboard.server.cache.TBRedisCacheConfiguration; | |
28 | +import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | |
29 | +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; | |
30 | + | |
31 | +import java.util.Optional; | |
32 | + | |
33 | +@Component | |
34 | +@TbLwM2mTransportComponent | |
35 | +public class TbLwM2mStoreFactory { | |
36 | + | |
37 | + @Autowired(required = false) | |
38 | + private Optional<TBRedisCacheConfiguration> redisConfiguration; | |
39 | + | |
40 | + @Autowired | |
41 | + @Lazy | |
42 | + private LwM2mClientContext clientContext; | |
43 | + | |
44 | + @Value("${transport.lwm2m.redis.enabled:false}") | |
45 | + private boolean useRedis; | |
46 | + | |
47 | + @Bean | |
48 | + private CaliforniumRegistrationStore registrationStore() { | |
49 | + return redisConfiguration.isPresent() && useRedis ? | |
50 | + new TbLwM2mRedisRegistrationStore(redisConfiguration.get().redisConnectionFactory()) : new InMemoryRegistrationStore(); | |
51 | + } | |
52 | + | |
53 | + @Bean | |
54 | + private EditableSecurityStore securityStore() { | |
55 | + return new TbLwM2mSecurityStore(clientContext, redisConfiguration.isPresent() && useRedis ? | |
56 | + new TbLwM2mRedisSecurityStore(redisConfiguration.get().redisConnectionFactory()) : new InMemorySecurityStore()); | |
57 | + } | |
58 | + | |
59 | +} | ... | ... |