Commit 6d20ca441ec43a1f678f38f72526509cad47701c
Committed by
Andrii Shvaika
1 parent
5834bbd7
Merge TS fix using cherry-pick
Showing
7 changed files
with
187 additions
and
38 deletions
1 | +package org.thingsboard.server.transport.lwm2m.server; | ||
2 | + | ||
3 | +import org.junit.jupiter.api.BeforeEach; | ||
4 | +import org.junit.jupiter.api.Test; | ||
5 | +import org.thingsboard.server.gen.transport.TransportProtos; | ||
6 | + | ||
7 | +import java.util.List; | ||
8 | +import java.util.concurrent.ConcurrentHashMap; | ||
9 | +import java.util.concurrent.ConcurrentMap; | ||
10 | +import java.util.concurrent.TimeUnit; | ||
11 | +import java.util.concurrent.atomic.AtomicLong; | ||
12 | + | ||
13 | +import static java.util.Collections.emptyList; | ||
14 | +import static org.assertj.core.api.Assertions.assertThat; | ||
15 | +import static org.mockito.ArgumentMatchers.any; | ||
16 | +import static org.mockito.ArgumentMatchers.anyLong; | ||
17 | +import static org.mockito.ArgumentMatchers.anyString; | ||
18 | +import static org.mockito.BDDMockito.willReturn; | ||
19 | +import static org.mockito.Mockito.mock; | ||
20 | +import static org.mockito.Mockito.never; | ||
21 | +import static org.mockito.Mockito.spy; | ||
22 | +import static org.mockito.Mockito.times; | ||
23 | +import static org.mockito.Mockito.verify; | ||
24 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LWM2M_TELEMETRY; | ||
25 | + | ||
26 | +class LwM2mTransportServerHelperTest { | ||
27 | + | ||
28 | + public static final String KEY_SW_STATE = "sw_state"; | ||
29 | + public static final String DOWNLOADING = "DOWNLOADING"; | ||
30 | + | ||
31 | + long now; | ||
32 | + List<TransportProtos.KeyValueProto> kvList; | ||
33 | + ConcurrentMap<String, AtomicLong> keyTsLatestMap; | ||
34 | + LwM2mTransportServerHelper helper; | ||
35 | + LwM2mTransportContext context; | ||
36 | + | ||
37 | + | ||
38 | + @BeforeEach | ||
39 | + void setUp() { | ||
40 | + now = System.currentTimeMillis(); | ||
41 | + context = mock(LwM2mTransportContext.class); | ||
42 | + helper = spy(new LwM2mTransportServerHelper(context)); | ||
43 | + willReturn(now).given(helper).getCurrentTimeMillis(); | ||
44 | + kvList = List.of( | ||
45 | + TransportProtos.KeyValueProto.newBuilder().setKey(KEY_SW_STATE).setStringV(DOWNLOADING).build(), | ||
46 | + TransportProtos.KeyValueProto.newBuilder().setKey(LOG_LWM2M_TELEMETRY).setStringV("Transport log example").build() | ||
47 | + ); | ||
48 | + keyTsLatestMap = new ConcurrentHashMap<>(); | ||
49 | + } | ||
50 | + | ||
51 | + @Test | ||
52 | + void givenKeyAndLatestTsMapAndCurrentTs_whenGetTs_thenVerifyNoGetTsByKeyCall() { | ||
53 | + assertThat(helper.getTs(null, null)).isEqualTo(now); | ||
54 | + assertThat(helper.getTs(null, keyTsLatestMap)).isEqualTo(now); | ||
55 | + assertThat(helper.getTs(emptyList(), null)).isEqualTo(now); | ||
56 | + assertThat(helper.getTs(emptyList(), keyTsLatestMap)).isEqualTo(now); | ||
57 | + assertThat(helper.getTs(kvList, null)).isEqualTo(now); | ||
58 | + | ||
59 | + verify(helper, never()).getTsByKey(anyString(), any(ConcurrentMap.class), anyLong()); | ||
60 | + verify(helper, times(5)).getCurrentTimeMillis(); | ||
61 | + } | ||
62 | + | ||
63 | + @Test | ||
64 | + void givenKeyAndLatestTsMapAndCurrentTs_whenGetTs_thenVerifyGetTsByKeyCallByFirstKey() { | ||
65 | + assertThat(helper.getTs(kvList, keyTsLatestMap)).isEqualTo(now); | ||
66 | + | ||
67 | + verify(helper, times(1)).getTsByKey(kvList.get(0).getKey(), keyTsLatestMap, now); | ||
68 | + verify(helper, times(1)).getTsByKey(anyString(), any(ConcurrentMap.class), anyLong()); | ||
69 | + } | ||
70 | + | ||
71 | + @Test | ||
72 | + void givenKeyAndEmptyLatestTsMap_whenGetTsByKey_thenAddToMapAndReturnNow() { | ||
73 | + assertThat(keyTsLatestMap).as("ts latest map before").isEmpty(); | ||
74 | + | ||
75 | + assertThat(helper.getTsByKey(KEY_SW_STATE, keyTsLatestMap, now)).as("getTsByKey").isEqualTo(now); | ||
76 | + | ||
77 | + assertThat(keyTsLatestMap).as("ts latest map after").hasSize(1); | ||
78 | + assertThat(keyTsLatestMap.get(KEY_SW_STATE)).as("key present").isNotNull(); | ||
79 | + assertThat(keyTsLatestMap.get(KEY_SW_STATE).get()).as("ts in map by key").isEqualTo(now); | ||
80 | + } | ||
81 | + | ||
82 | + @Test | ||
83 | + void givenKeyAndLatestTsMapWithExistedKey_whenGetTsByKey_thenCallSwapOrIncrementMethod() { | ||
84 | + keyTsLatestMap.put(KEY_SW_STATE, new AtomicLong()); | ||
85 | + keyTsLatestMap.put("other", new AtomicLong()); | ||
86 | + assertThat(keyTsLatestMap).as("ts latest map").hasSize(2); | ||
87 | + willReturn(now).given(helper).compareAndSwapOrIncrementTsAtomically(any(AtomicLong.class), anyLong()); | ||
88 | + | ||
89 | + assertThat(helper.getTsByKey(KEY_SW_STATE, keyTsLatestMap, now)).as("getTsByKey").isEqualTo(now); | ||
90 | + | ||
91 | + verify(helper, times(1)).compareAndSwapOrIncrementTsAtomically(keyTsLatestMap.get(KEY_SW_STATE), now); | ||
92 | + verify(helper, times(1)).compareAndSwapOrIncrementTsAtomically(any(AtomicLong.class), anyLong()); | ||
93 | + } | ||
94 | + | ||
95 | + @Test | ||
96 | + void givenMapWithTsValueLessThanNow_whenCompareAndSwapOrIncrementTsAtomically_thenReturnNow() { | ||
97 | + keyTsLatestMap.put(KEY_SW_STATE, new AtomicLong(now - 1)); | ||
98 | + assertThat(helper.compareAndSwapOrIncrementTsAtomically(keyTsLatestMap.get(KEY_SW_STATE), now)).isEqualTo(now); | ||
99 | + } | ||
100 | + | ||
101 | + @Test | ||
102 | + void givenMapWithTsValueEqualsNow_whenCompareAndSwapOrIncrementTsAtomically_thenReturnNowIncremented() { | ||
103 | + keyTsLatestMap.put(KEY_SW_STATE, new AtomicLong(now)); | ||
104 | + assertThat(helper.compareAndSwapOrIncrementTsAtomically(keyTsLatestMap.get(KEY_SW_STATE), now)).isEqualTo(now + 1); | ||
105 | + } | ||
106 | + | ||
107 | + @Test | ||
108 | + void givenMapWithTsValueGreaterThanNow_whenCompareAndSwapOrIncrementTsAtomically_thenReturnGreaterThanNowIncremented() { | ||
109 | + final long nextHourTs = now + TimeUnit.HOURS.toMillis(1); | ||
110 | + keyTsLatestMap.put(KEY_SW_STATE, new AtomicLong(nextHourTs)); | ||
111 | + assertThat(helper.compareAndSwapOrIncrementTsAtomically(keyTsLatestMap.get(KEY_SW_STATE), now)).isEqualTo(nextHourTs + 1); | ||
112 | + } | ||
113 | + | ||
114 | +} |
@@ -14,21 +14,6 @@ | @@ -14,21 +14,6 @@ | ||
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | package org.thingsboard.server.transport.lwm2m.server; | 16 | package org.thingsboard.server.transport.lwm2m.server; |
17 | -/** | ||
18 | - * Copyright © 2016-2020 The Thingsboard Authors | ||
19 | - * <p> | ||
20 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
21 | - * you may not use this file except in compliance with the License. | ||
22 | - * You may obtain a copy of the License at | ||
23 | - * <p> | ||
24 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
25 | - * <p> | ||
26 | - * Unless required by applicable law or agreed to in writing, software | ||
27 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
28 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
29 | - * See the License for the specific language governing permissions and | ||
30 | - * limitations under the License. | ||
31 | - */ | ||
32 | 17 | ||
33 | import lombok.RequiredArgsConstructor; | 18 | import lombok.RequiredArgsConstructor; |
34 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
@@ -37,10 +22,7 @@ import org.eclipse.leshan.core.model.DefaultDDFFileValidator; | @@ -37,10 +22,7 @@ import org.eclipse.leshan.core.model.DefaultDDFFileValidator; | ||
37 | import org.eclipse.leshan.core.model.InvalidDDFFileException; | 22 | import org.eclipse.leshan.core.model.InvalidDDFFileException; |
38 | import org.eclipse.leshan.core.model.ObjectModel; | 23 | import org.eclipse.leshan.core.model.ObjectModel; |
39 | import org.eclipse.leshan.core.model.ResourceModel; | 24 | import org.eclipse.leshan.core.model.ResourceModel; |
40 | -import org.eclipse.leshan.core.node.LwM2mPath; | ||
41 | -import org.eclipse.leshan.core.node.LwM2mResource; | ||
42 | import org.eclipse.leshan.core.node.codec.CodecException; | 25 | import org.eclipse.leshan.core.node.codec.CodecException; |
43 | -import org.eclipse.leshan.core.request.ContentFormat; | ||
44 | import org.springframework.stereotype.Component; | 26 | import org.springframework.stereotype.Component; |
45 | import org.thingsboard.server.common.transport.TransportServiceCallback; | 27 | import org.thingsboard.server.common.transport.TransportServiceCallback; |
46 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; | 28 | import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; |
@@ -49,19 +31,17 @@ import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg; | @@ -49,19 +31,17 @@ import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg; | ||
49 | import org.thingsboard.server.gen.transport.TransportProtos.PostTelemetryMsg; | 31 | import org.thingsboard.server.gen.transport.TransportProtos.PostTelemetryMsg; |
50 | import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; | 32 | import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; |
51 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | 33 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
52 | -import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor; | ||
53 | -import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; | ||
54 | -import org.thingsboard.server.transport.lwm2m.server.client.ResourceValue; | ||
55 | 34 | ||
35 | +import javax.annotation.Nonnull; | ||
36 | +import javax.annotation.Nullable; | ||
56 | import java.io.ByteArrayInputStream; | 37 | import java.io.ByteArrayInputStream; |
57 | import java.io.IOException; | 38 | import java.io.IOException; |
58 | import java.util.ArrayList; | 39 | import java.util.ArrayList; |
59 | import java.util.List; | 40 | import java.util.List; |
60 | -import java.util.concurrent.TimeUnit; | ||
61 | -import java.util.concurrent.atomic.AtomicInteger; | 41 | +import java.util.concurrent.ConcurrentMap; |
42 | +import java.util.concurrent.atomic.AtomicLong; | ||
62 | 43 | ||
63 | import static org.thingsboard.server.gen.transport.TransportProtos.KeyValueType.BOOLEAN_V; | 44 | import static org.thingsboard.server.gen.transport.TransportProtos.KeyValueType.BOOLEAN_V; |
64 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.fromVersionedIdToObjectId; | ||
65 | 45 | ||
66 | @Slf4j | 46 | @Slf4j |
67 | @Component | 47 | @Component |
@@ -70,11 +50,6 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.f | @@ -70,11 +50,6 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.f | ||
70 | public class LwM2mTransportServerHelper { | 50 | public class LwM2mTransportServerHelper { |
71 | 51 | ||
72 | private final LwM2mTransportContext context; | 52 | private final LwM2mTransportContext context; |
73 | - private final AtomicInteger atomicTs = new AtomicInteger(0); | ||
74 | - | ||
75 | - public long getTS() { | ||
76 | - return TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) * 1000L + (atomicTs.getAndIncrement() % 1000); | ||
77 | - } | ||
78 | 53 | ||
79 | public void sendParametersOnThingsboardAttribute(List<TransportProtos.KeyValueProto> result, SessionInfoProto sessionInfo) { | 54 | public void sendParametersOnThingsboardAttribute(List<TransportProtos.KeyValueProto> result, SessionInfoProto sessionInfo) { |
80 | PostAttributeMsg.Builder request = PostAttributeMsg.newBuilder(); | 55 | PostAttributeMsg.Builder request = PostAttributeMsg.newBuilder(); |
@@ -83,16 +58,67 @@ public class LwM2mTransportServerHelper { | @@ -83,16 +58,67 @@ public class LwM2mTransportServerHelper { | ||
83 | context.getTransportService().process(sessionInfo, postAttributeMsg, TransportServiceCallback.EMPTY); | 58 | context.getTransportService().process(sessionInfo, postAttributeMsg, TransportServiceCallback.EMPTY); |
84 | } | 59 | } |
85 | 60 | ||
86 | - public void sendParametersOnThingsboardTelemetry(List<TransportProtos.KeyValueProto> result, SessionInfoProto sessionInfo) { | ||
87 | - PostTelemetryMsg.Builder request = PostTelemetryMsg.newBuilder(); | ||
88 | - TransportProtos.TsKvListProto.Builder builder = TransportProtos.TsKvListProto.newBuilder(); | ||
89 | - builder.setTs(this.getTS()); | ||
90 | - builder.addAllKv(result); | ||
91 | - request.addTsKvList(builder.build()); | ||
92 | - PostTelemetryMsg postTelemetryMsg = request.build(); | 61 | + public void sendParametersOnThingsboardTelemetry(List<TransportProtos.KeyValueProto> kvList, SessionInfoProto sessionInfo) { |
62 | + sendParametersOnThingsboardTelemetry(kvList, sessionInfo, null); | ||
63 | + } | ||
64 | + | ||
65 | + public void sendParametersOnThingsboardTelemetry(List<TransportProtos.KeyValueProto> kvList, SessionInfoProto sessionInfo, @Nullable ConcurrentMap<String, AtomicLong> keyTsLatestMap) { | ||
66 | + TransportProtos.TsKvListProto tsKvList = toTsKvList(kvList, keyTsLatestMap); | ||
67 | + | ||
68 | + PostTelemetryMsg postTelemetryMsg = PostTelemetryMsg.newBuilder() | ||
69 | + .addTsKvList(tsKvList) | ||
70 | + .build(); | ||
71 | + | ||
93 | context.getTransportService().process(sessionInfo, postTelemetryMsg, TransportServiceCallback.EMPTY); | 72 | context.getTransportService().process(sessionInfo, postTelemetryMsg, TransportServiceCallback.EMPTY); |
94 | } | 73 | } |
95 | 74 | ||
75 | + TransportProtos.TsKvListProto toTsKvList(List<TransportProtos.KeyValueProto> kvList, ConcurrentMap<String, AtomicLong> keyTsLatestMap) { | ||
76 | + return TransportProtos.TsKvListProto.newBuilder() | ||
77 | + .setTs(getTs(kvList, keyTsLatestMap)) | ||
78 | + .addAllKv(kvList) | ||
79 | + .build(); | ||
80 | + } | ||
81 | + | ||
82 | + long getTs(List<TransportProtos.KeyValueProto> kvList, ConcurrentMap<String, AtomicLong> keyTsLatestMap) { | ||
83 | + if (keyTsLatestMap == null || kvList == null || kvList.isEmpty()) { | ||
84 | + return getCurrentTimeMillis(); | ||
85 | + } | ||
86 | + | ||
87 | + return getTsByKey(kvList.get(0).getKey(), keyTsLatestMap, getCurrentTimeMillis()); | ||
88 | + } | ||
89 | + | ||
90 | + long getTsByKey(@Nonnull String key, @Nonnull ConcurrentMap<String, AtomicLong> keyTsLatestMap, final long tsNow) { | ||
91 | + AtomicLong tsLatestAtomic = keyTsLatestMap.putIfAbsent(key, new AtomicLong(tsNow)); | ||
92 | + if (tsLatestAtomic == null) { | ||
93 | + return tsNow; // it is a first known timestamp for this key. return as the latest | ||
94 | + } | ||
95 | + | ||
96 | + return compareAndSwapOrIncrementTsAtomically(tsLatestAtomic, tsNow); | ||
97 | + } | ||
98 | + | ||
99 | + /** | ||
100 | + * This algorithm is sensitive to wall-clock time shift. | ||
101 | + * Once time have shifted *backward*, the latest ts never came back. | ||
102 | + * Ts latest will be incremented until current time overtake the latest ts. | ||
103 | + * In normal environment without race conditions method will return current ts (wall-clock) | ||
104 | + * */ | ||
105 | + long compareAndSwapOrIncrementTsAtomically(AtomicLong tsLatestAtomic, final long tsNow) { | ||
106 | + long tsLatest; | ||
107 | + while ((tsLatest = tsLatestAtomic.get()) < tsNow) { | ||
108 | + if (tsLatestAtomic.compareAndSet(tsLatest, tsNow)) { | ||
109 | + return tsNow; //swap successful | ||
110 | + } | ||
111 | + } | ||
112 | + return tsLatestAtomic.incrementAndGet(); //return next ms | ||
113 | + } | ||
114 | + | ||
115 | + /** | ||
116 | + * For the test ability to mock system timer | ||
117 | + * */ | ||
118 | + long getCurrentTimeMillis() { | ||
119 | + return System.currentTimeMillis(); | ||
120 | + } | ||
121 | + | ||
96 | /** | 122 | /** |
97 | * @return - sessionInfo after access connect client | 123 | * @return - sessionInfo after access connect client |
98 | */ | 124 | */ |
@@ -50,8 +50,10 @@ import java.util.Optional; | @@ -50,8 +50,10 @@ import java.util.Optional; | ||
50 | import java.util.Set; | 50 | import java.util.Set; |
51 | import java.util.UUID; | 51 | import java.util.UUID; |
52 | import java.util.concurrent.ConcurrentHashMap; | 52 | import java.util.concurrent.ConcurrentHashMap; |
53 | +import java.util.concurrent.ConcurrentMap; | ||
53 | import java.util.concurrent.Future; | 54 | import java.util.concurrent.Future; |
54 | import java.util.concurrent.atomic.AtomicInteger; | 55 | import java.util.concurrent.atomic.AtomicInteger; |
56 | +import java.util.concurrent.atomic.AtomicLong; | ||
55 | import java.util.concurrent.locks.Lock; | 57 | import java.util.concurrent.locks.Lock; |
56 | import java.util.concurrent.locks.ReentrantLock; | 58 | import java.util.concurrent.locks.ReentrantLock; |
57 | import java.util.stream.Collectors; | 59 | import java.util.stream.Collectors; |
@@ -80,6 +82,8 @@ public class LwM2mClient implements Serializable { | @@ -80,6 +82,8 @@ public class LwM2mClient implements Serializable { | ||
80 | private final Map<String, ResourceValue> resources; | 82 | private final Map<String, ResourceValue> resources; |
81 | @Getter | 83 | @Getter |
82 | private final Map<String, TsKvProto> sharedAttributes; | 84 | private final Map<String, TsKvProto> sharedAttributes; |
85 | + @Getter | ||
86 | + private final ConcurrentMap<String, AtomicLong> keyTsLatestMap; | ||
83 | 87 | ||
84 | @Getter | 88 | @Getter |
85 | private TenantId tenantId; | 89 | private TenantId tenantId; |
@@ -126,6 +130,7 @@ public class LwM2mClient implements Serializable { | @@ -126,6 +130,7 @@ public class LwM2mClient implements Serializable { | ||
126 | this.endpoint = endpoint; | 130 | this.endpoint = endpoint; |
127 | this.sharedAttributes = new ConcurrentHashMap<>(); | 131 | this.sharedAttributes = new ConcurrentHashMap<>(); |
128 | this.resources = new ConcurrentHashMap<>(); | 132 | this.resources = new ConcurrentHashMap<>(); |
133 | + this.keyTsLatestMap = new ConcurrentHashMap<>(); | ||
129 | this.state = LwM2MClientState.CREATED; | 134 | this.state = LwM2MClientState.CREATED; |
130 | this.lock = new ReentrantLock(); | 135 | this.lock = new ReentrantLock(); |
131 | this.retryAttempts = new AtomicInteger(0); | 136 | this.retryAttempts = new AtomicInteger(0); |
@@ -39,7 +39,7 @@ public class DefaultLwM2MTelemetryLogService implements LwM2MTelemetryLogService | @@ -39,7 +39,7 @@ public class DefaultLwM2MTelemetryLogService implements LwM2MTelemetryLogService | ||
39 | if (logMsg.length() > 1024) { | 39 | if (logMsg.length() > 1024) { |
40 | logMsg = logMsg.substring(0, 1024); | 40 | logMsg = logMsg.substring(0, 1024); |
41 | } | 41 | } |
42 | - this.helper.sendParametersOnThingsboardTelemetry(this.helper.getKvStringtoThingsboard(LOG_LWM2M_TELEMETRY, logMsg), client.getSession()); | 42 | + this.helper.sendParametersOnThingsboardTelemetry(this.helper.getKvStringtoThingsboard(LOG_LWM2M_TELEMETRY, logMsg), client.getSession(), client.getKeyTsLatestMap()); |
43 | } | 43 | } |
44 | } | 44 | } |
45 | 45 |
@@ -602,7 +602,7 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl | @@ -602,7 +602,7 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl | ||
602 | kvProto = TransportProtos.KeyValueProto.newBuilder().setKey(LOG_LWM2M_TELEMETRY); | 602 | kvProto = TransportProtos.KeyValueProto.newBuilder().setKey(LOG_LWM2M_TELEMETRY); |
603 | kvProto.setType(TransportProtos.KeyValueType.STRING_V).setStringV(log); | 603 | kvProto.setType(TransportProtos.KeyValueType.STRING_V).setStringV(log); |
604 | result.add(kvProto.build()); | 604 | result.add(kvProto.build()); |
605 | - helper.sendParametersOnThingsboardTelemetry(result, client.getSession()); | 605 | + helper.sendParametersOnThingsboardTelemetry(result, client.getSession(), client.getKeyTsLatestMap()); |
606 | } | 606 | } |
607 | 607 | ||
608 | private static Optional<OtaPackageUpdateStatus> toOtaPackageUpdateStatus(FirmwareUpdateResult fwUpdateResult) { | 608 | private static Optional<OtaPackageUpdateStatus> toOtaPackageUpdateStatus(FirmwareUpdateResult fwUpdateResult) { |
@@ -19,12 +19,14 @@ import com.fasterxml.jackson.annotation.JsonIgnore; | @@ -19,12 +19,14 @@ import com.fasterxml.jackson.annotation.JsonIgnore; | ||
19 | import lombok.Data; | 19 | import lombok.Data; |
20 | import lombok.EqualsAndHashCode; | 20 | import lombok.EqualsAndHashCode; |
21 | import lombok.NoArgsConstructor; | 21 | import lombok.NoArgsConstructor; |
22 | +import lombok.ToString; | ||
22 | import org.thingsboard.server.common.data.ota.OtaPackageType; | 23 | import org.thingsboard.server.common.data.ota.OtaPackageType; |
23 | import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MClientOtaInfo; | 24 | import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MClientOtaInfo; |
24 | 25 | ||
25 | @Data | 26 | @Data |
26 | @EqualsAndHashCode(callSuper = true) | 27 | @EqualsAndHashCode(callSuper = true) |
27 | @NoArgsConstructor | 28 | @NoArgsConstructor |
29 | +@ToString(callSuper = true) | ||
28 | public class LwM2MClientFwOtaInfo extends LwM2MClientOtaInfo<LwM2MFirmwareUpdateStrategy, FirmwareUpdateState, FirmwareUpdateResult> { | 30 | public class LwM2MClientFwOtaInfo extends LwM2MClientOtaInfo<LwM2MFirmwareUpdateStrategy, FirmwareUpdateState, FirmwareUpdateResult> { |
29 | 31 | ||
30 | private Integer deliveryMethod; | 32 | private Integer deliveryMethod; |
@@ -19,6 +19,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; | @@ -19,6 +19,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; | ||
19 | import lombok.Data; | 19 | import lombok.Data; |
20 | import lombok.EqualsAndHashCode; | 20 | import lombok.EqualsAndHashCode; |
21 | import lombok.NoArgsConstructor; | 21 | import lombok.NoArgsConstructor; |
22 | +import lombok.ToString; | ||
22 | import org.thingsboard.server.common.data.StringUtils; | 23 | import org.thingsboard.server.common.data.StringUtils; |
23 | import org.thingsboard.server.common.data.ota.OtaPackageType; | 24 | import org.thingsboard.server.common.data.ota.OtaPackageType; |
24 | import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MClientOtaInfo; | 25 | import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MClientOtaInfo; |
@@ -29,6 +30,7 @@ import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MFirmwareU | @@ -29,6 +30,7 @@ import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MFirmwareU | ||
29 | @Data | 30 | @Data |
30 | @EqualsAndHashCode(callSuper = true) | 31 | @EqualsAndHashCode(callSuper = true) |
31 | @NoArgsConstructor | 32 | @NoArgsConstructor |
33 | +@ToString(callSuper = true) | ||
32 | public class LwM2MClientSwOtaInfo extends LwM2MClientOtaInfo<LwM2MSoftwareUpdateStrategy, SoftwareUpdateState, SoftwareUpdateResult> { | 34 | public class LwM2MClientSwOtaInfo extends LwM2MClientOtaInfo<LwM2MSoftwareUpdateStrategy, SoftwareUpdateState, SoftwareUpdateResult> { |
33 | 35 | ||
34 | public LwM2MClientSwOtaInfo(String endpoint, String baseUrl, LwM2MSoftwareUpdateStrategy strategy) { | 36 | public LwM2MClientSwOtaInfo(String endpoint, String baseUrl, LwM2MSoftwareUpdateStrategy strategy) { |