feat(设备指标): 支持批量获取设备属性指标数据
This commit is contained in:
parent
858dab5529
commit
df8b6874ee
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package org.jetlinks.community.things.impl.metric;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository;
|
||||
import org.hswebframework.ezorm.rdb.mapping.defaults.SaveResult;
|
||||
import org.hswebframework.web.crud.events.EntityCreatedEvent;
|
||||
|
|
@ -33,13 +35,16 @@ import org.jetlinks.community.gateway.annotation.Subscribe;
|
|||
import org.jetlinks.community.things.impl.entity.PropertyMetricEntity;
|
||||
import org.jetlinks.community.things.metric.AbstractPropertyMetricManager;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DefaultPropertyMetricManager extends AbstractPropertyMetricManager {
|
||||
|
||||
|
|
@ -79,22 +84,105 @@ public class DefaultPropertyMetricManager extends AbstractPropertyMetricManager
|
|||
.map(PropertyMetadataConstants.Metrics::getMetrics)
|
||||
.orElse(Collections.emptyList()))
|
||||
.collectMap(PropertyMetric::getId, Function.identity(), LinkedHashMap::new),
|
||||
(exists, inMetadata) -> {
|
||||
for (Map.Entry<String, PropertyMetric> entry : exists.entrySet()) {
|
||||
String metric = entry.getKey();
|
||||
PropertyMetric independent = entry.getValue();
|
||||
PropertyMetric fromMetadata = inMetadata.get(metric);
|
||||
if (fromMetadata == null) {
|
||||
inMetadata.put(metric, independent);
|
||||
continue;
|
||||
}
|
||||
fromMetadata.setValue(independent.getValue());
|
||||
}
|
||||
return Flux.fromIterable(inMetadata.values());
|
||||
})
|
||||
this::merge)
|
||||
.flatMapMany(Function.identity());
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量获取指标
|
||||
*
|
||||
* @param thingType 物类型
|
||||
* @param thingId 物ID
|
||||
* @param properties 属性列表
|
||||
* @return 指标信息
|
||||
*/
|
||||
public Flux<DevicePropertyMetricInfo> getPropertyMetrics(String thingType,
|
||||
String thingId,
|
||||
List<String> properties) {
|
||||
if (CollectionUtils.isEmpty(properties)) {
|
||||
return Flux.empty();
|
||||
}
|
||||
|
||||
//数据库中记录的
|
||||
Mono<Map<String, Map<String, PropertyMetric>>> existsByProperty = repository
|
||||
.createQuery()
|
||||
.where(PropertyMetricEntity::getThingType, thingType)
|
||||
.and(PropertyMetricEntity::getThingId, thingId)
|
||||
.in(PropertyMetricEntity::getProperty, properties)
|
||||
.fetch()
|
||||
.groupBy(PropertyMetricEntity::getProperty)
|
||||
.flatMap(group -> group
|
||||
.map(PropertyMetricEntity::toMetric)
|
||||
.collectMap(PropertyMetric::getId, Function.identity())
|
||||
.map(map -> Map.entry(group.key(), map)))
|
||||
.collectMap(Map.Entry::getKey, Map.Entry::getValue);
|
||||
|
||||
//物模型中配置的
|
||||
Mono<Map<String, Map<String, PropertyMetric>>> metadataByProperty = registry
|
||||
.getThing(thingType, thingId)
|
||||
.flatMap(Thing::getTemplate)
|
||||
.flatMap(ThingTemplate::getMetadata)
|
||||
.flatMapMany(metadata -> Flux
|
||||
.fromIterable(properties)
|
||||
.map(prop -> Map.entry(
|
||||
prop,
|
||||
metadata
|
||||
.getProperty(prop)
|
||||
.map(PropertyMetadataConstants.Metrics::getMetrics)
|
||||
.orElse(Collections.emptyList())
|
||||
)))
|
||||
.flatMap(entry -> Flux
|
||||
.fromIterable(entry.getValue())
|
||||
.collectMap(PropertyMetric::getId, Function.identity())
|
||||
.map(map -> Map.entry(entry.getKey(), map)))
|
||||
.collectMap(Map.Entry::getKey, Map.Entry::getValue, LinkedHashMap::new);
|
||||
|
||||
return Mono
|
||||
.zip(existsByProperty, metadataByProperty)
|
||||
.flatMapMany(tuple -> {
|
||||
Map<String, Map<String, PropertyMetric>> exists = tuple.getT1();
|
||||
Map<String, Map<String, PropertyMetric>> metadata = tuple.getT2();
|
||||
|
||||
return Flux
|
||||
.fromIterable(properties)
|
||||
.flatMap(prop -> {
|
||||
Map<String, PropertyMetric> existsMetrics = exists.getOrDefault(prop, Collections.emptyMap());
|
||||
Map<String, PropertyMetric> metadataMetrics = new LinkedHashMap<>(metadata.getOrDefault(prop, Collections.emptyMap()));
|
||||
|
||||
return merge(existsMetrics, metadataMetrics)
|
||||
.collectList()
|
||||
.map(metrics -> new DevicePropertyMetricInfo(prop, metrics));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class DevicePropertyMetricInfo {
|
||||
private final String property;
|
||||
private final List<PropertyMetric> metrics;
|
||||
|
||||
public DevicePropertyMetricInfo(String property, List<PropertyMetric> metrics) {
|
||||
this.property = property;
|
||||
this.metrics = metrics;
|
||||
}
|
||||
}
|
||||
|
||||
private Flux<PropertyMetric> merge(Map<String, PropertyMetric> exists,
|
||||
Map<String, PropertyMetric> inMetadata) {
|
||||
for (Map.Entry<String, PropertyMetric> entry : exists.entrySet()) {
|
||||
String metric = entry.getKey();
|
||||
PropertyMetric independent = entry.getValue();
|
||||
PropertyMetric fromMetadata = inMetadata.get(metric);
|
||||
if (fromMetadata == null) {
|
||||
inMetadata.put(metric, independent);
|
||||
continue;
|
||||
}
|
||||
fromMetadata.setValue(independent.getValue());
|
||||
}
|
||||
return Flux.fromIterable(inMetadata.values());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Mono<SaveResult> savePropertyMetrics(String thingType,
|
||||
String thingId,
|
||||
String property,
|
||||
|
|
@ -112,7 +200,22 @@ public class DefaultPropertyMetricManager extends AbstractPropertyMetricManager
|
|||
entity.genericId();
|
||||
return entity;
|
||||
})
|
||||
.as(repository::save);
|
||||
.collectList()
|
||||
.flatMap(list -> {
|
||||
List<String> ids = list.stream().map(PropertyMetricEntity::getId).collect(Collectors.toList());
|
||||
return repository
|
||||
.createDelete()
|
||||
.where(PropertyMetricEntity::getThingType, thingType)
|
||||
.and(PropertyMetricEntity::getThingId, thingId)
|
||||
.and(PropertyMetricEntity::getProperty, property)
|
||||
// 删除当前物模型中的其他指标
|
||||
.when(CollectionUtils.isNotEmpty(ids),
|
||||
delete -> delete.notIn(PropertyMetricEntity::getId, ids))
|
||||
.execute()
|
||||
.then(
|
||||
repository.save(list)
|
||||
);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -171,4 +274,4 @@ public class DefaultPropertyMetricManager extends AbstractPropertyMetricManager
|
|||
.publish("/_sys/thing-property-metric/clear-cache", key)
|
||||
.then();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1149,6 +1149,16 @@ public class DeviceInstanceController implements
|
|||
.getPropertyMetrics(DeviceThingType.device.getId(), deviceId, property);
|
||||
}
|
||||
|
||||
@PostMapping("/{deviceId}/metric/properties")
|
||||
@Operation(summary = "批量获取设备属性指标数据")
|
||||
@QueryAction
|
||||
public Flux<DefaultPropertyMetricManager.DevicePropertyMetricInfo> getPropertyMetrics(@PathVariable String deviceId,
|
||||
@RequestBody Mono<List<String>> payload) {
|
||||
return payload
|
||||
.flatMapMany(properties -> metricManager
|
||||
.getPropertyMetrics(DeviceThingType.device.getId(), deviceId, properties));
|
||||
}
|
||||
|
||||
//仅解析文件为属性物模型
|
||||
@PostMapping(value = "/{productId}/property-metadata/file/analyze")
|
||||
@SaveAction
|
||||
|
|
|
|||
Loading…
Reference in New Issue