Showing
10 changed files
with
82 additions
and
149 deletions
@@ -151,20 +151,9 @@ public final class PluginProcessingContext implements PluginContext { | @@ -151,20 +151,9 @@ public final class PluginProcessingContext implements PluginContext { | ||
151 | } | 151 | } |
152 | 152 | ||
153 | @Override | 153 | @Override |
154 | - public List<TsKvEntry> loadTimeseries(DeviceId deviceId, TsKvQuery query) { | 154 | + public void loadTimeseries(DeviceId deviceId, List<TsKvQuery> queries, PluginCallback<List<TsKvEntry>> callback) { |
155 | validate(deviceId); | 155 | validate(deviceId); |
156 | - try { | ||
157 | - return pluginCtx.tsService.findAll(DataConstants.DEVICE, deviceId, query).get(); | ||
158 | - } catch (Exception e) { | ||
159 | - log.error("TODO", e); | ||
160 | - throw new RuntimeException(e); | ||
161 | - } | ||
162 | - } | ||
163 | - | ||
164 | - @Override | ||
165 | - public void loadTimeseries(DeviceId deviceId, TsKvQuery query, PluginCallback<List<TsKvEntry>> callback) { | ||
166 | - validate(deviceId); | ||
167 | - ListenableFuture<List<TsKvEntry>> future = pluginCtx.tsService.findAll(DataConstants.DEVICE, deviceId, query); | 156 | + ListenableFuture<List<TsKvEntry>> future = pluginCtx.tsService.findAll(DataConstants.DEVICE, deviceId, queries); |
168 | Futures.addCallback(future, getCallback(callback, v -> v), executor); | 157 | Futures.addCallback(future, getCallback(callback, v -> v), executor); |
169 | } | 158 | } |
170 | 159 |
@@ -96,7 +96,21 @@ public class BaseTimeseriesDao extends AbstractDao implements TimeseriesDao { | @@ -96,7 +96,21 @@ public class BaseTimeseriesDao extends AbstractDao implements TimeseriesDao { | ||
96 | } | 96 | } |
97 | 97 | ||
98 | @Override | 98 | @Override |
99 | - public ListenableFuture<List<TsKvEntry>> findAllAsync(String entityType, UUID entityId, TsKvQuery query) { | 99 | + public ListenableFuture<List<TsKvEntry>> findAllAsync(String entityType, UUID entityId, List<TsKvQuery> queries) { |
100 | + List<ListenableFuture<List<TsKvEntry>>> futures = queries.stream().map(query -> findAllAsync(entityType, entityId, query)).collect(Collectors.toList()); | ||
101 | + return Futures.transform(Futures.allAsList(futures), new Function<List<List<TsKvEntry>>, List<TsKvEntry>>() { | ||
102 | + @Nullable | ||
103 | + @Override | ||
104 | + public List<TsKvEntry> apply(@Nullable List<List<TsKvEntry>> results) { | ||
105 | + List<TsKvEntry> result = new ArrayList<TsKvEntry>(); | ||
106 | + results.forEach(r -> result.addAll(r)); | ||
107 | + return result; | ||
108 | + } | ||
109 | + }, readResultsProcessingExecutor); | ||
110 | + } | ||
111 | + | ||
112 | + | ||
113 | + private ListenableFuture<List<TsKvEntry>> findAllAsync(String entityType, UUID entityId, TsKvQuery query) { | ||
100 | if (query.getAggregation() == Aggregation.NONE) { | 114 | if (query.getAggregation() == Aggregation.NONE) { |
101 | return findAllAsyncWithLimit(entityType, entityId, query); | 115 | return findAllAsyncWithLimit(entityType, entityId, query); |
102 | } else { | 116 | } else { |
@@ -18,6 +18,7 @@ package org.thingsboard.server.dao.timeseries; | @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.timeseries; | ||
18 | import com.datastax.driver.core.ResultSet; | 18 | import com.datastax.driver.core.ResultSet; |
19 | import com.datastax.driver.core.ResultSetFuture; | 19 | import com.datastax.driver.core.ResultSetFuture; |
20 | import com.datastax.driver.core.Row; | 20 | import com.datastax.driver.core.Row; |
21 | +import com.google.common.base.Function; | ||
21 | import com.google.common.collect.Lists; | 22 | import com.google.common.collect.Lists; |
22 | import com.google.common.util.concurrent.Futures; | 23 | import com.google.common.util.concurrent.Futures; |
23 | import com.google.common.util.concurrent.ListenableFuture; | 24 | import com.google.common.util.concurrent.ListenableFuture; |
@@ -32,6 +33,7 @@ import org.springframework.beans.factory.annotation.Value; | @@ -32,6 +33,7 @@ import org.springframework.beans.factory.annotation.Value; | ||
32 | import org.springframework.stereotype.Service; | 33 | import org.springframework.stereotype.Service; |
33 | import org.thingsboard.server.dao.service.Validator; | 34 | import org.thingsboard.server.dao.service.Validator; |
34 | 35 | ||
36 | +import javax.annotation.Nullable; | ||
35 | import javax.annotation.PostConstruct; | 37 | import javax.annotation.PostConstruct; |
36 | import javax.annotation.PreDestroy; | 38 | import javax.annotation.PreDestroy; |
37 | import java.time.Instant; | 39 | import java.time.Instant; |
@@ -40,6 +42,7 @@ import java.time.ZoneOffset; | @@ -40,6 +42,7 @@ import java.time.ZoneOffset; | ||
40 | import java.util.*; | 42 | import java.util.*; |
41 | import java.util.concurrent.ExecutorService; | 43 | import java.util.concurrent.ExecutorService; |
42 | import java.util.concurrent.Executors; | 44 | import java.util.concurrent.Executors; |
45 | +import java.util.stream.Collectors; | ||
43 | 46 | ||
44 | import static org.apache.commons.lang3.StringUtils.isBlank; | 47 | import static org.apache.commons.lang3.StringUtils.isBlank; |
45 | 48 | ||
@@ -56,10 +59,10 @@ public class BaseTimeseriesService implements TimeseriesService { | @@ -56,10 +59,10 @@ public class BaseTimeseriesService implements TimeseriesService { | ||
56 | private TimeseriesDao timeseriesDao; | 59 | private TimeseriesDao timeseriesDao; |
57 | 60 | ||
58 | @Override | 61 | @Override |
59 | - public ListenableFuture<List<TsKvEntry>> findAll(String entityType, UUIDBased entityId, TsKvQuery query) { | 62 | + public ListenableFuture<List<TsKvEntry>> findAll(String entityType, UUIDBased entityId, List<TsKvQuery> queries) { |
60 | validate(entityType, entityId); | 63 | validate(entityType, entityId); |
61 | - validate(query); | ||
62 | - return timeseriesDao.findAllAsync(entityType, entityId.getId(), query); | 64 | + queries.forEach(query -> validate(query)); |
65 | + return timeseriesDao.findAllAsync(entityType, entityId.getId(), queries); | ||
63 | } | 66 | } |
64 | 67 | ||
65 | @Override | 68 | @Override |
@@ -132,7 +135,7 @@ public class BaseTimeseriesService implements TimeseriesService { | @@ -132,7 +135,7 @@ public class BaseTimeseriesService implements TimeseriesService { | ||
132 | throw new IncorrectParameterException("TsKvQuery can't be null"); | 135 | throw new IncorrectParameterException("TsKvQuery can't be null"); |
133 | } else if (isBlank(query.getKey())) { | 136 | } else if (isBlank(query.getKey())) { |
134 | throw new IncorrectParameterException("Incorrect TsKvQuery. Key can't be empty"); | 137 | throw new IncorrectParameterException("Incorrect TsKvQuery. Key can't be empty"); |
135 | - } else if (query.getAggregation() == null){ | 138 | + } else if (query.getAggregation() == null) { |
136 | throw new IncorrectParameterException("Incorrect TsKvQuery. Aggregation can't be empty"); | 139 | throw new IncorrectParameterException("Incorrect TsKvQuery. Aggregation can't be empty"); |
137 | } | 140 | } |
138 | } | 141 | } |
@@ -33,9 +33,7 @@ public interface TimeseriesDao { | @@ -33,9 +33,7 @@ public interface TimeseriesDao { | ||
33 | 33 | ||
34 | long toPartitionTs(long ts); | 34 | long toPartitionTs(long ts); |
35 | 35 | ||
36 | - ListenableFuture<List<TsKvEntry>> findAllAsync(String entityType, UUID entityId, TsKvQuery query); | ||
37 | - | ||
38 | -// List<TsKvEntry> find(String entityType, UUID entityId, TsKvQuery query, Optional<Long> minPartition, Optional<Long> maxPartition); | 36 | + ListenableFuture<List<TsKvEntry>> findAllAsync(String entityType, UUID entityId, List<TsKvQuery> queries); |
39 | 37 | ||
40 | ResultSetFuture findLatest(String entityType, UUID entityId, String key); | 38 | ResultSetFuture findLatest(String entityType, UUID entityId, String key); |
41 | 39 |
@@ -33,7 +33,7 @@ import java.util.Set; | @@ -33,7 +33,7 @@ import java.util.Set; | ||
33 | */ | 33 | */ |
34 | public interface TimeseriesService { | 34 | public interface TimeseriesService { |
35 | 35 | ||
36 | - ListenableFuture<List<TsKvEntry>> findAll(String entityType, UUIDBased entityId, TsKvQuery query); | 36 | + ListenableFuture<List<TsKvEntry>> findAll(String entityType, UUIDBased entityId, List<TsKvQuery> queries); |
37 | 37 | ||
38 | ListenableFuture<List<ResultSet>> findLatest(String entityType, UUIDBased entityId, Collection<String> keys); | 38 | ListenableFuture<List<ResultSet>> findLatest(String entityType, UUIDBased entityId, Collection<String> keys); |
39 | 39 |
@@ -82,9 +82,7 @@ public interface PluginContext { | @@ -82,9 +82,7 @@ public interface PluginContext { | ||
82 | 82 | ||
83 | void saveTsData(DeviceId deviceId, List<TsKvEntry> entry, PluginCallback<Void> callback); | 83 | void saveTsData(DeviceId deviceId, List<TsKvEntry> entry, PluginCallback<Void> callback); |
84 | 84 | ||
85 | - List<TsKvEntry> loadTimeseries(DeviceId deviceId, TsKvQuery query); | ||
86 | - | ||
87 | - void loadTimeseries(DeviceId deviceId, TsKvQuery query, PluginCallback<List<TsKvEntry>> callback); | 85 | + void loadTimeseries(DeviceId deviceId, List<TsKvQuery> queries, PluginCallback<List<TsKvEntry>> callback); |
88 | 86 | ||
89 | void loadLatestTimeseries(DeviceId deviceId, Collection<String> keys, PluginCallback<List<TsKvEntry>> callback); | 87 | void loadLatestTimeseries(DeviceId deviceId, Collection<String> keys, PluginCallback<List<TsKvEntry>> callback); |
90 | 88 |
@@ -15,9 +15,16 @@ | @@ -15,9 +15,16 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.extensions.core.plugin.telemetry.cmd; | 16 | package org.thingsboard.server.extensions.core.plugin.telemetry.cmd; |
17 | 17 | ||
18 | +import lombok.AllArgsConstructor; | ||
19 | +import lombok.Data; | ||
20 | +import lombok.NoArgsConstructor; | ||
21 | + | ||
18 | /** | 22 | /** |
19 | * @author Andrew Shvayka | 23 | * @author Andrew Shvayka |
20 | */ | 24 | */ |
25 | +@NoArgsConstructor | ||
26 | +@AllArgsConstructor | ||
27 | +@Data | ||
21 | public class GetHistoryCmd implements TelemetryPluginCmd { | 28 | public class GetHistoryCmd implements TelemetryPluginCmd { |
22 | 29 | ||
23 | private int cmdId; | 30 | private int cmdId; |
@@ -25,46 +32,7 @@ public class GetHistoryCmd implements TelemetryPluginCmd { | @@ -25,46 +32,7 @@ public class GetHistoryCmd implements TelemetryPluginCmd { | ||
25 | private String keys; | 32 | private String keys; |
26 | private long startTs; | 33 | private long startTs; |
27 | private long endTs; | 34 | private long endTs; |
35 | + private int limit; | ||
36 | + private String agg; | ||
28 | 37 | ||
29 | - @Override | ||
30 | - public int getCmdId() { | ||
31 | - return cmdId; | ||
32 | - } | ||
33 | - | ||
34 | - @Override | ||
35 | - public void setCmdId(int cmdId) { | ||
36 | - this.cmdId = cmdId; | ||
37 | - } | ||
38 | - | ||
39 | - public String getDeviceId() { | ||
40 | - return deviceId; | ||
41 | - } | ||
42 | - | ||
43 | - public void setDeviceId(String deviceId) { | ||
44 | - this.deviceId = deviceId; | ||
45 | - } | ||
46 | - | ||
47 | - public String getKeys() { | ||
48 | - return keys; | ||
49 | - } | ||
50 | - | ||
51 | - public void setKeys(String keys) { | ||
52 | - this.keys = keys; | ||
53 | - } | ||
54 | - | ||
55 | - public long getStartTs() { | ||
56 | - return startTs; | ||
57 | - } | ||
58 | - | ||
59 | - public void setStartTs(long startTs) { | ||
60 | - this.startTs = startTs; | ||
61 | - } | ||
62 | - | ||
63 | - public long getEndTs() { | ||
64 | - return endTs; | ||
65 | - } | ||
66 | - | ||
67 | - public void setEndTs(long endTs) { | ||
68 | - this.endTs = endTs; | ||
69 | - } | ||
70 | } | 38 | } |
@@ -16,11 +16,13 @@ | @@ -16,11 +16,13 @@ | ||
16 | package org.thingsboard.server.extensions.core.plugin.telemetry.cmd; | 16 | package org.thingsboard.server.extensions.core.plugin.telemetry.cmd; |
17 | 17 | ||
18 | import lombok.AllArgsConstructor; | 18 | import lombok.AllArgsConstructor; |
19 | +import lombok.Data; | ||
19 | import lombok.NoArgsConstructor; | 20 | import lombok.NoArgsConstructor; |
20 | import org.thingsboard.server.extensions.core.plugin.telemetry.sub.SubscriptionType; | 21 | import org.thingsboard.server.extensions.core.plugin.telemetry.sub.SubscriptionType; |
21 | 22 | ||
22 | @NoArgsConstructor | 23 | @NoArgsConstructor |
23 | @AllArgsConstructor | 24 | @AllArgsConstructor |
25 | +@Data | ||
24 | public abstract class SubscriptionCmd implements TelemetryPluginCmd { | 26 | public abstract class SubscriptionCmd implements TelemetryPluginCmd { |
25 | 27 | ||
26 | private int cmdId; | 28 | private int cmdId; |
@@ -31,46 +33,6 @@ public abstract class SubscriptionCmd implements TelemetryPluginCmd { | @@ -31,46 +33,6 @@ public abstract class SubscriptionCmd implements TelemetryPluginCmd { | ||
31 | 33 | ||
32 | public abstract SubscriptionType getType(); | 34 | public abstract SubscriptionType getType(); |
33 | 35 | ||
34 | - public int getCmdId() { | ||
35 | - return cmdId; | ||
36 | - } | ||
37 | - | ||
38 | - public void setCmdId(int cmdId) { | ||
39 | - this.cmdId = cmdId; | ||
40 | - } | ||
41 | - | ||
42 | - public String getDeviceId() { | ||
43 | - return deviceId; | ||
44 | - } | ||
45 | - | ||
46 | - public void setDeviceId(String deviceId) { | ||
47 | - this.deviceId = deviceId; | ||
48 | - } | ||
49 | - | ||
50 | - public String getKeys() { | ||
51 | - return keys; | ||
52 | - } | ||
53 | - | ||
54 | - public void setTags(String tags) { | ||
55 | - this.keys = tags; | ||
56 | - } | ||
57 | - | ||
58 | - public boolean isUnsubscribe() { | ||
59 | - return unsubscribe; | ||
60 | - } | ||
61 | - | ||
62 | - public void setUnsubscribe(boolean unsubscribe) { | ||
63 | - this.unsubscribe = unsubscribe; | ||
64 | - } | ||
65 | - | ||
66 | - public String getScope() { | ||
67 | - return scope; | ||
68 | - } | ||
69 | - | ||
70 | - public void setKeys(String keys) { | ||
71 | - this.keys = keys; | ||
72 | - } | ||
73 | - | ||
74 | @Override | 36 | @Override |
75 | public String toString() { | 37 | public String toString() { |
76 | return "SubscriptionCmd [deviceId=" + deviceId + ", tags=" + keys + ", unsubscribe=" + unsubscribe + "]"; | 38 | return "SubscriptionCmd [deviceId=" + deviceId + ", tags=" + keys + ", unsubscribe=" + unsubscribe + "]"; |
@@ -15,6 +15,8 @@ | @@ -15,6 +15,8 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.extensions.core.plugin.telemetry.cmd; | 16 | package org.thingsboard.server.extensions.core.plugin.telemetry.cmd; |
17 | 17 | ||
18 | +import lombok.AllArgsConstructor; | ||
19 | +import lombok.Data; | ||
18 | import lombok.NoArgsConstructor; | 20 | import lombok.NoArgsConstructor; |
19 | import org.thingsboard.server.extensions.core.plugin.telemetry.sub.SubscriptionType; | 21 | import org.thingsboard.server.extensions.core.plugin.telemetry.sub.SubscriptionType; |
20 | 22 | ||
@@ -22,17 +24,13 @@ import org.thingsboard.server.extensions.core.plugin.telemetry.sub.SubscriptionT | @@ -22,17 +24,13 @@ import org.thingsboard.server.extensions.core.plugin.telemetry.sub.SubscriptionT | ||
22 | * @author Andrew Shvayka | 24 | * @author Andrew Shvayka |
23 | */ | 25 | */ |
24 | @NoArgsConstructor | 26 | @NoArgsConstructor |
27 | +@AllArgsConstructor | ||
28 | +@Data | ||
25 | public class TimeseriesSubscriptionCmd extends SubscriptionCmd { | 29 | public class TimeseriesSubscriptionCmd extends SubscriptionCmd { |
26 | 30 | ||
27 | private long timeWindow; | 31 | private long timeWindow; |
28 | - | ||
29 | - public long getTimeWindow() { | ||
30 | - return timeWindow; | ||
31 | - } | ||
32 | - | ||
33 | - public void setTimeWindow(long timeWindow) { | ||
34 | - this.timeWindow = timeWindow; | ||
35 | - } | 32 | + private int limit; |
33 | + private String agg; | ||
36 | 34 | ||
37 | @Override | 35 | @Override |
38 | public SubscriptionType getType() { | 36 | public SubscriptionType getType() { |
@@ -158,40 +158,14 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { | @@ -158,40 +158,14 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { | ||
158 | log.debug("[{}] fetching timeseries data for last {} ms for keys: ({}) for device : {}", sessionId, cmd.getTimeWindow(), cmd.getKeys(), cmd.getDeviceId()); | 158 | log.debug("[{}] fetching timeseries data for last {} ms for keys: ({}) for device : {}", sessionId, cmd.getTimeWindow(), cmd.getKeys(), cmd.getDeviceId()); |
159 | long endTs = System.currentTimeMillis(); | 159 | long endTs = System.currentTimeMillis(); |
160 | startTs = endTs - cmd.getTimeWindow(); | 160 | startTs = endTs - cmd.getTimeWindow(); |
161 | - for (String key : keys) { | ||
162 | - TsKvQuery query = new BaseTsKvQuery(key, startTs, endTs); | ||
163 | - data.addAll(ctx.loadTimeseries(deviceId, query)); | ||
164 | - } | ||
165 | - sendWsMsg(ctx, sessionRef, new SubscriptionUpdate(cmd.getCmdId(), data)); | ||
166 | 161 | ||
167 | - Map<String, Long> subState = new HashMap<>(keys.size()); | ||
168 | - keys.forEach(key -> subState.put(key, startTs)); | ||
169 | - data.forEach(v -> subState.put(v.getKey(), v.getTs())); | ||
170 | - SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), deviceId, SubscriptionType.TIMESERIES, false, subState); | ||
171 | - subscriptionManager.addLocalWsSubscription(ctx, sessionId, deviceId, sub); | 162 | + List<TsKvQuery> queries = keys.stream().map(key -> new BaseTsKvQuery(key, startTs, endTs, cmd.getLimit(), Aggregation.valueOf(cmd.getAgg()))).collect(Collectors.toList()); |
163 | + ctx.loadTimeseries(deviceId, queries, getSubscriptionCallback(sessionRef, cmd, sessionId, deviceId, startTs, keys)); | ||
172 | } else { | 164 | } else { |
173 | List<String> keys = new ArrayList<>(getKeys(cmd).orElse(Collections.emptySet())); | 165 | List<String> keys = new ArrayList<>(getKeys(cmd).orElse(Collections.emptySet())); |
174 | startTs = System.currentTimeMillis(); | 166 | startTs = System.currentTimeMillis(); |
175 | log.debug("[{}] fetching latest timeseries data for keys: ({}) for device : {}", sessionId, cmd.getKeys(), cmd.getDeviceId()); | 167 | log.debug("[{}] fetching latest timeseries data for keys: ({}) for device : {}", sessionId, cmd.getKeys(), cmd.getDeviceId()); |
176 | - ctx.loadLatestTimeseries(deviceId, keys, new PluginCallback<List<TsKvEntry>>() { | ||
177 | - @Override | ||
178 | - public void onSuccess(PluginContext ctx, List<TsKvEntry> data) { | ||
179 | - sendWsMsg(ctx, sessionRef, new SubscriptionUpdate(cmd.getCmdId(), data)); | ||
180 | - | ||
181 | - Map<String, Long> subState = new HashMap<>(keys.size()); | ||
182 | - keys.forEach(key -> subState.put(key, startTs)); | ||
183 | - data.forEach(v -> subState.put(v.getKey(), v.getTs())); | ||
184 | - SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), deviceId, SubscriptionType.TIMESERIES, false, subState); | ||
185 | - subscriptionManager.addLocalWsSubscription(ctx, sessionId, deviceId, sub); | ||
186 | - } | ||
187 | - | ||
188 | - @Override | ||
189 | - public void onFailure(PluginContext ctx, Exception e) { | ||
190 | - SubscriptionUpdate update = new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, | ||
191 | - "Failed to fetch data!"); | ||
192 | - sendWsMsg(ctx, sessionRef, update); | ||
193 | - } | ||
194 | - }); | 168 | + ctx.loadLatestTimeseries(deviceId, keys, getSubscriptionCallback(sessionRef, cmd, sessionId, deviceId, startTs, keys)); |
195 | } | 169 | } |
196 | } else { | 170 | } else { |
197 | ctx.loadLatestTimeseries(deviceId, new PluginCallback<List<TsKvEntry>>() { | 171 | ctx.loadLatestTimeseries(deviceId, new PluginCallback<List<TsKvEntry>>() { |
@@ -216,6 +190,28 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { | @@ -216,6 +190,28 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { | ||
216 | } | 190 | } |
217 | } | 191 | } |
218 | 192 | ||
193 | + private PluginCallback<List<TsKvEntry>> getSubscriptionCallback(final PluginWebsocketSessionRef sessionRef, final TimeseriesSubscriptionCmd cmd, final String sessionId, final DeviceId deviceId, final long startTs, final List<String> keys) { | ||
194 | + return new PluginCallback<List<TsKvEntry>>() { | ||
195 | + @Override | ||
196 | + public void onSuccess(PluginContext ctx, List<TsKvEntry> data) { | ||
197 | + sendWsMsg(ctx, sessionRef, new SubscriptionUpdate(cmd.getCmdId(), data)); | ||
198 | + | ||
199 | + Map<String, Long> subState = new HashMap<>(keys.size()); | ||
200 | + keys.forEach(key -> subState.put(key, startTs)); | ||
201 | + data.forEach(v -> subState.put(v.getKey(), v.getTs())); | ||
202 | + SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), deviceId, SubscriptionType.TIMESERIES, false, subState); | ||
203 | + subscriptionManager.addLocalWsSubscription(ctx, sessionId, deviceId, sub); | ||
204 | + } | ||
205 | + | ||
206 | + @Override | ||
207 | + public void onFailure(PluginContext ctx, Exception e) { | ||
208 | + SubscriptionUpdate update = new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, | ||
209 | + "Failed to fetch data!"); | ||
210 | + sendWsMsg(ctx, sessionRef, update); | ||
211 | + } | ||
212 | + }; | ||
213 | + } | ||
214 | + | ||
219 | private void handleWsHistoryCmd(PluginContext ctx, PluginWebsocketSessionRef sessionRef, GetHistoryCmd cmd) { | 215 | private void handleWsHistoryCmd(PluginContext ctx, PluginWebsocketSessionRef sessionRef, GetHistoryCmd cmd) { |
220 | String sessionId = sessionRef.getSessionId(); | 216 | String sessionId = sessionRef.getSessionId(); |
221 | WsSessionMetaData sessionMD = wsSessionsMap.get(sessionId); | 217 | WsSessionMetaData sessionMD = wsSessionsMap.get(sessionId); |
@@ -246,12 +242,19 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { | @@ -246,12 +242,19 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { | ||
246 | return; | 242 | return; |
247 | } | 243 | } |
248 | List<String> keys = new ArrayList<>(getKeys(cmd).orElse(Collections.emptySet())); | 244 | List<String> keys = new ArrayList<>(getKeys(cmd).orElse(Collections.emptySet())); |
249 | - List<TsKvEntry> data = new ArrayList<>(); | ||
250 | - for (String key : keys) { | ||
251 | - TsKvQuery query = new BaseTsKvQuery(key, cmd.getStartTs(), cmd.getEndTs()); | ||
252 | - data.addAll(ctx.loadTimeseries(deviceId, query)); | ||
253 | - } | ||
254 | - sendWsMsg(ctx, sessionRef, new SubscriptionUpdate(cmd.getCmdId(), data)); | 245 | + List<TsKvQuery> queries = keys.stream().map(key -> new BaseTsKvQuery(key, cmd.getStartTs(), cmd.getEndTs(), cmd.getLimit(), Aggregation.valueOf(cmd.getAgg()))).collect(Collectors.toList()); |
246 | + ctx.loadTimeseries(deviceId, queries, new PluginCallback<List<TsKvEntry>>() { | ||
247 | + @Override | ||
248 | + public void onSuccess(PluginContext ctx, List<TsKvEntry> data) { | ||
249 | + sendWsMsg(ctx, sessionRef, new SubscriptionUpdate(cmd.getCmdId(), data)); | ||
250 | + } | ||
251 | + | ||
252 | + @Override | ||
253 | + public void onFailure(PluginContext ctx, Exception e) { | ||
254 | + sendWsMsg(ctx, sessionRef, new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, | ||
255 | + "Failed to fetch data!")); | ||
256 | + } | ||
257 | + }); | ||
255 | } | 258 | } |
256 | 259 | ||
257 | private boolean validateSessionMetadata(PluginContext ctx, PluginWebsocketSessionRef sessionRef, SubscriptionCmd cmd, String sessionId) { | 260 | private boolean validateSessionMetadata(PluginContext ctx, PluginWebsocketSessionRef sessionRef, SubscriptionCmd cmd, String sessionId) { |