|
|
@@ -0,0 +1,217 @@
|
|
|
+package com.shkpr.service.alambizplugin.commtools;
|
|
|
+
|
|
|
+import com.global.base.log.LogLevelFlag;
|
|
|
+import com.global.base.log.LogPrintMgr;
|
|
|
+import com.shkpr.service.alambizplugin.annotation.InfluxDbMapping;
|
|
|
+import com.shkpr.service.alambizplugin.commproperties.InfluxDbProperties;
|
|
|
+import com.shkpr.service.alambizplugin.constants.InfluxdbMetadata;
|
|
|
+import com.shkpr.service.alambizplugin.constants.LogFlagBusiType;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.influxdb.InfluxDB;
|
|
|
+import org.influxdb.InfluxDBException;
|
|
|
+import org.influxdb.dto.BatchPoints;
|
|
|
+import org.influxdb.dto.Point;
|
|
|
+import org.influxdb.dto.Query;
|
|
|
+import org.influxdb.dto.QueryResult;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import java.lang.reflect.Field;
|
|
|
+import java.lang.reflect.InvocationTargetException;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.ZonedDateTime;
|
|
|
+import java.util.*;
|
|
|
+import java.util.function.Function;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+import java.util.stream.IntStream;
|
|
|
+
|
|
|
+/**
|
|
|
+ * influxdb工具类
|
|
|
+ *
|
|
|
+ * @author 李兴
|
|
|
+ * @since 0.0.1-dev
|
|
|
+ **/
|
|
|
+@Component
|
|
|
+@Slf4j
|
|
|
+public class InfluxDbUtil {
|
|
|
+ /**
|
|
|
+ * log
|
|
|
+ */
|
|
|
+ private static final String mStrClassName = "InfluxDbUtil";
|
|
|
+ private static final String mBizType = LogFlagBusiType.BUSI_PIPE_BURST.toStrValue();
|
|
|
+ final
|
|
|
+ InfluxDB influxDb;
|
|
|
+ final
|
|
|
+ InfluxDbProperties properties;
|
|
|
+
|
|
|
+ public InfluxDbUtil(InfluxDbProperties properties, InfluxDB influxDb) {
|
|
|
+ this.influxDb = influxDb;
|
|
|
+ this.properties = properties;
|
|
|
+ try {
|
|
|
+ //查询数据库信息
|
|
|
+ QueryResult queryResult = influxDb.query(new Query(InfluxdbMetadata.Command.SHOW_DATABASE, null));
|
|
|
+ List<String> databases = getValues(queryResult).stream()
|
|
|
+ .map(database -> database.get(0).toString())
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ //数据库不存在,则创建数据库
|
|
|
+ if (databases.isEmpty() || !databases.contains(properties.getDatabase()))
|
|
|
+ influxDb.query(new Query(InfluxdbMetadata.Command.CREATE_DATABASE + properties.getDatabase(), null));
|
|
|
+ } catch (InfluxDBException e) {
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, mBizType, mStrClassName
|
|
|
+ , String.format("尝试初始化数据库失败 error:%s", e)
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ //设置要使用的数据库
|
|
|
+ influxDb.setDatabase(properties.getDatabase());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取series
|
|
|
+ *
|
|
|
+ * @param queryResult 查询结果
|
|
|
+ * @return series
|
|
|
+ */
|
|
|
+ public static QueryResult.Series getSeries(QueryResult queryResult) {
|
|
|
+ if (queryResult == null) return null;
|
|
|
+
|
|
|
+ //获取结果集合
|
|
|
+ List<QueryResult.Result> results = queryResult.getResults();
|
|
|
+ if (results == null || results.isEmpty()) return null;
|
|
|
+
|
|
|
+ //获取第一个结果
|
|
|
+ QueryResult.Result result = results.get(0);
|
|
|
+ if (result == null) return null;
|
|
|
+
|
|
|
+ //获取series
|
|
|
+ List<QueryResult.Series> series = result.getSeries();
|
|
|
+ if (series == null || series.isEmpty()) return null;
|
|
|
+
|
|
|
+ //获取第一个series
|
|
|
+ return series.get(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取值集合
|
|
|
+ *
|
|
|
+ * @param queryResult 查询结果
|
|
|
+ * @return 值集合
|
|
|
+ */
|
|
|
+ public static List<List<Object>> getValues(QueryResult queryResult) {
|
|
|
+ //获取series
|
|
|
+ QueryResult.Series firstSeries = getSeries(queryResult);
|
|
|
+ if (firstSeries == null) return Collections.emptyList();
|
|
|
+
|
|
|
+ //获取值集合
|
|
|
+ List<List<Object>> values = firstSeries.getValues();
|
|
|
+ return values != null ? values : Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 插入
|
|
|
+ *
|
|
|
+ * @param point 点
|
|
|
+ * @return 插入状态
|
|
|
+ */
|
|
|
+ public Boolean insert(Point point) {
|
|
|
+ try {
|
|
|
+ influxDb.write(point);
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, mBizType, mStrClassName
|
|
|
+ , String.format("插入InfluxDb失败 error:%s", e)
|
|
|
+ );
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量插入
|
|
|
+ *
|
|
|
+ * @param points 批量点
|
|
|
+ * @return 插入状态
|
|
|
+ */
|
|
|
+ public Boolean insertBatch(BatchPoints points) {
|
|
|
+ try {
|
|
|
+ influxDb.write(points);
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, mBizType, mStrClassName
|
|
|
+ , String.format("插入InfluxDb失败 error:%s", e)
|
|
|
+ );
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询
|
|
|
+ *
|
|
|
+ * @param sql sql
|
|
|
+ * @param clazz 实体类
|
|
|
+ * @param <E> 实体类类型
|
|
|
+ * @return 实体类集合
|
|
|
+ */
|
|
|
+ public <E> List<E> query(String sql, Class<E> clazz) {
|
|
|
+ //执行查询
|
|
|
+ QueryResult queryResult = influxDb.query(new Query(sql, properties.getDatabase()));
|
|
|
+ QueryResult.Series series = getSeries(queryResult);
|
|
|
+ if (series == null) return Collections.emptyList();
|
|
|
+ //获取字段
|
|
|
+ List<String> columns = series.getColumns();
|
|
|
+ //字段映射
|
|
|
+ Map<Integer, Field> fieldMap = Arrays.stream(clazz.getDeclaredFields())
|
|
|
+ //过滤需要导出的字段
|
|
|
+ .filter(f -> f.isAnnotationPresent(InfluxDbMapping.class))
|
|
|
+ //设置字段公开
|
|
|
+ .peek(f -> f.setAccessible(true))
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ f -> {
|
|
|
+ //获取映射值
|
|
|
+ String mapping = f.getAnnotation(InfluxDbMapping.class).value();
|
|
|
+ //获取对应的索引
|
|
|
+ return IntStream.range(0, columns.size())
|
|
|
+ //过滤相同的值
|
|
|
+ .filter(index -> columns.get(index).equals(mapping))
|
|
|
+ .findFirst().orElse(-1);
|
|
|
+ }, Function.identity(),
|
|
|
+ (it1, it2) -> it2,
|
|
|
+ HashMap::new
|
|
|
+ ));
|
|
|
+ //获取值
|
|
|
+ List<List<Object>> values = series.getValues();
|
|
|
+ //解析数据
|
|
|
+ List<E> dates = new ArrayList<>();
|
|
|
+ for (List<Object> value : values) {
|
|
|
+ try {
|
|
|
+ //实列化数据
|
|
|
+ E data = clazz.getDeclaredConstructor().newInstance();
|
|
|
+ //遍历字段
|
|
|
+ for (Map.Entry<Integer, Field> fieldEntry : fieldMap.entrySet()) {
|
|
|
+ //跳过未找到的字段
|
|
|
+ if (fieldEntry.getKey() == -1) continue;
|
|
|
+ //获取项
|
|
|
+ Object item = value.get(fieldEntry.getKey());
|
|
|
+ //设置字段
|
|
|
+ if (fieldEntry.getValue().getType().equals(LocalDateTime.class))
|
|
|
+ fieldEntry.getValue().set(data,
|
|
|
+ item != null ? ZonedDateTime.parse(item.toString())
|
|
|
+ .withZoneSameInstant(TimeZone.getDefault().toZoneId())
|
|
|
+ .toLocalDateTime()
|
|
|
+ : null);
|
|
|
+ else if (fieldEntry.getValue().getType().equals(Double.class)) {
|
|
|
+ fieldEntry.getValue().set(data, item != null ? Double.parseDouble(item.toString()) : null);
|
|
|
+ } else fieldEntry.getValue().set(data, item);
|
|
|
+ }
|
|
|
+ //存入数据
|
|
|
+ dates.add(data);
|
|
|
+ } catch (InstantiationException | IllegalAccessException | InvocationTargetException |
|
|
|
+ NoSuchMethodException e) {
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR, mBizType, mStrClassName
|
|
|
+ , String.format("构建数据失败 error:%s", e)
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return dates;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|