Преглед на файлове

模拟设备告警结果

xuYongJian преди 2 години
ревизия
cf01937461
променени са 96 файла, в които са добавени 11328 реда и са изтрити 0 реда
  1. 225 0
      flink_metro/pom.xml
  2. 46 0
      flink_metro/src/main/java/com/sunwin/metro/bean/DeviceName.java
  3. 79 0
      flink_metro/src/main/java/com/sunwin/metro/bean/DeviceWarn.java
  4. 341 0
      flink_metro/src/main/java/com/sunwin/metro/bean/ElectricityMeter.java
  5. 68 0
      flink_metro/src/main/java/com/sunwin/metro/bean/ErrorDevice.java
  6. 224 0
      flink_metro/src/main/java/com/sunwin/metro/bean/Meter.java
  7. 267 0
      flink_metro/src/main/java/com/sunwin/metro/bean/MetroDevice.java
  8. 45 0
      flink_metro/src/main/java/com/sunwin/metro/bean/RecentMsg.java
  9. 117 0
      flink_metro/src/main/java/com/sunwin/metro/bean/message/EquipmentWarn.java
  10. 604 0
      flink_metro/src/main/java/com/sunwin/metro/bean/train/BasTef.java
  11. 525 0
      flink_metro/src/main/java/com/sunwin/metro/bean/train/BasTvf.java
  12. 455 0
      flink_metro/src/main/java/com/sunwin/metro/bean/train/Ups.java
  13. 290 0
      flink_metro/src/main/java/com/sunwin/metro/bean/train/UpsBas.java
  14. 1083 0
      flink_metro/src/main/java/com/sunwin/metro/bean/train/UpsXjy.java
  15. 65 0
      flink_metro/src/main/java/com/sunwin/metro/config/ConfigFileHandler.java
  16. 32 0
      flink_metro/src/main/java/com/sunwin/metro/consumer/CustomKafkaDeserializationSchema.java
  17. 22 0
      flink_metro/src/main/java/com/sunwin/metro/consumer/TopicConsumer.java
  18. 23 0
      flink_metro/src/main/java/com/sunwin/metro/consumer/TopicKeyWordsConsumer.java
  19. 17 0
      flink_metro/src/main/java/com/sunwin/metro/filter/MetroFilterMp.java
  20. 26 0
      flink_metro/src/main/java/com/sunwin/metro/flatmap/DeviceClientFlatmap.java
  21. 24 0
      flink_metro/src/main/java/com/sunwin/metro/flatmap/MeterListFlatmap.java
  22. 94 0
      flink_metro/src/main/java/com/sunwin/metro/flatmap/MetroDevicePropertyFlatmap.java
  23. 17 0
      flink_metro/src/main/java/com/sunwin/metro/key/DeviceKeySelector.java
  24. 17 0
      flink_metro/src/main/java/com/sunwin/metro/key/DeviceNameKeySelector.java
  25. 17 0
      flink_metro/src/main/java/com/sunwin/metro/key/MeterIdSelector.java
  26. 20 0
      flink_metro/src/main/java/com/sunwin/metro/key/MetroKeySelector.java
  27. 24 0
      flink_metro/src/main/java/com/sunwin/metro/map/DeviceAlarmMap.java
  28. 53 0
      flink_metro/src/main/java/com/sunwin/metro/map/DeviceClientMap.java
  29. 190 0
      flink_metro/src/main/java/com/sunwin/metro/map/DeviceMetricsMap.java
  30. 36 0
      flink_metro/src/main/java/com/sunwin/metro/map/DeviceNormalMap.java
  31. 25 0
      flink_metro/src/main/java/com/sunwin/metro/map/MeterTimeMap.java
  32. 20 0
      flink_metro/src/main/java/com/sunwin/metro/map/MeterTimestampMap.java
  33. 62 0
      flink_metro/src/main/java/com/sunwin/metro/process/DeviceAlarmProcess.java
  34. 46 0
      flink_metro/src/main/java/com/sunwin/metro/process/DeviceUnrepeated.java
  35. 118 0
      flink_metro/src/main/java/com/sunwin/metro/process/ElectricityMeterProcess.java
  36. 55 0
      flink_metro/src/main/java/com/sunwin/metro/process/ErrorMeterProcess.java
  37. 69 0
      flink_metro/src/main/java/com/sunwin/metro/process/MetroKeyProcess.java
  38. 43 0
      flink_metro/src/main/java/com/sunwin/metro/process/ScheduleTimeProcess.java
  39. 25 0
      flink_metro/src/main/java/com/sunwin/metro/service/DeviceClient.java
  40. 19 0
      flink_metro/src/main/java/com/sunwin/metro/service/DeviceNormal.java
  41. 78 0
      flink_metro/src/main/java/com/sunwin/metro/service/EnergyConsumption.java
  42. 59 0
      flink_metro/src/main/java/com/sunwin/metro/service/MetroService.java
  43. 42 0
      flink_metro/src/main/java/com/sunwin/metro/service/WriteMetroTxt.java
  44. 103 0
      flink_metro/src/main/java/com/sunwin/metro/sink/impala/SinkToImpala.java
  45. 62 0
      flink_metro/src/main/java/com/sunwin/metro/sink/impala/SinkToImpalaMeterValue.java
  46. 60 0
      flink_metro/src/main/java/com/sunwin/metro/sink/impala/SinkToImpalaWarn.java
  47. 219 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/KuduInputFormat.java
  48. 125 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/KuduOutputFormat.java
  49. 136 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/KuduSink.java
  50. 214 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/connector/KuduColumnInfo.java
  51. 188 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/connector/KuduConnector.java
  52. 176 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/connector/KuduFilterInfo.java
  53. 235 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/connector/KuduMapper.java
  54. 88 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/connector/KuduRow.java
  55. 60 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/connector/KuduRowIterator.java
  56. 145 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/connector/KuduTableInfo.java
  57. 50 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/pojo/HbaseBeanFieldModel.java
  58. 43 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/serde/DefaultSerDe.java
  59. 30 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/serde/KuduDeserialization.java
  60. 31 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/serde/KuduSerialization.java
  61. 136 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/serde/PojoSerDe.java
  62. 43 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/utils/FieldUtility.java
  63. 59 0
      flink_metro/src/main/java/com/sunwin/metro/sink/kudu/utils/KuduUtils.java
  64. 53 0
      flink_metro/src/main/java/com/sunwin/metro/sink/mysql/SinkErrorMeterToMysql.java
  65. 53 0
      flink_metro/src/main/java/com/sunwin/metro/sink/mysql/SinkNormalMeterToMysql.java
  66. 66 0
      flink_metro/src/main/java/com/sunwin/metro/sink/mysql/SinkToMysql.java
  67. 56 0
      flink_metro/src/main/java/com/sunwin/metro/source/http/HttpMeterAtt.java
  68. 90 0
      flink_metro/src/main/java/com/sunwin/metro/source/http/HttpMeterMsg.java
  69. 80 0
      flink_metro/src/main/java/com/sunwin/metro/source/mysql/MysqlData.java
  70. 55 0
      flink_metro/src/main/java/com/sunwin/metro/source/mysql/MysqlSource.java
  71. 65 0
      flink_metro/src/main/java/com/sunwin/metro/source/mysql/MysqlSourceTime.java
  72. 114 0
      flink_metro/src/main/java/com/sunwin/metro/source/mysql/message/QueryEquipment.java
  73. 141 0
      flink_metro/src/main/java/com/sunwin/metro/start/StartMessage.java
  74. 231 0
      flink_metro/src/main/java/com/sunwin/metro/start/StartMetro.java
  75. 74 0
      flink_metro/src/main/java/com/sunwin/metro/start/StartMonitor.java
  76. 158 0
      flink_metro/src/main/java/com/sunwin/metro/start/StartService.java
  77. 35 0
      flink_metro/src/main/java/com/sunwin/metro/start/StreamPro.java
  78. 175 0
      flink_metro/src/main/java/com/sunwin/metro/utils/DateUtils.java
  79. 73 0
      flink_metro/src/main/java/com/sunwin/metro/utils/FileUtil.java
  80. 117 0
      flink_metro/src/main/java/com/sunwin/metro/utils/FileUtils.java
  81. 159 0
      flink_metro/src/main/java/com/sunwin/metro/utils/HBaseUtil.java
  82. 89 0
      flink_metro/src/main/java/com/sunwin/metro/utils/KafkaUtils.java
  83. 33 0
      flink_metro/src/main/java/com/sunwin/metro/utils/Md5Utils.java
  84. 50 0
      flink_metro/src/main/java/com/sunwin/metro/utils/MysqlUtils.java
  85. 464 0
      flink_metro/src/main/java/com/sunwin/metro/utils/PerStringUtils.java
  86. 93 0
      flink_metro/src/main/java/com/sunwin/metro/utils/Sign.java
  87. 104 0
      flink_metro/src/main/java/com/sunwin/metro/utils/websocket/Client.java
  88. 58 0
      flink_metro/src/main/java/com/sunwin/metro/utils/websocket/ClientManager.java
  89. 49 0
      flink_metro/src/main/java/com/sunwin/metro/utils/websocket/ClientSocket.java
  90. 23 0
      flink_metro/src/main/java/com/sunwin/metro/watermark/DeviceWaterLine.java
  91. 23 0
      flink_metro/src/main/java/com/sunwin/metro/watermark/MeterWaterLine.java
  92. 162 0
      flink_metro/src/main/resources/local/log4j.properties
  93. 100 0
      flink_metro/src/main/resources/local/metro.properties
  94. 162 0
      flink_metro/src/main/resources/test/log4j.properties
  95. 100 0
      flink_metro/src/main/resources/test/metro.properties
  96. 113 0
      pom.xml

+ 225 - 0
flink_metro/pom.xml

@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>sunwin_metro</artifactId>
+        <groupId>org.sunwin</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>flink_metro</artifactId>
+    <properties>
+        <skipTests>true</skipTests>
+        <flink.version>1.10.2</flink.version>
+        <java.version>1.8</java.version>
+        <scala.binary.version>2.12</scala.binary.version>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+        <cdh.version>cdh5.16.2</cdh.version>
+        <hbase.version>1.2.0</hbase.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <zookeeper.version>3.4.8</zookeeper.version>
+        <kudu.version>1.9.0</kudu.version>
+    </properties>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-cep_${scala.binary.version}</artifactId>
+            <version>${flink.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-shaded-hadoop-2-uber</artifactId>
+            <version>2.8.3-10.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.java-websocket</groupId>
+            <artifactId>Java-WebSocket</artifactId>
+            <version>1.3.8</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-streaming-java_${scala.binary.version}</artifactId>
+            <version>${flink.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-runtime-web_${scala.binary.version}</artifactId>
+            <version>${flink.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-connector-kafka_${scala.binary.version}</artifactId>
+            <version>${flink.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-core</artifactId>
+            <version>${flink.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-statebackend-rocksdb_${scala.binary.version}</artifactId>
+            <version>${flink.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-clients_${scala.binary.version}</artifactId>
+            <version>${flink.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-hbase_${scala.binary.version}</artifactId>
+            <version>${flink.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.hadoop</groupId>
+            <artifactId>hadoop-common</artifactId>
+            <version>2.8.3</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ahocorasick</groupId>
+            <artifactId>ahocorasick</artifactId>
+            <version>0.4.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.cloudera.impala</groupId>
+            <artifactId>ImpalaJDBC41</artifactId>
+            <version>2.6.4</version>
+        </dependency>
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+            <version>2.3</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>2.6.7</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-recipes</artifactId>
+            <version>2.13.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.kudu</groupId>
+            <artifactId>kudu-client</artifactId>
+            <version>${kudu.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-csv</artifactId>
+            <version>${flink.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-jdbc_${scala.binary.version}</artifactId>
+            <version>${flink.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-table-api-java-bridge_${scala.binary.version}</artifactId>
+            <version>${flink.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-table-planner-blink_${scala.binary.version}</artifactId>
+            <version>${flink.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-table-common</artifactId>
+            <version>${flink.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-json</artifactId>
+            <version>${flink.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-shaded-guava</artifactId>
+            <version>18.0-5.0</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-connector-elasticsearch7_2.11</artifactId>
+            <version>${flink.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.flink</groupId>
+            <artifactId>flink-metrics-core</artifactId>
+            <version>1.12.2</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-dbcp2</artifactId>
+            <version>2.1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>8.0.11</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <configuration>
+                    <descriptorRefs>
+                        <descriptorRef>jar-with-dependencies</descriptorRef>
+                    </descriptorRefs>
+                    <archive>
+                        <manifest>
+                            <mainClass>com.sunwin.metro.start.StartMessage</mainClass>
+                        </manifest>
+                    </archive>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>make-assembly</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.1</version>
+                <configuration>
+                    <source>8</source>
+                    <target>8</target>
+                    <encoding>UTF-8</encoding>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 46 - 0
flink_metro/src/main/java/com/sunwin/metro/bean/DeviceName.java

@@ -0,0 +1,46 @@
+package com.sunwin.metro.bean;
+
+import java.io.Serializable;
+
+/**
+ * @program: sunwin_metro
+ * @description: mysql设备名
+ * @author: xuYJ
+ * @create: 2021-02-18 11:10
+ **/
+public class DeviceName implements Serializable {
+    private String deviceName;
+    private Long sendTime;
+
+    public DeviceName(String deviceName, Long sendTime) {
+        this.deviceName = deviceName;
+        this.sendTime = sendTime;
+    }
+
+    public DeviceName() {
+    }
+
+    public String getDeviceName() {
+        return deviceName;
+    }
+
+    public void setDeviceName(String deviceName) {
+        this.deviceName = deviceName;
+    }
+
+    public Long getSendTime() {
+        return sendTime;
+    }
+
+    public void setSendTime(Long sendTime) {
+        this.sendTime = sendTime;
+    }
+
+    @Override
+    public String toString() {
+        return "DeviceName{" +
+                "deviceName='" + deviceName + '\'' +
+                ", sendTime=" + sendTime +
+                '}';
+    }
+}

+ 79 - 0
flink_metro/src/main/java/com/sunwin/metro/bean/DeviceWarn.java

@@ -0,0 +1,79 @@
+package com.sunwin.metro.bean;
+
+import java.io.Serializable;
+
+/**
+ * @program: sunwin_metro
+ * @description: 设备预警信息对象
+ * @author: xuYJ
+ * @create: 2021-03-05 09:54
+ **/
+public class DeviceWarn implements Serializable {
+    private String device_id;
+    private String device_name;
+    private String fault_seq;
+    private String fault_message;
+    private String fault_time;
+
+    public DeviceWarn() {
+    }
+
+    public DeviceWarn(String device_id, String device_name, String fault_seq, String fault_message, String fault_time) {
+        this.device_id = device_id;
+        this.device_name = device_name;
+        this.fault_seq = fault_seq;
+        this.fault_message = fault_message;
+        this.fault_time = fault_time;
+    }
+
+    public String getDevice_id() {
+        return device_id;
+    }
+
+    public void setDevice_id(String device_id) {
+        this.device_id = device_id;
+    }
+
+    public String getDevice_name() {
+        return device_name;
+    }
+
+    public void setDevice_name(String device_name) {
+        this.device_name = device_name;
+    }
+
+    public String getFault_seq() {
+        return fault_seq;
+    }
+
+    public void setFault_seq(String fault_seq) {
+        this.fault_seq = fault_seq;
+    }
+
+    public String getFault_message() {
+        return fault_message;
+    }
+
+    public void setFault_message(String fault_message) {
+        this.fault_message = fault_message;
+    }
+
+    public String getFault_time() {
+        return fault_time;
+    }
+
+    public void setFault_time(String fault_time) {
+        this.fault_time = fault_time;
+    }
+
+    @Override
+    public String toString() {
+        return "DeviceWarn{" +
+                "device_id='" + device_id + '\'' +
+                ", device_name='" + device_name + '\'' +
+                ", fault_seq='" + fault_seq + '\'' +
+                ", fault_message='" + fault_message + '\'' +
+                ", fault_time='" + fault_time + '\'' +
+                '}';
+    }
+}

+ 341 - 0
flink_metro/src/main/java/com/sunwin/metro/bean/ElectricityMeter.java

@@ -0,0 +1,341 @@
+package com.sunwin.metro.bean;
+
+import com.alibaba.fastjson.JSON;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @program: sunwin_metro
+ * @description: 电表值对象
+ * @author: xuYJ
+ * @create: 2021-04-14 16:50
+ **/
+public class ElectricityMeter implements Serializable {
+
+    private String meter_number;
+
+
+    private Double electric_total_active;
+
+
+    private Map<String,Double> frequency;
+
+    private Map<String,Double> a_current;
+
+    private Map<String,Double> b_current;
+
+    private Map<String,Double> c_current;
+
+    private Map<String,Double> a_voltage;
+
+    private Map<String,Double> b_voltage;
+
+    private Map<String,Double> c_voltage;
+
+    private Map<String,Double> total_negative_active;
+
+    private Map<String,Double> a_negative_active;
+
+    private Map<String,Double> b_negative_active;
+
+    private Map<String,Double> c_negative_active;
+
+    private Map<String,Double> total_power_factor;
+
+    private Map<String,Double> a_power_factor;
+
+    private Map<String,Double> b_power_factor;
+
+    private Map<String,Double> c_power_factor;
+
+    private Map<String,Double> total_apparent_power;
+
+    private Map<String,Double> a_apparent_power;
+
+    private Map<String,Double> b_apparent_power;
+
+    private Map<String,Double> c_apparent_power;
+
+    private Map<String,Double> total_active_power;
+
+    private Map<String,Double> a_active_power;
+
+    private Map<String,Double> b_active_power;
+
+    private Map<String,Double> c_active_power;
+
+    private Integer electric_status;
+
+    private Map<String,Double> total_active;
+
+    private String update_time;
+
+    public ElectricityMeter() {
+    }
+
+    public ElectricityMeter(String meter_number, Integer electric_status, String update_time) {
+        this.meter_number = meter_number;
+        this.electric_status = electric_status;
+        this.update_time = update_time;
+    }
+
+    public String getMeter_number() {
+        return meter_number;
+    }
+
+    public void setMeter_number(String meter_number) {
+        this.meter_number = meter_number;
+    }
+
+    public Double getElectric_total_active() {
+        return electric_total_active;
+    }
+
+    public void setElectric_total_active(Double electric_total_active) {
+        this.electric_total_active = electric_total_active;
+    }
+
+    public Map<String, Double> getFrequency() {
+        return frequency;
+    }
+
+    public void setFrequency(Map<String, Double> frequency) {
+        this.frequency = frequency;
+    }
+
+    public Map<String, Double> getA_current() {
+        return a_current;
+    }
+
+    public void setA_current(Map<String, Double> a_current) {
+        this.a_current = a_current;
+    }
+
+    public Map<String, Double> getB_current() {
+        return b_current;
+    }
+
+    public void setB_current(Map<String, Double> b_current) {
+        this.b_current = b_current;
+    }
+
+    public Map<String, Double> getC_current() {
+        return c_current;
+    }
+
+    public void setC_current(Map<String, Double> c_current) {
+        this.c_current = c_current;
+    }
+
+    public Map<String, Double> getA_voltage() {
+        return a_voltage;
+    }
+
+    public void setA_voltage(Map<String, Double> a_voltage) {
+        this.a_voltage = a_voltage;
+    }
+
+    public Map<String, Double> getB_voltage() {
+        return b_voltage;
+    }
+
+    public void setB_voltage(Map<String, Double> b_voltage) {
+        this.b_voltage = b_voltage;
+    }
+
+    public Map<String, Double> getC_voltage() {
+        return c_voltage;
+    }
+
+    public void setC_voltage(Map<String, Double> c_voltage) {
+        this.c_voltage = c_voltage;
+    }
+
+    public Map<String, Double> getTotal_negative_active() {
+        return total_negative_active;
+    }
+
+    public void setTotal_negative_active(Map<String, Double> total_negative_active) {
+        this.total_negative_active = total_negative_active;
+    }
+
+    public Map<String, Double> getA_negative_active() {
+        return a_negative_active;
+    }
+
+    public void setA_negative_active(Map<String, Double> a_negative_active) {
+        this.a_negative_active = a_negative_active;
+    }
+
+    public Map<String, Double> getB_negative_active() {
+        return b_negative_active;
+    }
+
+    public void setB_negative_active(Map<String, Double> b_negative_active) {
+        this.b_negative_active = b_negative_active;
+    }
+
+    public Map<String, Double> getC_negative_active() {
+        return c_negative_active;
+    }
+
+    public void setC_negative_active(Map<String, Double> c_negative_active) {
+        this.c_negative_active = c_negative_active;
+    }
+
+    public Map<String, Double> getTotal_power_factor() {
+        return total_power_factor;
+    }
+
+    public void setTotal_power_factor(Map<String, Double> total_power_factor) {
+        this.total_power_factor = total_power_factor;
+    }
+
+    public Map<String, Double> getA_power_factor() {
+        return a_power_factor;
+    }
+
+    public void setA_power_factor(Map<String, Double> a_power_factor) {
+        this.a_power_factor = a_power_factor;
+    }
+
+    public Map<String, Double> getB_power_factor() {
+        return b_power_factor;
+    }
+
+    public void setB_power_factor(Map<String, Double> b_power_factor) {
+        this.b_power_factor = b_power_factor;
+    }
+
+    public Map<String, Double> getC_power_factor() {
+        return c_power_factor;
+    }
+
+    public void setC_power_factor(Map<String, Double> c_power_factor) {
+        this.c_power_factor = c_power_factor;
+    }
+
+    public Map<String, Double> getTotal_apparent_power() {
+        return total_apparent_power;
+    }
+
+    public void setTotal_apparent_power(Map<String, Double> total_apparent_power) {
+        this.total_apparent_power = total_apparent_power;
+    }
+
+    public Map<String, Double> getA_apparent_power() {
+        return a_apparent_power;
+    }
+
+    public void setA_apparent_power(Map<String, Double> a_apparent_power) {
+        this.a_apparent_power = a_apparent_power;
+    }
+
+    public Map<String, Double> getB_apparent_power() {
+        return b_apparent_power;
+    }
+
+    public void setB_apparent_power(Map<String, Double> b_apparent_power) {
+        this.b_apparent_power = b_apparent_power;
+    }
+
+    public Map<String, Double> getC_apparent_power() {
+        return c_apparent_power;
+    }
+
+    public void setC_apparent_power(Map<String, Double> c_apparent_power) {
+        this.c_apparent_power = c_apparent_power;
+    }
+
+    public Map<String, Double> getTotal_active_power() {
+        return total_active_power;
+    }
+
+    public void setTotal_active_power(Map<String, Double> total_active_power) {
+        this.total_active_power = total_active_power;
+    }
+
+    public Map<String, Double> getA_active_power() {
+        return a_active_power;
+    }
+
+    public void setA_active_power(Map<String, Double> a_active_power) {
+        this.a_active_power = a_active_power;
+    }
+
+    public Map<String, Double> getB_active_power() {
+        return b_active_power;
+    }
+
+    public void setB_active_power(Map<String, Double> b_active_power) {
+        this.b_active_power = b_active_power;
+    }
+
+    public Map<String, Double> getC_active_power() {
+        return c_active_power;
+    }
+
+    public void setC_active_power(Map<String, Double> c_active_power) {
+        this.c_active_power = c_active_power;
+    }
+
+    public Integer getElectric_status() {
+        return electric_status;
+    }
+
+    public void setElectric_status(Integer electric_status) {
+        this.electric_status = electric_status;
+    }
+
+    public Map<String, Double> getTotal_active() {
+        return total_active;
+    }
+
+    public void setTotal_active(Map<String, Double> total_active) {
+        this.total_active = total_active;
+    }
+
+    public String getUpdate_time() {
+        return update_time;
+    }
+
+    public void setUpdate_time(String update_time) {
+        this.update_time = update_time;
+    }
+
+    @Override
+    public String toString() {
+        return "ElectricityMeter{" +
+                "meter_number='" + meter_number + '\'' +
+                ", electric_total_active=" + JSON.toJSONString(electric_total_active) +
+                ", frequency=" + JSON.toJSONString(frequency) +
+                ", a_current=" + JSON.toJSONString(a_current) +
+                ", b_current=" + JSON.toJSONString(b_current) +
+                ", c_current=" + JSON.toJSONString(c_current) +
+                ", a_voltage=" + JSON.toJSONString(a_voltage) +
+                ", b_voltage=" + JSON.toJSONString(b_voltage) +
+                ", c_voltage=" + JSON.toJSONString(c_voltage) +
+                ", total_negative_active=" + JSON.toJSONString(total_negative_active) +
+                ", a_negative_active=" + JSON.toJSONString(a_negative_active) +
+                ", b_negative_active=" + JSON.toJSONString(b_negative_active) +
+                ", c_negative_active=" + JSON.toJSONString(c_negative_active) +
+                ", total_power_factor=" + JSON.toJSONString(total_power_factor) +
+                ", a_power_factor=" + JSON.toJSONString(a_power_factor) +
+                ", b_power_factor=" + JSON.toJSONString(b_power_factor) +
+                ", c_power_factor=" + JSON.toJSONString(c_power_factor) +
+                ", total_apparent_power=" + JSON.toJSONString(total_apparent_power) +
+                ", a_apparent_power=" + JSON.toJSONString(a_apparent_power) +
+                ", b_apparent_power=" + JSON.toJSONString(b_apparent_power) +
+                ", c_apparent_power=" + JSON.toJSONString(c_apparent_power) +
+                ", total_active_power=" + JSON.toJSONString(total_active_power) +
+                ", a_active_power=" + JSON.toJSONString(a_active_power) +
+                ", b_active_power=" + JSON.toJSONString(b_active_power) +
+                ", c_active_power=" + JSON.toJSONString(c_active_power) +
+                ", electric_status=" + electric_status +
+                ", total_active=" + JSON.toJSONString(total_active) +
+                ", update_time='" + update_time + '\'' +
+                '}';
+    }
+}

+ 68 - 0
flink_metro/src/main/java/com/sunwin/metro/bean/ErrorDevice.java

@@ -0,0 +1,68 @@
+package com.sunwin.metro.bean;
+
+import java.io.Serializable;
+
+/**
+ * @program: sunwin_metro
+ * @description: 写到mysql的设备号对象
+ * @author: xuYJ
+ * @create: 2021-01-19 14:17
+ **/
+public class ErrorDevice implements Serializable {
+    private String id;
+    private String deviceName;
+    private String resultInfo;
+    private String date;
+
+    public ErrorDevice(String id, String deviceName, String resultInfo, String date) {
+        this.id = id;
+        this.deviceName = deviceName;
+        this.resultInfo = resultInfo;
+        this.date = date;
+    }
+
+    public ErrorDevice() {
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getDeviceName() {
+        return deviceName;
+    }
+
+    public void setDeviceName(String deviceName) {
+        this.deviceName = deviceName;
+    }
+
+    public String getResultInfo() {
+        return resultInfo;
+    }
+
+    public void setResultInfo(String resultInfo) {
+        this.resultInfo = resultInfo;
+    }
+
+    public String getDate() {
+        return date;
+    }
+
+    public void setDate(String date) {
+        this.date = date;
+    }
+
+    @Override
+    public String toString() {
+        return "ErrorDevice{" +
+                "id='" + id + '\'' +
+                ", deviceName='" + deviceName + '\'' +
+                ", resultInfo='" + resultInfo + '\'' +
+                ", date='" + date + '\'' +
+                '}';
+    }
+}

+ 224 - 0
flink_metro/src/main/java/com/sunwin/metro/bean/Meter.java

@@ -0,0 +1,224 @@
+package com.sunwin.metro.bean;
+
+
+import java.io.Serializable;
+
+/**
+ * @program: sunwin_metro
+ * @description: 仪表对象
+ * @author: xuYJ
+ * @create: 2021-04-14 10:29
+ **/
+public class Meter implements Serializable {
+
+    private String id;
+
+    private String meterNumber;
+
+    private int meterType;
+
+    private String name;
+
+    private String brandName;
+
+    private String personName;
+
+    private String personTel;
+
+    private boolean isOnline;
+
+    private String installLocation;
+
+    private String meterAttribute;
+
+    private String remarks;
+
+    private String collectorId;
+
+    private String stationId;
+
+    private String gmtModified;
+
+    private String gmtCreate;
+
+    private String meterName;
+
+
+    public Meter() {
+    }
+
+    public Meter(String id, String meterNumber, int meterType) {
+        this.id = id;
+        this.meterNumber = meterNumber;
+        this.meterType = meterType;
+    }
+
+    public Meter(String id, String meterNumber, int meterType, String name, String brandName, String personName, String personTel, boolean isOnline, String installLocation, String meterAttribute, String remarks, String collectorId, String stationId, String gmtModified, String gmtCreate, String meterName) {
+        this.id = id;
+        this.meterNumber = meterNumber;
+        this.meterType = meterType;
+        this.name = name;
+        this.brandName = brandName;
+        this.personName = personName;
+        this.personTel = personTel;
+        this.isOnline = isOnline;
+        this.installLocation = installLocation;
+        this.meterAttribute = meterAttribute;
+        this.remarks = remarks;
+        this.collectorId = collectorId;
+        this.stationId = stationId;
+        this.gmtModified = gmtModified;
+        this.gmtCreate = gmtCreate;
+        this.meterName = meterName;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getMeterNumber() {
+        return meterNumber;
+    }
+
+    public void setMeterNumber(String meterNumber) {
+        this.meterNumber = meterNumber;
+    }
+
+    public int getMeterType() {
+        return meterType;
+    }
+
+    public void setMeterType(int meterType) {
+        this.meterType = meterType;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getBrandName() {
+        return brandName;
+    }
+
+    public void setBrandName(String brandName) {
+        this.brandName = brandName;
+    }
+
+    public String getPersonName() {
+        return personName;
+    }
+
+    public void setPersonName(String personName) {
+        this.personName = personName;
+    }
+
+    public String getPersonTel() {
+        return personTel;
+    }
+
+    public void setPersonTel(String personTel) {
+        this.personTel = personTel;
+    }
+
+    public boolean isOnline() {
+        return isOnline;
+    }
+
+    public void setOnline(boolean online) {
+        isOnline = online;
+    }
+
+    public String getInstallLocation() {
+        return installLocation;
+    }
+
+    public void setInstallLocation(String installLocation) {
+        this.installLocation = installLocation;
+    }
+
+    public String getMeterAttribute() {
+        return meterAttribute;
+    }
+
+    public void setMeterAttribute(String meterAttribute) {
+        this.meterAttribute = meterAttribute;
+    }
+
+    public String getRemarks() {
+        return remarks;
+    }
+
+    public void setRemarks(String remarks) {
+        this.remarks = remarks;
+    }
+
+    public String getCollectorId() {
+        return collectorId;
+    }
+
+    public void setCollectorId(String collectorId) {
+        this.collectorId = collectorId;
+    }
+
+    public String getStationId() {
+        return stationId;
+    }
+
+    public void setStationId(String stationId) {
+        this.stationId = stationId;
+    }
+
+    public String getGmtModified() {
+        return gmtModified;
+    }
+
+    public void setGmtModified(String gmtModified) {
+        this.gmtModified = gmtModified;
+    }
+
+    public String getGmtCreate() {
+        return gmtCreate;
+    }
+
+    public void setGmtCreate(String gmtCreate) {
+        this.gmtCreate = gmtCreate;
+    }
+
+    public String getMeterName() {
+        return meterName;
+    }
+
+    public void setMeterName(String meterName) {
+        this.meterName = meterName;
+    }
+
+    @Override
+    public String toString() {
+        return "Meter{" +
+                "id='" + id + '\'' +
+                ", meterNumber='" + meterNumber + '\'' +
+                ", meterType=" + meterType +
+                ", name='" + name + '\'' +
+                ", brandName='" + brandName + '\'' +
+                ", personName='" + personName + '\'' +
+                ", personTel='" + personTel + '\'' +
+                ", isOnline=" + isOnline +
+                ", installLocation='" + installLocation + '\'' +
+                ", meterAttribute='" + meterAttribute + '\'' +
+                ", remarks='" + remarks + '\'' +
+                ", collectorId='" + collectorId + '\'' +
+                ", stationId='" + stationId + '\'' +
+                ", gmtModified='" + gmtModified + '\'' +
+                ", gmtCreate='" + gmtCreate + '\'' +
+                ", meterName='" + meterName + '\'' +
+                '}';
+    }
+}

+ 267 - 0
flink_metro/src/main/java/com/sunwin/metro/bean/MetroDevice.java

@@ -0,0 +1,267 @@
+package com.sunwin.metro.bean;
+
+import java.io.Serializable;
+
+/**
+ * @program: SWStream
+ * @description: 设备属性
+ * @author: xuYJ
+ * @create: 2021-01-13 07:37
+ **/
+public class MetroDevice implements Serializable {
+    private static final long serialVersionUID = 1228653073721709093L;
+
+    private String websocket_time;
+
+    private String comp_des;
+
+    private String station_name;
+
+    private String device_time;
+
+    private String original_compname;
+
+    private String device_id;
+
+    private String station_id;
+
+    private String attribute_result;
+
+    private String device_des;
+
+    private String action_text;
+
+    private String result_type;
+
+    private String original_dpe;
+
+    private String attribute_time;
+
+    private String action_user;
+
+    private String device_warn;
+
+    private String metro_system;
+
+    private String device_name;
+
+    private String sub_sys;
+
+    private String attribute_type;
+
+    private String attribute_name;
+
+    public MetroDevice() {
+    }
+
+    public MetroDevice(String websocket_time, String comp_des, String station_name, String device_time, String original_compname, String device_id, String station_id, String attribute_result, String device_des, String action_text, String result_type, String original_dpe, String attribute_time, String action_user, String device_warn, String metro_system, String device_name, String sub_sys, String attribute_type, String attribute_name) {
+        this.websocket_time = websocket_time;
+        this.comp_des = comp_des;
+        this.station_name = station_name;
+        this.device_time = device_time;
+        this.original_compname = original_compname;
+        this.device_id = device_id;
+        this.station_id = station_id;
+        this.attribute_result = attribute_result;
+        this.device_des = device_des;
+        this.action_text = action_text;
+        this.result_type = result_type;
+        this.original_dpe = original_dpe;
+        this.attribute_time = attribute_time;
+        this.action_user = action_user;
+        this.device_warn = device_warn;
+        this.metro_system = metro_system;
+        this.device_name = device_name;
+        this.sub_sys = sub_sys;
+        this.attribute_type = attribute_type;
+        this.attribute_name = attribute_name;
+    }
+
+
+
+    public String getWebsocket_time() {
+        return websocket_time;
+    }
+
+    public void setWebsocket_time(String websocket_time) {
+        this.websocket_time = websocket_time;
+    }
+
+    public String getComp_des() {
+        return comp_des;
+    }
+
+    public void setComp_des(String comp_des) {
+        this.comp_des = comp_des;
+    }
+
+    public String getStation_name() {
+        return station_name;
+    }
+
+    public void setStation_name(String station_name) {
+        this.station_name = station_name;
+    }
+
+    public String getDevice_time() {
+        return device_time;
+    }
+
+    public void setDevice_time(String device_time) {
+        this.device_time = device_time;
+    }
+
+    public String getOriginal_compname() {
+        return original_compname;
+    }
+
+    public void setOriginal_compname(String original_compname) {
+        this.original_compname = original_compname;
+    }
+
+    public String getDevice_id() {
+        return device_id;
+    }
+
+    public void setDevice_id(String device_id) {
+        this.device_id = device_id;
+    }
+
+    public String getStation_id() {
+        return station_id;
+    }
+
+    public void setStation_id(String station_id) {
+        this.station_id = station_id;
+    }
+
+    public String getAttribute_result() {
+        return attribute_result;
+    }
+
+    public void setAttribute_result(String attribute_result) {
+        this.attribute_result = attribute_result;
+    }
+
+    public String getDevice_des() {
+        return device_des;
+    }
+
+    public void setDevice_des(String device_des) {
+        this.device_des = device_des;
+    }
+
+    public String getAction_text() {
+        return action_text;
+    }
+
+    public void setAction_text(String action_text) {
+        this.action_text = action_text;
+    }
+
+    public String getResult_type() {
+        return result_type;
+    }
+
+    public void setResult_type(String result_type) {
+        this.result_type = result_type;
+    }
+
+    public String getOriginal_dpe() {
+        return original_dpe;
+    }
+
+    public void setOriginal_dpe(String original_dpe) {
+        this.original_dpe = original_dpe;
+    }
+
+    public String getAttribute_time() {
+        return attribute_time;
+    }
+
+    public void setAttribute_time(String attribute_time) {
+        this.attribute_time = attribute_time;
+    }
+
+    public String getAction_user() {
+        return action_user;
+    }
+
+    public void setAction_user(String action_user) {
+        this.action_user = action_user;
+    }
+
+    public String getDevice_warn() {
+        return device_warn;
+    }
+
+    public void setDevice_warn(String device_warn) {
+        this.device_warn = device_warn;
+    }
+
+    public String getMetro_system() {
+        return metro_system;
+    }
+
+    public void setMetro_system(String metro_system) {
+        this.metro_system = metro_system;
+    }
+
+    public String getDevice_name() {
+        return device_name;
+    }
+
+    public void setDevice_name(String device_name) {
+        this.device_name = device_name;
+    }
+
+    public String getSub_sys() {
+        return sub_sys;
+    }
+
+    public void setSub_sys(String sub_sys) {
+        this.sub_sys = sub_sys;
+    }
+
+    public String getAttribute_type() {
+        return attribute_type;
+    }
+
+    public void setAttribute_type(String attribute_type) {
+        this.attribute_type = attribute_type;
+    }
+
+    public String getAttribute_name() {
+        return attribute_name;
+    }
+
+    public void setAttribute_name(String attribute_name) {
+        this.attribute_name = attribute_name;
+    }
+
+    @Override
+    public String toString() {
+        return "MetroDevice{" +
+                "websocket_time='" + websocket_time + '\'' +
+                ", comp_des='" + comp_des + '\'' +
+                ", station_name='" + station_name + '\'' +
+                ", device_time='" + device_time + '\'' +
+                ", original_compname='" + original_compname + '\'' +
+                ", device_id='" + device_id + '\'' +
+                ", station_id='" + station_id + '\'' +
+                ", attribute_result='" + attribute_result + '\'' +
+                ", device_des='" + device_des + '\'' +
+                ", action_text='" + action_text + '\'' +
+                ", result_type='" + result_type + '\'' +
+                ", original_dpe='" + original_dpe + '\'' +
+                ", attribute_time='" + attribute_time + '\'' +
+                ", action_user='" + action_user + '\'' +
+                ", device_warn='" + device_warn + '\'' +
+                ", metro_system='" + metro_system + '\'' +
+                ", device_name='" + device_name + '\'' +
+                ", sub_sys='" + sub_sys + '\'' +
+                ", attribute_type='" + attribute_type + '\'' +
+                ", attribute_name='" + attribute_name + '\'' +
+                '}';
+    }
+}

+ 45 - 0
flink_metro/src/main/java/com/sunwin/metro/bean/RecentMsg.java

@@ -0,0 +1,45 @@
+package com.sunwin.metro.bean;
+
+import java.io.Serializable;
+
+/**
+ * @program: sunwin_metro
+ * @description: 近期数据
+ * @author: xuYJ
+ * @create: 2021-04-15 08:35
+ **/
+public class RecentMsg implements Serializable {
+
+    private String date;
+
+    private Double value;
+
+    public RecentMsg(String date, Double value) {
+        this.date = date;
+        this.value = value;
+    }
+
+    public String getDate() {
+        return date;
+    }
+
+    public void setDate(String date) {
+        this.date = date;
+    }
+
+    public Double getValue() {
+        return value;
+    }
+
+    public void setValue(Double value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return "RecentMsg{" +
+                "date='" + date + '\'' +
+                ", value=" + value +
+                '}';
+    }
+}

+ 117 - 0
flink_metro/src/main/java/com/sunwin/metro/bean/message/EquipmentWarn.java

@@ -0,0 +1,117 @@
+package com.sunwin.metro.bean.message;
+
+import java.io.Serializable;
+
+/**
+ * @program: sunwin_metro
+ * @description: 设备模拟预警信息
+ * @author: xuYJ
+ * @create: 2021-05-31 12:27
+ **/
+public class EquipmentWarn implements Serializable {
+    private Integer line;
+    private Integer equipment_code;
+    private Integer station;
+    private String equipment_name;
+
+    private String warn_time;
+
+    private String current_time;
+
+
+    private String warn_type;
+
+    private String flag;
+
+    public EquipmentWarn() {
+    }
+
+    public EquipmentWarn(Integer line, Integer equipment_code, Integer station, String equipment_name, String warn_time, String current_time, String warn_type, String flag) {
+        this.line = line;
+        this.equipment_code = equipment_code;
+        this.station = station;
+        this.equipment_name = equipment_name;
+        this.warn_time = warn_time;
+        this.current_time = current_time;
+        this.warn_type = warn_type;
+        this.flag = flag;
+    }
+
+    public Integer getLine() {
+        return line;
+    }
+
+    public void setLine(Integer line) {
+        this.line = line;
+    }
+
+    public Integer getEquipment_code() {
+        return equipment_code;
+    }
+
+    public void setEquipment_code(Integer equipment_code) {
+        this.equipment_code = equipment_code;
+    }
+
+    public Integer getStation() {
+        return station;
+    }
+
+    public void setStation(Integer station) {
+        this.station = station;
+    }
+
+    public String getEquipment_name() {
+        return equipment_name;
+    }
+
+    public void setEquipment_name(String equipment_name) {
+        this.equipment_name = equipment_name;
+    }
+
+    public String getWarn_time() {
+        return warn_time;
+    }
+
+    public void setWarn_time(String warn_time) {
+        this.warn_time = warn_time;
+    }
+
+    public String getCurrent_time() {
+        return current_time;
+    }
+
+    public void setCurrent_time(String current_time) {
+        this.current_time = current_time;
+    }
+
+    public String getWarn_type() {
+        return warn_type;
+    }
+
+    public void setWarn_type(String warn_type) {
+        this.warn_type = warn_type;
+    }
+
+    public String getFlag() {
+        return flag;
+    }
+
+    public void setFlag(String flag) {
+        this.flag = flag;
+    }
+
+    @Override
+    public String toString() {
+        return "EquipmentWarn{" +
+                "line=" + line +
+                ", equipment_code=" + equipment_code +
+                ", station=" + station +
+                ", equipment_name='" + equipment_name + '\'' +
+                ", warn_time='" + warn_time + '\'' +
+                ", current_time='" + current_time + '\'' +
+                ", warn_type='" + warn_type + '\'' +
+                ", flag='" + flag + '\'' +
+                '}';
+    }
+}

+ 604 - 0
flink_metro/src/main/java/com/sunwin/metro/bean/train/BasTef.java

@@ -0,0 +1,604 @@
+package com.sunwin.metro.bean.train;
+
+import java.io.Serializable;
+
+/**
+ * @program: sunwin_metro
+ * @description:
+ * @author: xuYJ
+ * @create: 2021-05-08 11:06
+ **/
+public class BasTef implements Serializable {
+        private String di_movl;
+        private Integer ai_fltno;
+        private String di_aflagst;
+        private Integer ai_windta;
+        private Integer ai_windtb;
+        private Integer ai_windtc;
+        private Integer ai_y_vibr;
+        private Integer ao_fset;
+        private Integer ao_sptm;
+        private String di_fail;
+        private Integer ai_fbak;
+        private String di_vfflt;
+        private String di_senablest;
+        private String di_aovt;
+        private String di_vibr;
+        private Integer ai_faxlet;
+        private Integer ai_x_vibr;
+        private String di_frun;
+        private Integer ao_kptm;
+        private String di_stp;
+        private String do_aflagst;
+        private String name;
+        private String di_vrun;
+        private Integer ai_raxlet;
+        private Double ai_tacc;
+        private String do_fres;
+        private String di_vfbas;
+        private String do_fst;
+        private String di_commokst;
+        private String do_senablest;
+        private String stime;
+        private String do_sfrestst;
+        private String do_sp;
+        private Integer ai_pvoltc;
+        private String do_st;
+        private Integer ai_pvolta;
+        private Integer ai_pvoltb;
+        private String di_wovt;
+        private String di_run;
+        private Integer ai_comm_word;
+        private String di_hang;
+        private String di_sflagst;
+        private String do_sunablest;
+        private String di_pfvf;
+        private String do_hang;
+        private String do_sflagst;
+        private String do_nhang;
+        private String do_srtrestst;
+        private Integer ao_kitm;
+        private String di_lr;
+        private Integer ai_pcurra;
+        private Integer ai_pcurrc;
+        private Integer ai_pcurrb;
+
+    public BasTef(String di_movl, Integer ai_fltno, String di_aflagst, Integer ai_windta, Integer ai_windtb, Integer ai_windtc, Integer ai_y_vibr, Integer ao_fset, Integer ao_sptm, String di_fail, Integer ai_fbak, String di_vfflt, String di_senablest, String di_aovt, String di_vibr, Integer ai_faxlet, Integer ai_x_vibr, String di_frun, Integer ao_kptm, String di_stp, String do_aflagst, String name, String di_vrun, Integer ai_raxlet, Double ai_tacc, String do_fres, String di_vfbas, String do_fst, String di_commokst, String do_senablest, String stime, String do_sfrestst, String do_sp, Integer ai_pvoltc, String do_st, Integer ai_pvolta, Integer ai_pvoltb, String di_wovt, String di_run, Integer ai_comm_word, String di_hang, String di_sflagst, String do_sunablest, String di_pfvf, String do_hang, String do_sflagst, String do_nhang, String do_srtrestst, Integer ao_kitm, String di_lr, Integer ai_pcurra, Integer ai_pcurrc, Integer ai_pcurrb) {
+        this.di_movl = di_movl;
+        this.ai_fltno = ai_fltno;
+        this.di_aflagst = di_aflagst;
+        this.ai_windta = ai_windta;
+        this.ai_windtb = ai_windtb;
+        this.ai_windtc = ai_windtc;
+        this.ai_y_vibr = ai_y_vibr;
+        this.ao_fset = ao_fset;
+        this.ao_sptm = ao_sptm;
+        this.di_fail = di_fail;
+        this.ai_fbak = ai_fbak;
+        this.di_vfflt = di_vfflt;
+        this.di_senablest = di_senablest;
+        this.di_aovt = di_aovt;
+        this.di_vibr = di_vibr;
+        this.ai_faxlet = ai_faxlet;
+        this.ai_x_vibr = ai_x_vibr;
+        this.di_frun = di_frun;
+        this.ao_kptm = ao_kptm;
+        this.di_stp = di_stp;
+        this.do_aflagst = do_aflagst;
+        this.name = name;
+        this.di_vrun = di_vrun;
+        this.ai_raxlet = ai_raxlet;
+        this.ai_tacc = ai_tacc;
+        this.do_fres = do_fres;
+        this.di_vfbas = di_vfbas;
+        this.do_fst = do_fst;
+        this.di_commokst = di_commokst;
+        this.do_senablest = do_senablest;
+        this.stime = stime;
+        this.do_sfrestst = do_sfrestst;
+        this.do_sp = do_sp;
+        this.ai_pvoltc = ai_pvoltc;
+        this.do_st = do_st;
+        this.ai_pvolta = ai_pvolta;
+        this.ai_pvoltb = ai_pvoltb;
+        this.di_wovt = di_wovt;
+        this.di_run = di_run;
+        this.ai_comm_word = ai_comm_word;
+        this.di_hang = di_hang;
+        this.di_sflagst = di_sflagst;
+        this.do_sunablest = do_sunablest;
+        this.di_pfvf = di_pfvf;
+        this.do_hang = do_hang;
+        this.do_sflagst = do_sflagst;
+        this.do_nhang = do_nhang;
+        this.do_srtrestst = do_srtrestst;
+        this.ao_kitm = ao_kitm;
+        this.di_lr = di_lr;
+        this.ai_pcurra = ai_pcurra;
+        this.ai_pcurrc = ai_pcurrc;
+        this.ai_pcurrb = ai_pcurrb;
+    }
+
+    public String getDi_movl() {
+        return di_movl;
+    }
+
+    public void setDi_movl(String di_movl) {
+        this.di_movl = di_movl;
+    }
+
+    public Integer getAi_fltno() {
+        return ai_fltno;
+    }
+
+    public void setAi_fltno(Integer ai_fltno) {
+        this.ai_fltno = ai_fltno;
+    }
+
+    public String getDi_aflagst() {
+        return di_aflagst;
+    }
+
+    public void setDi_aflagst(String di_aflagst) {
+        this.di_aflagst = di_aflagst;
+    }
+
+    public Integer getAi_windta() {
+        return ai_windta;
+    }
+
+    public void setAi_windta(Integer ai_windta) {
+        this.ai_windta = ai_windta;
+    }
+
+    public Integer getAi_windtb() {
+        return ai_windtb;
+    }
+
+    public void setAi_windtb(Integer ai_windtb) {
+        this.ai_windtb = ai_windtb;
+    }
+
+    public Integer getAi_windtc() {
+        return ai_windtc;
+    }
+
+    public void setAi_windtc(Integer ai_windtc) {
+        this.ai_windtc = ai_windtc;
+    }
+
+    public Integer getAi_y_vibr() {
+        return ai_y_vibr;
+    }
+
+    public void setAi_y_vibr(Integer ai_y_vibr) {
+        this.ai_y_vibr = ai_y_vibr;
+    }
+
+    public Integer getAo_fset() {
+        return ao_fset;
+    }
+
+    public void setAo_fset(Integer ao_fset) {
+        this.ao_fset = ao_fset;
+    }
+
+    public Integer getAo_sptm() {
+        return ao_sptm;
+    }
+
+    public void setAo_sptm(Integer ao_sptm) {
+        this.ao_sptm = ao_sptm;
+    }
+
+    public String getDi_fail() {
+        return di_fail;
+    }
+
+    public void setDi_fail(String di_fail) {
+        this.di_fail = di_fail;
+    }
+
+    public Integer getAi_fbak() {
+        return ai_fbak;
+    }
+
+    public void setAi_fbak(Integer ai_fbak) {
+        this.ai_fbak = ai_fbak;
+    }
+
+    public String getDi_vfflt() {
+        return di_vfflt;
+    }
+
+    public void setDi_vfflt(String di_vfflt) {
+        this.di_vfflt = di_vfflt;
+    }
+
+    public String getDi_senablest() {
+        return di_senablest;
+    }
+
+    public void setDi_senablest(String di_senablest) {
+        this.di_senablest = di_senablest;
+    }
+
+    public String getDi_aovt() {
+        return di_aovt;
+    }
+
+    public void setDi_aovt(String di_aovt) {
+        this.di_aovt = di_aovt;
+    }
+
+    public String getDi_vibr() {
+        return di_vibr;
+    }
+
+    public void setDi_vibr(String di_vibr) {
+        this.di_vibr = di_vibr;
+    }
+
+    public Integer getAi_faxlet() {
+        return ai_faxlet;
+    }
+
+    public void setAi_faxlet(Integer ai_faxlet) {
+        this.ai_faxlet = ai_faxlet;
+    }
+
+    public Integer getAi_x_vibr() {
+        return ai_x_vibr;
+    }
+
+    public void setAi_x_vibr(Integer ai_x_vibr) {
+        this.ai_x_vibr = ai_x_vibr;
+    }
+
+    public String getDi_frun() {
+        return di_frun;
+    }
+
+    public void setDi_frun(String di_frun) {
+        this.di_frun = di_frun;
+    }
+
+    public Integer getAo_kptm() {
+        return ao_kptm;
+    }
+
+    public void setAo_kptm(Integer ao_kptm) {
+        this.ao_kptm = ao_kptm;
+    }
+
+    public String getDi_stp() {
+        return di_stp;
+    }
+
+    public void setDi_stp(String di_stp) {
+        this.di_stp = di_stp;
+    }
+
+    public String getDo_aflagst() {
+        return do_aflagst;
+    }
+
+    public void setDo_aflagst(String do_aflagst) {
+        this.do_aflagst = do_aflagst;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDi_vrun() {
+        return di_vrun;
+    }
+
+    public void setDi_vrun(String di_vrun) {
+        this.di_vrun = di_vrun;
+    }
+
+    public Integer getAi_raxlet() {
+        return ai_raxlet;
+    }
+
+    public void setAi_raxlet(Integer ai_raxlet) {
+        this.ai_raxlet = ai_raxlet;
+    }
+
+    public Double getAi_tacc() {
+        return ai_tacc;
+    }
+
+    public void setAi_tacc(Double ai_tacc) {
+        this.ai_tacc = ai_tacc;
+    }
+
+    public String getDo_fres() {
+        return do_fres;
+    }
+
+    public void setDo_fres(String do_fres) {
+        this.do_fres = do_fres;
+    }
+
+    public String getDi_vfbas() {
+        return di_vfbas;
+    }
+
+    public void setDi_vfbas(String di_vfbas) {
+        this.di_vfbas = di_vfbas;
+    }
+
+    public String getDo_fst() {
+        return do_fst;
+    }
+
+    public void setDo_fst(String do_fst) {
+        this.do_fst = do_fst;
+    }
+
+    public String getDi_commokst() {
+        return di_commokst;
+    }
+
+    public void setDi_commokst(String di_commokst) {
+        this.di_commokst = di_commokst;
+    }
+
+    public String getDo_senablest() {
+        return do_senablest;
+    }
+
+    public void setDo_senablest(String do_senablest) {
+        this.do_senablest = do_senablest;
+    }
+
+    public String getStime() {
+        return stime;
+    }
+
+    public void setStime(String stime) {
+        this.stime = stime;
+    }
+
+    public String getDo_sfrestst() {
+        return do_sfrestst;
+    }
+
+    public void setDo_sfrestst(String do_sfrestst) {
+        this.do_sfrestst = do_sfrestst;
+    }
+
+    public String getDo_sp() {
+        return do_sp;
+    }
+
+    public void setDo_sp(String do_sp) {
+        this.do_sp = do_sp;
+    }
+
+    public Integer getAi_pvoltc() {
+        return ai_pvoltc;
+    }
+
+    public void setAi_pvoltc(Integer ai_pvoltc) {
+        this.ai_pvoltc = ai_pvoltc;
+    }
+
+    public String getDo_st() {
+        return do_st;
+    }
+
+    public void setDo_st(String do_st) {
+        this.do_st = do_st;
+    }
+
+    public Integer getAi_pvolta() {
+        return ai_pvolta;
+    }
+
+    public void setAi_pvolta(Integer ai_pvolta) {
+        this.ai_pvolta = ai_pvolta;
+    }
+
+    public Integer getAi_pvoltb() {
+        return ai_pvoltb;
+    }
+
+    public void setAi_pvoltb(Integer ai_pvoltb) {
+        this.ai_pvoltb = ai_pvoltb;
+    }
+
+    public String getDi_wovt() {
+        return di_wovt;
+    }
+
+    public void setDi_wovt(String di_wovt) {
+        this.di_wovt = di_wovt;
+    }
+
+    public String getDi_run() {
+        return di_run;
+    }
+
+    public void setDi_run(String di_run) {
+        this.di_run = di_run;
+    }
+
+    public Integer getAi_comm_word() {
+        return ai_comm_word;
+    }
+
+    public void setAi_comm_word(Integer ai_comm_word) {
+        this.ai_comm_word = ai_comm_word;
+    }
+
+    public String getDi_hang() {
+        return di_hang;
+    }
+
+    public void setDi_hang(String di_hang) {
+        this.di_hang = di_hang;
+    }
+
+    public String getDi_sflagst() {
+        return di_sflagst;
+    }
+
+    public void setDi_sflagst(String di_sflagst) {
+        this.di_sflagst = di_sflagst;
+    }
+
+    public String getDo_sunablest() {
+        return do_sunablest;
+    }
+
+    public void setDo_sunablest(String do_sunablest) {
+        this.do_sunablest = do_sunablest;
+    }
+
+    public String getDi_pfvf() {
+        return di_pfvf;
+    }
+
+    public void setDi_pfvf(String di_pfvf) {
+        this.di_pfvf = di_pfvf;
+    }
+
+    public String getDo_hang() {
+        return do_hang;
+    }
+
+    public void setDo_hang(String do_hang) {
+        this.do_hang = do_hang;
+    }
+
+    public String getDo_sflagst() {
+        return do_sflagst;
+    }
+
+    public void setDo_sflagst(String do_sflagst) {
+        this.do_sflagst = do_sflagst;
+    }
+
+    public String getDo_nhang() {
+        return do_nhang;
+    }
+
+    public void setDo_nhang(String do_nhang) {
+        this.do_nhang = do_nhang;
+    }
+
+    public String getDo_srtrestst() {
+        return do_srtrestst;
+    }
+
+    public void setDo_srtrestst(String do_srtrestst) {
+        this.do_srtrestst = do_srtrestst;
+    }
+
+    public Integer getAo_kitm() {
+        return ao_kitm;
+    }
+
+    public void setAo_kitm(Integer ao_kitm) {
+        this.ao_kitm = ao_kitm;
+    }
+
+    public String getDi_lr() {
+        return di_lr;
+    }
+
+    public void setDi_lr(String di_lr) {
+        this.di_lr = di_lr;
+    }
+
+    public Integer getAi_pcurra() {
+        return ai_pcurra;
+    }
+
+    public void setAi_pcurra(Integer ai_pcurra) {
+        this.ai_pcurra = ai_pcurra;
+    }
+
+    public Integer getAi_pcurrc() {
+        return ai_pcurrc;
+    }
+
+    public void setAi_pcurrc(Integer ai_pcurrc) {
+        this.ai_pcurrc = ai_pcurrc;
+    }
+
+    public Integer getAi_pcurrb() {
+        return ai_pcurrb;
+    }
+
+    public void setAi_pcurrb(Integer ai_pcurrb) {
+        this.ai_pcurrb = ai_pcurrb;
+    }
+
+    @Override
+    public String toString() {
+        return "BasTef{" +
+                "di_movl='" + di_movl + '\'' +
+                ", ai_fltno=" + ai_fltno +
+                ", di_aflagst='" + di_aflagst + '\'' +
+                ", ai_windta=" + ai_windta +
+                ", ai_windtb=" + ai_windtb +
+                ", ai_windtc=" + ai_windtc +
+                ", ai_y_vibr=" + ai_y_vibr +
+                ", ao_fset=" + ao_fset +
+                ", ao_sptm=" + ao_sptm +
+                ", di_fail='" + di_fail + '\'' +
+                ", ai_fbak=" + ai_fbak +
+                ", di_vfflt='" + di_vfflt + '\'' +
+                ", di_senablest='" + di_senablest + '\'' +
+                ", di_aovt='" + di_aovt + '\'' +
+                ", di_vibr='" + di_vibr + '\'' +
+                ", ai_faxlet=" + ai_faxlet +
+                ", ai_x_vibr=" + ai_x_vibr +
+                ", di_frun='" + di_frun + '\'' +
+                ", ao_kptm=" + ao_kptm +
+                ", di_stp='" + di_stp + '\'' +
+                ", do_aflagst='" + do_aflagst + '\'' +
+                ", name='" + name + '\'' +
+                ", di_vrun='" + di_vrun + '\'' +
+                ", ai_raxlet=" + ai_raxlet +
+                ", ai_tacc=" + ai_tacc +
+                ", do_fres='" + do_fres + '\'' +
+                ", di_vfbas='" + di_vfbas + '\'' +
+                ", do_fst='" + do_fst + '\'' +
+                ", di_commokst='" + di_commokst + '\'' +
+                ", do_senablest='" + do_senablest + '\'' +
+                ", stime='" + stime + '\'' +
+                ", do_sfrestst='" + do_sfrestst + '\'' +
+                ", do_sp='" + do_sp + '\'' +
+                ", ai_pvoltc=" + ai_pvoltc +
+                ", do_st='" + do_st + '\'' +
+                ", ai_pvolta=" + ai_pvolta +
+                ", ai_pvoltb=" + ai_pvoltb +
+                ", di_wovt='" + di_wovt + '\'' +
+                ", di_run='" + di_run + '\'' +
+                ", ai_comm_word=" + ai_comm_word +
+                ", di_hang='" + di_hang + '\'' +
+                ", di_sflagst='" + di_sflagst + '\'' +
+                ", do_sunablest='" + do_sunablest + '\'' +
+                ", di_pfvf='" + di_pfvf + '\'' +
+                ", do_hang='" + do_hang + '\'' +
+                ", do_sflagst='" + do_sflagst + '\'' +
+                ", do_nhang='" + do_nhang + '\'' +
+                ", do_srtrestst='" + do_srtrestst + '\'' +
+                ", ao_kitm=" + ao_kitm +
+                ", di_lr='" + di_lr + '\'' +
+                ", ai_pcurra=" + ai_pcurra +
+                ", ai_pcurrc=" + ai_pcurrc +
+                ", ai_pcurrb=" + ai_pcurrb +
+                '}';
+    }
+}

+ 525 - 0
flink_metro/src/main/java/com/sunwin/metro/bean/train/BasTvf.java

@@ -0,0 +1,525 @@
+package com.sunwin.metro.bean.train;
+
+/**
+ * @program: sunwin_metro
+ * @description:
+ * @author: xuYJ
+ * @create: 2021-05-10 10_21
+ **/
+public class BasTvf {
+        private Integer ai_tacc;
+        private String do_fres;
+        private String do_firesp;
+        private String di_movl;
+        private Integer ai_fltno;
+        private String do_fst;
+        private String di_bypass;
+        private String di_commokst;
+        private String di_aflagst;
+        private String stime;
+        private String do_sp;
+        private String do_sfrestst;
+        private String di_wovl;
+        private Integer ai_pvoltc;
+        private Integer ai_pvolta;
+        private String do_firerst;
+        private Integer ai_pvoltb;
+        private Integer ai_windta;
+        private String do_firefst;
+        private Integer ai_windtb;
+        private Integer ai_windtc;
+        private Integer ai_y_vibr;
+        private String di_fail;
+        private String di_vfflt;
+        private String di_aovt;
+        private String di_sflagst;
+        private String di_hang;
+        private String di_vibr;
+        private String do_hang;
+        private String do_sflagst;
+        private String di_sfbas;
+        private Integer ai_faxlet;
+        private Integer ai_x_vibr;
+        private String di_frun;
+        private String di_stp;
+        private String do_aflagst;
+        private String do_nhang;
+        private String name;
+        private String do_srtrestst;
+        private String do_rst;
+        private String di_lr;
+        private Integer ai_pcurra;
+        private Integer ai_raxlet;
+        private Integer ai_pcurrc;
+        private Integer ai_pcurrb;
+        private String di_rrun;
+
+    public BasTvf(Integer ai_tacc, String do_fres, String do_firesp, String di_movl, Integer ai_fltno, String do_fst, String di_bypass, String di_commokst, String di_aflagst, String stime, String do_sp, String do_sfrestst, String di_wovl, Integer ai_pvoltc, Integer ai_pvolta, String do_firerst, Integer ai_pvoltb, Integer ai_windta, String do_firefst, Integer ai_windtb, Integer ai_windtc, Integer ai_y_vibr, String di_fail, String di_vfflt, String di_aovt, String di_sflagst, String di_hang, String di_vibr, String do_hang, String do_sflagst, String di_sfbas, Integer ai_faxlet, Integer ai_x_vibr, String di_frun, String di_stp, String do_aflagst, String do_nhang, String name, String do_srtrestst, String do_rst, String di_lr, Integer ai_pcurra, Integer ai_raxlet, Integer ai_pcurrc, Integer ai_pcurrb, String di_rrun) {
+        this.ai_tacc = ai_tacc;
+        this.do_fres = do_fres;
+        this.do_firesp = do_firesp;
+        this.di_movl = di_movl;
+        this.ai_fltno = ai_fltno;
+        this.do_fst = do_fst;
+        this.di_bypass = di_bypass;
+        this.di_commokst = di_commokst;
+        this.di_aflagst = di_aflagst;
+        this.stime = stime;
+        this.do_sp = do_sp;
+        this.do_sfrestst = do_sfrestst;
+        this.di_wovl = di_wovl;
+        this.ai_pvoltc = ai_pvoltc;
+        this.ai_pvolta = ai_pvolta;
+        this.do_firerst = do_firerst;
+        this.ai_pvoltb = ai_pvoltb;
+        this.ai_windta = ai_windta;
+        this.do_firefst = do_firefst;
+        this.ai_windtb = ai_windtb;
+        this.ai_windtc = ai_windtc;
+        this.ai_y_vibr = ai_y_vibr;
+        this.di_fail = di_fail;
+        this.di_vfflt = di_vfflt;
+        this.di_aovt = di_aovt;
+        this.di_sflagst = di_sflagst;
+        this.di_hang = di_hang;
+        this.di_vibr = di_vibr;
+        this.do_hang = do_hang;
+        this.do_sflagst = do_sflagst;
+        this.di_sfbas = di_sfbas;
+        this.ai_faxlet = ai_faxlet;
+        this.ai_x_vibr = ai_x_vibr;
+        this.di_frun = di_frun;
+        this.di_stp = di_stp;
+        this.do_aflagst = do_aflagst;
+        this.do_nhang = do_nhang;
+        this.name = name;
+        this.do_srtrestst = do_srtrestst;
+        this.do_rst = do_rst;
+        this.di_lr = di_lr;
+        this.ai_pcurra = ai_pcurra;
+        this.ai_raxlet = ai_raxlet;
+        this.ai_pcurrc = ai_pcurrc;
+        this.ai_pcurrb = ai_pcurrb;
+        this.di_rrun = di_rrun;
+    }
+
+    public Integer getAi_tacc() {
+        return ai_tacc;
+    }
+
+    public void setAi_tacc(Integer ai_tacc) {
+        this.ai_tacc = ai_tacc;
+    }
+
+    public String getDo_fres() {
+        return do_fres;
+    }
+
+    public void setDo_fres(String do_fres) {
+        this.do_fres = do_fres;
+    }
+
+    public String getDo_firesp() {
+        return do_firesp;
+    }
+
+    public void setDo_firesp(String do_firesp) {
+        this.do_firesp = do_firesp;
+    }
+
+    public String getDi_movl() {
+        return di_movl;
+    }
+
+    public void setDi_movl(String di_movl) {
+        this.di_movl = di_movl;
+    }
+
+    public Integer getAi_fltno() {
+        return ai_fltno;
+    }
+
+    public void setAi_fltno(Integer ai_fltno) {
+        this.ai_fltno = ai_fltno;
+    }
+
+    public String getDo_fst() {
+        return do_fst;
+    }
+
+    public void setDo_fst(String do_fst) {
+        this.do_fst = do_fst;
+    }
+
+    public String getDi_bypass() {
+        return di_bypass;
+    }
+
+    public void setDi_bypass(String di_bypass) {
+        this.di_bypass = di_bypass;
+    }
+
+    public String getDi_commokst() {
+        return di_commokst;
+    }
+
+    public void setDi_commokst(String di_commokst) {
+        this.di_commokst = di_commokst;
+    }
+
+    public String getDi_aflagst() {
+        return di_aflagst;
+    }
+
+    public void setDi_aflagst(String di_aflagst) {
+        this.di_aflagst = di_aflagst;
+    }
+
+    public String getStime() {
+        return stime;
+    }
+
+    public void setStime(String stime) {
+        this.stime = stime;
+    }
+
+    public String getDo_sp() {
+        return do_sp;
+    }
+
+    public void setDo_sp(String do_sp) {
+        this.do_sp = do_sp;
+    }
+
+    public String getDo_sfrestst() {
+        return do_sfrestst;
+    }
+
+    public void setDo_sfrestst(String do_sfrestst) {
+        this.do_sfrestst = do_sfrestst;
+    }
+
+    public String getDi_wovl() {
+        return di_wovl;
+    }
+
+    public void setDi_wovl(String di_wovl) {
+        this.di_wovl = di_wovl;
+    }
+
+    public Integer getAi_pvoltc() {
+        return ai_pvoltc;
+    }
+
+    public void setAi_pvoltc(Integer ai_pvoltc) {
+        this.ai_pvoltc = ai_pvoltc;
+    }
+
+    public Integer getAi_pvolta() {
+        return ai_pvolta;
+    }
+
+    public void setAi_pvolta(Integer ai_pvolta) {
+        this.ai_pvolta = ai_pvolta;
+    }
+
+    public String getDo_firerst() {
+        return do_firerst;
+    }
+
+    public void setDo_firerst(String do_firerst) {
+        this.do_firerst = do_firerst;
+    }
+
+    public Integer getAi_pvoltb() {
+        return ai_pvoltb;
+    }
+
+    public void setAi_pvoltb(Integer ai_pvoltb) {
+        this.ai_pvoltb = ai_pvoltb;
+    }
+
+    public Integer getAi_windta() {
+        return ai_windta;
+    }
+
+    public void setAi_windta(Integer ai_windta) {
+        this.ai_windta = ai_windta;
+    }
+
+    public String getDo_firefst() {
+        return do_firefst;
+    }
+
+    public void setDo_firefst(String do_firefst) {
+        this.do_firefst = do_firefst;
+    }
+
+    public Integer getAi_windtb() {
+        return ai_windtb;
+    }
+
+    public void setAi_windtb(Integer ai_windtb) {
+        this.ai_windtb = ai_windtb;
+    }
+
+    public Integer getAi_windtc() {
+        return ai_windtc;
+    }
+
+    public void setAi_windtc(Integer ai_windtc) {
+        this.ai_windtc = ai_windtc;
+    }
+
+    public Integer getAi_y_vibr() {
+        return ai_y_vibr;
+    }
+
+    public void setAi_y_vibr(Integer ai_y_vibr) {
+        this.ai_y_vibr = ai_y_vibr;
+    }
+
+    public String getDi_fail() {
+        return di_fail;
+    }
+
+    public void setDi_fail(String di_fail) {
+        this.di_fail = di_fail;
+    }
+
+    public String getDi_vfflt() {
+        return di_vfflt;
+    }
+
+    public void setDi_vfflt(String di_vfflt) {
+        this.di_vfflt = di_vfflt;
+    }
+
+    public String getDi_aovt() {
+        return di_aovt;
+    }
+
+    public void setDi_aovt(String di_aovt) {
+        this.di_aovt = di_aovt;
+    }
+
+    public String getDi_sflagst() {
+        return di_sflagst;
+    }
+
+    public void setDi_sflagst(String di_sflagst) {
+        this.di_sflagst = di_sflagst;
+    }
+
+    public String getDi_hang() {
+        return di_hang;
+    }
+
+    public void setDi_hang(String di_hang) {
+        this.di_hang = di_hang;
+    }
+
+    public String getDi_vibr() {
+        return di_vibr;
+    }
+
+    public void setDi_vibr(String di_vibr) {
+        this.di_vibr = di_vibr;
+    }
+
+    public String getDo_hang() {
+        return do_hang;
+    }
+
+    public void setDo_hang(String do_hang) {
+        this.do_hang = do_hang;
+    }
+
+    public String getDo_sflagst() {
+        return do_sflagst;
+    }
+
+    public void setDo_sflagst(String do_sflagst) {
+        this.do_sflagst = do_sflagst;
+    }
+
+    public String getDi_sfbas() {
+        return di_sfbas;
+    }
+
+    public void setDi_sfbas(String di_sfbas) {
+        this.di_sfbas = di_sfbas;
+    }
+
+    public Integer getAi_faxlet() {
+        return ai_faxlet;
+    }
+
+    public void setAi_faxlet(Integer ai_faxlet) {
+        this.ai_faxlet = ai_faxlet;
+    }
+
+    public Integer getAi_x_vibr() {
+        return ai_x_vibr;
+    }
+
+    public void setAi_x_vibr(Integer ai_x_vibr) {
+        this.ai_x_vibr = ai_x_vibr;
+    }
+
+    public String getDi_frun() {
+        return di_frun;
+    }
+
+    public void setDi_frun(String di_frun) {
+        this.di_frun = di_frun;
+    }
+
+    public String getDi_stp() {
+        return di_stp;
+    }
+
+    public void setDi_stp(String di_stp) {
+        this.di_stp = di_stp;
+    }
+
+    public String getDo_aflagst() {
+        return do_aflagst;
+    }
+
+    public void setDo_aflagst(String do_aflagst) {
+        this.do_aflagst = do_aflagst;
+    }
+
+    public String getDo_nhang() {
+        return do_nhang;
+    }
+
+    public void setDo_nhang(String do_nhang) {
+        this.do_nhang = do_nhang;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDo_srtrestst() {
+        return do_srtrestst;
+    }
+
+    public void setDo_srtrestst(String do_srtrestst) {
+        this.do_srtrestst = do_srtrestst;
+    }
+
+    public String getDo_rst() {
+        return do_rst;
+    }
+
+    public void setDo_rst(String do_rst) {
+        this.do_rst = do_rst;
+    }
+
+    public String getDi_lr() {
+        return di_lr;
+    }
+
+    public void setDi_lr(String di_lr) {
+        this.di_lr = di_lr;
+    }
+
+    public Integer getAi_pcurra() {
+        return ai_pcurra;
+    }
+
+    public void setAi_pcurra(Integer ai_pcurra) {
+        this.ai_pcurra = ai_pcurra;
+    }
+
+    public Integer getAi_raxlet() {
+        return ai_raxlet;
+    }
+
+    public void setAi_raxlet(Integer ai_raxlet) {
+        this.ai_raxlet = ai_raxlet;
+    }
+
+    public Integer getAi_pcurrc() {
+        return ai_pcurrc;
+    }
+
+    public void setAi_pcurrc(Integer ai_pcurrc) {
+        this.ai_pcurrc = ai_pcurrc;
+    }
+
+    public Integer getAi_pcurrb() {
+        return ai_pcurrb;
+    }
+
+    public void setAi_pcurrb(Integer ai_pcurrb) {
+        this.ai_pcurrb = ai_pcurrb;
+    }
+
+    public String getDi_rrun() {
+        return di_rrun;
+    }
+
+    public void setDi_rrun(String di_rrun) {
+        this.di_rrun = di_rrun;
+    }
+
+    @Override
+    public String toString() {
+        return "BasTvf{" +
+                "ai_tacc=" + ai_tacc +
+                ", do_fres='" + do_fres + '\'' +
+                ", do_firesp='" + do_firesp + '\'' +
+                ", di_movl='" + di_movl + '\'' +
+                ", ai_fltno=" + ai_fltno +
+                ", do_fst='" + do_fst + '\'' +
+                ", di_bypass='" + di_bypass + '\'' +
+                ", di_commokst='" + di_commokst + '\'' +
+                ", di_aflagst='" + di_aflagst + '\'' +
+                ", stime='" + stime + '\'' +
+                ", do_sp='" + do_sp + '\'' +
+                ", do_sfrestst='" + do_sfrestst + '\'' +
+                ", di_wovl='" + di_wovl + '\'' +
+                ", ai_pvoltc=" + ai_pvoltc +
+                ", ai_pvolta=" + ai_pvolta +
+                ", do_firerst='" + do_firerst + '\'' +
+                ", ai_pvoltb=" + ai_pvoltb +
+                ", ai_windta=" + ai_windta +
+                ", do_firefst='" + do_firefst + '\'' +
+                ", ai_windtb=" + ai_windtb +
+                ", ai_windtc=" + ai_windtc +
+                ", ai_y_vibr=" + ai_y_vibr +
+                ", di_fail='" + di_fail + '\'' +
+                ", di_vfflt='" + di_vfflt + '\'' +
+                ", di_aovt='" + di_aovt + '\'' +
+                ", di_sflagst='" + di_sflagst + '\'' +
+                ", di_hang='" + di_hang + '\'' +
+                ", di_vibr='" + di_vibr + '\'' +
+                ", do_hang='" + do_hang + '\'' +
+                ", do_sflagst='" + do_sflagst + '\'' +
+                ", di_sfbas='" + di_sfbas + '\'' +
+                ", ai_faxlet=" + ai_faxlet +
+                ", ai_x_vibr=" + ai_x_vibr +
+                ", di_frun='" + di_frun + '\'' +
+                ", di_stp='" + di_stp + '\'' +
+                ", do_aflagst='" + do_aflagst + '\'' +
+                ", do_nhang='" + do_nhang + '\'' +
+                ", name='" + name + '\'' +
+                ", do_srtrestst='" + do_srtrestst + '\'' +
+                ", do_rst='" + do_rst + '\'' +
+                ", di_lr='" + di_lr + '\'' +
+                ", ai_pcurra=" + ai_pcurra +
+                ", ai_raxlet=" + ai_raxlet +
+                ", ai_pcurrc=" + ai_pcurrc +
+                ", ai_pcurrb=" + ai_pcurrb +
+                ", di_rrun='" + di_rrun + '\'' +
+                '}';
+    }
+}

+ 455 - 0
flink_metro/src/main/java/com/sunwin/metro/bean/train/Ups.java

@@ -0,0 +1,455 @@
+package com.sunwin.metro.bean.train;
+
+import java.io.Serializable;
+
+/**
+ * @program_ sunwin_metro
+ * @description_ ups巡检仪
+ * @author_ xuYJ
+ * @create_ 2021-05-10 11_02
+ **/
+public class Ups implements Serializable {
+
+
+    private String stime;
+    private String name;
+    private String station;
+    private Integer ai_dp17;
+    private Integer ai_dp18;
+    private Integer ai_dp19;
+    private Integer ai_dp20;
+    private Integer ai_dp21;
+    private Integer ai_dp22;
+    private Integer ai_dp23;
+    private Integer ai_dp24;
+    private Integer ai_dp25;
+    private Integer ai_dp26;
+    private Integer ai_dp27;
+    private Integer ai_dp28;
+    private Integer ai_dp29;
+    private Integer ai_dp32;
+    private Integer ai_dp34;
+    private Integer ai_dp35;
+    private Integer ai_dp36;
+    private String di_dp17;
+    private String di_dp18;
+    private String di_dp19;
+    private String di_dp20;
+    private String di_dp21;
+    private String di_dp22;
+    private String di_dp23;
+    private String di_dp24;
+    private String di_dp25;
+    private String di_dp26;
+    private String di_dp27;
+    private String di_dp29;
+    private String di_dp30;
+    private String di_dp31;
+    private String di_dp32;
+    private String di_dp33;
+    private String di_dp34;
+    private String di_dp35;
+    private String di_dp36;
+
+    public Ups() {
+    }
+
+    public Ups(String stime, String name, String station, Integer ai_dp17, Integer ai_dp18, Integer ai_dp19, Integer ai_dp20, Integer ai_dp21, Integer ai_dp22, Integer ai_dp23, Integer ai_dp24, Integer ai_dp25, Integer ai_dp26, Integer ai_dp27, Integer ai_dp28, Integer ai_dp29, Integer ai_dp32, Integer ai_dp34, Integer ai_dp35, Integer ai_dp36, String di_dp17, String di_dp18, String di_dp19, String di_dp20, String di_dp21, String di_dp22, String di_dp23, String di_dp24, String di_dp25, String di_dp26, String di_dp27, String di_dp29, String di_dp30, String di_dp31, String di_dp32, String di_dp33, String di_dp34, String di_dp35, String di_dp36) {
+        this.stime = stime;
+        this.name = name;
+        this.station = station;
+        this.ai_dp17 = ai_dp17;
+        this.ai_dp18 = ai_dp18;
+        this.ai_dp19 = ai_dp19;
+        this.ai_dp20 = ai_dp20;
+        this.ai_dp21 = ai_dp21;
+        this.ai_dp22 = ai_dp22;
+        this.ai_dp23 = ai_dp23;
+        this.ai_dp24 = ai_dp24;
+        this.ai_dp25 = ai_dp25;
+        this.ai_dp26 = ai_dp26;
+        this.ai_dp27 = ai_dp27;
+        this.ai_dp28 = ai_dp28;
+        this.ai_dp29 = ai_dp29;
+        this.ai_dp32 = ai_dp32;
+        this.ai_dp34 = ai_dp34;
+        this.ai_dp35 = ai_dp35;
+        this.ai_dp36 = ai_dp36;
+        this.di_dp17 = di_dp17;
+        this.di_dp18 = di_dp18;
+        this.di_dp19 = di_dp19;
+        this.di_dp20 = di_dp20;
+        this.di_dp21 = di_dp21;
+        this.di_dp22 = di_dp22;
+        this.di_dp23 = di_dp23;
+        this.di_dp24 = di_dp24;
+        this.di_dp25 = di_dp25;
+        this.di_dp26 = di_dp26;
+        this.di_dp27 = di_dp27;
+        this.di_dp29 = di_dp29;
+        this.di_dp30 = di_dp30;
+        this.di_dp31 = di_dp31;
+        this.di_dp32 = di_dp32;
+        this.di_dp33 = di_dp33;
+        this.di_dp34 = di_dp34;
+        this.di_dp35 = di_dp35;
+        this.di_dp36 = di_dp36;
+    }
+
+    public String getStime() {
+        return stime;
+    }
+
+    public void setStime(String stime) {
+        this.stime = stime;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getStation() {
+        return station;
+    }
+
+    public void setStation(String station) {
+        this.station = station;
+    }
+
+    public Integer getAi_dp17() {
+        return ai_dp17;
+    }
+
+    public void setAi_dp17(Integer ai_dp17) {
+        this.ai_dp17 = ai_dp17;
+    }
+
+    public Integer getAi_dp18() {
+        return ai_dp18;
+    }
+
+    public void setAi_dp18(Integer ai_dp18) {
+        this.ai_dp18 = ai_dp18;
+    }
+
+    public Integer getAi_dp19() {
+        return ai_dp19;
+    }
+
+    public void setAi_dp19(Integer ai_dp19) {
+        this.ai_dp19 = ai_dp19;
+    }
+
+    public Integer getAi_dp20() {
+        return ai_dp20;
+    }
+
+    public void setAi_dp20(Integer ai_dp20) {
+        this.ai_dp20 = ai_dp20;
+    }
+
+    public Integer getAi_dp21() {
+        return ai_dp21;
+    }
+
+    public void setAi_dp21(Integer ai_dp21) {
+        this.ai_dp21 = ai_dp21;
+    }
+
+    public Integer getAi_dp22() {
+        return ai_dp22;
+    }
+
+    public void setAi_dp22(Integer ai_dp22) {
+        this.ai_dp22 = ai_dp22;
+    }
+
+    public Integer getAi_dp23() {
+        return ai_dp23;
+    }
+
+    public void setAi_dp23(Integer ai_dp23) {
+        this.ai_dp23 = ai_dp23;
+    }
+
+    public Integer getAi_dp24() {
+        return ai_dp24;
+    }
+
+    public void setAi_dp24(Integer ai_dp24) {
+        this.ai_dp24 = ai_dp24;
+    }
+
+    public Integer getAi_dp25() {
+        return ai_dp25;
+    }
+
+    public void setAi_dp25(Integer ai_dp25) {
+        this.ai_dp25 = ai_dp25;
+    }
+
+    public Integer getAi_dp26() {
+        return ai_dp26;
+    }
+
+    public void setAi_dp26(Integer ai_dp26) {
+        this.ai_dp26 = ai_dp26;
+    }
+
+    public Integer getAi_dp27() {
+        return ai_dp27;
+    }
+
+    public void setAi_dp27(Integer ai_dp27) {
+        this.ai_dp27 = ai_dp27;
+    }
+
+    public Integer getAi_dp28() {
+        return ai_dp28;
+    }
+
+    public void setAi_dp28(Integer ai_dp28) {
+        this.ai_dp28 = ai_dp28;
+    }
+
+    public Integer getAi_dp29() {
+        return ai_dp29;
+    }
+
+    public void setAi_dp29(Integer ai_dp29) {
+        this.ai_dp29 = ai_dp29;
+    }
+
+    public Integer getAi_dp32() {
+        return ai_dp32;
+    }
+
+    public void setAi_dp32(Integer ai_dp32) {
+        this.ai_dp32 = ai_dp32;
+    }
+
+    public Integer getAi_dp34() {
+        return ai_dp34;
+    }
+
+    public void setAi_dp34(Integer ai_dp34) {
+        this.ai_dp34 = ai_dp34;
+    }
+
+    public Integer getAi_dp35() {
+        return ai_dp35;
+    }
+
+    public void setAi_dp35(Integer ai_dp35) {
+        this.ai_dp35 = ai_dp35;
+    }
+
+    public Integer getAi_dp36() {
+        return ai_dp36;
+    }
+
+    public void setAi_dp36(Integer ai_dp36) {
+        this.ai_dp36 = ai_dp36;
+    }
+
+    public String getDi_dp17() {
+        return di_dp17;
+    }
+
+    public void setDi_dp17(String di_dp17) {
+        this.di_dp17 = di_dp17;
+    }
+
+    public String getDi_dp18() {
+        return di_dp18;
+    }
+
+    public void setDi_dp18(String di_dp18) {
+        this.di_dp18 = di_dp18;
+    }
+
+    public String getDi_dp19() {
+        return di_dp19;
+    }
+
+    public void setDi_dp19(String di_dp19) {
+        this.di_dp19 = di_dp19;
+    }
+
+    public String getDi_dp20() {
+        return di_dp20;
+    }
+
+    public void setDi_dp20(String di_dp20) {
+        this.di_dp20 = di_dp20;
+    }
+
+    public String getDi_dp21() {
+        return di_dp21;
+    }
+
+    public void setDi_dp21(String di_dp21) {
+        this.di_dp21 = di_dp21;
+    }
+
+    public String getDi_dp22() {
+        return di_dp22;
+    }
+
+    public void setDi_dp22(String di_dp22) {
+        this.di_dp22 = di_dp22;
+    }
+
+    public String getDi_dp23() {
+        return di_dp23;
+    }
+
+    public void setDi_dp23(String di_dp23) {
+        this.di_dp23 = di_dp23;
+    }
+
+    public String getDi_dp24() {
+        return di_dp24;
+    }
+
+    public void setDi_dp24(String di_dp24) {
+        this.di_dp24 = di_dp24;
+    }
+
+    public String getDi_dp25() {
+        return di_dp25;
+    }
+
+    public void setDi_dp25(String di_dp25) {
+        this.di_dp25 = di_dp25;
+    }
+
+    public String getDi_dp26() {
+        return di_dp26;
+    }
+
+    public void setDi_dp26(String di_dp26) {
+        this.di_dp26 = di_dp26;
+    }
+
+    public String getDi_dp27() {
+        return di_dp27;
+    }
+
+    public void setDi_dp27(String di_dp27) {
+        this.di_dp27 = di_dp27;
+    }
+
+    public String getDi_dp29() {
+        return di_dp29;
+    }
+
+    public void setDi_dp29(String di_dp29) {
+        this.di_dp29 = di_dp29;
+    }
+
+    public String getDi_dp30() {
+        return di_dp30;
+    }
+
+    public void setDi_dp30(String di_dp30) {
+        this.di_dp30 = di_dp30;
+    }
+
+    public String getDi_dp31() {
+        return di_dp31;
+    }
+
+    public void setDi_dp31(String di_dp31) {
+        this.di_dp31 = di_dp31;
+    }
+
+    public String getDi_dp32() {
+        return di_dp32;
+    }
+
+    public void setDi_dp32(String di_dp32) {
+        this.di_dp32 = di_dp32;
+    }
+
+    public String getDi_dp33() {
+        return di_dp33;
+    }
+
+    public void setDi_dp33(String di_dp33) {
+        this.di_dp33 = di_dp33;
+    }
+
+    public String getDi_dp34() {
+        return di_dp34;
+    }
+
+    public void setDi_dp34(String di_dp34) {
+        this.di_dp34 = di_dp34;
+    }
+
+    public String getDi_dp35() {
+        return di_dp35;
+    }
+
+    public void setDi_dp35(String di_dp35) {
+        this.di_dp35 = di_dp35;
+    }
+
+    public String getDi_dp36() {
+        return di_dp36;
+    }
+
+    public void setDi_dp36(String di_dp36) {
+        this.di_dp36 = di_dp36;
+    }
+
+    @Override
+    public String toString() {
+        return "Ups{" +
+                "stime='" + stime + '\'' +
+                ", name='" + name + '\'' +
+                ", station='" + station + '\'' +
+                ", ai_dp17=" + ai_dp17 +
+                ", ai_dp18=" + ai_dp18 +
+                ", ai_dp19=" + ai_dp19 +
+                ", ai_dp20=" + ai_dp20 +
+                ", ai_dp21=" + ai_dp21 +
+                ", ai_dp22=" + ai_dp22 +
+                ", ai_dp23=" + ai_dp23 +
+                ", ai_dp24=" + ai_dp24 +
+                ", ai_dp25=" + ai_dp25 +
+                ", ai_dp26=" + ai_dp26 +
+                ", ai_dp27=" + ai_dp27 +
+                ", ai_dp28=" + ai_dp28 +
+                ", ai_dp29=" + ai_dp29 +
+                ", ai_dp32=" + ai_dp32 +
+                ", ai_dp34=" + ai_dp34 +
+                ", ai_dp35=" + ai_dp35 +
+                ", ai_dp36=" + ai_dp36 +
+                ", di_dp17='" + di_dp17 + '\'' +
+                ", di_dp18='" + di_dp18 + '\'' +
+                ", di_dp19='" + di_dp19 + '\'' +
+                ", di_dp20='" + di_dp20 + '\'' +
+                ", di_dp21='" + di_dp21 + '\'' +
+                ", di_dp22='" + di_dp22 + '\'' +
+                ", di_dp23='" + di_dp23 + '\'' +
+                ", di_dp24='" + di_dp24 + '\'' +
+                ", di_dp25='" + di_dp25 + '\'' +
+                ", di_dp26='" + di_dp26 + '\'' +
+                ", di_dp27='" + di_dp27 + '\'' +
+                ", di_dp29='" + di_dp29 + '\'' +
+                ", di_dp30='" + di_dp30 + '\'' +
+                ", di_dp31='" + di_dp31 + '\'' +
+                ", di_dp32='" + di_dp32 + '\'' +
+                ", di_dp33='" + di_dp33 + '\'' +
+                ", di_dp34='" + di_dp34 + '\'' +
+                ", di_dp35='" + di_dp35 + '\'' +
+                ", di_dp36='" + di_dp36 + '\'' +
+                '}';
+    }
+}

+ 290 - 0
flink_metro/src/main/java/com/sunwin/metro/bean/train/UpsBas.java

@@ -0,0 +1,290 @@
+package com.sunwin.metro.bean.train;
+
+import java.io.Serializable;
+
+/**
+ * @program_ sunwin_metro
+ * @description_ 应急电源
+ * @author_ xuYJ
+ * @create_ 2021-05-10 11_02
+ **/
+public class UpsBas implements Serializable {
+
+    private String name;
+    private String station;
+    private String stime;
+    private Integer ai_bvp;
+    private Integer ai_op;
+    private Integer ai_iv;
+    private Integer ai_rov;
+    private Integer ai_ifv;
+    private Integer ai_ov;
+    private Integer ai_bv;
+    private Integer ai_temp;
+    private Integer ai_rofre;
+    private Integer ai_rbv;
+    private Integer ai_roc;
+    private Integer ai_ifre;
+    private String di_bvll;
+    private String di_sdactive;
+    private String di_upstype;
+    private String di_systesting;
+    private String di_commok;
+    private String di_upsfault;
+    private String di_upsmode;
+    private String di_voiceopen;
+    private String di_esfault;
+
+
+    public UpsBas() {
+    }
+
+    public UpsBas(String name, String station, String stime, Integer ai_bvp, Integer ai_op, Integer ai_iv, Integer ai_rov, Integer ai_ifv, Integer ai_ov, Integer ai_bv, Integer ai_temp, Integer ai_rofre, Integer ai_rbv, Integer ai_roc, Integer ai_ifre, String di_bvll, String di_sdactive, String di_upstype, String di_systesting, String di_commok, String di_upsfault, String di_upsmode, String di_voiceopen, String di_esfault) {
+        this.name = name;
+        this.station = station;
+        this.stime = stime;
+        this.ai_bvp = ai_bvp;
+        this.ai_op = ai_op;
+        this.ai_iv = ai_iv;
+        this.ai_rov = ai_rov;
+        this.ai_ifv = ai_ifv;
+        this.ai_ov = ai_ov;
+        this.ai_bv = ai_bv;
+        this.ai_temp = ai_temp;
+        this.ai_rofre = ai_rofre;
+        this.ai_rbv = ai_rbv;
+        this.ai_roc = ai_roc;
+        this.ai_ifre = ai_ifre;
+        this.di_bvll = di_bvll;
+        this.di_sdactive = di_sdactive;
+        this.di_upstype = di_upstype;
+        this.di_systesting = di_systesting;
+        this.di_commok = di_commok;
+        this.di_upsfault = di_upsfault;
+        this.di_upsmode = di_upsmode;
+        this.di_voiceopen = di_voiceopen;
+        this.di_esfault = di_esfault;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getStation() {
+        return station;
+    }
+
+    public void setStation(String station) {
+        this.station = station;
+    }
+
+    public String getStime() {
+        return stime;
+    }
+
+    public void setStime(String stime) {
+        this.stime = stime;
+    }
+
+    public Integer getAi_bvp() {
+        return ai_bvp;
+    }
+
+    public void setAi_bvp(Integer ai_bvp) {
+        this.ai_bvp = ai_bvp;
+    }
+
+    public Integer getAi_op() {
+        return ai_op;
+    }
+
+    public void setAi_op(Integer ai_op) {
+        this.ai_op = ai_op;
+    }
+
+    public Integer getAi_iv() {
+        return ai_iv;
+    }
+
+    public void setAi_iv(Integer ai_iv) {
+        this.ai_iv = ai_iv;
+    }
+
+    public Integer getAi_rov() {
+        return ai_rov;
+    }
+
+    public void setAi_rov(Integer ai_rov) {
+        this.ai_rov = ai_rov;
+    }
+
+    public Integer getAi_ifv() {
+        return ai_ifv;
+    }
+
+    public void setAi_ifv(Integer ai_ifv) {
+        this.ai_ifv = ai_ifv;
+    }
+
+    public Integer getAi_ov() {
+        return ai_ov;
+    }
+
+    public void setAi_ov(Integer ai_ov) {
+        this.ai_ov = ai_ov;
+    }
+
+    public Integer getAi_bv() {
+        return ai_bv;
+    }
+
+    public void setAi_bv(Integer ai_bv) {
+        this.ai_bv = ai_bv;
+    }
+
+    public Integer getAi_temp() {
+        return ai_temp;
+    }
+
+    public void setAi_temp(Integer ai_temp) {
+        this.ai_temp = ai_temp;
+    }
+
+    public Integer getAi_rofre() {
+        return ai_rofre;
+    }
+
+    public void setAi_rofre(Integer ai_rofre) {
+        this.ai_rofre = ai_rofre;
+    }
+
+    public Integer getAi_rbv() {
+        return ai_rbv;
+    }
+
+    public void setAi_rbv(Integer ai_rbv) {
+        this.ai_rbv = ai_rbv;
+    }
+
+    public Integer getAi_roc() {
+        return ai_roc;
+    }
+
+    public void setAi_roc(Integer ai_roc) {
+        this.ai_roc = ai_roc;
+    }
+
+    public Integer getAi_ifre() {
+        return ai_ifre;
+    }
+
+    public void setAi_ifre(Integer ai_ifre) {
+        this.ai_ifre = ai_ifre;
+    }
+
+    public String getDi_bvll() {
+        return di_bvll;
+    }
+
+    public void setDi_bvll(String di_bvll) {
+        this.di_bvll = di_bvll;
+    }
+
+    public String getDi_sdactive() {
+        return di_sdactive;
+    }
+
+    public void setDi_sdactive(String di_sdactive) {
+        this.di_sdactive = di_sdactive;
+    }
+
+    public String getDi_upstype() {
+        return di_upstype;
+    }
+
+    public void setDi_upstype(String di_upstype) {
+        this.di_upstype = di_upstype;
+    }
+
+    public String getDi_systesting() {
+        return di_systesting;
+    }
+
+    public void setDi_systesting(String di_systesting) {
+        this.di_systesting = di_systesting;
+    }
+
+    public String getDi_commok() {
+        return di_commok;
+    }
+
+    public void setDi_commok(String di_commok) {
+        this.di_commok = di_commok;
+    }
+
+    public String getDi_upsfault() {
+        return di_upsfault;
+    }
+
+    public void setDi_upsfault(String di_upsfault) {
+        this.di_upsfault = di_upsfault;
+    }
+
+    public String getDi_upsmode() {
+        return di_upsmode;
+    }
+
+    public void setDi_upsmode(String di_upsmode) {
+        this.di_upsmode = di_upsmode;
+    }
+
+    public String getDi_voiceopen() {
+        return di_voiceopen;
+    }
+
+    public void setDi_voiceopen(String di_voiceopen) {
+        this.di_voiceopen = di_voiceopen;
+    }
+
+    public String getDi_esfault() {
+        return di_esfault;
+    }
+
+    public void setDi_esfault(String di_esfault) {
+        this.di_esfault = di_esfault;
+    }
+
+    @Override
+    public String toString() {
+        return "UpsBas{" +
+                "name='" + name + '\'' +
+                ", station='" + station + '\'' +
+                ", stime='" + stime + '\'' +
+                ", ai_bvp=" + ai_bvp +
+                ", ai_op=" + ai_op +
+                ", ai_iv=" + ai_iv +
+                ", ai_rov=" + ai_rov +
+                ", ai_ifv=" + ai_ifv +
+                ", ai_ov=" + ai_ov +
+                ", ai_bv=" + ai_bv +
+                ", ai_temp=" + ai_temp +
+                ", ai_rofre=" + ai_rofre +
+                ", ai_rbv=" + ai_rbv +
+                ", ai_roc=" + ai_roc +
+                ", ai_ifre=" + ai_ifre +
+                ", di_bvll='" + di_bvll + '\'' +
+                ", di_sdactive='" + di_sdactive + '\'' +
+                ", di_upstype='" + di_upstype + '\'' +
+                ", di_systesting='" + di_systesting + '\'' +
+                ", di_commok='" + di_commok + '\'' +
+                ", di_upsfault='" + di_upsfault + '\'' +
+                ", di_upsmode='" + di_upsmode + '\'' +
+                ", di_voiceopen='" + di_voiceopen + '\'' +
+                ", di_esfault='" + di_esfault + '\'' +
+                '}';
+    }
+}

+ 1083 - 0
flink_metro/src/main/java/com/sunwin/metro/bean/train/UpsXjy.java

@@ -0,0 +1,1083 @@
+package com.sunwin.metro.bean.train;
+
+import java.io.Serializable;
+
+/**
+ * @program_ sunwin_metro
+ * @description_ ups巡检仪
+ * @author_ xuYJ
+ * @create_ 2021-05-10 11_02
+ **/
+public class UpsXjy implements Serializable {
+
+
+    private String stime;
+    private String name;
+    private String station;
+    private Integer ai_r1;
+    private Integer ai_r2;
+    private Integer ai_r3;
+    private Integer ai_r4;
+    private Integer ai_r5;
+    private Integer ai_r6;
+    private Integer ai_r7;
+    private Integer ai_r8;
+    private Integer ai_r9;
+    private Integer ai_r10;
+    private Integer ai_r11;
+    private Integer ai_r12;
+    private Integer ai_r13;
+    private Integer ai_r14;
+    private Integer ai_r15;
+    private Integer ai_r16;
+    private Integer ai_r17;
+    private Integer ai_r18;
+    private Integer ai_r19;
+    private Integer ai_r20;
+    private Integer ai_r21;
+    private Integer ai_r22;
+    private Integer ai_r23;
+    private Integer ai_r24;
+    private Integer ai_r25;
+    private Integer ai_r26;
+    private Integer ai_r27;
+    private Integer ai_r28;
+    private Integer ai_r29;
+    private Integer ai_r30;
+    private Integer ai_t1;
+    private Integer ai_t2;
+    private Integer ai_t3;
+    private Integer ai_t4;
+    private Integer ai_t5;
+    private Integer ai_t6;
+    private Integer ai_t7;
+    private Integer ai_t8;
+    private Integer ai_t9;
+    private Integer ai_t10;
+    private Integer ai_t11;
+    private Integer ai_t12;
+    private Integer ai_t13;
+    private Integer ai_t14;
+    private Integer ai_t15;
+    private Integer ai_t16;
+    private Integer ai_t17;
+    private Integer ai_t18;
+    private Integer ai_t19;
+    private Integer ai_t20;
+    private Integer ai_t21;
+    private Integer ai_t22;
+    private Integer ai_t23;
+    private Integer ai_t24;
+    private Integer ai_t25;
+    private Integer ai_t26;
+    private Integer ai_t27;
+    private Integer ai_t28;
+    private Integer ai_t29;
+    private Integer ai_t30;
+    private Integer ai_u1;
+    private Integer ai_u2;
+    private Integer ai_u3;
+    private Integer ai_u4;
+    private Integer ai_u5;
+    private Integer ai_u6;
+    private Integer ai_u7;
+    private Integer ai_u8;
+    private Integer ai_u9;
+    private Integer ai_u10;
+    private Integer ai_u11;
+    private Integer ai_u12;
+    private Integer ai_u13;
+    private Integer ai_u14;
+    private Integer ai_u15;
+    private Integer ai_u16;
+    private Integer ai_u17;
+    private Integer ai_u18;
+    private Integer ai_u19;
+    private Integer ai_u20;
+    private Integer ai_u21;
+    private Integer ai_u22;
+    private Integer ai_u23;
+    private Integer ai_u24;
+    private Integer ai_u25;
+    private Integer ai_u26;
+    private Integer ai_u27;
+    private Integer ai_u28;
+    private Integer ai_u29;
+    private Integer ai_u30;
+    private Integer ai_wd;
+    private Integer ai_zdl;
+    private Integer ai_zdy;
+
+
+    public UpsXjy() {
+    }
+
+    public UpsXjy(String stime, String name, String station, Integer ai_r1, Integer ai_r2, Integer ai_r3, Integer ai_r4, Integer ai_r5, Integer ai_r6, Integer ai_r7, Integer ai_r8, Integer ai_r9, Integer ai_r10, Integer ai_r11, Integer ai_r12, Integer ai_r13, Integer ai_r14, Integer ai_r15, Integer ai_r16, Integer ai_r17, Integer ai_r18, Integer ai_r19, Integer ai_r20, Integer ai_r21, Integer ai_r22, Integer ai_r23, Integer ai_r24, Integer ai_r25, Integer ai_r26, Integer ai_r27, Integer ai_r28, Integer ai_r29, Integer ai_r30, Integer ai_t1, Integer ai_t2, Integer ai_t3, Integer ai_t4, Integer ai_t5, Integer ai_t6, Integer ai_t7, Integer ai_t8, Integer ai_t9, Integer ai_t10, Integer ai_t11, Integer ai_t12, Integer ai_t13, Integer ai_t14, Integer ai_t15, Integer ai_t16, Integer ai_t17, Integer ai_t18, Integer ai_t19, Integer ai_t20, Integer ai_t21, Integer ai_t22, Integer ai_t23, Integer ai_t24, Integer ai_t25, Integer ai_t26, Integer ai_t27, Integer ai_t28, Integer ai_t29, Integer ai_t30, Integer ai_u1, Integer ai_u2, Integer ai_u3, Integer ai_u4, Integer ai_u5, Integer ai_u6, Integer ai_u7, Integer ai_u8, Integer ai_u9, Integer ai_u10, Integer ai_u11, Integer ai_u12, Integer ai_u13, Integer ai_u14, Integer ai_u15, Integer ai_u16, Integer ai_u17, Integer ai_u18, Integer ai_u19, Integer ai_u20, Integer ai_u21, Integer ai_u22, Integer ai_u23, Integer ai_u24, Integer ai_u25, Integer ai_u26, Integer ai_u27, Integer ai_u28, Integer ai_u29, Integer ai_u30, Integer ai_wd, Integer ai_zdl, Integer ai_zdy) {
+        this.stime = stime;
+        this.name = name;
+        this.station = station;
+        this.ai_r1 = ai_r1;
+        this.ai_r2 = ai_r2;
+        this.ai_r3 = ai_r3;
+        this.ai_r4 = ai_r4;
+        this.ai_r5 = ai_r5;
+        this.ai_r6 = ai_r6;
+        this.ai_r7 = ai_r7;
+        this.ai_r8 = ai_r8;
+        this.ai_r9 = ai_r9;
+        this.ai_r10 = ai_r10;
+        this.ai_r11 = ai_r11;
+        this.ai_r12 = ai_r12;
+        this.ai_r13 = ai_r13;
+        this.ai_r14 = ai_r14;
+        this.ai_r15 = ai_r15;
+        this.ai_r16 = ai_r16;
+        this.ai_r17 = ai_r17;
+        this.ai_r18 = ai_r18;
+        this.ai_r19 = ai_r19;
+        this.ai_r20 = ai_r20;
+        this.ai_r21 = ai_r21;
+        this.ai_r22 = ai_r22;
+        this.ai_r23 = ai_r23;
+        this.ai_r24 = ai_r24;
+        this.ai_r25 = ai_r25;
+        this.ai_r26 = ai_r26;
+        this.ai_r27 = ai_r27;
+        this.ai_r28 = ai_r28;
+        this.ai_r29 = ai_r29;
+        this.ai_r30 = ai_r30;
+        this.ai_t1 = ai_t1;
+        this.ai_t2 = ai_t2;
+        this.ai_t3 = ai_t3;
+        this.ai_t4 = ai_t4;
+        this.ai_t5 = ai_t5;
+        this.ai_t6 = ai_t6;
+        this.ai_t7 = ai_t7;
+        this.ai_t8 = ai_t8;
+        this.ai_t9 = ai_t9;
+        this.ai_t10 = ai_t10;
+        this.ai_t11 = ai_t11;
+        this.ai_t12 = ai_t12;
+        this.ai_t13 = ai_t13;
+        this.ai_t14 = ai_t14;
+        this.ai_t15 = ai_t15;
+        this.ai_t16 = ai_t16;
+        this.ai_t17 = ai_t17;
+        this.ai_t18 = ai_t18;
+        this.ai_t19 = ai_t19;
+        this.ai_t20 = ai_t20;
+        this.ai_t21 = ai_t21;
+        this.ai_t22 = ai_t22;
+        this.ai_t23 = ai_t23;
+        this.ai_t24 = ai_t24;
+        this.ai_t25 = ai_t25;
+        this.ai_t26 = ai_t26;
+        this.ai_t27 = ai_t27;
+        this.ai_t28 = ai_t28;
+        this.ai_t29 = ai_t29;
+        this.ai_t30 = ai_t30;
+        this.ai_u1 = ai_u1;
+        this.ai_u2 = ai_u2;
+        this.ai_u3 = ai_u3;
+        this.ai_u4 = ai_u4;
+        this.ai_u5 = ai_u5;
+        this.ai_u6 = ai_u6;
+        this.ai_u7 = ai_u7;
+        this.ai_u8 = ai_u8;
+        this.ai_u9 = ai_u9;
+        this.ai_u10 = ai_u10;
+        this.ai_u11 = ai_u11;
+        this.ai_u12 = ai_u12;
+        this.ai_u13 = ai_u13;
+        this.ai_u14 = ai_u14;
+        this.ai_u15 = ai_u15;
+        this.ai_u16 = ai_u16;
+        this.ai_u17 = ai_u17;
+        this.ai_u18 = ai_u18;
+        this.ai_u19 = ai_u19;
+        this.ai_u20 = ai_u20;
+        this.ai_u21 = ai_u21;
+        this.ai_u22 = ai_u22;
+        this.ai_u23 = ai_u23;
+        this.ai_u24 = ai_u24;
+        this.ai_u25 = ai_u25;
+        this.ai_u26 = ai_u26;
+        this.ai_u27 = ai_u27;
+        this.ai_u28 = ai_u28;
+        this.ai_u29 = ai_u29;
+        this.ai_u30 = ai_u30;
+        this.ai_wd = ai_wd;
+        this.ai_zdl = ai_zdl;
+        this.ai_zdy = ai_zdy;
+    }
+
+    public String getStime() {
+        return stime;
+    }
+
+    public void setStime(String stime) {
+        this.stime = stime;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getStation() {
+        return station;
+    }
+
+    public void setStation(String station) {
+        this.station = station;
+    }
+
+    public Integer getAi_r1() {
+        return ai_r1;
+    }
+
+    public void setAi_r1(Integer ai_r1) {
+        this.ai_r1 = ai_r1;
+    }
+
+    public Integer getAi_r2() {
+        return ai_r2;
+    }
+
+    public void setAi_r2(Integer ai_r2) {
+        this.ai_r2 = ai_r2;
+    }
+
+    public Integer getAi_r3() {
+        return ai_r3;
+    }
+
+    public void setAi_r3(Integer ai_r3) {
+        this.ai_r3 = ai_r3;
+    }
+
+    public Integer getAi_r4() {
+        return ai_r4;
+    }
+
+    public void setAi_r4(Integer ai_r4) {
+        this.ai_r4 = ai_r4;
+    }
+
+    public Integer getAi_r5() {
+        return ai_r5;
+    }
+
+    public void setAi_r5(Integer ai_r5) {
+        this.ai_r5 = ai_r5;
+    }
+
+    public Integer getAi_r6() {
+        return ai_r6;
+    }
+
+    public void setAi_r6(Integer ai_r6) {
+        this.ai_r6 = ai_r6;
+    }
+
+    public Integer getAi_r7() {
+        return ai_r7;
+    }
+
+    public void setAi_r7(Integer ai_r7) {
+        this.ai_r7 = ai_r7;
+    }
+
+    public Integer getAi_r8() {
+        return ai_r8;
+    }
+
+    public void setAi_r8(Integer ai_r8) {
+        this.ai_r8 = ai_r8;
+    }
+
+    public Integer getAi_r9() {
+        return ai_r9;
+    }
+
+    public void setAi_r9(Integer ai_r9) {
+        this.ai_r9 = ai_r9;
+    }
+
+    public Integer getAi_r10() {
+        return ai_r10;
+    }
+
+    public void setAi_r10(Integer ai_r10) {
+        this.ai_r10 = ai_r10;
+    }
+
+    public Integer getAi_r11() {
+        return ai_r11;
+    }
+
+    public void setAi_r11(Integer ai_r11) {
+        this.ai_r11 = ai_r11;
+    }
+
+    public Integer getAi_r12() {
+        return ai_r12;
+    }
+
+    public void setAi_r12(Integer ai_r12) {
+        this.ai_r12 = ai_r12;
+    }
+
+    public Integer getAi_r13() {
+        return ai_r13;
+    }
+
+    public void setAi_r13(Integer ai_r13) {
+        this.ai_r13 = ai_r13;
+    }
+
+    public Integer getAi_r14() {
+        return ai_r14;
+    }
+
+    public void setAi_r14(Integer ai_r14) {
+        this.ai_r14 = ai_r14;
+    }
+
+    public Integer getAi_r15() {
+        return ai_r15;
+    }
+
+    public void setAi_r15(Integer ai_r15) {
+        this.ai_r15 = ai_r15;
+    }
+
+    public Integer getAi_r16() {
+        return ai_r16;
+    }
+
+    public void setAi_r16(Integer ai_r16) {
+        this.ai_r16 = ai_r16;
+    }
+
+    public Integer getAi_r17() {
+        return ai_r17;
+    }
+
+    public void setAi_r17(Integer ai_r17) {
+        this.ai_r17 = ai_r17;
+    }
+
+    public Integer getAi_r18() {
+        return ai_r18;
+    }
+
+    public void setAi_r18(Integer ai_r18) {
+        this.ai_r18 = ai_r18;
+    }
+
+    public Integer getAi_r19() {
+        return ai_r19;
+    }
+
+    public void setAi_r19(Integer ai_r19) {
+        this.ai_r19 = ai_r19;
+    }
+
+    public Integer getAi_r20() {
+        return ai_r20;
+    }
+
+    public void setAi_r20(Integer ai_r20) {
+        this.ai_r20 = ai_r20;
+    }
+
+    public Integer getAi_r21() {
+        return ai_r21;
+    }
+
+    public void setAi_r21(Integer ai_r21) {
+        this.ai_r21 = ai_r21;
+    }
+
+    public Integer getAi_r22() {
+        return ai_r22;
+    }
+
+    public void setAi_r22(Integer ai_r22) {
+        this.ai_r22 = ai_r22;
+    }
+
+    public Integer getAi_r23() {
+        return ai_r23;
+    }
+
+    public void setAi_r23(Integer ai_r23) {
+        this.ai_r23 = ai_r23;
+    }
+
+    public Integer getAi_r24() {
+        return ai_r24;
+    }
+
+    public void setAi_r24(Integer ai_r24) {
+        this.ai_r24 = ai_r24;
+    }
+
+    public Integer getAi_r25() {
+        return ai_r25;
+    }
+
+    public void setAi_r25(Integer ai_r25) {
+        this.ai_r25 = ai_r25;
+    }
+
+    public Integer getAi_r26() {
+        return ai_r26;
+    }
+
+    public void setAi_r26(Integer ai_r26) {
+        this.ai_r26 = ai_r26;
+    }
+
+    public Integer getAi_r27() {
+        return ai_r27;
+    }
+
+    public void setAi_r27(Integer ai_r27) {
+        this.ai_r27 = ai_r27;
+    }
+
+    public Integer getAi_r28() {
+        return ai_r28;
+    }
+
+    public void setAi_r28(Integer ai_r28) {
+        this.ai_r28 = ai_r28;
+    }
+
+    public Integer getAi_r29() {
+        return ai_r29;
+    }
+
+    public void setAi_r29(Integer ai_r29) {
+        this.ai_r29 = ai_r29;
+    }
+
+    public Integer getAi_r30() {
+        return ai_r30;
+    }
+
+    public void setAi_r30(Integer ai_r30) {
+        this.ai_r30 = ai_r30;
+    }
+
+    public Integer getAi_t1() {
+        return ai_t1;
+    }
+
+    public void setAi_t1(Integer ai_t1) {
+        this.ai_t1 = ai_t1;
+    }
+
+    public Integer getAi_t2() {
+        return ai_t2;
+    }
+
+    public void setAi_t2(Integer ai_t2) {
+        this.ai_t2 = ai_t2;
+    }
+
+    public Integer getAi_t3() {
+        return ai_t3;
+    }
+
+    public void setAi_t3(Integer ai_t3) {
+        this.ai_t3 = ai_t3;
+    }
+
+    public Integer getAi_t4() {
+        return ai_t4;
+    }
+
+    public void setAi_t4(Integer ai_t4) {
+        this.ai_t4 = ai_t4;
+    }
+
+    public Integer getAi_t5() {
+        return ai_t5;
+    }
+
+    public void setAi_t5(Integer ai_t5) {
+        this.ai_t5 = ai_t5;
+    }
+
+    public Integer getAi_t6() {
+        return ai_t6;
+    }
+
+    public void setAi_t6(Integer ai_t6) {
+        this.ai_t6 = ai_t6;
+    }
+
+    public Integer getAi_t7() {
+        return ai_t7;
+    }
+
+    public void setAi_t7(Integer ai_t7) {
+        this.ai_t7 = ai_t7;
+    }
+
+    public Integer getAi_t8() {
+        return ai_t8;
+    }
+
+    public void setAi_t8(Integer ai_t8) {
+        this.ai_t8 = ai_t8;
+    }
+
+    public Integer getAi_t9() {
+        return ai_t9;
+    }
+
+    public void setAi_t9(Integer ai_t9) {
+        this.ai_t9 = ai_t9;
+    }
+
+    public Integer getAi_t10() {
+        return ai_t10;
+    }
+
+    public void setAi_t10(Integer ai_t10) {
+        this.ai_t10 = ai_t10;
+    }
+
+    public Integer getAi_t11() {
+        return ai_t11;
+    }
+
+    public void setAi_t11(Integer ai_t11) {
+        this.ai_t11 = ai_t11;
+    }
+
+    public Integer getAi_t12() {
+        return ai_t12;
+    }
+
+    public void setAi_t12(Integer ai_t12) {
+        this.ai_t12 = ai_t12;
+    }
+
+    public Integer getAi_t13() {
+        return ai_t13;
+    }
+
+    public void setAi_t13(Integer ai_t13) {
+        this.ai_t13 = ai_t13;
+    }
+
+    public Integer getAi_t14() {
+        return ai_t14;
+    }
+
+    public void setAi_t14(Integer ai_t14) {
+        this.ai_t14 = ai_t14;
+    }
+
+    public Integer getAi_t15() {
+        return ai_t15;
+    }
+
+    public void setAi_t15(Integer ai_t15) {
+        this.ai_t15 = ai_t15;
+    }
+
+    public Integer getAi_t16() {
+        return ai_t16;
+    }
+
+    public void setAi_t16(Integer ai_t16) {
+        this.ai_t16 = ai_t16;
+    }
+
+    public Integer getAi_t17() {
+        return ai_t17;
+    }
+
+    public void setAi_t17(Integer ai_t17) {
+        this.ai_t17 = ai_t17;
+    }
+
+    public Integer getAi_t18() {
+        return ai_t18;
+    }
+
+    public void setAi_t18(Integer ai_t18) {
+        this.ai_t18 = ai_t18;
+    }
+
+    public Integer getAi_t19() {
+        return ai_t19;
+    }
+
+    public void setAi_t19(Integer ai_t19) {
+        this.ai_t19 = ai_t19;
+    }
+
+    public Integer getAi_t20() {
+        return ai_t20;
+    }
+
+    public void setAi_t20(Integer ai_t20) {
+        this.ai_t20 = ai_t20;
+    }
+
+    public Integer getAi_t21() {
+        return ai_t21;
+    }
+
+    public void setAi_t21(Integer ai_t21) {
+        this.ai_t21 = ai_t21;
+    }
+
+    public Integer getAi_t22() {
+        return ai_t22;
+    }
+
+    public void setAi_t22(Integer ai_t22) {
+        this.ai_t22 = ai_t22;
+    }
+
+    public Integer getAi_t23() {
+        return ai_t23;
+    }
+
+    public void setAi_t23(Integer ai_t23) {
+        this.ai_t23 = ai_t23;
+    }
+
+    public Integer getAi_t24() {
+        return ai_t24;
+    }
+
+    public void setAi_t24(Integer ai_t24) {
+        this.ai_t24 = ai_t24;
+    }
+
+    public Integer getAi_t25() {
+        return ai_t25;
+    }
+
+    public void setAi_t25(Integer ai_t25) {
+        this.ai_t25 = ai_t25;
+    }
+
+    public Integer getAi_t26() {
+        return ai_t26;
+    }
+
+    public void setAi_t26(Integer ai_t26) {
+        this.ai_t26 = ai_t26;
+    }
+
+    public Integer getAi_t27() {
+        return ai_t27;
+    }
+
+    public void setAi_t27(Integer ai_t27) {
+        this.ai_t27 = ai_t27;
+    }
+
+    public Integer getAi_t28() {
+        return ai_t28;
+    }
+
+    public void setAi_t28(Integer ai_t28) {
+        this.ai_t28 = ai_t28;
+    }
+
+    public Integer getAi_t29() {
+        return ai_t29;
+    }
+
+    public void setAi_t29(Integer ai_t29) {
+        this.ai_t29 = ai_t29;
+    }
+
+    public Integer getAi_t30() {
+        return ai_t30;
+    }
+
+    public void setAi_t30(Integer ai_t30) {
+        this.ai_t30 = ai_t30;
+    }
+
+    public Integer getAi_u1() {
+        return ai_u1;
+    }
+
+    public void setAi_u1(Integer ai_u1) {
+        this.ai_u1 = ai_u1;
+    }
+
+    public Integer getAi_u2() {
+        return ai_u2;
+    }
+
+    public void setAi_u2(Integer ai_u2) {
+        this.ai_u2 = ai_u2;
+    }
+
+    public Integer getAi_u3() {
+        return ai_u3;
+    }
+
+    public void setAi_u3(Integer ai_u3) {
+        this.ai_u3 = ai_u3;
+    }
+
+    public Integer getAi_u4() {
+        return ai_u4;
+    }
+
+    public void setAi_u4(Integer ai_u4) {
+        this.ai_u4 = ai_u4;
+    }
+
+    public Integer getAi_u5() {
+        return ai_u5;
+    }
+
+    public void setAi_u5(Integer ai_u5) {
+        this.ai_u5 = ai_u5;
+    }
+
+    public Integer getAi_u6() {
+        return ai_u6;
+    }
+
+    public void setAi_u6(Integer ai_u6) {
+        this.ai_u6 = ai_u6;
+    }
+
+    public Integer getAi_u7() {
+        return ai_u7;
+    }
+
+    public void setAi_u7(Integer ai_u7) {
+        this.ai_u7 = ai_u7;
+    }
+
+    public Integer getAi_u8() {
+        return ai_u8;
+    }
+
+    public void setAi_u8(Integer ai_u8) {
+        this.ai_u8 = ai_u8;
+    }
+
+    public Integer getAi_u9() {
+        return ai_u9;
+    }
+
+    public void setAi_u9(Integer ai_u9) {
+        this.ai_u9 = ai_u9;
+    }
+
+    public Integer getAi_u10() {
+        return ai_u10;
+    }
+
+    public void setAi_u10(Integer ai_u10) {
+        this.ai_u10 = ai_u10;
+    }
+
+    public Integer getAi_u11() {
+        return ai_u11;
+    }
+
+    public void setAi_u11(Integer ai_u11) {
+        this.ai_u11 = ai_u11;
+    }
+
+    public Integer getAi_u12() {
+        return ai_u12;
+    }
+
+    public void setAi_u12(Integer ai_u12) {
+        this.ai_u12 = ai_u12;
+    }
+
+    public Integer getAi_u13() {
+        return ai_u13;
+    }
+
+    public void setAi_u13(Integer ai_u13) {
+        this.ai_u13 = ai_u13;
+    }
+
+    public Integer getAi_u14() {
+        return ai_u14;
+    }
+
+    public void setAi_u14(Integer ai_u14) {
+        this.ai_u14 = ai_u14;
+    }
+
+    public Integer getAi_u15() {
+        return ai_u15;
+    }
+
+    public void setAi_u15(Integer ai_u15) {
+        this.ai_u15 = ai_u15;
+    }
+
+    public Integer getAi_u16() {
+        return ai_u16;
+    }
+
+    public void setAi_u16(Integer ai_u16) {
+        this.ai_u16 = ai_u16;
+    }
+
+    public Integer getAi_u17() {
+        return ai_u17;
+    }
+
+    public void setAi_u17(Integer ai_u17) {
+        this.ai_u17 = ai_u17;
+    }
+
+    public Integer getAi_u18() {
+        return ai_u18;
+    }
+
+    public void setAi_u18(Integer ai_u18) {
+        this.ai_u18 = ai_u18;
+    }
+
+    public Integer getAi_u19() {
+        return ai_u19;
+    }
+
+    public void setAi_u19(Integer ai_u19) {
+        this.ai_u19 = ai_u19;
+    }
+
+    public Integer getAi_u20() {
+        return ai_u20;
+    }
+
+    public void setAi_u20(Integer ai_u20) {
+        this.ai_u20 = ai_u20;
+    }
+
+    public Integer getAi_u21() {
+        return ai_u21;
+    }
+
+    public void setAi_u21(Integer ai_u21) {
+        this.ai_u21 = ai_u21;
+    }
+
+    public Integer getAi_u22() {
+        return ai_u22;
+    }
+
+    public void setAi_u22(Integer ai_u22) {
+        this.ai_u22 = ai_u22;
+    }
+
+    public Integer getAi_u23() {
+        return ai_u23;
+    }
+
+    public void setAi_u23(Integer ai_u23) {
+        this.ai_u23 = ai_u23;
+    }
+
+    public Integer getAi_u24() {
+        return ai_u24;
+    }
+
+    public void setAi_u24(Integer ai_u24) {
+        this.ai_u24 = ai_u24;
+    }
+
+    public Integer getAi_u25() {
+        return ai_u25;
+    }
+
+    public void setAi_u25(Integer ai_u25) {
+        this.ai_u25 = ai_u25;
+    }
+
+    public Integer getAi_u26() {
+        return ai_u26;
+    }
+
+    public void setAi_u26(Integer ai_u26) {
+        this.ai_u26 = ai_u26;
+    }
+
+    public Integer getAi_u27() {
+        return ai_u27;
+    }
+
+    public void setAi_u27(Integer ai_u27) {
+        this.ai_u27 = ai_u27;
+    }
+
+    public Integer getAi_u28() {
+        return ai_u28;
+    }
+
+    public void setAi_u28(Integer ai_u28) {
+        this.ai_u28 = ai_u28;
+    }
+
+    public Integer getAi_u29() {
+        return ai_u29;
+    }
+
+    public void setAi_u29(Integer ai_u29) {
+        this.ai_u29 = ai_u29;
+    }
+
+    public Integer getAi_u30() {
+        return ai_u30;
+    }
+
+    public void setAi_u30(Integer ai_u30) {
+        this.ai_u30 = ai_u30;
+    }
+
+    public Integer getAi_wd() {
+        return ai_wd;
+    }
+
+    public void setAi_wd(Integer ai_wd) {
+        this.ai_wd = ai_wd;
+    }
+
+    public Integer getAi_zdl() {
+        return ai_zdl;
+    }
+
+    public void setAi_zdl(Integer ai_zdl) {
+        this.ai_zdl = ai_zdl;
+    }
+
+    public Integer getAi_zdy() {
+        return ai_zdy;
+    }
+
+    public void setAi_zdy(Integer ai_zdy) {
+        this.ai_zdy = ai_zdy;
+    }
+
+    @Override
+    public String toString() {
+        return "UpsXjy{" +
+                "stime='" + stime + '\'' +
+                ", name='" + name + '\'' +
+                ", station='" + station + '\'' +
+                ", ai_r1=" + ai_r1 +
+                ", ai_r2=" + ai_r2 +
+                ", ai_r3=" + ai_r3 +
+                ", ai_r4=" + ai_r4 +
+                ", ai_r5=" + ai_r5 +
+                ", ai_r6=" + ai_r6 +
+                ", ai_r7=" + ai_r7 +
+                ", ai_r8=" + ai_r8 +
+                ", ai_r9=" + ai_r9 +
+                ", ai_r10=" + ai_r10 +
+                ", ai_r11=" + ai_r11 +
+                ", ai_r12=" + ai_r12 +
+                ", ai_r13=" + ai_r13 +
+                ", ai_r14=" + ai_r14 +
+                ", ai_r15=" + ai_r15 +
+                ", ai_r16=" + ai_r16 +
+                ", ai_r17=" + ai_r17 +
+                ", ai_r18=" + ai_r18 +
+                ", ai_r19=" + ai_r19 +
+                ", ai_r20=" + ai_r20 +
+                ", ai_r21=" + ai_r21 +
+                ", ai_r22=" + ai_r22 +
+                ", ai_r23=" + ai_r23 +
+                ", ai_r24=" + ai_r24 +
+                ", ai_r25=" + ai_r25 +
+                ", ai_r26=" + ai_r26 +
+                ", ai_r27=" + ai_r27 +
+                ", ai_r28=" + ai_r28 +
+                ", ai_r29=" + ai_r29 +
+                ", ai_r30=" + ai_r30 +
+                ", ai_t1=" + ai_t1 +
+                ", ai_t2=" + ai_t2 +
+                ", ai_t3=" + ai_t3 +
+                ", ai_t4=" + ai_t4 +
+                ", ai_t5=" + ai_t5 +
+                ", ai_t6=" + ai_t6 +
+                ", ai_t7=" + ai_t7 +
+                ", ai_t8=" + ai_t8 +
+                ", ai_t9=" + ai_t9 +
+                ", ai_t10=" + ai_t10 +
+                ", ai_t11=" + ai_t11 +
+                ", ai_t12=" + ai_t12 +
+                ", ai_t13=" + ai_t13 +
+                ", ai_t14=" + ai_t14 +
+                ", ai_t15=" + ai_t15 +
+                ", ai_t16=" + ai_t16 +
+                ", ai_t17=" + ai_t17 +
+                ", ai_t18=" + ai_t18 +
+                ", ai_t19=" + ai_t19 +
+                ", ai_t20=" + ai_t20 +
+                ", ai_t21=" + ai_t21 +
+                ", ai_t22=" + ai_t22 +
+                ", ai_t23=" + ai_t23 +
+                ", ai_t24=" + ai_t24 +
+                ", ai_t25=" + ai_t25 +
+                ", ai_t26=" + ai_t26 +
+                ", ai_t27=" + ai_t27 +
+                ", ai_t28=" + ai_t28 +
+                ", ai_t29=" + ai_t29 +
+                ", ai_t30=" + ai_t30 +
+                ", ai_u1=" + ai_u1 +
+                ", ai_u2=" + ai_u2 +
+                ", ai_u3=" + ai_u3 +
+                ", ai_u4=" + ai_u4 +
+                ", ai_u5=" + ai_u5 +
+                ", ai_u6=" + ai_u6 +
+                ", ai_u7=" + ai_u7 +
+                ", ai_u8=" + ai_u8 +
+                ", ai_u9=" + ai_u9 +
+                ", ai_u10=" + ai_u10 +
+                ", ai_u11=" + ai_u11 +
+                ", ai_u12=" + ai_u12 +
+                ", ai_u13=" + ai_u13 +
+                ", ai_u14=" + ai_u14 +
+                ", ai_u15=" + ai_u15 +
+                ", ai_u16=" + ai_u16 +
+                ", ai_u17=" + ai_u17 +
+                ", ai_u18=" + ai_u18 +
+                ", ai_u19=" + ai_u19 +
+                ", ai_u20=" + ai_u20 +
+                ", ai_u21=" + ai_u21 +
+                ", ai_u22=" + ai_u22 +
+                ", ai_u23=" + ai_u23 +
+                ", ai_u24=" + ai_u24 +
+                ", ai_u25=" + ai_u25 +
+                ", ai_u26=" + ai_u26 +
+                ", ai_u27=" + ai_u27 +
+                ", ai_u28=" + ai_u28 +
+                ", ai_u29=" + ai_u29 +
+                ", ai_u30=" + ai_u30 +
+                ", ai_wd=" + ai_wd +
+                ", ai_zdl=" + ai_zdl +
+                ", ai_zdy=" + ai_zdy +
+                '}';
+    }
+}

+ 65 - 0
flink_metro/src/main/java/com/sunwin/metro/config/ConfigFileHandler.java

@@ -0,0 +1,65 @@
+package com.sunwin.metro.config;
+
+import java.util.ResourceBundle;
+
+/**
+ * @author xuYJ
+ * @description: 配置文件类
+ * @create: 2020-08-26 14:10
+ */
+public class ConfigFileHandler {
+
+    private static final ResourceBundle RESOURCE = ResourceBundle.getBundle("metro");
+
+
+    public static String getKafkaAddress() {
+        return RESOURCE.getString("kafkaAddress5");
+    }
+
+
+    public static String getCheckPoint() {
+        return RESOURCE.getString("checkPoint5");
+    }
+
+
+    public static String getMetroTopicName() {
+        return RESOURCE.getString("metroTopicName");
+    }
+
+
+    public static String getMetroId() { return RESOURCE.getString("metro.groupId"); }
+
+
+    public static String getMysqlUrl() {
+        return RESOURCE.getString("DB_URL");
+    }
+
+    public static String getMysqlUserName() {
+        return RESOURCE.getString("USER_NAME");
+    }
+
+
+    public static String getMysqlPassWord() {
+        return RESOURCE.getString("PASSWROD");
+    }
+
+
+    public static String getZookeeperHost() {
+        return RESOURCE.getString("zookeeper_host");
+    }
+
+
+    public static String getRuleName() {
+        return RESOURCE.getString("rule.namespace");
+    }
+
+
+    public static String getRulePath() {
+        return RESOURCE.getString("rule.param.path");
+    }
+
+    public static String getAppName() {
+        return RESOURCE.getString("app_name");
+    }
+
+}

+ 32 - 0
flink_metro/src/main/java/com/sunwin/metro/consumer/CustomKafkaDeserializationSchema.java

@@ -0,0 +1,32 @@
+package com.sunwin.metro.consumer;
+
+import org.apache.flink.api.common.typeinfo.BasicTypeInfo;
+import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.api.java.typeutils.TupleTypeInfo;
+import org.apache.flink.streaming.connectors.kafka.KafkaDeserializationSchema;
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * @author xuYJ
+ * @description: kafka定义约束
+ * @create: 2020-08-26 14:10
+ */
+public class CustomKafkaDeserializationSchema implements KafkaDeserializationSchema<Tuple4<String, Integer, Long, String>> {
+    @Override
+    public boolean isEndOfStream(Tuple4<String, Integer, Long, String> nextElement) {
+        return false;
+    }
+
+    @Override
+    public Tuple4<String, Integer, Long, String> deserialize(ConsumerRecord<byte[], byte[]> record) throws Exception {
+        return new Tuple4<>(record.topic(), record.partition(), record.offset(), new String(record.value(), StandardCharsets.UTF_8));
+    }
+
+    @Override
+    public TypeInformation<Tuple4<String, Integer, Long, String>> getProducedType() {
+        return new TupleTypeInfo<>(BasicTypeInfo.STRING_TYPE_INFO, BasicTypeInfo.INT_TYPE_INFO, BasicTypeInfo.LONG_TYPE_INFO, BasicTypeInfo.STRING_TYPE_INFO);
+    }
+}

+ 22 - 0
flink_metro/src/main/java/com/sunwin/metro/consumer/TopicConsumer.java

@@ -0,0 +1,22 @@
+package com.sunwin.metro.consumer;
+
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.streaming.api.datastream.DataStreamSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+
+/**
+ * @author xuYJ
+ * @description: 用于kafka数据消费的接口
+ * @create: 2020-08-26 14:10
+ */
+public interface TopicConsumer extends Serializable {
+
+    Logger logger = LoggerFactory.getLogger(TopicConsumer.class);
+
+    void process(DataStreamSource<Tuple4<String, Integer, Long, String>> input);
+
+}
+

+ 23 - 0
flink_metro/src/main/java/com/sunwin/metro/consumer/TopicKeyWordsConsumer.java

@@ -0,0 +1,23 @@
+package com.sunwin.metro.consumer;
+
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.streaming.api.datastream.DataStreamSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+
+/**
+ * @author xuYJ
+ * @description: 用于kafka数据消费的接口
+ * @create: 2020-08-26 14:10
+ * ,BroadcastStream<Map<String, List<String>>> broadcast
+ */
+public interface TopicKeyWordsConsumer extends Serializable {
+
+    Logger logger = LoggerFactory.getLogger(TopicKeyWordsConsumer.class);
+
+    void process(DataStreamSource<Tuple4<String, Integer, Long, String>> input);
+    
+}
+

+ 17 - 0
flink_metro/src/main/java/com/sunwin/metro/filter/MetroFilterMp.java

@@ -0,0 +1,17 @@
+package com.sunwin.metro.filter;
+
+import org.apache.flink.api.common.functions.FilterFunction;
+import org.apache.flink.api.java.tuple.Tuple4;
+
+/**
+ * @program: sunwin_metro
+ * @description: 过滤系统mp的设备名
+ * @author: xuYJ
+ * @create: 2021-02-19 10:24
+ **/
+public class MetroFilterMp implements FilterFunction<Tuple4<String, Integer, Long, String>> {
+    @Override
+    public boolean filter(Tuple4<String, Integer, Long, String> tuple4) throws Exception {
+        return !tuple4.f3.contains("_mp_");
+    }
+}

+ 26 - 0
flink_metro/src/main/java/com/sunwin/metro/flatmap/DeviceClientFlatmap.java

@@ -0,0 +1,26 @@
+package com.sunwin.metro.flatmap;
+
+import org.apache.flink.api.common.functions.FlatMapFunction;
+import org.apache.flink.api.java.tuple.Tuple2;
+import org.apache.flink.util.Collector;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @program: sunwin_metro
+ * @description: 采集webSocket服务端信息拆分每个设备数据
+ * @author: xuYJ
+ * @create: 2021-02-19 11:04
+ **/
+public class DeviceClientFlatmap implements FlatMapFunction<Map<String, List<String>>, Tuple2<String, String>> {
+    @Override
+    public void flatMap(Map<String, List<String>> listMap, Collector<Tuple2<String, String>> collector) throws Exception {
+        if (null != listMap && !listMap.isEmpty()) {
+            List<String> list = listMap.get("devices");
+            for (String s : list) {
+                collector.collect(new Tuple2<>(String.valueOf((s.hashCode() > 0 ? s.hashCode() : -s.hashCode()) % 3), s));
+            }
+        }
+    }
+}

+ 24 - 0
flink_metro/src/main/java/com/sunwin/metro/flatmap/MeterListFlatmap.java

@@ -0,0 +1,24 @@
+package com.sunwin.metro.flatmap;
+
+import com.alibaba.fastjson.JSONArray;
+import com.sunwin.metro.bean.Meter;
+import org.apache.flink.api.common.functions.FlatMapFunction;
+import org.apache.flink.util.Collector;
+
+import java.util.List;
+
+/**
+ * @program: sunwin_metro
+ * @description: 转化源数据生成不同仪表清单
+ * @author: xuYJ
+ * @create: 2021-04-25 15:40
+ **/
+public class MeterListFlatmap implements FlatMapFunction<String, Meter>{
+    @Override
+    public void flatMap(String s, Collector<Meter> collector) throws Exception {
+        List<Meter> meters = JSONArray.parseArray(s, Meter.class);
+        for (Meter meter : meters) {
+            collector.collect(meter);
+        }
+    }
+}

+ 94 - 0
flink_metro/src/main/java/com/sunwin/metro/flatmap/MetroDevicePropertyFlatmap.java

@@ -0,0 +1,94 @@
+package com.sunwin.metro.flatmap;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.sunwin.metro.bean.MetroDevice;
+import com.sunwin.metro.source.mysql.MysqlData;
+import com.sunwin.metro.utils.DateUtils;
+import com.sunwin.metro.utils.Md5Utils;
+import com.sunwin.metro.utils.PerStringUtils;
+import org.apache.flink.api.common.functions.FlatMapFunction;
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.util.Collector;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+import java.util.Date;
+
+/**
+ * @program: sunwin_metro
+ * @description: 把设备属性拆分成一条一条数据
+ * @author: xuYJ
+ * @create: 2021-01-15 09:10
+ **/
+public class MetroDevicePropertyFlatmap implements FlatMapFunction<String, MetroDevice> {
+    public static final Logger logger = LoggerFactory.getLogger(MetroDevicePropertyFlatmap.class);
+
+    @Override
+    public void flatMap(String input, Collector<MetroDevice> collector) throws Exception {
+        JSONObject device = JSON.parseObject(input);
+        JSONArray dpeList = device.getJSONArray("dpes");
+        String deviceTime = DateUtils.stringDateFormat(device.getString("stime"), "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyyMMddHHmmssSSS");
+        String compName = device.getString("compname");
+        String system = "非常规系统";
+        String deviceName = "设备名为空";
+        if (compName.contains("_")) {
+            String[] systems = compName.split("_");
+            if (!PerStringUtils.isNullOrEmpty(systems[0])) {
+                system = systems[0];
+                deviceName = compName.replace(systems[0] + "_", "").trim();
+            } else {
+                logger.error("异常设备号" + compName);
+            }
+        } else {
+            system = compName;
+            deviceName = compName;
+        }
+        for (Object s : dpeList) {
+            JSONObject dpeObject = JSONObject.parseObject(s.toString());
+            String collectTime = device.getString("collectTime");
+            String compDes = device.getString("compDes");
+            String stationName = device.getString("stationName");
+            String stationId = device.getString("stationId");
+            String subSys = device.getString("subSys");
+            String result = dpeObject.getString("val");
+            String valType = String.valueOf(dpeObject.getInteger("valType"));
+            String dpe = dpeObject.getString("dpe");
+            String des = dpeObject.getString("des");
+            String startTime = DateUtils.stringDateFormat(dpeObject.getString("stime"), "yyyy.MM.dd HH:mm:ss.SSS", "yyyyMMddHHmmssSSS");
+            String user = dpeObject.getString("user");
+            String warn = dpeObject.getString("hdl_Abbr");
+            String offLineText = dpeObject.getString("offLineText");
+            String id = String.valueOf(Md5Utils.getDeviceId(startTime, dpe));
+            String attributeType = "非常规属性状态";
+            String attributeVal = "系统携带默认属性";
+            if (dpe.contains("DI")) {
+                attributeType = "DI";
+            } else if (dpe.contains("AI")) {
+                attributeType = "AI";
+            } else if (dpe.contains("DO")) {
+                attributeType = "DO";
+            } else if (dpe.contains("AO")) {
+                attributeType = "AO";
+            }
+            if (!"非常规属性状态".equals(attributeType)) {
+                String[] split = dpe.split(attributeType);
+                if (split.length>1 && !PerStringUtils.isNullOrEmpty(split[1].replace(".", " ").trim())) {
+                    attributeVal = split[1].replace(".", "").trim();
+                }
+            }
+            collector.collect(new MetroDevice(collectTime, compDes, stationName, deviceTime, compName, id, stationId, result, des, offLineText, valType, dpe, startTime, user, warn, system, deviceName, subSys, attributeType, attributeVal));
+        }
+    }
+
+    public static void main(String[] args) {
+        String a="sw404:FAS_Fiber_LW1.AI";
+        String[] ais = a.split("AI");
+        System.out.println("Arrays.toString(ais) = " + Arrays.toString(ais));
+        System.out.println("ais = " + ais.length);
+        System.out.println("ais = " + ais[1]);
+    }
+}

+ 17 - 0
flink_metro/src/main/java/com/sunwin/metro/key/DeviceKeySelector.java

@@ -0,0 +1,17 @@
+package com.sunwin.metro.key;
+
+import com.sunwin.metro.bean.MetroDevice;
+import org.apache.flink.api.java.functions.KeySelector;
+
+/**
+ * @program: sunwin_metro
+ * @description: 对设备属性值进行分组
+ * @author: xuYJ
+ * @create: 2021-03-08 14:52
+ **/
+public class DeviceKeySelector implements KeySelector<MetroDevice, String> {
+    @Override
+    public String getKey(MetroDevice metroDevice) throws Exception {
+        return metroDevice.getOriginal_dpe();
+    }
+}

+ 17 - 0
flink_metro/src/main/java/com/sunwin/metro/key/DeviceNameKeySelector.java

@@ -0,0 +1,17 @@
+package com.sunwin.metro.key;
+
+import com.sunwin.metro.bean.MetroDevice;
+import org.apache.flink.api.java.functions.KeySelector;
+
+/**
+ * @program: sunwin_metro
+ * @description: 对设备名进行分组
+ * @author: xuYJ
+ * @create: 2021-03-08 14:52
+ **/
+public class DeviceNameKeySelector implements KeySelector<MetroDevice, String> {
+    @Override
+    public String getKey(MetroDevice metroDevice) throws Exception {
+        return metroDevice.getOriginal_compname();
+    }
+}

+ 17 - 0
flink_metro/src/main/java/com/sunwin/metro/key/MeterIdSelector.java

@@ -0,0 +1,17 @@
+package com.sunwin.metro.key;
+
+import org.apache.flink.api.java.functions.KeySelector;
+import org.apache.flink.api.java.tuple.Tuple4;
+
+/**
+ * @program: sunwin_metro
+ * @description: 根据仪表标识分组
+ * @author: xuYJ
+ * @create: 2021-04-25 15:52
+ **/
+public class MeterIdSelector implements KeySelector<Tuple4<String, String, String, Long>, String> {
+    @Override
+    public String getKey(Tuple4<String, String, String, Long> tuple4) throws Exception {
+        return tuple4.f0;
+    }
+}

+ 20 - 0
flink_metro/src/main/java/com/sunwin/metro/key/MetroKeySelector.java

@@ -0,0 +1,20 @@
+package com.sunwin.metro.key;
+
+import com.alibaba.fastjson.JSON;
+import com.sunwin.metro.utils.PerStringUtils;
+import org.apache.flink.api.java.functions.KeySelector;
+import org.apache.flink.api.java.tuple.Tuple4;
+
+/**
+ * @program: sunwin_metro
+ * @description: 地铁进行自定义分组(没有实现窗口)
+ * @author: xuYJ
+ * @create: 2021-01-15 11:53
+ **/
+public class MetroKeySelector implements KeySelector<Tuple4<String, Integer, Long, String>, String> {
+    @Override
+    public String getKey(Tuple4<String, Integer, Long, String> tuple4) throws Exception {
+        String[] split = JSON.parseObject(tuple4.f3).getString("compname").split("_");
+        return PerStringUtils.isNullOrEmpty(split[0]) ? split[1] : split[0];
+    }
+}

+ 24 - 0
flink_metro/src/main/java/com/sunwin/metro/map/DeviceAlarmMap.java

@@ -0,0 +1,24 @@
+package com.sunwin.metro.map;
+
+import com.alibaba.fastjson.JSON;
+import com.sunwin.metro.bean.DeviceWarn;
+import com.sunwin.metro.bean.MetroDevice;
+import com.sunwin.metro.utils.DateUtils;
+import org.apache.flink.api.common.functions.MapFunction;
+import org.apache.flink.api.java.tuple.Tuple2;
+
+import java.util.Date;
+
+/**
+ * @program: sunwin_metro
+ * @description: 把设备属性值转换成设备报警输出对象
+ * @author: xuYJ
+ * @create: 2021-03-08 15:12
+ **/
+public class DeviceAlarmMap implements MapFunction<Tuple2<String, MetroDevice>, DeviceWarn> {
+    @Override
+    public DeviceWarn map(Tuple2<String, MetroDevice> value) throws Exception {
+        MetroDevice metroDevice = value.f1;
+        return new DeviceWarn(metroDevice.getDevice_id(), metroDevice.getOriginal_compname(), value.f0, JSON.toJSONString(metroDevice), DateUtils.dateToStringWithFormat(new Date(), "yyyyMMddHHmmss"));
+    }
+}

+ 53 - 0
flink_metro/src/main/java/com/sunwin/metro/map/DeviceClientMap.java

@@ -0,0 +1,53 @@
+package com.sunwin.metro.map;
+
+import com.alibaba.fastjson.JSONObject;
+import com.sunwin.metro.utils.websocket.Client;
+import org.apache.flink.api.common.functions.RichMapFunction;
+import org.apache.flink.api.common.state.MapState;
+import org.apache.flink.api.common.state.MapStateDescriptor;
+import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.api.java.tuple.Tuple2;
+import org.apache.flink.configuration.Configuration;
+
+/**
+ * @program: sunwin_metro
+ * @description: 采集webSocket服务端的设备信息,发送到kafka
+ * @author: xuYJ
+ * @create: 2021-02-19 11:07
+ **/
+public class DeviceClientMap extends RichMapFunction<Tuple2<String, String>, String> {
+    private transient MapState<String, Integer> mapState;
+    @Override
+    public void open(Configuration parameters) throws Exception {
+        MapStateDescriptor<String, Integer> descriptor = new MapStateDescriptor<>("mapState", TypeInformation.of(String.class), TypeInformation.of(Integer.class));
+        mapState = getRuntimeContext().getMapState(descriptor);
+        System.out.println("当前分区" + getRuntimeContext().getIndexOfThisSubtask());
+        Client.createConnect();
+        super.open(parameters);
+    }
+
+    @Override
+    public String map(Tuple2<String, String> input) throws Exception {
+        String inputNew = input.f1.trim();
+        if (mapState.isEmpty()) {
+            System.out.println("当前分区" + getRuntimeContext().getIndexOfThisSubtask());
+            JSONObject object = new JSONObject();
+            System.out.println("input = " + input);
+            object.put("dpes", inputNew);
+            Client.send(object.toJSONString());
+            mapState.put(inputNew, 1);
+            return "设备号请求成功 - " + inputNew;
+        } else if (null != mapState.get(inputNew)) {
+            System.out.println("当前分区" + getRuntimeContext().getIndexOfThisSubtask());
+            System.out.println("请求失败,重复设备 - " + inputNew);
+            return "设备号请求失败,重复设备采集 - " + inputNew;
+        } else {
+            System.out.println("当前分区" + getRuntimeContext().getIndexOfThisSubtask());
+            JSONObject object = new JSONObject();
+            object.put("dpes", inputNew);
+            Client.send(object.toJSONString());
+            mapState.put(inputNew, 1);
+            return "设备号请求成功 - " + inputNew;
+        }
+    }
+}

+ 190 - 0
flink_metro/src/main/java/com/sunwin/metro/map/DeviceMetricsMap.java

@@ -0,0 +1,190 @@
+package com.sunwin.metro.map;
+
+import com.sunwin.metro.bean.MetroDevice;
+import com.sunwin.metro.utils.PerStringUtils;
+import org.apache.flink.api.common.functions.RichMapFunction;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.metrics.Gauge;
+import org.apache.flink.metrics.MetricGroup;
+
+/**
+ * @program: sunwin_metro  (该类监控ups系统信息)
+ * @description: 自定义设备metic信息,发送监控信息到Grafana可视化展示
+ * @author: xuYJ
+ * @create: 2021-01-22 10:50
+ **/
+public class DeviceMetricsMap extends RichMapFunction<MetroDevice, MetroDevice> {
+    private transient int valueToExpose = 0;
+    private transient String valueToExpose2 ;
+    private transient int valueToExpose3 = 0;
+    private transient Double valueToExpose4 = 0.0;
+    private transient int valueToExpose5 = 0;
+    private transient Double valueToExpose6 = 0.0;
+    private transient int valueToExpose7 = 0;
+    private transient int valueToExpose8 = 0;
+    private transient int valueToExpose9 = 0;
+    private transient Double valueToExpose10 = 0.0;
+    private transient int valueToExpose11 = 0;
+    private transient Double valueToExpose12 = 0.0;
+
+    @Override
+    public void open(Configuration parameters) throws Exception {
+        MetricGroup metricGroup = getRuntimeContext()
+                .getMetricGroup();
+        metricGroup
+                .gauge("sw404:UPS_BAS.AI.BV", new Gauge<Integer>() {
+                    @Override
+                    public Integer getValue() {
+                        return valueToExpose;
+                    }
+                });
+        metricGroup
+                .gauge("sw404:UPS_BAS.AI.BVP", new Gauge<String>() {
+                    @Override
+                    public String getValue() {
+                        return valueToExpose2;
+                    }
+                });
+        metricGroup
+                .gauge("sw404:UPS_BAS.AI.IFV", new Gauge<Integer>() {
+                    @Override
+                    public Integer getValue() {
+                        return valueToExpose3;
+                    }
+                });
+        metricGroup
+                .gauge("sw404:UPS_BAS.AI.IFre", new Gauge<Double>() {
+                    @Override
+                    public Double getValue() {
+                        return valueToExpose4;
+                    }
+                });
+        metricGroup
+                .gauge("sw404:UPS_BAS.AI.IV", new Gauge<Integer>() {
+                    @Override
+                    public Integer getValue() {
+                        return valueToExpose5;
+                    }
+                });
+        metricGroup
+                .gauge("sw404:UPS_BAS.AI.OP", new Gauge<Double>() {
+                    @Override
+                    public Double getValue() {
+                        return valueToExpose6;
+                    }
+                });
+        metricGroup
+                .gauge("sw404:UPS_BAS.AI.OV", new Gauge<Integer>() {
+                    @Override
+                    public Integer getValue() {
+                        return valueToExpose7;
+                    }
+                });
+        metricGroup
+                .gauge("sw404:UPS_BAS.AI.RBV", new Gauge<Integer>() {
+                    @Override
+                    public Integer getValue() {
+                        return valueToExpose8;
+                    }
+                });
+        metricGroup
+                .gauge("sw404:UPS_BAS.AI.ROC", new Gauge<Integer>() {
+                    @Override
+                    public Integer getValue() {
+                        return valueToExpose9;
+                    }
+                });
+        metricGroup
+                .gauge("sw404:UPS_BAS.AI.ROFre", new Gauge<Double>() {
+                    @Override
+                    public Double getValue() {
+                        return valueToExpose10;
+                    }
+                });
+        metricGroup
+                .gauge("sw404:UPS_BAS.AI.ROV", new Gauge<Integer>() {
+                    @Override
+                    public Integer getValue() {
+                        return valueToExpose11;
+                    }
+                });
+        metricGroup
+                .gauge("sw404:UPS_BAS.AI.Temp", new Gauge<Double>() {
+                    @Override
+                    public Double getValue() {
+                        return valueToExpose12;
+                    }
+                });
+        super.open(parameters);
+    }
+
+    @Override
+    public void close() throws Exception {
+        super.close();
+    }
+
+    @Override
+    public MetroDevice map(MetroDevice metroDevice) throws Exception {
+        if (!PerStringUtils.isNullOrEmpty(metroDevice.getOriginal_dpe()) && "sw404:UPS_BAS.AI.BV".equals(metroDevice.getOriginal_dpe())) {
+            if (!PerStringUtils.isNullOrEmpty(metroDevice.getAttribute_result())) {
+                valueToExpose = Integer.parseInt(metroDevice.getAttribute_result());
+            }
+        }
+        if (!PerStringUtils.isNullOrEmpty(metroDevice.getOriginal_dpe()) && "sw404:UPS_BAS.AI.BVP".equals(metroDevice.getOriginal_dpe())) {
+            if (!PerStringUtils.isNullOrEmpty(metroDevice.getAttribute_result())) {
+                valueToExpose2 = metroDevice.getAttribute_result();
+            }
+        }
+        if (!PerStringUtils.isNullOrEmpty(metroDevice.getOriginal_dpe()) && "sw404:UPS_BAS.AI.IFV".equals(metroDevice.getOriginal_dpe())) {
+            if (!PerStringUtils.isNullOrEmpty(metroDevice.getAttribute_result())) {
+                valueToExpose3 = Integer.parseInt(metroDevice.getAttribute_result());
+            }
+        }
+        if (!PerStringUtils.isNullOrEmpty(metroDevice.getOriginal_dpe()) && "sw404:UPS_BAS.AI.IFre".equals(metroDevice.getOriginal_dpe())) {
+            if (!PerStringUtils.isNullOrEmpty(metroDevice.getAttribute_result())) {
+                valueToExpose4 = Double.parseDouble(metroDevice.getAttribute_result());
+            }
+        }
+        if (!PerStringUtils.isNullOrEmpty(metroDevice.getOriginal_dpe()) && "sw404:UPS_BAS.AI.IV".equals(metroDevice.getOriginal_dpe())) {
+            if (!PerStringUtils.isNullOrEmpty(metroDevice.getAttribute_result())) {
+                valueToExpose5 = Integer.parseInt(metroDevice.getAttribute_result());
+            }
+        }
+        if (!PerStringUtils.isNullOrEmpty(metroDevice.getOriginal_dpe()) && "sw404:UPS_BAS.AI.OP".equals(metroDevice.getOriginal_dpe())) {
+            if (!PerStringUtils.isNullOrEmpty(metroDevice.getAttribute_result())) {
+                valueToExpose6 =  Double.parseDouble(metroDevice.getAttribute_result());
+            }
+        }
+        if (!PerStringUtils.isNullOrEmpty(metroDevice.getOriginal_dpe()) && "sw404:UPS_BAS.AI.OV".equals(metroDevice.getOriginal_dpe())) {
+            if (!PerStringUtils.isNullOrEmpty(metroDevice.getAttribute_result())) {
+                valueToExpose7 = Integer.parseInt(metroDevice.getAttribute_result());
+            }
+        }
+        if (!PerStringUtils.isNullOrEmpty(metroDevice.getOriginal_dpe()) && "sw404:UPS_BAS.AI.RBV".equals(metroDevice.getOriginal_dpe())) {
+            if (!PerStringUtils.isNullOrEmpty(metroDevice.getAttribute_result())) {
+                valueToExpose8 = Integer.parseInt(metroDevice.getAttribute_result());
+            }
+        }
+        if (!PerStringUtils.isNullOrEmpty(metroDevice.getOriginal_dpe()) && "sw404:UPS_BAS.AI.ROC".equals(metroDevice.getOriginal_dpe())) {
+            if (!PerStringUtils.isNullOrEmpty(metroDevice.getAttribute_result())) {
+                valueToExpose9 = Integer.parseInt(metroDevice.getAttribute_result());
+            }
+        }
+        if (!PerStringUtils.isNullOrEmpty(metroDevice.getOriginal_dpe()) && "sw404:UPS_BAS.AI.ROFre".equals(metroDevice.getOriginal_dpe())) {
+            if (!PerStringUtils.isNullOrEmpty(metroDevice.getAttribute_result())) {
+                valueToExpose10 = Double.parseDouble(metroDevice.getAttribute_result());
+            }
+        }
+        if (!PerStringUtils.isNullOrEmpty(metroDevice.getOriginal_dpe()) && "sw404:UPS_BAS.AI.ROV".equals(metroDevice.getOriginal_dpe())) {
+            if (!PerStringUtils.isNullOrEmpty(metroDevice.getAttribute_result())) {
+                valueToExpose11 = Integer.parseInt(metroDevice.getAttribute_result());
+            }
+        }
+        if (!PerStringUtils.isNullOrEmpty(metroDevice.getOriginal_dpe()) && "sw404:UPS_BAS.AI.Temp".equals(metroDevice.getOriginal_dpe())) {
+            if (!PerStringUtils.isNullOrEmpty(metroDevice.getAttribute_result())) {
+                valueToExpose12 = Double.parseDouble(metroDevice.getAttribute_result());
+            }
+        }
+        return metroDevice;
+    }
+}

+ 36 - 0
flink_metro/src/main/java/com/sunwin/metro/map/DeviceNormalMap.java

@@ -0,0 +1,36 @@
+package com.sunwin.metro.map;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.sunwin.metro.utils.websocket.ClientManager;
+import org.apache.flink.api.common.functions.RichMapFunction;
+import org.apache.flink.configuration.Configuration;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @program: sunwin_metro
+ * @description: 验证设备通讯是否正常,结果发到mysql
+ * @author: xuYJ
+ * @create: 2021-02-19 10:50
+ **/
+public class DeviceNormalMap extends RichMapFunction<Map<String, List<String>>, String> {
+    private ClientManager clientManager;
+    @Override
+    public void open(Configuration parameters) throws Exception {
+        clientManager = new ClientManager();
+    }
+
+    @Override
+    public String map(Map<String, List<String>> input) throws Exception {
+        JSONArray array = new JSONArray();
+        for (String s : input.get("devices")) {
+            array.add("sw404:"+s.trim());
+        }
+        JSONObject object = new JSONObject();
+        object.put("dpes", array);
+        clientManager.connect("ws://127.0.0.1:12108/dpsubSys_websocket", object.toJSONString());
+        return null;
+    }
+}

+ 25 - 0
flink_metro/src/main/java/com/sunwin/metro/map/MeterTimeMap.java

@@ -0,0 +1,25 @@
+package com.sunwin.metro.map;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.sunwin.metro.utils.DateUtils;
+import org.apache.flink.api.common.functions.MapFunction;
+import org.apache.flink.api.java.tuple.Tuple3;
+import org.apache.flink.api.java.tuple.Tuple4;
+
+/**
+ * @program: sunwin_metro
+ * @description: 把数据中时间戳转化成时间字符串(用来定义事件时间)
+ * @author: xuYJ
+ * @create: 2021-04-25 15:50
+ **/
+public class MeterTimeMap implements MapFunction<Tuple3<String, String, String>, Tuple4<String, String, String, Long>> {
+    @Override
+    public Tuple4<String, String, String, Long> map(Tuple3<String, String, String> tuple3) throws Exception {
+        String f2 = tuple3.f2;
+        JSONObject data = JSON.parseObject(JSON.parseObject(f2).getString("data"));
+        JSONObject current = JSON.parseObject(data.getString("0"));
+        long updateTime = DateUtils.stringToTimeStampWithFormat(current.getString("update_time"), "yyyy-MM-dd HH:mm:ss");
+        return new Tuple4<>(tuple3.f0, tuple3.f1, tuple3.f2, updateTime);
+    }
+}

+ 20 - 0
flink_metro/src/main/java/com/sunwin/metro/map/MeterTimestampMap.java

@@ -0,0 +1,20 @@
+package com.sunwin.metro.map;
+
+import com.sunwin.metro.utils.DateUtils;
+import org.apache.flink.api.common.functions.MapFunction;
+import org.apache.flink.api.java.tuple.Tuple4;
+
+import java.util.Date;
+
+/**
+ * @program: sunwin_metro
+ * @description: 提取时间戳转换成时间
+ * @author: xuYJ
+ * @create: 2021-04-25 16:06
+ **/
+public class MeterTimestampMap implements MapFunction<Tuple4<String, String, String, Long>, String> {
+    @Override
+    public String map(Tuple4<String, String, String, Long> tuple4) throws Exception {
+        return DateUtils.dateToLongStringNoSep(new Date(tuple4.f3));
+    }
+}

+ 62 - 0
flink_metro/src/main/java/com/sunwin/metro/process/DeviceAlarmProcess.java

@@ -0,0 +1,62 @@
+package com.sunwin.metro.process;
+
+import com.sunwin.metro.bean.MetroDevice;
+import com.sunwin.metro.utils.FileUtils;
+import org.apache.flink.api.common.state.MapState;
+import org.apache.flink.api.common.state.MapStateDescriptor;
+import org.apache.flink.api.common.state.ValueState;
+import org.apache.flink.api.common.state.ValueStateDescriptor;
+import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.api.java.tuple.Tuple2;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.streaming.api.functions.KeyedProcessFunction;
+import org.apache.flink.util.Collector;
+
+/**
+ * @program: sunwin_metro
+ * @description: 设备某一属性进行报警过程中输出该设备所有属性
+ * @author: xuYJ
+ * @create: 2021-03-08 15:09
+ **/
+public class DeviceAlarmProcess extends KeyedProcessFunction<String, MetroDevice, Tuple2<String, MetroDevice>> {
+    private transient ValueState<Integer> valueState;
+    private transient MapState<String, Long> mapState;
+
+    @Override
+    public void open(Configuration parameters) throws Exception {
+        MapStateDescriptor<String, Long> descriptor = new MapStateDescriptor<>("mapState", TypeInformation.of(String.class), TypeInformation.of(Long.class));
+        mapState = getRuntimeContext().getMapState(descriptor);
+        ValueStateDescriptor<Integer> descriptor2 = new ValueStateDescriptor<>("valueState", TypeInformation.of(Integer.class));
+        valueState = getRuntimeContext().getState(descriptor2);
+        super.open(parameters);
+    }
+
+    @Override
+    public void processElement(MetroDevice metroDevice, Context context, Collector<Tuple2<String, MetroDevice>> collector) throws Exception {
+        Integer value = valueState.value();
+        String[] words = {"动作", "故障", "屏蔽", "监管", "报警", "离线", "通讯故障", "火警"};
+        if (mapState.isEmpty()) {
+            if (metroDevice.getDevice_warn().contains("报警")) {
+                if (FileUtils.containsWords(metroDevice.getAction_text(), words)) {
+                    valueState.update(null == value ? 1 : value + 1);
+                    mapState.put(metroDevice.getOriginal_dpe(), Long.valueOf(metroDevice.getAttribute_time()));
+                    collector.collect(new Tuple2<>(valueState.value().toString(), metroDevice));
+                }
+            }
+        } else {
+            if (FileUtils.containsWords(metroDevice.getAction_text(), words)) {
+                if (metroDevice.getDevice_warn().contains("报警")) {
+                    mapState.put(metroDevice.getOriginal_dpe(), Long.valueOf(metroDevice.getAttribute_time()));
+                }
+                collector.collect(new Tuple2<>(valueState.value().toString(), metroDevice));
+            } else {
+                if (mapState.contains(metroDevice.getOriginal_dpe())) {
+                    collector.collect(new Tuple2<>(valueState.value().toString(), metroDevice));
+                    mapState.remove(metroDevice.getOriginal_dpe());
+                } else {
+                    collector.collect(new Tuple2<>(valueState.value().toString(), metroDevice));
+                }
+            }
+        }
+    }
+}

+ 46 - 0
flink_metro/src/main/java/com/sunwin/metro/process/DeviceUnrepeated.java

@@ -0,0 +1,46 @@
+package com.sunwin.metro.process;
+
+import com.sunwin.metro.bean.MetroDevice;
+import org.apache.flink.api.common.state.MapState;
+import org.apache.flink.api.common.state.MapStateDescriptor;
+import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.streaming.api.functions.KeyedProcessFunction;
+import org.apache.flink.util.Collector;
+
+/**
+ * @program: sunwin_metro
+ * @description: 对设备属性进行去重
+ * @author: xuYJ
+ * @create: 2021-03-08 14:56
+ **/
+public class DeviceUnrepeated extends KeyedProcessFunction<String, MetroDevice, MetroDevice> {
+    private transient MapState<String, String> mapState;
+
+    @Override
+    public void open(Configuration parameters) throws Exception {
+        MapStateDescriptor<String, String> descriptor = new MapStateDescriptor<>("mapState", TypeInformation.of(String.class), TypeInformation.of(String.class));
+        mapState = getRuntimeContext().getMapState(descriptor);
+        super.open(parameters);
+    }
+
+    @Override
+    public void processElement(MetroDevice metroDevice, Context context, Collector<MetroDevice> collector) throws Exception {
+        String metro = metroDevice.getAction_text() + metroDevice.getDevice_warn() + metroDevice.getAttribute_result();
+        if (mapState.isEmpty()) {
+            mapState.put(metroDevice.getOriginal_dpe(), metro);
+            collector.collect(metroDevice);
+        } else {
+            if (mapState.contains(metroDevice.getOriginal_dpe())) {
+                if (mapState.get(metroDevice.getOriginal_dpe()).equals(metro)) {
+                } else {
+                    mapState.put(metroDevice.getOriginal_dpe(), metro);
+                    collector.collect(metroDevice);
+                }
+            } else {
+                mapState.put(metroDevice.getOriginal_dpe(), metro);
+                collector.collect(metroDevice);
+            }
+        }
+    }
+}

+ 118 - 0
flink_metro/src/main/java/com/sunwin/metro/process/ElectricityMeterProcess.java

@@ -0,0 +1,118 @@
+package com.sunwin.metro.process;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.sunwin.metro.bean.ElectricityMeter;
+import com.sunwin.metro.utils.DateUtils;
+import com.sunwin.metro.utils.PerStringUtils;
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.streaming.api.functions.windowing.ProcessWindowFunction;
+import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
+import org.apache.flink.util.Collector;
+import java.util.Date;
+import java.util.HashMap;
+
+
+
+/**
+ * @program: sunwin_metro
+ * @description: 对于窗口中的电表详情数据进行处理
+ * @author: xuYJ
+ * @create: 2021-04-25 16:03
+ **/
+public class ElectricityMeterProcess extends ProcessWindowFunction<Tuple4<String, String, String, Long>, ElectricityMeter, String, TimeWindow> {
+    @Override
+    public void process(String s, Context context, Iterable<Tuple4<String, String, String, Long>> elements, Collector<ElectricityMeter> out) throws Exception {
+        ElectricityMeter electricityMeter = new ElectricityMeter();
+        HashMap<String, Double> aVoltage = new HashMap<>(16);
+        HashMap<String, Double> bVoltage = new HashMap<>(16);
+        HashMap<String, Double> cVoltage = new HashMap<>(16);
+        HashMap<String, Double> aCurrent = new HashMap<>(16);
+        HashMap<String, Double> bCurrent = new HashMap<>(16);
+        HashMap<String, Double> cCurrent = new HashMap<>(16);
+        HashMap<String, Double> totalActivePower = new HashMap<>(16);
+        HashMap<String, Double> aActivePower = new HashMap<>(16);
+        HashMap<String, Double> bActivePower = new HashMap<>(16);
+        HashMap<String, Double> cActivePower = new HashMap<>(16);
+        HashMap<String, Double> totalNegativeActive = new HashMap<>(16);
+        HashMap<String, Double> aNegativeActive = new HashMap<>(16);
+        HashMap<String, Double> bNegativeActive = new HashMap<>(16);
+        HashMap<String, Double> cNegativeActive = new HashMap<>(16);
+        HashMap<String, Double> totalApparentPower = new HashMap<>(16);
+        HashMap<String, Double> aApparentPower = new HashMap<>(16);
+        HashMap<String, Double> bApparentPower = new HashMap<>(16);
+        HashMap<String, Double> cApparentPower = new HashMap<>(16);
+        HashMap<String, Double> totalPowerFactor = new HashMap<>(16);
+        HashMap<String, Double> aPowerFactor = new HashMap<>(16);
+        HashMap<String, Double> bPowerFactor = new HashMap<>(16);
+        HashMap<String, Double> cPowerFactor = new HashMap<>(16);
+        HashMap<String, Double> frequency = new HashMap<>(16);
+        HashMap<String, Object> electricTotalActive = new HashMap<>(16);
+        HashMap<String, Double> totalActive = new HashMap<>(16);
+        HashMap<String, Object> meterNumber = new HashMap<>(16);
+        HashMap<String, Object> electricStatus = new HashMap<>(16);
+
+        elements.forEach(tuple3 -> {
+            String f2 = tuple3.f2;
+            JSONObject data = JSON.parseObject(JSON.parseObject(f2).getString("data"));
+            JSONObject current = JSON.parseObject(data.getString("0"));
+            String updateTime = String.valueOf(tuple3.f3);
+            meterNumber.put(updateTime, current.getString("meter_number"));
+            electricStatus.put(updateTime, current.getInteger("electric_status"));
+            aVoltage.put(updateTime, current.getDouble("a_voltage"));
+            bVoltage.put(updateTime, current.getDouble("b_voltage"));
+            cVoltage.put(updateTime, current.getDouble("c_voltage"));
+            aCurrent.put(updateTime, current.getDouble("a_current"));
+            bCurrent.put(updateTime, current.getDouble("b_current"));
+            cCurrent.put(updateTime, current.getDouble("c_current"));
+            totalActivePower.put(updateTime, current.getDouble("total_active_power"));
+            aActivePower.put(updateTime, current.getDouble("a_active_power"));
+            bActivePower.put(updateTime, current.getDouble("b_active_power"));
+            cActivePower.put(updateTime, current.getDouble("c_active_power"));
+            totalNegativeActive.put(updateTime, current.getDouble("total_negative_active"));
+            aNegativeActive.put(updateTime, current.getDouble("a_negative_active"));
+            bNegativeActive.put(updateTime, current.getDouble("b_negative_active"));
+            cNegativeActive.put(updateTime, current.getDouble("c_negative_active"));
+            totalApparentPower.put(updateTime, current.getDouble("total_apparent_power"));
+            aApparentPower.put(updateTime, current.getDouble("a_apparent_power"));
+            bApparentPower.put(updateTime, current.getDouble("b_apparent_power"));
+            cApparentPower.put(updateTime, current.getDouble("c_apparent_power"));
+            totalPowerFactor.put(updateTime, current.getDouble("total_power_factor"));
+            aPowerFactor.put(updateTime, current.getDouble("a_power_factor"));
+            bPowerFactor.put(updateTime, current.getDouble("b_power_factor"));
+            cPowerFactor.put(updateTime, current.getDouble("c_power_factor"));
+            frequency.put(updateTime, current.getDouble("frequency"));
+            electricTotalActive.put(updateTime, current.getDouble("electric_total_active"));
+            totalActive.put(updateTime, current.getDouble("total_active"));
+        });
+        electricityMeter.setA_voltage(aVoltage);
+        electricityMeter.setB_voltage(bVoltage);
+        electricityMeter.setC_voltage(cVoltage);
+        electricityMeter.setA_current(aCurrent);
+        electricityMeter.setB_current(bCurrent);
+        electricityMeter.setC_current(cCurrent);
+        electricityMeter.setTotal_active_power(totalActivePower);
+        electricityMeter.setA_active_power(aActivePower);
+        electricityMeter.setB_active_power(bActivePower);
+        electricityMeter.setC_active_power(cActivePower);
+        electricityMeter.setTotal_negative_active(totalNegativeActive);
+        electricityMeter.setA_negative_active(aNegativeActive);
+        electricityMeter.setB_negative_active(bNegativeActive);
+        electricityMeter.setC_negative_active(cNegativeActive);
+        electricityMeter.setTotal_apparent_power(totalApparentPower);
+        electricityMeter.setA_apparent_power(aApparentPower);
+        electricityMeter.setB_apparent_power(bApparentPower);
+        electricityMeter.setC_apparent_power(cApparentPower);
+        electricityMeter.setTotal_power_factor(totalPowerFactor);
+        electricityMeter.setA_power_factor(aPowerFactor);
+        electricityMeter.setB_power_factor(bPowerFactor);
+        electricityMeter.setC_power_factor(cPowerFactor);
+        electricityMeter.setFrequency(frequency);
+        electricityMeter.setElectric_total_active(Double.parseDouble(String.valueOf(PerStringUtils.getMaxValue(electricTotalActive))));
+        electricityMeter.setTotal_active(totalActive);
+        electricityMeter.setUpdate_time(PerStringUtils.getMaxKey(aVoltage));
+        electricityMeter.setMeter_number(String.valueOf(PerStringUtils.getMaxValue(meterNumber)));
+        electricityMeter.setElectric_status(Integer.parseInt(String.valueOf(PerStringUtils.getMaxValue(electricStatus))));
+        out.collect(electricityMeter);
+    }
+}

+ 55 - 0
flink_metro/src/main/java/com/sunwin/metro/process/ErrorMeterProcess.java

@@ -0,0 +1,55 @@
+package com.sunwin.metro.process;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.flink.api.java.tuple.Tuple2;
+import org.apache.flink.api.java.tuple.Tuple3;
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.streaming.api.functions.ProcessFunction;
+import org.apache.flink.util.Collector;
+import org.apache.flink.util.OutputTag;
+
+/**
+ * @program: sunwin_metro
+ * @description: 过滤异常仪表号(携带的数据为空的仪表号)
+ * @author: xuYJ
+ * @create: 2021-04-25 15:43
+ **/
+public class ErrorMeterProcess extends ProcessFunction<Tuple4<String, String, String, String>, Tuple3<String, String, String>> {
+    private final OutputTag<Tuple3<String, String, String>> errorMeter;
+    private final OutputTag<Tuple3<String, String, String>> waterMeter;
+    private final OutputTag<Tuple3<String, String, String>> gasMeter;
+
+    public ErrorMeterProcess(OutputTag<Tuple3<String, String, String>> errorMeter, OutputTag<Tuple3<String, String, String>> waterMeter, OutputTag<Tuple3<String, String, String>> gasMeter) {
+        this.errorMeter = errorMeter;
+        this.waterMeter = waterMeter;
+        this.gasMeter = gasMeter;
+    }
+
+    @Override
+    public void processElement(Tuple4<String, String, String, String> tuple4, Context context, Collector<Tuple3<String, String, String>> collector) throws Exception {
+        try {
+            JSONObject jsonObject = JSON.parseObject(tuple4.f3);
+            JSONObject date = JSON.parseObject(jsonObject.getString("data"));
+            if (jsonObject.getInteger("code") == 0
+                    && "操作成功".equals(jsonObject.getString("msg"))
+                    && !"".equals(date.getString("0"))
+                    && !"".equals(date.getString("m15"))
+                    && !"".equals(date.getString("m30"))
+                    && !"".equals(date.getString("h1"))
+                    && !"".equals(date.getString("h2"))) {
+                if (Integer.parseInt(tuple4.f2) == 1) {
+                    collector.collect(new Tuple3<>(tuple4.f0, tuple4.f1, tuple4.f3));
+                } else if (Integer.parseInt(tuple4.f2) == 2) {
+                    context.output(waterMeter, new Tuple3<>(tuple4.f0, tuple4.f1, tuple4.f3));
+                } else {
+                    context.output(gasMeter, new Tuple3<>(tuple4.f0, tuple4.f1, tuple4.f3));
+                }
+            } else {
+                context.output(errorMeter, new Tuple3<>(tuple4.f0,tuple4.f1,tuple4.f2));
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 69 - 0
flink_metro/src/main/java/com/sunwin/metro/process/MetroKeyProcess.java

@@ -0,0 +1,69 @@
+package com.sunwin.metro.process;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.sunwin.metro.utils.Sign;
+import org.apache.flink.api.common.state.*;
+import org.apache.flink.api.common.time.Time;
+import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.api.java.tuple.Tuple2;
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.streaming.api.functions.KeyedProcessFunction;
+import org.apache.flink.util.Collector;
+import org.apache.flink.util.OutputTag;
+
+/**
+ * @program: sunwin_metro
+ * @description: 地铁数据分组后进行的mapState+valueState去重
+ * @author: xuYJ
+ * @create: 2021-01-15 11:56
+ **/
+public class MetroKeyProcess extends KeyedProcessFunction<String, Tuple4<String, Integer, Long, String>, String> {
+    private final OutputTag<Tuple2<String, Integer>> tag;
+    private transient MapState<String, Integer> mapState;
+    private transient ValueState<Integer> valueState;
+
+    public MetroKeyProcess(OutputTag<Tuple2<String, Integer>> tag) {
+        this.tag = tag;
+    }
+
+    @Override
+    public void open(Configuration parameters) throws Exception {
+        StateTtlConfig ttlConfig = StateTtlConfig
+                .newBuilder(Time.minutes(24 * 60))
+                .setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite)
+                .setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired)
+                .build();
+        MapStateDescriptor<String, Integer> descriptor = new MapStateDescriptor<>("mapState", TypeInformation.of(String.class), TypeInformation.of(Integer.class));
+        descriptor.enableTimeToLive(ttlConfig);
+        ValueStateDescriptor<Integer> descriptor2 = new ValueStateDescriptor<>("valueState", TypeInformation.of(Integer.class));
+        //设置过期时间
+        descriptor2.enableTimeToLive(ttlConfig);
+        mapState = getRuntimeContext().getMapState(descriptor);
+        valueState = getRuntimeContext().getState(descriptor2);
+        super.open(parameters);
+        super.open(parameters);
+    }
+
+    @Override
+    public void processElement(Tuple4<String, Integer, Long, String> tuple4, Context context, Collector<String> collector) throws Exception {
+        String line = tuple4.f3;
+        JSONObject jsonObject = JSON.parseObject(line);
+        String key = context.getCurrentKey();
+        String id = String.valueOf(Sign.getMd5(jsonObject.getString("compname") + jsonObject.getString("dpes")));
+        if (mapState.isEmpty()) {
+            mapState.put(id, 1);
+            collector.collect(line);
+        } else {
+            if (null != mapState.get(id)) {
+                Integer value = valueState.value();
+                valueState.update(null == value ? 1 : value + 1);
+                context.output(tag, new Tuple2<>(key, value));
+            } else {
+                mapState.put(id, 1);
+                collector.collect(line);
+            }
+        }
+    }
+}

+ 43 - 0
flink_metro/src/main/java/com/sunwin/metro/process/ScheduleTimeProcess.java

@@ -0,0 +1,43 @@
+package com.sunwin.metro.process;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.sunwin.metro.bean.ElectricityMeter;
+import com.sunwin.metro.utils.DateUtils;
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.streaming.api.functions.KeyedProcessFunction;
+import org.apache.flink.util.Collector;
+
+import java.util.Date;
+
+/**
+ * @program: sunwin_metro
+ * @description: 固定整点时间提取数据输出
+ * @author: xuYJ
+ * @create: 2021-04-25 15:55
+ **/
+public class ScheduleTimeProcess extends KeyedProcessFunction<String, Tuple4<String, String, String, Long>, ElectricityMeter> {
+
+    private final int time;
+
+    public ScheduleTimeProcess(int time) {
+        this.time = time;
+    }
+
+    @Override
+    public void processElement(Tuple4<String, String, String, Long> value, Context ctx, Collector<ElectricityMeter> out) throws Exception {
+        ElectricityMeter electricityMeter = new ElectricityMeter();
+        String updateTime = DateUtils.dateToLongStringNoSep(new Date(value.f3));
+        String min = updateTime.substring(10, 12);
+        if (Integer.parseInt(min) % time == 0) {
+            String input = value.f2;
+            JSONObject data = JSON.parseObject(JSON.parseObject(input).getString("data"));
+            JSONObject current = JSON.parseObject(data.getString("0"));
+            electricityMeter.setElectric_status(current.getInteger("electric_status"));
+            electricityMeter.setUpdate_time(updateTime.substring(0, 12));
+            electricityMeter.setMeter_number(current.getString("meter_number"));
+            electricityMeter.setElectric_total_active(current.getDouble("electric_total_active"));
+            out.collect(electricityMeter);
+        }
+    }
+}

+ 25 - 0
flink_metro/src/main/java/com/sunwin/metro/service/DeviceClient.java

@@ -0,0 +1,25 @@
+package com.sunwin.metro.service;
+
+import com.sunwin.metro.flatmap.DeviceClientFlatmap;
+import com.sunwin.metro.map.DeviceClientMap;
+import org.apache.flink.api.common.functions.Partitioner;
+import org.apache.flink.streaming.api.datastream.DataStreamSource;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @program: sunwin_metro
+ * @description: 从webSocket服务端采集设备数据信息
+ * @author: xuYJ
+ * @create: 2021-01-19 14:47
+ **/
+public class DeviceClient {
+
+    public static void process(DataStreamSource<Map<String, List<String>>> source) {
+        source
+                .flatMap(new DeviceClientFlatmap())
+                .keyBy(0)
+                .map(new DeviceClientMap());
+    }
+}

+ 19 - 0
flink_metro/src/main/java/com/sunwin/metro/service/DeviceNormal.java

@@ -0,0 +1,19 @@
+package com.sunwin.metro.service;
+
+import com.sunwin.metro.map.DeviceNormalMap;
+import org.apache.flink.streaming.api.datastream.DataStreamSource;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @program: sunwin_metro
+ * @description: 定时检查设备通讯是否正常
+ * @author: xuYJ
+ * @create: 2021-01-19 14:47
+ **/
+public class DeviceNormal {
+    public static void process(DataStreamSource<Map<String, List<String>>> source) {
+        source.map(new DeviceNormalMap());
+    }
+}

+ 78 - 0
flink_metro/src/main/java/com/sunwin/metro/service/EnergyConsumption.java

@@ -0,0 +1,78 @@
+package com.sunwin.metro.service;
+
+import com.sunwin.metro.bean.ElectricityMeter;
+import com.sunwin.metro.bean.Meter;
+import com.sunwin.metro.flatmap.MeterListFlatmap;
+import com.sunwin.metro.key.MeterIdSelector;
+import com.sunwin.metro.map.MeterTimeMap;
+import com.sunwin.metro.map.MeterTimestampMap;
+import com.sunwin.metro.process.ElectricityMeterProcess;
+import com.sunwin.metro.process.ErrorMeterProcess;
+import com.sunwin.metro.process.ScheduleTimeProcess;
+import com.sunwin.metro.sink.impala.SinkToImpala;
+import com.sunwin.metro.sink.impala.SinkToImpalaMeterValue;
+import com.sunwin.metro.sink.mysql.SinkErrorMeterToMysql;
+import com.sunwin.metro.sink.mysql.SinkNormalMeterToMysql;
+import com.sunwin.metro.sink.mysql.SinkToMysql;
+import com.sunwin.metro.watermark.MeterWaterLine;
+import org.apache.flink.api.java.tuple.Tuple3;
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.streaming.api.datastream.*;
+import org.apache.flink.streaming.api.windowing.time.Time;
+import org.apache.flink.util.OutputTag;
+
+
+/**
+ * @program: sunwin_metro
+ * @description: 能耗业务
+ * @author: xuYJ
+ * @create: 2021-04-14 09:54
+ **/
+public class EnergyConsumption {
+    public static void process(SingleOutputStreamOperator<String> source, SingleOutputStreamOperator<Tuple4<String, String, String, String>> source1) {
+        OutputTag<Tuple3<String, String, String>> errorMeter = new OutputTag<Tuple3<String, String, String>>("error_meter") {
+        };
+        OutputTag<Tuple3<String, String, String>> waterMeter = new OutputTag<Tuple3<String, String, String>>("waterMeter") {
+        };
+        OutputTag<Tuple3<String, String, String>> gasMeter = new OutputTag<Tuple3<String, String, String>>("gasMeter") {
+        };
+        OutputTag<Tuple4<String, String, String, Long>> lateOutputTag = new OutputTag<Tuple4<String, String, String, Long>>("late_data_output_tag") {
+        };
+        SingleOutputStreamOperator<Meter> flatMap = source.flatMap(new MeterListFlatmap());
+        flatMap.addSink(new SinkToMysql());
+        SingleOutputStreamOperator<Tuple3<String, String, String>> electricityMeter = source1.process(new ErrorMeterProcess(errorMeter, waterMeter, gasMeter));
+        electricityMeter.addSink(new SinkNormalMeterToMysql());
+        DataStream<Tuple3<String, String, String>> errorSide = electricityMeter.getSideOutput(errorMeter);
+        errorSide.addSink(new SinkErrorMeterToMysql());
+        DataStream<Tuple3<String, String, String>> waterSide = electricityMeter.getSideOutput(waterMeter);
+        waterSide.addSink(new SinkNormalMeterToMysql());
+        DataStream<Tuple3<String, String, String>> gasSide = electricityMeter.getSideOutput(gasMeter);
+        gasSide.addSink(new SinkNormalMeterToMysql());
+        //TODO:电表业务处理逻辑
+        //把时间字符串转化成毫秒时间戳
+        SingleOutputStreamOperator<Tuple4<String, String, String, Long>> map = electricityMeter.map(new MeterTimeMap());
+        //设置水位线(0 延迟)
+        SingleOutputStreamOperator<Tuple4<String, String, String, Long>> watermarks = map.assignTimestampsAndWatermarks(new MeterWaterLine(Time.seconds(0)));
+        //根据仪表标识分组
+        KeyedStream<Tuple4<String, String, String, Long>, String> keyedStream = watermarks.keyBy(new MeterIdSelector());
+        //提取出字段中分钟  间隔5分钟(%5) 间隔15分钟(%15)
+        keyedStream.process(new ScheduleTimeProcess(15))
+                //输出到impala表 电表隔5分钟的实时度数
+                .addSink(new SinkToImpalaMeterValue());
+
+        //TODO:设定窗口时间+无水位线(不准延迟数据)
+        SingleOutputStreamOperator<ElectricityMeter> process = keyedStream.timeWindow(Time.seconds(60 * 5))
+                //设置数据延迟到达的时间
+                .allowedLateness(Time.seconds(5 * 60))
+                //侧视图收集迟到5分钟内的数据
+                .sideOutputLateData(lateOutputTag)
+                .process(new ElectricityMeterProcess());
+        //电表业务数据处理后输出到impala
+        process.addSink(new SinkToImpala());
+        //窗口中电表延迟数据
+        DataStream<Tuple4<String, String, String, Long>> sideOutput = process.getSideOutput(lateOutputTag);
+        sideOutput.map(new MeterTimestampMap());
+    }
+
+
+}

+ 59 - 0
flink_metro/src/main/java/com/sunwin/metro/service/MetroService.java

@@ -0,0 +1,59 @@
+package com.sunwin.metro.service;
+
+import com.sunwin.metro.bean.DeviceWarn;
+import com.sunwin.metro.bean.MetroDevice;
+import com.sunwin.metro.consumer.TopicKeyWordsConsumer;
+import com.sunwin.metro.filter.MetroFilterMp;
+import com.sunwin.metro.flatmap.MetroDevicePropertyFlatmap;
+import com.sunwin.metro.key.DeviceKeySelector;
+import com.sunwin.metro.key.DeviceNameKeySelector;
+import com.sunwin.metro.key.MetroKeySelector;
+import com.sunwin.metro.map.DeviceAlarmMap;
+import com.sunwin.metro.map.DeviceMetricsMap;
+import com.sunwin.metro.process.DeviceAlarmProcess;
+import com.sunwin.metro.process.DeviceUnrepeated;
+import com.sunwin.metro.process.MetroKeyProcess;
+import com.sunwin.metro.sink.kudu.KuduSink;
+import com.sunwin.metro.sink.kudu.connector.KuduTableInfo;
+import com.sunwin.metro.watermark.DeviceWaterLine;
+import org.apache.flink.api.java.tuple.Tuple2;
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.streaming.api.datastream.DataStream;
+import org.apache.flink.streaming.api.datastream.DataStreamSource;
+import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
+import org.apache.flink.streaming.api.windowing.time.Time;
+import org.apache.flink.util.OutputTag;
+
+
+/**
+ * @author xuYJ
+ * @description: 消费kafka中地铁业务数据
+ * @create: 2020-08-26 14:10
+ * , BroadcastStream<Map<String, List<String>>> broadcast
+ */
+public class MetroService implements TopicKeyWordsConsumer {
+
+    @Override
+    public void process(DataStreamSource<Tuple4<String, Integer, Long, String>> input) {
+        KuduTableInfo kuduTableInfo = KuduTableInfo.Builder.open("impala::urtdb.metro_system_record").build();
+        KuduTableInfo tableName = KuduTableInfo.Builder.open("impala::urtdb.metro_warn_record").build();
+        OutputTag<Tuple2<String, Integer>> tag = new OutputTag<Tuple2<String, Integer>>("heavy") {
+        };
+        SingleOutputStreamOperator<String> process = input
+                .filter(new MetroFilterMp())
+                .keyBy(new MetroKeySelector()).process(new MetroKeyProcess(tag));
+        DataStream<Tuple2<String, Integer>> sideOutput = process.getSideOutput(tag);
+        sideOutput.print();
+        SingleOutputStreamOperator<MetroDevice> state = process.flatMap(new MetroDevicePropertyFlatmap())
+                .map(new DeviceMetricsMap())
+                .keyBy(new DeviceKeySelector())
+                .process(new DeviceUnrepeated());
+        state.addSink(new KuduSink<MetroDevice>("192.168.20.63:7051,192.168.20.64:7051,192.168.20.65:7051", kuduTableInfo, MetroDevice.class).withStrongConsistency());
+        state.assignTimestampsAndWatermarks(new DeviceWaterLine(Time.milliseconds(1000)));
+        SingleOutputStreamOperator<Tuple2<String, MetroDevice>> operator = state.keyBy(new DeviceNameKeySelector())
+                .process(new DeviceAlarmProcess());
+        operator
+                .map(new DeviceAlarmMap())
+                .addSink(new KuduSink<DeviceWarn>("192.168.20.63:7051,192.168.20.64:7051,192.168.20.65:7051", tableName, DeviceWarn.class).withStrongConsistency());
+    }
+}

+ 42 - 0
flink_metro/src/main/java/com/sunwin/metro/service/WriteMetroTxt.java

@@ -0,0 +1,42 @@
+package com.sunwin.metro.service;
+
+import com.alibaba.fastjson.JSON;
+import com.sunwin.metro.bean.MetroDevice;
+import com.sunwin.metro.consumer.TopicKeyWordsConsumer;
+import com.sunwin.metro.filter.MetroFilterMp;
+import com.sunwin.metro.flatmap.MetroDevicePropertyFlatmap;
+import com.sunwin.metro.key.MetroKeySelector;
+import com.sunwin.metro.process.MetroKeyProcess;
+import org.apache.commons.io.FileUtils;
+import org.apache.flink.api.java.tuple.Tuple2;
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.streaming.api.datastream.DataStreamSource;
+import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
+import org.apache.flink.streaming.api.functions.sink.SinkFunction;
+import org.apache.flink.util.OutputTag;
+
+import java.io.File;
+
+/**
+ * @program: sunwin_metro
+ * @description: 把kafka地铁数据整理写到txt
+ * @author: xuYJ
+ * @create: 2021-02-03 15:25
+ **/
+public class WriteMetroTxt implements TopicKeyWordsConsumer {
+
+    @Override
+    public void process(DataStreamSource<Tuple4<String, Integer, Long, String>> input) {
+        OutputTag<Tuple2<String, Integer>> tag = new OutputTag<Tuple2<String, Integer>>("heavy") {
+        };
+        SingleOutputStreamOperator<String> process = input.filter(new MetroFilterMp())
+                .keyBy(new MetroKeySelector()).process(new MetroKeyProcess(tag));
+        process.flatMap(new MetroDevicePropertyFlatmap())
+                .addSink(new SinkFunction<MetroDevice>() {
+                    @Override
+                    public void invoke(MetroDevice value, Context context) throws Exception {
+                        FileUtils.write(new File("C:\\Users\\daoda\\Desktop\\新建文件夹\\metro.txt"), JSON.toJSONString(value) + "\n", "UTF-8", true);
+                    }
+                });
+    }
+}

+ 103 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/impala/SinkToImpala.java

@@ -0,0 +1,103 @@
+package com.sunwin.metro.sink.impala;
+
+import com.alibaba.fastjson.JSON;
+import com.sunwin.metro.bean.ElectricityMeter;
+import com.sunwin.metro.utils.MysqlUtils;
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * @program: sunwin_metro
+ * @description: 把能耗结果输出到impala
+ * @author: xuYJ
+ * @create: 2021-04-15 09:54
+ **/
+public class SinkToImpala extends RichSinkFunction<ElectricityMeter> {
+    private Connection con = null;
+    private ResultSet rs = null;
+    private PreparedStatement ps = null;
+
+    @Override
+    public void open(Configuration parameters) throws Exception {
+        con = MysqlUtils.getImpalaCon(new BasicDataSource());
+        super.open(parameters);
+    }
+
+    @Override
+    public void close() throws Exception {
+        rs.close();
+        ps.close();
+        con.close();
+        super.close();
+    }
+
+    @Override
+    public void invoke(ElectricityMeter electricityMeter, Context context) throws Exception {
+        String sql = " INSERT  INTO electricity_meter (" +
+                "meter_number, update_time, electric_total_active, frequency, a_current, " +
+                "b_current, c_current, a_voltage, b_voltage, " +
+                "c_voltage, total_negative_active, a_negative_active, b_negative_active, " +
+                "c_negative_active, total_power_factor, a_power_factor, b_power_factor, c_power_factor, total_apparent_power, a_apparent_power, " +
+                "b_apparent_power, c_apparent_power, total_active_power, a_active_power, b_active_power, c_active_power, electric_status, total_active) " +
+                "VALUES(?, ?, ?, ?, ?, ? , ? , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )";
+        ps = con.prepareStatement(sql);
+        try {
+            ps.setString(1, electricityMeter.getMeter_number());
+            ps.setString(2, electricityMeter.getUpdate_time());
+            ps.setDouble(3, electricityMeter.getElectric_total_active());
+            ps.setObject(4, JSON.toJSONString(mapSort(electricityMeter.getFrequency())));
+            ps.setObject(5, JSON.toJSONString(mapSort(electricityMeter.getA_current())));
+            ps.setObject(6, JSON.toJSONString(mapSort(electricityMeter.getB_current())));
+            ps.setObject(7, JSON.toJSONString(mapSort(electricityMeter.getC_current())));
+            ps.setObject(8, JSON.toJSONString(mapSort(electricityMeter.getA_voltage())));
+            ps.setObject(9, JSON.toJSONString(mapSort(electricityMeter.getB_voltage())));
+            ps.setObject(10, JSON.toJSONString(mapSort(electricityMeter.getC_voltage())));
+            ps.setObject(11, JSON.toJSONString(mapSort(electricityMeter.getTotal_negative_active())));
+            ps.setObject(12, JSON.toJSONString(mapSort(electricityMeter.getA_negative_active())));
+            ps.setObject(13, JSON.toJSONString(mapSort(electricityMeter.getB_negative_active())));
+            ps.setObject(14, JSON.toJSONString(mapSort(electricityMeter.getC_negative_active())));
+            ps.setObject(15, JSON.toJSONString(mapSort(electricityMeter.getTotal_power_factor())));
+            ps.setObject(16, JSON.toJSONString(mapSort(electricityMeter.getA_power_factor())));
+            ps.setObject(17, JSON.toJSONString(mapSort(electricityMeter.getB_power_factor())));
+            ps.setObject(18, JSON.toJSONString(mapSort(electricityMeter.getC_power_factor())));
+            ps.setObject(19, JSON.toJSONString(mapSort(electricityMeter.getTotal_apparent_power())));
+            ps.setObject(20, JSON.toJSONString(mapSort(electricityMeter.getA_apparent_power())));
+            ps.setObject(21, JSON.toJSONString(mapSort(electricityMeter.getB_apparent_power())));
+            ps.setObject(22, JSON.toJSONString(mapSort(electricityMeter.getC_apparent_power())));
+            ps.setObject(23, JSON.toJSONString(mapSort(electricityMeter.getTotal_active_power())));
+            ps.setObject(24, JSON.toJSONString(mapSort(electricityMeter.getA_active_power())));
+            ps.setObject(25, JSON.toJSONString(mapSort(electricityMeter.getB_active_power())));
+            ps.setObject(26, JSON.toJSONString(mapSort(electricityMeter.getC_active_power())));
+            ps.setInt(27, electricityMeter.getElectric_status());
+            ps.setObject(28, JSON.toJSONString(mapSort(electricityMeter.getTotal_active())));
+            ps.addBatch();
+            ps.executeBatch();
+            con.commit();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public Map<String, Double> mapSort(Map<String, Double> map) {
+        Map<String, Double> mapSort = new TreeMap<>(Comparator.reverseOrder());
+        mapSort.putAll(map);
+        return mapSort;
+    }
+
+    public String mapSortValue(Map<String, Double> map) {
+        Map<String, Double> mapSort = new TreeMap<>(Comparator.reverseOrder());
+        mapSort.putAll(map);
+        return String.valueOf(mapSort.values());
+    }
+
+
+}

+ 62 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/impala/SinkToImpalaMeterValue.java

@@ -0,0 +1,62 @@
+package com.sunwin.metro.sink.impala;
+
+import com.alibaba.fastjson.JSON;
+import com.sunwin.metro.bean.ElectricityMeter;
+import com.sunwin.metro.utils.MysqlUtils;
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * @program: sunwin_metro
+ * @description: 把能耗结果输出到impala
+ * @author: xuYJ
+ * @create: 2021-04-15 09:54
+ **/
+public class SinkToImpalaMeterValue extends RichSinkFunction<ElectricityMeter> {
+    private Connection con = null;
+    private ResultSet rs = null;
+    private PreparedStatement ps = null;
+
+    @Override
+    public void open(Configuration parameters) throws Exception {
+        con = MysqlUtils.getImpalaCon(new BasicDataSource());
+        super.open(parameters);
+    }
+
+    @Override
+    public void close() throws Exception {
+        rs.close();
+        ps.close();
+        con.close();
+        super.close();
+    }
+
+    @Override
+    public void invoke(ElectricityMeter electricityMeter, Context context) throws Exception {
+        String sql = " INSERT  INTO electricity_meter_value (" +
+                "meter_number, update_time, electric_total_active, electric_status) " +
+                "VALUES(?, ?, ?, ? )";
+        ps = con.prepareStatement(sql);
+        try {
+            ps.setString(1, electricityMeter.getMeter_number());
+            ps.setString(2, electricityMeter.getUpdate_time());
+            ps.setDouble(3, electricityMeter.getElectric_total_active());
+            ps.setInt(4, electricityMeter.getElectric_status());
+            ps.addBatch();
+            ps.executeBatch();
+            con.commit();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+}

+ 60 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/impala/SinkToImpalaWarn.java

@@ -0,0 +1,60 @@
+package com.sunwin.metro.sink.impala;
+
+import com.sunwin.metro.bean.message.EquipmentWarn;
+import com.sunwin.metro.utils.MysqlUtils;
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+
+/**
+ * @program: sunwin_metro
+ * @description:impala插入数据
+ * @author: xuYJ
+ * @create: 2021-04-15 09:54
+ **/
+public class SinkToImpalaWarn extends RichSinkFunction<EquipmentWarn> {
+    private Connection con = null;
+    private PreparedStatement ps = null;
+
+    @Override
+    public void open(Configuration parameters) throws Exception {
+        con = MysqlUtils.getImpalaCon(new BasicDataSource());
+        super.open(parameters);
+    }
+
+    @Override
+    public void close() throws Exception {
+        ps.close();
+        con.close();
+        super.close();
+    }
+
+    @Override
+    public void invoke(EquipmentWarn value, Context context) throws Exception {
+        String sql = " INSERT  INTO  equipment_warn(" +
+                "line, equipment_code, station, equipment_name, warn_type, warn_time, " +
+                "current_time, flag ) " +
+                "VALUES(?, ?, ?, cast (? as string), cast (? as string), ? , ? , ?)";
+        ps = con.prepareStatement(sql);
+        try {
+            ps.setInt(1, value.getLine());
+            ps.setInt(2, value.getEquipment_code());
+            ps.setInt(3, value.getStation());
+            ps.setString(4, value.getEquipment_name());
+            ps.setString(5, value.getWarn_type());
+            ps.setString(6, value.getWarn_time());
+            ps.setString(7, value.getCurrent_time());
+            ps.setString(8, value.getFlag());
+            ps.addBatch();
+            ps.executeBatch();
+            con.commit();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+}

+ 219 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/KuduInputFormat.java

@@ -0,0 +1,219 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sunwin.metro.sink.kudu;
+
+
+import com.sunwin.metro.sink.kudu.connector.*;
+import org.apache.flink.api.common.io.LocatableInputSplitAssigner;
+
+import org.apache.flink.api.common.io.RichInputFormat;
+import org.apache.flink.api.common.io.statistics.BaseStatistics;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.core.io.InputSplitAssigner;
+import org.apache.flink.core.io.LocatableInputSplit;
+import org.apache.flink.util.Preconditions;
+import org.apache.kudu.client.KuduException;
+import org.apache.kudu.client.KuduScanToken;
+import org.apache.kudu.client.LocatedTablet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author xuYj
+ */
+public class KuduInputFormat extends RichInputFormat<KuduRow, KuduInputFormat.KuduInputSplit> {
+
+    private static final long serialVersionUID = 3262080936460631267L;
+    private String kuduMasters;
+    private KuduTableInfo tableInfo;
+    private List<KuduFilterInfo> tableFilters;
+    private List<String> tableProjections;
+    private Long rowsLimit;
+    private boolean endReached;
+
+    private transient KuduConnector tableContext;
+    private transient KuduRowIterator resultIterator;
+
+    private static final Logger LOG = LoggerFactory.getLogger(KuduInputFormat.class);
+
+    public KuduInputFormat(String kuduMasters, KuduTableInfo tableInfo) {
+        Preconditions.checkNotNull(kuduMasters, "kuduMasters could not be null");
+        this.kuduMasters = kuduMasters;
+
+        Preconditions.checkNotNull(tableInfo, "tableInfo could not be null");
+        this.tableInfo = tableInfo;
+
+        this.endReached = false;
+    }
+
+    public KuduInputFormat withTableFilters(KuduFilterInfo... tableFilters) {
+        return withTableFilters(Arrays.asList(tableFilters));
+    }
+
+    public KuduInputFormat withTableFilters(List<KuduFilterInfo> tableFilters) {
+        this.tableFilters = tableFilters;
+        return this;
+    }
+
+    public KuduInputFormat withTableProjections(String... tableProjections) {
+        return withTableProjections(Arrays.asList(tableProjections));
+    }
+
+    public KuduInputFormat withTableProjections(List<String> tableProjections) {
+        this.tableProjections = tableProjections;
+        return this;
+    }
+
+    public KuduInputFormat withRowsLimit(Long rowsLimit) {
+        this.rowsLimit = rowsLimit;
+        return this;
+    }
+
+    @Override
+    public void configure(Configuration parameters) {
+
+    }
+
+    @Override
+    public void open(KuduInputSplit split) throws IOException {
+        endReached = false;
+        startTableContext();
+
+        resultIterator = tableContext.scanner(split.getScanToken());
+    }
+
+    @Override
+    public void close() {
+        if (resultIterator != null) {
+            try {
+                resultIterator.close();
+            } catch (KuduException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    @Override
+    public BaseStatistics getStatistics(BaseStatistics cachedStatistics) throws IOException {
+        return cachedStatistics;
+    }
+
+    @Override
+    public InputSplitAssigner getInputSplitAssigner(KuduInputSplit[] inputSplits) {
+        return new LocatableInputSplitAssigner(inputSplits);
+    }
+
+    private void startTableContext() throws IOException {
+        if (tableContext == null) {
+            tableContext = new KuduConnector(kuduMasters, tableInfo);
+        }
+    }
+
+    @Override
+    public KuduInputSplit[] createInputSplits(int minNumSplits) throws IOException {
+        startTableContext();
+        Preconditions.checkNotNull(tableContext, "tableContext should not be null");
+
+        List<KuduScanToken> tokens = tableContext.scanTokens(tableFilters, tableProjections, rowsLimit);
+
+        KuduInputSplit[] splits = new KuduInputSplit[tokens.size()];
+
+        for (int i = 0; i < tokens.size(); i++) {
+            KuduScanToken token = tokens.get(i);
+
+            List<String> locations = new ArrayList<>(token.getTablet().getReplicas().size());
+
+            for (LocatedTablet.Replica replica : token.getTablet().getReplicas()) {
+                locations.add(getLocation(replica.getRpcHost(), replica.getRpcPort()));
+            }
+
+            KuduInputSplit split = new KuduInputSplit(
+                    token.serialize(),
+                    i,
+                    locations.toArray(new String[locations.size()])
+            );
+            splits[i] = split;
+        }
+
+        if (splits.length < minNumSplits) {
+            LOG.warn(" The minimum desired number of splits with your configured parallelism level " +
+                            "is {}. Current kudu splits = {}. {} instances will remain idle.",
+                    minNumSplits,
+                    splits.length,
+                    (minNumSplits - splits.length)
+            );
+        }
+
+        return splits;
+    }
+
+    @Override
+    public boolean reachedEnd() throws IOException {
+        return endReached;
+    }
+
+    @Override
+    public KuduRow nextRecord(KuduRow reuse) throws IOException {
+        // check that current iterator has next rows
+        if (this.resultIterator.hasNext()) {
+            return resultIterator.next();
+        } else {
+            endReached = true;
+            return null;
+        }
+    }
+
+    /**
+     * Returns a endpoint url in the following format: <host>:<ip>
+     *
+     * @param host Hostname
+     * @param port Port
+     * @return Formatted URL
+     */
+    private String getLocation(String host, Integer port) {
+        StringBuilder builder = new StringBuilder();
+        builder.append(host).append(":").append(port);
+        return builder.toString();
+    }
+
+
+    public class KuduInputSplit extends LocatableInputSplit {
+
+        private byte[] scanToken;
+
+        /**
+         * Creates a new KuduInputSplit
+         *
+         * @param splitNumber the number of the input split
+         * @param hostnames   The names of the hosts storing the data this input split refers to.
+         */
+        public KuduInputSplit(byte[] scanToken, final int splitNumber, final String[] hostnames) {
+            super(splitNumber, hostnames);
+
+            this.scanToken = scanToken;
+        }
+
+        public byte[] getScanToken() {
+            return scanToken;
+        }
+    }
+}

+ 125 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/KuduOutputFormat.java

@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sunwin.metro.sink.kudu;
+
+import com.sunwin.metro.sink.kudu.connector.KuduConnector;
+import com.sunwin.metro.sink.kudu.connector.KuduRow;
+import com.sunwin.metro.sink.kudu.connector.KuduTableInfo;
+import com.sunwin.metro.sink.kudu.serde.KuduSerialization;
+import org.apache.flink.api.common.io.RichOutputFormat;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.util.Preconditions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+
+/**
+ * @author xuYj
+ */
+public class KuduOutputFormat<OUT> extends RichOutputFormat<OUT> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(KuduOutputFormat.class);
+
+    private String kuduMasters;
+    private KuduTableInfo tableInfo;
+    private KuduConnector.Consistency consistency;
+    private KuduConnector.WriteMode writeMode;
+
+    private KuduSerialization<OUT> serializer;
+
+    private transient KuduConnector connector;
+
+
+    public KuduOutputFormat(String kuduMasters, KuduTableInfo tableInfo, KuduSerialization<OUT> serializer) {
+        Preconditions.checkNotNull(kuduMasters, "kuduMasters could not be null");
+        this.kuduMasters = kuduMasters;
+
+        Preconditions.checkNotNull(tableInfo, "tableInfo could not be null");
+        this.tableInfo = tableInfo;
+        this.consistency = KuduConnector.Consistency.STRONG;
+        this.writeMode = KuduConnector.WriteMode.UPSERT;
+        this.serializer = serializer.withSchema(tableInfo.getSchema());
+    }
+
+
+    public KuduOutputFormat<OUT> withEventualConsistency() {
+        this.consistency = KuduConnector.Consistency.EVENTUAL;
+        return this;
+    }
+
+    public KuduOutputFormat<OUT> withStrongConsistency() {
+        this.consistency = KuduConnector.Consistency.STRONG;
+        return this;
+    }
+
+    public KuduOutputFormat<OUT> withUpsertWriteMode() {
+        this.writeMode = KuduConnector.WriteMode.UPSERT;
+        return this;
+    }
+
+    public KuduOutputFormat<OUT> withInsertWriteMode() {
+        this.writeMode = KuduConnector.WriteMode.INSERT;
+        return this;
+    }
+
+    public KuduOutputFormat<OUT> withUpdateWriteMode() {
+        this.writeMode = KuduConnector.WriteMode.UPDATE;
+        return this;
+    }
+
+    @Override
+    public void configure(Configuration parameters) {
+
+    }
+
+    @Override
+    public void open(int taskNumber, int numTasks) throws IOException {
+        if (connector != null) {
+            return;
+        }
+        connector = new KuduConnector(kuduMasters, tableInfo, consistency, writeMode);
+        serializer = serializer.withSchema(tableInfo.getSchema());
+    }
+
+    @Override
+    public void writeRecord(OUT row) throws IOException {
+        boolean response;
+        try {
+            KuduRow kuduRow = serializer.serialize(row);
+            response = connector.writeRow(kuduRow);
+        } catch (Exception e) {
+            throw new IOException(e.getLocalizedMessage(), e);
+        }
+
+        if (!response) {
+            throw new IOException("error with some transaction");
+        }
+    }
+
+    @Override
+    public void close() throws IOException {
+        if (this.connector == null) {
+            return;
+        }
+        try {
+            this.connector.close();
+        } catch (Exception e) {
+            throw new IOException(e.getLocalizedMessage(), e);
+        }
+    }
+}

+ 136 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/KuduSink.java

@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sunwin.metro.sink.kudu;
+
+import com.sunwin.metro.sink.kudu.connector.KuduConnector;
+import com.sunwin.metro.sink.kudu.connector.KuduTableInfo;
+import com.sunwin.metro.sink.kudu.pojo.HbaseBeanFieldModel;
+import com.sunwin.metro.sink.kudu.serde.KuduSerialization;
+import com.sunwin.metro.sink.kudu.utils.KuduUtils;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
+import org.apache.flink.util.Preconditions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+
+/**
+ * @author xuYj
+ */
+public class KuduSink<OUT> extends RichSinkFunction<OUT> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(KuduSink.class);
+
+    private static final long serialVersionUID = -893553371298868553L;
+
+    private String kuduMasters;
+    private KuduTableInfo tableInfo;
+    private KuduConnector.Consistency consistency;
+    private KuduConnector.WriteMode writeMode;
+
+    private KuduSerialization<OUT> serializer;
+
+    private transient KuduConnector connector;
+
+    private Class aClass;
+
+    public KuduSink(String kuduMasters, KuduTableInfo tableInfo, KuduSerialization<OUT> serializer) {
+        Preconditions.checkNotNull(kuduMasters, "kuduMasters could not be null");
+        this.kuduMasters = kuduMasters;
+
+        Preconditions.checkNotNull(tableInfo, "tableInfo could not be null");
+        this.tableInfo = tableInfo;
+        this.consistency = KuduConnector.Consistency.STRONG;
+        this.writeMode = KuduConnector.WriteMode.UPSERT;
+        this.serializer = serializer.withSchema(tableInfo.getSchema());
+    }
+
+
+    public KuduSink(String kuduMasters, KuduTableInfo tableInfo, Class aClass) {
+        Preconditions.checkNotNull(kuduMasters, "kuduMasters could not be null");
+        this.kuduMasters = kuduMasters;
+
+        Preconditions.checkNotNull(tableInfo, "tableInfo could not be null");
+        this.tableInfo = tableInfo;
+        this.consistency = KuduConnector.Consistency.STRONG;
+        this.writeMode = KuduConnector.WriteMode.UPSERT;
+        this.aClass = aClass;
+    }
+
+    public KuduSink<OUT> withEventualConsistency() {
+        this.consistency = KuduConnector.Consistency.EVENTUAL;
+        return this;
+    }
+
+    public KuduSink<OUT> withStrongConsistency() {
+        this.consistency = KuduConnector.Consistency.STRONG;
+        return this;
+    }
+
+    public KuduSink<OUT> withUpsertWriteMode() {
+        this.writeMode = KuduConnector.WriteMode.UPSERT;
+        return this;
+    }
+
+    public KuduSink<OUT> withInsertWriteMode() {
+        this.writeMode = KuduConnector.WriteMode.INSERT;
+        return this;
+    }
+
+    public KuduSink<OUT> withUpdateWriteMode() {
+        this.writeMode = KuduConnector.WriteMode.UPDATE;
+        return this;
+    }
+
+    @Override
+    public void open(Configuration parameters) throws IOException {
+        if (connector != null) {
+            return;
+        }
+        connector = new KuduConnector(kuduMasters, tableInfo, consistency, writeMode);
+//        serializer.withSchema(tableInfo.getSchema());
+    }
+
+
+    @Override
+    public void invoke(OUT value, Context context) throws Exception {
+//        KuduRow kuduRow = serializer.serialize(value);
+//        boolean response = connector.writeRow(kuduRow);
+        HbaseBeanFieldModel[] hbaseBeanFieldModels = KuduUtils.getBeanFieldModels(aClass);
+        boolean response = false;
+        if (null != hbaseBeanFieldModels) {
+            response = connector.writeRow(hbaseBeanFieldModels, value);
+        }
+
+        if (!response) {
+            throw new IOException("error with some transaction");
+        }
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (this.connector == null) {
+            return;
+        }
+        try {
+            this.connector.close();
+        } catch (Exception e) {
+            throw new IOException(e.getLocalizedMessage(), e);
+        }
+    }
+}

+ 214 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/connector/KuduColumnInfo.java

@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sunwin.metro.sink.kudu.connector;
+
+import org.apache.kudu.ColumnSchema;
+import org.apache.kudu.Type;
+
+import java.io.Serializable;
+
+/**
+ * @author xuYj
+ */
+public class KuduColumnInfo implements Serializable {
+
+    private  String name;
+    private  Type type;
+    private boolean key;
+    private boolean rangeKey;
+    private boolean hashKey;
+    private boolean nullable;
+    private Object defaultValue;
+    private int blockSize;
+    private Encoding encoding;
+    private Compression compression;
+
+    private KuduColumnInfo(String name, Type type) {
+        this.name = name;
+        this.type = type;
+        this.blockSize = 0;
+        this.key = false;
+        this.rangeKey = false;
+        this.hashKey = false;
+        this.nullable = false;
+        this.defaultValue = null;
+        this.encoding = Encoding.AUTO;
+        this.compression = Compression.DEFAULT;
+    }
+
+    protected String name() {
+        return name;
+    }
+
+    protected boolean isRangeKey() {
+        return rangeKey;
+    }
+
+    protected boolean isHashKey() {
+        return hashKey;
+    }
+
+    protected ColumnSchema columnSchema() {
+        return new ColumnSchema.ColumnSchemaBuilder(name, type)
+                    .key(key)
+                    .nullable(nullable)
+                    .defaultValue(defaultValue)
+                    .desiredBlockSize(blockSize)
+                    .encoding(encoding.encode)
+                    .compressionAlgorithm(compression.algorithm)
+                    .build();
+    }
+
+    public static class Builder {
+        private KuduColumnInfo column;
+
+        private Builder(String name, Type type) {
+            this.column = new KuduColumnInfo(name, type);
+        }
+
+        public static Builder create(String name, Type type) {
+            return new Builder(name, type);
+        }
+        public static Builder createByte(String name) {
+            return create(name, Type.INT8);
+        }
+        public static Builder createShort(String name) {
+            return create(name, Type.INT16);
+        }
+        public static Builder createInteger(String name) {
+            return create(name, Type.INT32);
+        }
+        public static Builder createLong(String name) {
+            return create(name, Type.INT64);
+        }
+        public static Builder createDouble(String name) {
+            return create(name, Type.DOUBLE);
+        }
+        public static Builder createFloat(String name) {
+            return create(name, Type.FLOAT);
+        }
+        public static Builder createString(String name) {
+            return create(name, Type.STRING);
+        }
+        public static Builder createBool(String name) {
+            return create(name, Type.BOOL);
+        }
+        public static Builder createByteArray(String name) {
+            return create(name, Type.BINARY);
+        }
+        public static Builder createUnixTime(String name) {
+            return create(name, Type.UNIXTIME_MICROS);
+        }
+
+        public Builder asKey() {
+            return key(true);
+        }
+
+        public Builder key(boolean key) {
+            this.column.key = key;
+            return this;
+        }
+
+        public Builder asRangeKey() {
+            return rangeKey(true);
+        }
+
+        public Builder rangeKey(boolean rangeKey) {
+            this.column.rangeKey = rangeKey;
+            return this;
+        }
+
+        public Builder asHashKey() {
+            return hashKey(true);
+        }
+
+        public Builder hashKey(boolean hashKey) {
+            this.column.hashKey = hashKey;
+            return this;
+        }
+
+        public Builder asNullable() {
+            return nullable(true);
+        }
+
+        public Builder asNotNullable() {
+            return nullable(false);
+        }
+
+        public Builder nullable(boolean nullable) {
+            this.column.nullable = nullable;
+            return this;
+        }
+
+        public Builder defaultValue(Object defaultValue) {
+            this.column.defaultValue = defaultValue;
+            return this;
+        }
+
+        public Builder desiredBlockSize(int blockSize) {
+            this.column.blockSize = blockSize;
+            return this;
+        }
+
+        public Builder encoding(Encoding encoding) {
+            this.column.encoding = encoding;
+            return this;
+        }
+
+        public Builder compressionAlgorithm(Compression compression) {
+            this.column.compression = compression;
+            return this;
+        }
+
+        public KuduColumnInfo build() {
+            return column;
+        }
+    }
+
+    public enum Compression {
+        UNKNOWN(ColumnSchema.CompressionAlgorithm.UNKNOWN),
+        DEFAULT(ColumnSchema.CompressionAlgorithm.DEFAULT_COMPRESSION),
+        WITHOUT(ColumnSchema.CompressionAlgorithm.NO_COMPRESSION),
+        SNAPPY(ColumnSchema.CompressionAlgorithm.SNAPPY),
+        LZ4(ColumnSchema.CompressionAlgorithm.LZ4),
+        ZLIB(ColumnSchema.CompressionAlgorithm.ZLIB);
+
+        final ColumnSchema.CompressionAlgorithm algorithm;
+
+        Compression(ColumnSchema.CompressionAlgorithm algorithm) {
+            this.algorithm = algorithm;
+        }
+    }
+
+    public enum Encoding {
+        UNKNOWN(ColumnSchema.Encoding.UNKNOWN),
+        AUTO(ColumnSchema.Encoding.AUTO_ENCODING),
+        PLAIN(ColumnSchema.Encoding.PLAIN_ENCODING),
+        PREFIX(ColumnSchema.Encoding.PREFIX_ENCODING),
+        GROUP_VARINT(ColumnSchema.Encoding.GROUP_VARINT),
+        RLE(ColumnSchema.Encoding.RLE),
+        DICT(ColumnSchema.Encoding.DICT_ENCODING),
+        BIT_SHUFFLE(ColumnSchema.Encoding.BIT_SHUFFLE);
+
+        final ColumnSchema.Encoding encode;
+
+        Encoding(ColumnSchema.Encoding encode) {
+            this.encode = encode;
+        }
+    }
+
+}

+ 188 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/connector/KuduConnector.java

@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sunwin.metro.sink.kudu.connector;
+
+import com.stumbleupon.async.Callback;
+import com.stumbleupon.async.Deferred;
+import com.sunwin.metro.sink.kudu.pojo.HbaseBeanFieldModel;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.flink.api.common.time.Time;
+import org.apache.kudu.client.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @author xuYj
+ */
+public class KuduConnector implements AutoCloseable {
+
+    private final Logger LOG = LoggerFactory.getLogger(this.getClass());
+
+    private Callback<Boolean, OperationResponse> defaultCB;
+
+    public enum Consistency {EVENTUAL, STRONG}
+
+
+    public enum WriteMode {INSERT, UPDATE, UPSERT}
+
+    private AsyncKuduClient client;
+    private KuduTable table;
+
+    private Consistency consistency;
+    private WriteMode writeMode;
+
+    private static AtomicInteger pendingTransactions = new AtomicInteger();
+    private static AtomicBoolean errorTransactions = new AtomicBoolean(false);
+
+    public KuduConnector(String kuduMasters, KuduTableInfo tableInfo) throws IOException {
+        this(kuduMasters, tableInfo, Consistency.STRONG, WriteMode.UPSERT);
+    }
+
+    public KuduConnector(String kuduMasters, KuduTableInfo tableInfo, Consistency consistency, WriteMode writeMode) throws IOException {
+        this.client = client(kuduMasters);
+        this.table = table(tableInfo);
+        this.consistency = consistency;
+        this.writeMode = writeMode;
+        this.defaultCB = new ResponseCallback();
+    }
+
+    private AsyncKuduClient client(String kuduMasters) {
+        return new AsyncKuduClient.AsyncKuduClientBuilder(kuduMasters).build();
+    }
+
+    private KuduTable table(KuduTableInfo infoTable) throws IOException {
+        KuduClient syncClient = client.syncClient();
+
+        String tableName = infoTable.getName();
+        if (syncClient.tableExists(tableName)) {
+            return syncClient.openTable(tableName);
+        }
+        if (infoTable.createIfNotExist()) {
+            return syncClient.createTable(tableName, infoTable.getSchema(), infoTable.getCreateTableOptions());
+        }
+        throw new UnsupportedOperationException("table not exists and is marketed to not be created");
+    }
+
+    public boolean deleteTable() throws IOException {
+        String tableName = table.getName();
+        client.syncClient().deleteTable(tableName);
+        return true;
+    }
+
+    public KuduRowIterator scanner(byte[] token) throws IOException {
+        return new KuduRowIterator(KuduScanToken.deserializeIntoScanner(token, client.syncClient()));
+    }
+
+    public List<KuduScanToken> scanTokens(List<KuduFilterInfo> tableFilters, List<String> tableProjections, Long rowLimit) {
+        KuduScanToken.KuduScanTokenBuilder tokenBuilder = client.syncClient().newScanTokenBuilder(table);
+
+        if (CollectionUtils.isNotEmpty(tableProjections)) {
+            tokenBuilder.setProjectedColumnNames(tableProjections);
+        }
+
+        if (CollectionUtils.isNotEmpty(tableFilters)) {
+            tableFilters.stream()
+                    .map(filter -> filter.toPredicate(table.getSchema()))
+                    .forEach(tokenBuilder::addPredicate);
+        }
+
+        if (rowLimit != null && rowLimit > 0) {
+            tokenBuilder.limit(rowLimit);
+        }
+
+        return tokenBuilder.build();
+    }
+
+    public boolean writeRow(KuduRow row) throws Exception {
+        final Operation operation = KuduMapper.toOperation(table, writeMode, row);
+
+        AsyncKuduSession session = client.newSession();
+        Deferred<OperationResponse> response = session.apply(operation);
+
+        if (Consistency.EVENTUAL.equals(consistency)) {
+            pendingTransactions.incrementAndGet();
+            response.addCallback(defaultCB);
+        } else {
+            processResponse(response.join());
+        }
+
+        session.close();
+        return !errorTransactions.get();
+
+    }
+
+    public boolean writeRow(HbaseBeanFieldModel[] hbaseBeanFieldModels, Object object) throws Exception {
+        final Operation operation = KuduMapper.toOperation(table, writeMode, hbaseBeanFieldModels, object);
+
+        AsyncKuduSession session = client.newSession();
+        Deferred<OperationResponse> response = session.apply(operation);
+
+        if (Consistency.EVENTUAL.equals(consistency)) {
+            pendingTransactions.incrementAndGet();
+            response.addCallback(defaultCB);
+        } else {
+            processResponse(response.join());
+        }
+
+        session.close();
+        return !errorTransactions.get();
+
+    }
+
+
+    @Override
+    public void close() throws Exception {
+        while (pendingTransactions.get() > 0) {
+            LOG.info("sleeping {}s by pending transactions", pendingTransactions.get());
+            Thread.sleep(Time.seconds(pendingTransactions.get()).toMilliseconds());
+        }
+
+        if (client == null) {
+            return;
+        }
+        client.close();
+    }
+
+    private class ResponseCallback implements Callback<Boolean, OperationResponse> {
+        @Override
+        public Boolean call(OperationResponse operationResponse) {
+            pendingTransactions.decrementAndGet();
+            processResponse(operationResponse);
+            return errorTransactions.get();
+        }
+    }
+
+    protected void processResponse(OperationResponse operationResponse) {
+        if (operationResponse == null) {
+            return;
+        }
+        if (operationResponse.hasRowError()) {
+            logResponseError(operationResponse.getRowError());
+            errorTransactions.set(true);
+        }
+    }
+
+    private void logResponseError(RowError error) {
+        LOG.error("Error {} on {}: {} ", error.getErrorStatus(), error.getOperation(), error.toString());
+    }
+
+}

+ 176 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/connector/KuduFilterInfo.java

@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sunwin.metro.sink.kudu.connector;
+
+import org.apache.kudu.ColumnSchema;
+import org.apache.kudu.Schema;
+import org.apache.kudu.client.KuduPredicate;
+
+import java.util.List;
+
+
+/**
+ * @author xuYj
+ */
+public class KuduFilterInfo {
+
+    private String column;
+    private FilterType type;
+    private Object value;
+
+    private KuduFilterInfo() { }
+
+    public KuduPredicate toPredicate(Schema schema) {
+        return toPredicate(schema.getColumn(this.column));
+    }
+    public KuduPredicate toPredicate(ColumnSchema column) {
+        KuduPredicate predicate;
+        switch (this.type) {
+            case IS_IN:
+                predicate = KuduPredicate.newInListPredicate(column, (List) this.value);
+                break;
+            case IS_NULL:
+                predicate = KuduPredicate.newIsNullPredicate(column);
+                break;
+            case IS_NOT_NULL:
+                predicate = KuduPredicate.newIsNotNullPredicate(column);
+                break;
+            default:
+                predicate = predicateComparator(column);
+                break;
+        }
+        return predicate;
+    }
+
+    private KuduPredicate predicateComparator(ColumnSchema column) {
+
+        KuduPredicate.ComparisonOp comparison = this.type.comparator;
+
+        KuduPredicate predicate;
+
+        switch (column.getType()) {
+            case STRING:
+                predicate = KuduPredicate.newComparisonPredicate(column, comparison, (String)this.value);
+                break;
+            case FLOAT:
+                predicate = KuduPredicate.newComparisonPredicate(column, comparison, (Float)this.value);
+                break;
+            case INT8:
+                predicate = KuduPredicate.newComparisonPredicate(column, comparison, (Byte)this.value);
+                break;
+            case INT16:
+                predicate = KuduPredicate.newComparisonPredicate(column, comparison, (Short)this.value);
+                break;
+            case INT32:
+                predicate = KuduPredicate.newComparisonPredicate(column, comparison, (Integer)this.value);
+                break;
+            case INT64:
+                predicate = KuduPredicate.newComparisonPredicate(column, comparison, (Long)this.value);
+                break;
+            case DOUBLE:
+                predicate = KuduPredicate.newComparisonPredicate(column, comparison, (Double)this.value);
+                break;
+            case BOOL:
+                predicate = KuduPredicate.newComparisonPredicate(column, comparison, (Boolean)this.value);
+                break;
+            case UNIXTIME_MICROS:
+                Long time = (Long)this.value;
+                predicate = KuduPredicate.newComparisonPredicate(column, comparison, time*1000);
+                break;
+            case BINARY:
+                predicate = KuduPredicate.newComparisonPredicate(column, comparison, (byte[])this.value);
+                break;
+            default:
+                throw new IllegalArgumentException("Illegal var type: " + column.getType());
+        }
+        return predicate;
+    }
+
+    public static class Builder {
+        private KuduFilterInfo filter;
+
+        private Builder(String column) {
+            this.filter = new KuduFilterInfo();
+            this.filter.column = column;
+        }
+
+        public static Builder create(String column) {
+            return new Builder(column);
+        }
+
+        public Builder greaterThan(Object value) {
+            return filter(FilterType.GREATER, value);
+        }
+
+        public Builder lessThan(Object value) {
+            return filter(FilterType.LESS, value);
+        }
+
+        public Builder equalTo(Object value) {
+            return filter(FilterType.EQUAL, value);
+        }
+
+        public Builder greaterOrEqualTo(Object value) {
+            return filter(FilterType.GREATER_EQUAL, value);
+        }
+
+        public Builder lessOrEqualTo(Object value) {
+            return filter(FilterType.LESS_EQUAL, value);
+        }
+
+        public Builder isNotNull() {
+            return filter(FilterType.IS_NOT_NULL, null);
+        }
+
+        public Builder isNull() {
+            return filter(FilterType.IS_NULL, null);
+        }
+
+        public Builder isIn(List values) {
+            return filter(FilterType.IS_IN, values);
+        }
+
+        public Builder filter(FilterType type, Object value) {
+            this.filter.type = type;
+            this.filter.value = value;
+            return this;
+        }
+
+        public KuduFilterInfo build() {
+            return filter;
+        }
+    }
+
+    public enum FilterType {
+        GREATER(KuduPredicate.ComparisonOp.GREATER),
+        GREATER_EQUAL(KuduPredicate.ComparisonOp.GREATER_EQUAL),
+        EQUAL(KuduPredicate.ComparisonOp.EQUAL),
+        LESS(KuduPredicate.ComparisonOp.LESS),
+        LESS_EQUAL(KuduPredicate.ComparisonOp.LESS_EQUAL),
+        IS_NOT_NULL(null),
+        IS_NULL(null),
+        IS_IN(null);
+
+        final KuduPredicate.ComparisonOp comparator;
+
+        FilterType(KuduPredicate.ComparisonOp comparator) {
+            this.comparator = comparator;
+        }
+
+    }
+
+}

+ 235 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/connector/KuduMapper.java

@@ -0,0 +1,235 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sunwin.metro.sink.kudu.connector;
+
+
+
+import com.sunwin.metro.sink.kudu.pojo.HbaseBeanFieldModel;
+import org.apache.kudu.Schema;
+import org.apache.kudu.Type;
+import org.apache.kudu.client.KuduTable;
+import org.apache.kudu.client.Operation;
+import org.apache.kudu.client.PartialRow;
+import org.apache.kudu.client.RowResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.InvocationTargetException;
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.util.Date;
+
+final class KuduMapper {
+    private static final Logger LOG = LoggerFactory.getLogger(KuduMapper.class);
+
+    private KuduMapper() {
+    }
+
+    static KuduRow toKuduRow(RowResult row) {
+        Schema schema = row.getColumnProjection();
+
+        KuduRow values = new KuduRow(schema.getColumnCount());
+        schema.getColumns().forEach(column -> {
+            String name = column.getName();
+            int pos = schema.getColumnIndex(name);
+            if (row.isNull(name)) {
+                values.setField(pos, name, null);
+            } else {
+                Type type = column.getType();
+                switch (type) {
+                    case BINARY:
+                        values.setField(pos, name, row.getBinary(name));
+                        break;
+                    case STRING:
+                        values.setField(pos, name, row.getString(name));
+                        break;
+                    case BOOL:
+                        values.setField(pos, name, row.getBoolean(name));
+                        break;
+                    case DOUBLE:
+                        values.setField(pos, name, row.getDouble(name));
+                        break;
+                    case FLOAT:
+                        values.setField(pos, name, row.getFloat(name));
+                        break;
+                    case INT8:
+                        values.setField(pos, name, row.getByte(name));
+                        break;
+                    case INT16:
+                        values.setField(pos, name, row.getShort(name));
+                        break;
+                    case INT32:
+                        values.setField(pos, name, row.getInt(name));
+                        break;
+                    case INT64:
+                        values.setField(pos, name, row.getLong(name));
+                        break;
+                    case UNIXTIME_MICROS:
+                        values.setField(pos, name, row.getLong(name) / 1000);
+                        break;
+                    default:
+                        throw new IllegalArgumentException("Illegal var type: " + type);
+                }
+            }
+        });
+        return values;
+    }
+
+
+    static Operation toOperation(KuduTable table, KuduConnector.WriteMode writeMode, KuduRow row) {
+        final Operation operation = toOperation(table, writeMode);
+        final PartialRow partialRow = operation.getRow();
+
+        table.getSchema().getColumns().forEach(column -> {
+            String columnName = column.getName();
+            Object value = row.getField(column.getName());
+
+            if (value == null) {
+                partialRow.setNull(columnName);
+            } else {
+                Type type = column.getType();
+                switch (type) {
+                    case STRING:
+                        partialRow.addString(columnName, (String) value);
+                        break;
+                    case FLOAT:
+                        partialRow.addFloat(columnName, (Float) value);
+                        break;
+                    case INT8:
+                        partialRow.addByte(columnName, (Byte) value);
+                        break;
+                    case INT16:
+                        partialRow.addShort(columnName, (Short) value);
+                        break;
+                    case INT32:
+                        partialRow.addInt(columnName, (Integer) value);
+                        break;
+                    case INT64:
+                        partialRow.addLong(columnName, (Long) value);
+                        break;
+                    case DOUBLE:
+                        partialRow.addDouble(columnName, (Double) value);
+                        break;
+                    case BOOL:
+                        partialRow.addBoolean(columnName, (Boolean) value);
+                        break;
+                    case UNIXTIME_MICROS:
+                        //*1000 to correctly create date on kudu
+                        partialRow.addLong(columnName, ((Long) value) * 1000);
+                        break;
+                    case BINARY:
+                        partialRow.addBinary(columnName, (byte[]) value);
+                        break;
+                    default:
+                        throw new IllegalArgumentException("Illegal var type: " + type);
+                }
+            }
+        });
+        return operation;
+    }
+
+
+    static Operation toOperation(KuduTable table, KuduConnector.WriteMode writeMode, HbaseBeanFieldModel[] hbaseBeanFieldModels, Object object) {
+        if (null == table) {
+            throw new IllegalArgumentException("Table Open Failed , please check table exists");
+        }
+        final Operation operation = toOperation(table, writeMode);
+        PartialRow partialRow = operation.getRow();
+
+
+        for (HbaseBeanFieldModel hbaseBeanFieldModel : hbaseBeanFieldModels) {
+            String fieldName = hbaseBeanFieldModel.getFieldName().toLowerCase();
+            try {
+                if (null == hbaseBeanFieldModel.getGetMethod().invoke(object)) {
+                    partialRow.setNull(fieldName);
+                } else {
+                    if ("String".equalsIgnoreCase(hbaseBeanFieldModel.getFieldType().getSimpleName())) {
+                        partialRow.addString(fieldName, (String) hbaseBeanFieldModel.getGetMethod().invoke(object));
+                        continue;
+                    }
+                    if ("Float".equalsIgnoreCase(hbaseBeanFieldModel.getFieldType().getSimpleName())) {
+                        partialRow.addFloat(fieldName, (Float) hbaseBeanFieldModel.getGetMethod().invoke(object));
+                        continue;
+                    }
+                    if ("Byte".equalsIgnoreCase(hbaseBeanFieldModel.getFieldType().getSimpleName())) {
+                        partialRow.addByte(fieldName, (Byte) hbaseBeanFieldModel.getGetMethod().invoke(object));
+                        continue;
+                    }
+                    if ("Short".equalsIgnoreCase(hbaseBeanFieldModel.getFieldType().getSimpleName())) {
+                        partialRow.addShort(fieldName, (Short) hbaseBeanFieldModel.getGetMethod().invoke(object));
+                        continue;
+                    }
+                    if ("Integer".equalsIgnoreCase(hbaseBeanFieldModel.getFieldType().getSimpleName())) {
+                        partialRow.addInt(fieldName, (Integer) hbaseBeanFieldModel.getGetMethod().invoke(object));
+                        continue;
+                    }
+                    if ("Long".equalsIgnoreCase(hbaseBeanFieldModel.getFieldType().getSimpleName())) {
+                        partialRow.addLong(fieldName, (Long) hbaseBeanFieldModel.getGetMethod().invoke(object));
+                        continue;
+                    }
+                    if ("Double".equalsIgnoreCase(hbaseBeanFieldModel.getFieldType().getSimpleName())) {
+                        partialRow.addDouble(fieldName, (Double) hbaseBeanFieldModel.getGetMethod().invoke(object));
+                        continue;
+                    }
+                    if ("BigDecimal".equalsIgnoreCase(hbaseBeanFieldModel.getFieldType().getSimpleName())) {
+                        partialRow.addDecimal(fieldName, (BigDecimal) hbaseBeanFieldModel.getGetMethod().invoke(object));
+                        continue;
+                    }
+                    if ("Boolean".equalsIgnoreCase(hbaseBeanFieldModel.getFieldType().getSimpleName())) {
+                        partialRow.addBoolean(fieldName, (Boolean) hbaseBeanFieldModel.getGetMethod().invoke(object));
+                        continue;
+                    }
+                    if ("Date".equalsIgnoreCase(hbaseBeanFieldModel.getFieldType().getSimpleName())) {
+                        partialRow.addTimestamp(fieldName, new Timestamp(((Date) hbaseBeanFieldModel.getGetMethod().invoke(object)).getTime()));
+                        continue;
+                    }
+                    if ("Timestamp".equalsIgnoreCase(hbaseBeanFieldModel.getFieldType().getSimpleName())) {
+                        partialRow.addTimestamp(fieldName, (Timestamp) hbaseBeanFieldModel.getGetMethod().invoke(object));
+                        continue;
+                    }
+                    if ("byte[]".equalsIgnoreCase(hbaseBeanFieldModel.getFieldType().getSimpleName())) {
+                        partialRow.addBinary(fieldName, (byte[]) hbaseBeanFieldModel.getGetMethod().invoke(object));
+                        continue;
+                    }
+                    throw new IllegalArgumentException("Illegal var type: " + hbaseBeanFieldModel.getFieldType().getSimpleName());
+                }
+            } catch (IllegalAccessException | InvocationTargetException e) {
+                LOG.error("从hbaseBeanFieldModels获取字段类型失败");
+                e.printStackTrace();
+                throw new IllegalArgumentException(" KuduMapper toOperation get hbaseBeanFieldModels Field Type fail");
+
+            }
+        }
+        return operation;
+
+    }
+
+
+    static Operation toOperation(KuduTable table, KuduConnector.WriteMode writeMode) {
+        switch (writeMode) {
+            case INSERT:
+                return table.newInsert();
+            case UPDATE:
+                return table.newUpdate();
+            case UPSERT:
+                return table.newUpsert();
+            default:
+                return table.newUpdate();
+        }
+    }
+
+}

+ 88 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/connector/KuduRow.java

@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sunwin.metro.sink.kudu.connector;
+
+
+
+
+
+import org.apache.flink.types.Row;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.stream.Stream;
+
+/**
+ * @author xuYj
+ */
+public class KuduRow extends Row {
+
+    private Map<String, Integer> rowNames;
+
+    public KuduRow(Integer arity) {
+        super(arity);
+        rowNames = new LinkedHashMap<>();
+    }
+
+    public Object getField(String name) {
+        return super.getField(rowNames.get(name));
+    }
+
+    public void setField(int pos, String name, Object value) {
+        super.setField(pos, value);
+        this.rowNames.put(name, pos);
+    }
+
+    public boolean isNull(String name) {
+        return isNull(rowNames.get(name));
+    }
+
+    public boolean isNull(int pos) {
+        return getField(pos) == null;
+    }
+
+    private static int validFields(Object object) {
+        Long validField = 0L;
+        for (Class<?> c = object.getClass(); c != null; c = c.getSuperclass()) {
+            validField += basicValidation(c.getDeclaredFields()).count();
+        }
+        return validField.intValue();
+    }
+
+    private static Stream<Field> basicValidation(Field[] fields) {
+        return Arrays.stream(fields)
+                .filter(cField -> !Modifier.isStatic(cField.getModifiers()))
+                .filter(cField -> !Modifier.isTransient(cField.getModifiers()));
+    }
+
+    public Map<String,Object> blindMap() {
+        Map<String,Object> toRet = new LinkedHashMap<>();
+        rowNames.entrySet().stream()
+                .sorted(Comparator.comparing(Map.Entry::getValue))
+                .forEach(entry -> toRet.put(entry.getKey(), super.getField(entry.getValue())));
+        return  toRet;
+    }
+
+    @Override
+    public String toString() {
+        return blindMap().toString();
+    }
+}

+ 60 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/connector/KuduRowIterator.java

@@ -0,0 +1,60 @@
+/*
+ * Licensed serialize the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file serialize You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed serialize in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sunwin.metro.sink.kudu.connector;
+
+import org.apache.kudu.client.KuduException;
+import org.apache.kudu.client.KuduScanner;
+import org.apache.kudu.client.RowResult;
+import org.apache.kudu.client.RowResultIterator;
+
+/**
+ * @author xuYj
+ */
+public class KuduRowIterator {
+
+    private KuduScanner scanner;
+    private RowResultIterator rowIterator;
+
+    public KuduRowIterator(KuduScanner scanner) throws KuduException {
+        this.scanner = scanner;
+        nextRows();
+    }
+
+    public void close() throws KuduException {
+        scanner.close();
+    }
+
+    public boolean hasNext() throws KuduException {
+        if (rowIterator.hasNext()) {
+            return true;
+        } else if (scanner.hasMoreRows()) {
+            nextRows();
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public KuduRow next() {
+        RowResult row = this.rowIterator.next();
+        return KuduMapper.toKuduRow(row);
+    }
+
+    private void nextRows() throws KuduException {
+        this.rowIterator = scanner.nextRows();
+    }
+}

+ 145 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/connector/KuduTableInfo.java

@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sunwin.metro.sink.kudu.connector;
+
+import org.apache.kudu.ColumnSchema;
+import org.apache.kudu.Schema;
+import org.apache.kudu.client.CreateTableOptions;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author xuYj
+ */
+public class KuduTableInfo implements Serializable {
+
+    private static final Integer DEFAULT_REPLICAS = 1;
+    private static final boolean DEFAULT_CREATE_IF_NOT_EXIST =  false;
+
+    private Integer replicas;
+    private String name;
+    private boolean createIfNotExist;
+    private List<KuduColumnInfo> columns;
+
+    private KuduTableInfo(String name){
+        this.name = name;
+        this.replicas = DEFAULT_REPLICAS;
+        this.createIfNotExist = DEFAULT_CREATE_IF_NOT_EXIST;
+        this.columns = new ArrayList<>();
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Schema getSchema() {
+        if(hasNotColumns()) {
+            return null;
+        }
+        List<ColumnSchema> schemaColumns = new ArrayList<>();
+        for(KuduColumnInfo column : columns){
+            schemaColumns.add(column.columnSchema());
+        }
+        return new Schema(schemaColumns);
+    }
+
+    public boolean createIfNotExist() {
+        return createIfNotExist;
+    }
+
+    public CreateTableOptions getCreateTableOptions() {
+        CreateTableOptions options = new CreateTableOptions();
+        if(replicas!=null){
+            options.setNumReplicas(replicas);
+        }
+        //TODO:此处创表的时候进行设备表分区有问题
+        if(hasColummns()) {
+            List<String> rangeKeys = new ArrayList<>();
+            List<String> hashKeys = new ArrayList<>();
+            for(KuduColumnInfo column : columns){
+                if(column.isRangeKey()){
+                    rangeKeys.add(column.name());
+                }
+                if(column.isHashKey()){
+                    hashKeys.add(column.name());
+                }
+            }
+            options.setRangePartitionColumns(rangeKeys);
+            options.addHashPartitions(hashKeys, replicas*2);
+        }
+
+        return options;
+    }
+
+    public boolean hasNotColumns(){
+        return !hasColummns();
+    }
+    public boolean hasColummns(){
+        return (columns!=null && columns.size()>0);
+    }
+
+    public static class Builder {
+        KuduTableInfo table;
+
+        private Builder(String name) {
+            table = new KuduTableInfo(name);
+        }
+
+        public static Builder create(String name) {
+            return new Builder(name);
+        }
+
+        public static Builder open(String name) {
+            return new Builder(name);
+        }
+
+        public Builder createIfNotExist(boolean createIfNotExist) {
+            this.table.createIfNotExist = createIfNotExist;
+            return this;
+        }
+
+        public Builder replicas(int replicas) {
+            if (replicas == 0) {
+                return this;
+            }
+            this.table.replicas = replicas;
+            return this;
+        }
+
+        public Builder columns(List<KuduColumnInfo> columns) {
+            if(columns==null) {
+                return this;
+            }
+            this.table.columns.addAll(columns);
+            return this;
+        }
+
+        public Builder addColumn(KuduColumnInfo column) {
+            if(column==null) {
+                return this;
+            }
+            this.table.columns.add(column);
+            return this;
+        }
+
+        public KuduTableInfo build() {
+            return table;
+        }
+    }
+}

+ 50 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/pojo/HbaseBeanFieldModel.java

@@ -0,0 +1,50 @@
+package com.sunwin.metro.sink.kudu.pojo;
+
+import java.lang.reflect.Method;
+
+/**
+ * @author xuYj
+ */
+public class HbaseBeanFieldModel {
+    private Method getMethod;
+    private Method setMethod;
+    private String fieldName;
+    private Class<?> fieldType;
+
+    public HbaseBeanFieldModel() {
+    }
+
+    public Method getGetMethod() {
+        return this.getMethod;
+    }
+
+    public void setGetMethod(Method getMethod) {
+        this.getMethod = getMethod;
+    }
+
+    public Method getSetMethod() {
+        return this.setMethod;
+    }
+
+    public void setSetMethod(Method setMethod) {
+        this.setMethod = setMethod;
+    }
+
+    public Class<?> getFieldType() {
+        return this.fieldType;
+    }
+
+    public void setFieldType(Class<?> fieldType) {
+        this.fieldType = fieldType;
+    }
+
+    public String getFieldName() {
+        return this.fieldName;
+    }
+
+    public void setFieldName(String fieldName) {
+        this.fieldName = fieldName;
+    }
+
+
+}

+ 43 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/serde/DefaultSerDe.java

@@ -0,0 +1,43 @@
+/*
+ * Licensed serialize the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file serialize You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed serialize in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sunwin.metro.sink.kudu.serde;
+
+
+import com.sunwin.metro.sink.kudu.connector.KuduRow;
+import org.apache.kudu.Schema;
+
+/**
+ * @author xuYj
+ */
+public class DefaultSerDe implements KuduSerialization<KuduRow>, KuduDeserialization<KuduRow> {
+
+    @Override
+    public KuduRow deserialize(KuduRow row) {
+        return row;
+    }
+
+    @Override
+    public KuduRow serialize(KuduRow value) {
+        return value;
+    }
+
+    @Override
+    public DefaultSerDe withSchema(Schema schema) {
+        return this;
+    }
+
+}

+ 30 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/serde/KuduDeserialization.java

@@ -0,0 +1,30 @@
+/*
+ * Licensed serialize the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file serialize You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed serialize in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sunwin.metro.sink.kudu.serde;
+
+
+
+import com.sunwin.metro.sink.kudu.connector.KuduRow;
+
+import java.io.Serializable;
+
+/**
+ * @author xuYj
+ */
+public interface KuduDeserialization<T> extends Serializable {
+    T deserialize(KuduRow row);
+}

+ 31 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/serde/KuduSerialization.java

@@ -0,0 +1,31 @@
+/*
+ * Licensed serialize the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file serialize You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed serialize in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sunwin.metro.sink.kudu.serde;
+
+import com.sunwin.metro.sink.kudu.connector.KuduRow;
+import org.apache.kudu.Schema;
+
+import java.io.Serializable;
+
+/**
+ * @author xuYj
+ */
+public interface KuduSerialization<T> extends Serializable {
+    KuduRow serialize(T value);
+
+    KuduSerialization<T> withSchema(Schema schema);
+}

+ 136 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/serde/PojoSerDe.java

@@ -0,0 +1,136 @@
+/*
+ * Licensed serialize the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file serialize You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed serialize in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sunwin.metro.sink.kudu.serde;
+
+import com.sunwin.metro.sink.kudu.connector.KuduRow;
+import com.sunwin.metro.sink.kudu.connector.KuduTableInfo;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.kudu.Schema;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.stream.Stream;
+
+public class PojoSerDe<P> implements KuduSerialization<P>, KuduDeserialization<P> {
+
+
+    private Class<P> clazz;
+
+    public transient KuduTableInfo tableInfo;
+    public transient Schema schema;
+
+
+    public PojoSerDe(Class<P> clazz) {
+        this.clazz = clazz;
+    }
+
+    @Override
+    public PojoSerDe<P> withSchema(Schema schema) {
+        this.schema = schema;
+        return this;
+    }
+
+    @Override
+    public KuduRow serialize(P object) {
+        return mapTo(object);
+    }
+
+    private KuduRow mapTo(P object) {
+        if (schema == null) {
+            throw new IllegalArgumentException("schema must be set to serialize");
+        }
+
+        KuduRow row = new KuduRow(schema.getRowSize());
+
+        for (Class<?> c = object.getClass(); c != null; c = c.getSuperclass()) {
+            basicValidation(c.getDeclaredFields())
+                    .forEach(cField -> {
+                        try {
+                            cField.setAccessible(true);
+                            row.setField(schema.getColumnIndex(cField.getName()), cField.getName(), cField.get(object));
+                        } catch (IllegalAccessException e) {
+                            String error = String.format("Cannot get value for %s", cField.getName());
+                            throw new IllegalArgumentException(error, e);
+                        }
+                    });
+        }
+
+        return row;
+    }
+
+    private Stream<Field> basicValidation(Field[] fields) {
+        return Arrays.stream(fields)
+                .filter(field -> schemaHasColumn(field.getName()))
+                .filter(field -> !Modifier.isStatic(field.getModifiers()))
+                .filter(field -> !Modifier.isTransient(field.getModifiers()));
+    }
+
+    private boolean schemaHasColumn(String field) {
+        return schema.getColumns().stream().anyMatch(col -> StringUtils.equalsIgnoreCase(col.getName(), field));
+    }
+
+    @Override
+    public P deserialize(KuduRow row) {
+        return mapFrom(row);
+    }
+
+    private P mapFrom(KuduRow row) {
+        P o = createInstance(clazz);
+
+        for (Class<?> c = clazz; c != null; c = c.getSuperclass()) {
+            Field[] fields = c.getDeclaredFields();
+
+            basicValidation(fields)
+                    .forEach(cField -> {
+                        try {
+                            cField.setAccessible(true);
+                            Object value = row.getField(cField.getName());
+                            if (value != null) {
+                                if (cField.getType() == value.getClass()) {
+                                    cField.set(o, value);
+                                } else if (cField.getType() == Long.class && value.getClass() == Date.class) {
+                                    cField.set(o, ((Date) value).getTime());
+                                } else {
+                                    cField.set(o, value);
+                                }
+                            }
+                        } catch (IllegalAccessException e) {
+                            String error = String.format("Cannot get value for %s", cField.getName());
+                            throw new IllegalArgumentException(error, e);
+                        }
+                    });
+        }
+
+        return o;
+
+    }
+
+    private P createInstance(Class<P> clazz) {
+        try {
+            Constructor<P> constructor = clazz.getDeclaredConstructor();
+            constructor.setAccessible(true);
+            return constructor.newInstance();
+        } catch (ReflectiveOperationException e) {
+            String error = String.format("Cannot create instance for %s", clazz.getSimpleName());
+            throw new IllegalArgumentException(error, e);
+        }
+    }
+
+}

+ 43 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/utils/FieldUtility.java

@@ -0,0 +1,43 @@
+package com.sunwin.metro.sink.kudu.utils;
+
+import java.lang.reflect.Field;
+
+/**
+ * @author xuYj
+ */
+public class FieldUtility {
+    private static final String getPrefix = "get";
+    private static final String isPrefix = "is";
+    private static final String setPrefix = "set";
+
+    public FieldUtility() {
+    }
+
+    public static String getGetMethodName(Field field) {
+        return getGetMethodName(field.getName(), field.getType());
+    }
+
+    public static String getSetMethodName(Field field) {
+        return getSetMethodName(field.getName(), field.getType());
+    }
+
+    public static String getSetMethodName(String fieldName, Class<?> fieldType) {
+        if (fieldType.equals(Boolean.class) && fieldName.startsWith("is")) {
+            fieldName = fieldName.substring(2);
+        }
+
+        StringBuilder stringBuilder = new StringBuilder("set");
+        stringBuilder.append(fieldName.substring(0, 1).toUpperCase()).append(fieldName.substring(1));
+        return stringBuilder.toString();
+    }
+
+    public static String getGetMethodName(String fieldName, Class<?> fieldType) {
+        if (fieldType.equals(Boolean.class) && fieldName.startsWith("is")) {
+            fieldName = fieldName.substring(2);
+        }
+
+        StringBuilder stringBuilder = new StringBuilder();
+        stringBuilder.append(fieldName.substring(0, 1).toUpperCase()).append(fieldName.substring(1));
+        return fieldType.equals(Boolean.TYPE) ? stringBuilder.insert(0, "is").toString() : stringBuilder.insert(0, "get").toString();
+    }
+}

+ 59 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/kudu/utils/KuduUtils.java

@@ -0,0 +1,59 @@
+package com.sunwin.metro.sink.kudu.utils;
+
+
+import com.sunwin.metro.sink.kudu.pojo.HbaseBeanFieldModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author xuYj
+ */
+public class KuduUtils {
+    private static final Logger LOG = LoggerFactory.getLogger(KuduUtils.class);
+
+    private KuduUtils() {
+
+    }
+
+
+    public static Map<String, HbaseBeanFieldModel[]> beanFieldModelMap = new HashMap<>();
+
+    private static HbaseBeanFieldModel[] getBeanModel(Class<?> beanClass) throws Exception {
+        Field[] fields = beanClass.getDeclaredFields();
+        List<HbaseBeanFieldModel> hbaseBeanFieldModelList = new ArrayList<>(fields.length);
+        for (Field field : fields) {
+            HbaseBeanFieldModel model = new HbaseBeanFieldModel();
+            if ("serialVersionUID".equalsIgnoreCase(field.getName())) {
+                continue;
+            }
+            model.setGetMethod(beanClass.getDeclaredMethod(FieldUtility.getGetMethodName(field)));
+            model.setSetMethod(beanClass.getDeclaredMethod(FieldUtility.getSetMethodName(field), field.getType()));
+            model.setFieldName(field.getName());
+            model.setFieldType(field.getType());
+            hbaseBeanFieldModelList.add(model);
+        }
+        return hbaseBeanFieldModelList.toArray(new HbaseBeanFieldModel[0]);
+    }
+
+
+    public static HbaseBeanFieldModel[] getBeanFieldModels(Class<?> beanClass) {
+        if (null != beanFieldModelMap.get(beanClass.getSimpleName())) {
+            return beanFieldModelMap.get(beanClass.getSimpleName());
+        }
+        try {
+            HbaseBeanFieldModel[] hbaseBeanFieldModels = getBeanModel(beanClass);
+            beanFieldModelMap.put(beanClass.getSimpleName(), hbaseBeanFieldModels);
+            return hbaseBeanFieldModels;
+        } catch (Exception e) {
+            e.printStackTrace();
+            LOG.error("反射类失败,类名为:{},具体异常为:{}", beanClass.getSimpleName(), e.getMessage());
+        }
+        return null;
+    }
+}

+ 53 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/mysql/SinkErrorMeterToMysql.java

@@ -0,0 +1,53 @@
+
+package com.sunwin.metro.sink.mysql;
+
+import com.sunwin.metro.utils.MysqlUtils;
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.flink.api.java.tuple.Tuple2;
+import org.apache.flink.api.java.tuple.Tuple3;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+
+/**
+ * @author xuYJ
+ */
+public class SinkErrorMeterToMysql extends RichSinkFunction<Tuple3<String, String, String>> {
+    PreparedStatement ps;
+    BasicDataSource dataSource;
+    private Connection connection;
+
+    @Override
+    public void open(Configuration parameters) throws Exception {
+        super.open(parameters);
+        dataSource = new BasicDataSource();
+        connection = MysqlUtils.getMysqlCon(dataSource);
+        //修改通讯状态
+        String sql = "UPDATE meter SET communicate_ok = 0 WHERE meter_number = ? AND id = ?;";
+        ps = this.connection.prepareStatement(sql);
+    }
+
+    @Override
+    public void close() throws Exception {
+        super.close();
+        if (connection != null) {
+            connection.close();
+        }
+        if (ps != null) {
+            ps.close();
+        }
+    }
+
+    @Override
+    public void invoke(Tuple3<String, String, String> input, Context context) throws Exception {
+        ps.setString(1, input.f1);
+        ps.setString(2, input.f0);
+        ps.addBatch();
+        ps.executeBatch();
+        connection.commit();
+    }
+
+
+}

+ 53 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/mysql/SinkNormalMeterToMysql.java

@@ -0,0 +1,53 @@
+
+package com.sunwin.metro.sink.mysql;
+
+import com.sunwin.metro.utils.MysqlUtils;
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.flink.api.java.tuple.Tuple2;
+import org.apache.flink.api.java.tuple.Tuple3;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+
+/**
+ * @author xuYJ
+ */
+public class SinkNormalMeterToMysql extends RichSinkFunction<Tuple3<String, String, String>> {
+    PreparedStatement ps;
+    BasicDataSource dataSource;
+    private Connection connection;
+
+    @Override
+    public void open(Configuration parameters) throws Exception {
+        super.open(parameters);
+        dataSource = new BasicDataSource();
+        connection = MysqlUtils.getMysqlCon(dataSource);
+        //修改通讯状态
+        String sql = "UPDATE meter SET communicate_ok = 1 WHERE meter_number = ? AND id = ?;";
+        ps = this.connection.prepareStatement(sql);
+    }
+
+    @Override
+    public void close() throws Exception {
+        super.close();
+        if (connection != null) {
+            connection.close();
+        }
+        if (ps != null) {
+            ps.close();
+        }
+    }
+
+
+    @Override
+    public void invoke(Tuple3<String, String, String> input, Context context) throws Exception {
+        ps.setString(1, input.f1);
+        ps.setString(2, input.f0);
+        ps.addBatch();
+        ps.executeBatch();
+        connection.commit();
+    }
+
+}

+ 66 - 0
flink_metro/src/main/java/com/sunwin/metro/sink/mysql/SinkToMysql.java

@@ -0,0 +1,66 @@
+
+package com.sunwin.metro.sink.mysql;
+
+import com.sunwin.metro.bean.Meter;
+import com.sunwin.metro.utils.MysqlUtils;
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+
+/**
+ * @author xuYJ
+ */
+public class SinkToMysql extends RichSinkFunction<Meter> {
+    PreparedStatement ps;
+    BasicDataSource dataSource;
+    private Connection connection;
+
+    @Override
+    public void open(Configuration parameters) throws Exception {
+        super.open(parameters);
+        dataSource = new BasicDataSource();
+        connection = MysqlUtils.getMysqlCon(dataSource);
+        String sql = "REPLACE into meter(id, meter_number, meter_type, name, brand_name, person_name, " +
+                "person_tel, is_online, install_location, meter_attribute, remarks, collector_id, " +
+                "station_id, gmt_modified, gmt_create, meter_name) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
+        ps = this.connection.prepareStatement(sql);
+    }
+
+    @Override
+    public void close() throws Exception {
+        super.close();
+        if (connection != null) {
+            connection.close();
+        }
+        if (ps != null) {
+            ps.close();
+        }
+    }
+
+    @Override
+    public void invoke(Meter meter, Context context) throws Exception {
+        ps.setString(1, meter.getId());
+        ps.setString(2, meter.getMeterNumber());
+        ps.setInt(3, meter.getMeterType());
+        ps.setString(4, meter.getName());
+        ps.setString(5, meter.getBrandName());
+        ps.setString(6, meter.getPersonName());
+        ps.setString(7, meter.getPersonTel());
+        ps.setInt(8, meter.isOnline() ? 1 : 0);
+        ps.setString(9, meter.getInstallLocation());
+        ps.setString(10, meter.getMeterAttribute());
+        ps.setString(11, meter.getRemarks());
+        ps.setString(12, meter.getCollectorId());
+        ps.setString(13, meter.getStationId());
+        ps.setString(14, meter.getGmtModified());
+        ps.setString(15, meter.getGmtCreate());
+        ps.setString(16, meter.getMeterName());
+        ps.addBatch();
+        ps.executeBatch();
+        connection.commit();
+    }
+
+}

+ 56 - 0
flink_metro/src/main/java/com/sunwin/metro/source/http/HttpMeterAtt.java

@@ -0,0 +1,56 @@
+package com.sunwin.metro.source.http;
+
+import com.alibaba.fastjson.JSONArray;
+import com.chinaway.http.client.HttpClientResponse;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.metrics.reporter.Scheduled;
+import org.apache.flink.streaming.api.functions.source.RichSourceFunction;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @program: sunwin_metro
+ * @description: http数据源
+ * @author: xuYJ
+ * @create: 2021-04-14 09:37
+ **/
+public class HttpMeterAtt extends RichSourceFunction<String> {
+    private  HttpClientResponse<String> httpClient;
+    private  Map<String, String> params;
+    private  boolean isRunning=true;
+    @Override
+    public void open(Configuration parameters) throws Exception {
+         params = new HashMap<>(16);
+         httpClient = new HttpClientResponse<>();
+        super.open(parameters);
+    }
+
+    @Override
+    public void close() throws Exception {
+        super.close();
+    }
+
+    @Override
+    public void run(SourceContext<String> sourceContext) throws Exception {
+        while (isRunning){
+            String type1 = httpClient.getForString("http://192.168.20.134:8083//home/getMeter/1", params, new HashMap<>(16));
+            String type2 = httpClient.getForString("http://192.168.20.134:8083//home/getMeter/2", params, new HashMap<>(16));
+            String type3 = httpClient.getForString("http://192.168.20.134:8083//home/getMeter/3", params, new HashMap<>(16));
+            JSONArray out = new JSONArray();
+            JSONArray array1 = JSONArray.parseArray(type1);
+            JSONArray array2 = JSONArray.parseArray(type2);
+            JSONArray array3 = JSONArray.parseArray(type3);
+            out.addAll(array1);
+            out.addAll(array2);
+            out.addAll(array3);
+            sourceContext.collect(out.toJSONString());
+            Thread.sleep(1000*60*30L);
+        }
+    }
+
+    @Override
+    public void cancel() {
+        isRunning=false;
+    }
+}

+ 90 - 0
flink_metro/src/main/java/com/sunwin/metro/source/http/HttpMeterMsg.java

@@ -0,0 +1,90 @@
+package com.sunwin.metro.source.http;
+
+
+import com.chinaway.http.client.HttpClientResponse;
+import com.sunwin.metro.bean.Meter;
+import com.sunwin.metro.utils.MysqlUtils;
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.streaming.api.functions.source.RichSourceFunction;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * @program: sunwin_metro
+ * @description: http数据源 - 10s采集一次
+ * @author: xuYJ
+ * @create: 2021-04-14 09:37
+ **/
+public class HttpMeterMsg extends RichSourceFunction<Tuple4<String, String, String, String>> {
+    private HttpClientResponse<String> httpClient;
+    private Map<String, String> params;
+    private Connection con;
+    private ResultSet rs;
+    private PreparedStatement pStatement;
+
+    @Override
+    public void open(Configuration parameters) throws Exception {
+        params = new HashMap<>(16);
+        httpClient = new HttpClientResponse<>();
+        con = MysqlUtils.getMysqlCon(new BasicDataSource());
+        super.open(parameters);
+    }
+
+    @Override
+    public void close() throws Exception {
+        super.close();
+        rs.close();
+        pStatement.close();
+        con.close();
+        super.close();
+    }
+
+    @Override
+    public void run(SourceContext<Tuple4<String, String, String, String>> sourceContext) throws Exception {
+        String sql = "select id, meter_number, meter_type from meter";
+        while (true) {
+            List<Meter> meters = new ArrayList<>();
+            try {
+                pStatement = con.prepareStatement(sql);
+                rs = pStatement.executeQuery();
+                while (rs.next()) {
+                    meters.add(new Meter(rs.getString("id"),rs.getString("meter_number"),rs.getInt("meter_type")));
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw e;
+            }
+            List<Meter> newList = meters.stream().filter(distinctByKey(Meter::getMeterNumber)).collect(Collectors.toList());
+            for (Meter meter : newList) {
+                params.put("meterNumber", meter.getMeterNumber());
+                String result = httpClient.getForString("http://192.168.20.134:8083//home/forTimes", params, new HashMap<>(16));
+                sourceContext.collect(new Tuple4<>(meter.getId(), meter.getMeterNumber(), String.valueOf(meter.getMeterType()), result));
+            }
+            Thread.sleep(10000L);
+        }
+    }
+
+    @Override
+    public void cancel() {
+
+    }
+
+    private static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
+        Map<Object, Boolean> seen = new ConcurrentHashMap<>(16);
+        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
+    }
+
+
+}

+ 80 - 0
flink_metro/src/main/java/com/sunwin/metro/source/mysql/MysqlData.java

@@ -0,0 +1,80 @@
+package com.sunwin.metro.source.mysql;
+
+
+import com.sunwin.metro.bean.DeviceName;
+import com.sunwin.metro.bean.ErrorDevice;
+import com.sunwin.metro.utils.MysqlUtils;
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author xuYJ
+ */
+public class MysqlData {
+    public static final Logger logger = LoggerFactory.getLogger(MysqlData.class);
+    private static final Connection CONNECTION;
+
+    static {
+        CONNECTION =MysqlUtils.getMysqlCon(new BasicDataSource());
+    }
+
+    public static List<String> getWords(String table) throws Exception {
+        String sql = "select device_name from " + table;
+        List<String> devices = new ArrayList<>();
+        PreparedStatement pStatement;
+        try {
+            pStatement = CONNECTION.prepareStatement(sql);
+            ResultSet rs = pStatement.executeQuery();
+            while (rs.next()) {
+                devices.add(rs.getString("device_name"));
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw e;
+        }
+        return devices;
+    }
+
+
+    public static List<DeviceName> getWordsWithTime(String table, long time) throws Exception {
+        String sql = "select device_name,send_time from " + table + " WHERE send_time > " +time;
+        List<DeviceName> devices = new ArrayList<>();
+        PreparedStatement pStatement;
+        try {
+            pStatement = CONNECTION.prepareStatement(sql);
+            ResultSet rs = pStatement.executeQuery();
+            while (rs.next()) {
+                devices.add(new DeviceName(rs.getString("device_name"),rs.getLong("send_time")));
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw e;
+        }
+        return devices;
+    }
+
+
+    public static void insertData(List<ErrorDevice> values, String table) {
+        PreparedStatement pstm;
+        String sql = " REPLACE  INTO " + table + " (id,device_name ,result_info , send_time) VALUES(?,?,?,?)";
+        try {
+            pstm = CONNECTION.prepareStatement(sql);
+            CONNECTION.setAutoCommit(false);
+            for (ErrorDevice value : values) {
+                pstm.setString(1, value.getId());
+                pstm.setString(2, value.getDeviceName());
+                pstm.setString(3, value.getResultInfo());
+                pstm.setString(4, value.getDate());
+                pstm.addBatch();
+            }
+            pstm.executeBatch();
+            CONNECTION.commit();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 55 - 0
flink_metro/src/main/java/com/sunwin/metro/source/mysql/MysqlSource.java

@@ -0,0 +1,55 @@
+package com.sunwin.metro.source.mysql;
+
+import com.sunwin.metro.utils.PerStringUtils;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.streaming.api.functions.source.RichSourceFunction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @program: boryou-flink
+ * @description: 获取mysql关键字自定义流
+ * @author: xuYJ
+ * @create: 2020-10-19 15:42
+ **/
+
+public class MysqlSource extends RichSourceFunction<Map<String, List<String>>> {
+    public static final Logger logger = LoggerFactory.getLogger(MysqlSource.class);
+    private volatile boolean isRunning = true;
+
+    private final Long time;
+
+    public MysqlSource(Long time) {
+        this.time = time;
+    }
+
+    @Override
+    public void open(Configuration parameters) throws Exception {
+        super.open(parameters);
+    }
+
+    @Override
+    public void run(SourceContext<Map<String,List<String>>> ctx) throws Exception {
+        while (isRunning) {
+            Map<String,List<String>> keyWords = new HashMap<>(16);
+            try {
+                List<String> words = MysqlData.getWords("metro_device_all");
+                if (!PerStringUtils.isNullOrEmpty(words)) {
+                    keyWords.put("devices",words);
+                    ctx.collect(keyWords);
+                }
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+            Thread.sleep(time);
+        }
+    }
+
+    @Override
+    public void cancel() {
+        isRunning = false;
+    }
+}

+ 65 - 0
flink_metro/src/main/java/com/sunwin/metro/source/mysql/MysqlSourceTime.java

@@ -0,0 +1,65 @@
+package com.sunwin.metro.source.mysql;
+
+import com.sunwin.metro.bean.DeviceName;
+import com.sunwin.metro.utils.PerStringUtils;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.streaming.api.functions.source.RichSourceFunction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @program: boryou-flink
+ * @description: 获取mysql关键字自定义流
+ * @author: xuYJ
+ * @create: 2020-10-19 15:42
+ **/
+
+public class MysqlSourceTime extends RichSourceFunction<Map<String, List<String>>> {
+    public static final Logger logger = LoggerFactory.getLogger(MysqlSourceTime.class);
+    private volatile boolean isRunning = true;
+
+    private final Long time;
+
+    public MysqlSourceTime(Long time) {
+        this.time = time;
+    }
+
+    @Override
+    public void open(Configuration parameters) throws Exception {
+        super.open(parameters);
+    }
+
+    @Override
+    public void run(SourceContext<Map<String,List<String>>> ctx) throws Exception {
+        long date=20000000000000L;
+        while (isRunning) {
+            ArrayList<String> out = new ArrayList<>();
+            Map<String,List<String>> keyWords = new HashMap<>(16);
+            try {
+                List<DeviceName> devices = MysqlData.getWordsWithTime("metro_device_all",date);
+                for (DeviceName device : devices) {
+                    out.add(device.getDeviceName());
+                    if(device.getSendTime()>date){
+                        date=device.getSendTime();
+                    }
+                }
+                if (!PerStringUtils.isNullOrEmpty(out)) {
+                    keyWords.put("devices",out);
+                    ctx.collect(keyWords);
+                }
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+            Thread.sleep(time);
+        }
+    }
+
+    @Override
+    public void cancel() {
+        isRunning = false;
+    }
+}

+ 114 - 0
flink_metro/src/main/java/com/sunwin/metro/source/mysql/message/QueryEquipment.java

@@ -0,0 +1,114 @@
+package com.sunwin.metro.source.mysql.message;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.sunwin.metro.source.mysql.MysqlData;
+import com.sunwin.metro.utils.MysqlUtils;
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.flink.api.java.tuple.Tuple2;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @program: sunwin_metro
+ * @description: 查询所有设备id
+ * @author: xuYJ
+ * @create: 2021-05-31 11:44
+ **/
+public class QueryEquipment {
+    public static final Logger logger = LoggerFactory.getLogger(MysqlData.class);
+    private static final Connection CONNECTION;
+
+    static {
+        CONNECTION = MysqlUtils.getMysqlCon(new BasicDataSource());
+    }
+
+    public static void closeCon() throws Exception {
+        CONNECTION.close();
+    }
+    public static JSONArray getId() throws Exception {
+        String sql = "SELECT line,station,equipment_id,equipment_code FROM tst_equipment_life ";
+        JSONArray array = new JSONArray();
+        PreparedStatement pStatement;
+        try {
+            pStatement = CONNECTION.prepareStatement(sql);
+            ResultSet rs = pStatement.executeQuery();
+            while (rs.next()) {
+                JSONObject json = new JSONObject();
+                json.put("line",rs.getString("line"));
+                json.put("station",rs.getString("station"));
+                json.put("equipment_id",rs.getString("equipment_id"));
+                json.put("equipment_code",rs.getString("equipment_code"));
+                array.add(json);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw e;
+        }
+        return array;
+    }
+
+    public static Map<String,JSONArray>getWarnMessage() throws Exception {
+        String sql = "SELECT id,type,type_name FROM ea_alarm ";
+        HashMap<String, JSONArray> map = new HashMap<>(16);
+        PreparedStatement pStatement;
+        try {
+            pStatement = CONNECTION.prepareStatement(sql);
+            ResultSet rs = pStatement.executeQuery();
+            while (rs.next()) {
+                String id = String.valueOf(rs.getInt("id"));
+                String type = String.valueOf(rs.getInt("type"));
+                String typeName =rs.getString("type_name");
+                if(map.containsKey(id)){
+                    JSONArray array = map.get(id);
+                    array.add(type+"_"+typeName);
+                    map.put(id,array);
+                }else {
+                    JSONArray array = new JSONArray();
+                    array.add(type+"_"+typeName);
+                    map.put(id,array);
+                }
+
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw e;
+        }
+        return map;
+    }
+
+    public static Map<String,String>getEquipmentName() throws Exception {
+        String sql = "SELECT equipment_id,equipment_name  FROM tste_equipmentname ";
+        HashMap<String, String> map = new HashMap<>(16);
+        PreparedStatement pStatement;
+        try {
+            pStatement = CONNECTION.prepareStatement(sql);
+            ResultSet rs = pStatement.executeQuery();
+            while (rs.next()) {
+                String id = String.valueOf(rs.getInt("equipment_id"));
+                String name = rs.getString("equipment_name");
+                map.put(id,name);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw e;
+        }
+        return map;
+    }
+
+    public static void main(String[] args) throws Exception {
+        Map<String, String> equipmentName = getEquipmentName();
+        for (Map.Entry<String, String> entry : equipmentName.entrySet()) {
+            System.out.println("entry = " + entry);
+        }
+    }
+}

+ 141 - 0
flink_metro/src/main/java/com/sunwin/metro/start/StartMessage.java

@@ -0,0 +1,141 @@
+package com.sunwin.metro.start;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.sunwin.metro.bean.message.EquipmentWarn;
+import com.sunwin.metro.sink.impala.SinkToImpalaWarn;
+import com.sunwin.metro.sink.kudu.connector.KuduTableInfo;
+import com.sunwin.metro.source.mysql.message.QueryEquipment;
+import com.sunwin.metro.utils.DateUtils;
+import org.apache.flink.api.common.JobExecutionResult;
+import org.apache.flink.api.common.state.*;
+import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.api.java.tuple.Tuple;
+import org.apache.flink.api.java.tuple.Tuple2;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.metrics.Counter;
+import org.apache.flink.streaming.api.datastream.DataStreamSource;
+import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
+import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
+import org.apache.flink.streaming.api.functions.KeyedProcessFunction;
+import org.apache.flink.streaming.api.functions.source.RichSourceFunction;
+import org.apache.flink.util.Collector;
+import java.util.*;
+
+/**
+ * @program: sunwin_metro
+ * @description: 模拟数据
+ * @author: xuYJ
+ * @create: 2021-05-31 11:33
+ **/
+public class StartMessage {
+    public static void main(String[] args) throws Exception {
+        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
+        StreamPro.envPro(env, args[0]);
+        DataStreamSource<Tuple2<String, String>> source = env.addSource(new RichSourceFunction<Tuple2<String, String>>() {
+            @Override
+            public void run(SourceContext<Tuple2<String, String>> ctx) throws Exception {
+                JSONArray array = QueryEquipment.getId();
+                while (true) {
+                    int i = new Random().nextInt(20) + 1;
+                    JSONArray jsonArray = getArray(array, i);
+                    for (Object o : jsonArray) {
+                        ctx.collect(new Tuple2<>("key", o.toString()));
+                    }
+                    Thread.sleep(1000 * 60 * i);
+                }
+            }
+            @Override
+            public void cancel() {
+            }
+        });
+        SingleOutputStreamOperator<EquipmentWarn> result = source.keyBy(0).process(new KeyedProcessFunction<Tuple, Tuple2<String, String>, EquipmentWarn>() {
+            private transient MapState<String, JSONArray> mapState;
+            private transient MapState<String, String> mapState2;
+            private transient ListState<EquipmentWarn> listState;
+            private transient Counter ct;
+            private transient ValueState<Long> valueState;
+
+            @Override
+            public void open(Configuration parameters) throws Exception {
+                MapStateDescriptor<String, JSONArray> descriptor = new MapStateDescriptor<>("mapState", TypeInformation.of(String.class), TypeInformation.of(JSONArray.class));
+                MapStateDescriptor<String, String> descriptor2 = new MapStateDescriptor<>("mapState2", TypeInformation.of(String.class), TypeInformation.of(String.class));
+                ValueStateDescriptor<Long> descriptor4 = new ValueStateDescriptor<>("count", TypeInformation.of(Long.class));
+                mapState = getRuntimeContext().getMapState(descriptor);
+                mapState2 = getRuntimeContext().getMapState(descriptor2);
+                valueState = getRuntimeContext().getState(descriptor4);
+                ListStateDescriptor<EquipmentWarn> descriptor3 = new ListStateDescriptor<>("listState", TypeInformation.of(EquipmentWarn.class));
+                listState = getRuntimeContext().getListState(descriptor3);
+                ct = getRuntimeContext().getMetricGroup().counter("ct");
+                super.open(parameters);
+            }
+
+            @Override
+            public void close() throws Exception {
+                super.close();
+                QueryEquipment.closeCon();
+            }
+
+            @Override
+            public void processElement(Tuple2<String, String> value, Context ctx, Collector<EquipmentWarn> out) throws Exception {
+                ct.inc();
+                long count = ct.getCount();
+                valueState.update(count);
+                if (mapState.isEmpty()) {
+                    mapState.putAll(QueryEquipment.getWarnMessage());
+                }
+                if (mapState2.isEmpty()) {
+                    mapState2.putAll(QueryEquipment.getEquipmentName());
+                    QueryEquipment.closeCon();
+                }
+                ArrayList<String> list = new ArrayList<>();
+                list.add("m_0");
+                list.add("m_30");
+                list.add("h_1");
+                list.add("h_2");
+                list.add("h_4");
+                list.add("h_8");
+                EquipmentWarn equipmentWarn = new EquipmentWarn();
+                JSONObject jsonObject = JSONObject.parseObject(value.f1);
+                String equipmentId = String.valueOf(jsonObject.getInteger("equipment_id"));
+                equipmentWarn.setCurrent_time(DateUtils.dateToShortStringNoSep(new Date()));
+                equipmentWarn.setEquipment_code(jsonObject.getInteger("equipment_code"));
+                equipmentWarn.setEquipment_name(mapState2.get(equipmentId));
+                equipmentWarn.setStation(jsonObject.getInteger("station"));
+                equipmentWarn.setFlag("true");
+                equipmentWarn.setLine(jsonObject.getInteger("line"));
+                equipmentWarn.setWarn_time(list.get(new Random().nextInt(list.size())));
+                JSONArray array = mapState.get(equipmentId);
+                equipmentWarn.setWarn_type(array.getString(new Random().nextInt(array.size())));
+                GregorianCalendar calendar = new GregorianCalendar();
+                int hour = calendar.get(Calendar.HOUR_OF_DAY);
+                JSONArray jsonArray = new JSONArray();
+                Iterable<EquipmentWarn> equipmentWarns = listState.get();
+                equipmentWarns.forEach(jsonArray::add);
+                if (hour == 1 && jsonArray.size() > 200) {
+                    List<EquipmentWarn> warns = getArray(jsonArray, 200).toJavaList(EquipmentWarn.class);
+                    for (EquipmentWarn warn : warns) {
+                        out.collect(warn);
+                    }
+                    listState.clear();
+                }
+                listState.add(equipmentWarn);
+                out.collect(equipmentWarn);
+                System.out.println("状态变量中的集合数目" + jsonArray.size());
+            }
+        });
+        result.addSink(new SinkToImpalaWarn());
+    }
+    public static JSONArray getArray(JSONArray list, int count) {
+        JSONArray backList;
+        backList = new JSONArray();
+        Random random = new Random();
+        int backSum = Math.min(list.size(), count);
+        for (int i = 0; i < backSum; i++) {
+            int target = random.nextInt(list.size());
+            backList.add(list.get(target));
+            list.remove(target);
+        }
+        return backList;
+    }
+}

+ 231 - 0
flink_metro/src/main/java/com/sunwin/metro/start/StartMetro.java

@@ -0,0 +1,231 @@
+package com.sunwin.metro.start;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.sunwin.metro.bean.train.*;
+import com.sunwin.metro.sink.kudu.KuduSink;
+import com.sunwin.metro.sink.kudu.connector.KuduTableInfo;
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.streaming.api.datastream.DataStreamSource;
+import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
+import org.apache.flink.streaming.api.environment.LocalStreamEnvironment;
+import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
+import org.apache.flink.streaming.api.functions.ProcessFunction;
+import org.apache.flink.util.Collector;
+import org.apache.flink.util.OutputTag;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.sunwin.metro.start.StartService.getInput;
+
+/**
+ * @author xuYJ
+ * @description: 清洗3号线设备属性数据
+ * @create: 2020-08-26 14:10
+ */
+public class StartMetro {
+    public static final Logger logger = LoggerFactory.getLogger(StartMetro.class);
+
+    public static void main(String[] args) throws Exception {
+        KuduTableInfo kuduTableInfo4 = KuduTableInfo.Builder.open("impala::urtdb.ups_bas").build();
+        LocalStreamEnvironment env = StreamExecutionEnvironment.createLocalEnvironment();
+
+        OutputTag<BasTef> tef = new OutputTag<BasTef>("BasTef") {
+        };
+        OutputTag<BasTvf> tvf = new OutputTag<BasTvf>("BasTvf") {
+        };
+        OutputTag<UpsBas> ups = new OutputTag<UpsBas>("UpsBasStation") {
+        };
+        OutputTag<UpsXjy> ups2 = new OutputTag<UpsXjy>("UpsXjy") {
+        };
+        OutputTag<Ups> ups3 = new OutputTag<Ups>("Ups") {
+        };
+        StreamPro.envPro(env, "BAS_TEF");
+        DataStreamSource<Tuple4<String, Integer, Long, String>> source = getInput(env, "ups_bas", "bas1");
+        SingleOutputStreamOperator<String> process = source.process(new ProcessFunction<Tuple4<String, Integer, Long, String>, String>() {
+            @Override
+            public void processElement(Tuple4<String, Integer, Long, String> tuple4, Context ctx, Collector<String> out) throws Exception {
+                JSONObject json = JSONObject.parseObject(tuple4.f3);
+                String name = json.getString("name").trim().split(":")[2].trim();
+                String station = json.getString("name").trim().split(":")[1].trim();
+                if (json.getString("name").contains("BAS_TEF")) {
+                    ctx.output(tef, new BasTef(json.getString("DI:MOvL"), json.getIntValue("AI:FltNo"), json.getString("DI:AFlagSt"), json.getIntValue("AI:WindTA"), json.getIntValue("AI:WindTB"), json.getIntValue("AI:WindTC"), json.getIntValue("AI:Y_Vibr"), json.getIntValue("AO:SPTm"), json.getIntValue("AO:FSet"), json.getString("DI:Fail"), json.getIntValue("AI:FBak"), json.getString("DI:VFFlt"), json.getString("DI:sEnableSt"), json.getString("DI:AOvT"), json.getString("DI:Vibr"), json.getIntValue("AI:FAxleT"), json.getIntValue("AI:X_Vibr"), json.getString("DI:FRun"), json.getIntValue("AO:KpTm"), json.getString("DO:AFlagSt"), json.getString("DI:Stp"), json.getString("name"), json.getString("DI:VRun"), json.getIntValue("AI:RAxleT"), json.getDouble("AI:TAcc"), json.getString("DO:FRes"), json.getString("DI:VFBas"), json.getString("DO:FST"), json.getString("DI:CommOKSt"), json.getString("DO:sEnableSt"), json.getString("stime"), json.getString("DO:sFRestSt"), json.getString("DO:SP"), json.getIntValue("AI:PvoltC"), json.getString("DO:ST"), json.getIntValue("AI:PvoltA"), json.getIntValue("AI:PvoltB"), json.getString("DI:WOvT"), json.getString("DI:Run"), json.getIntValue("AI:Comm_Word"), json.getString("DI:Hang"), json.getString("DI:SFlagSt"), json.getString("DO:sUnableSt"), json.getString("DI:PFVF"), json.getString("DO:Hang"), json.getString("DO:SFlagSt"), json.getString("DO:NHang"), json.getString("DO:sRTRestSt"), json.getIntValue("AO:KiTm"), json.getString("DI:LR"), json.getIntValue("AI:PcurrA"), json.getIntValue("AI:PcurrC"), json.getIntValue("AI:PcurrB")));
+                } else if (json.getString("name").contains("BAS_TVF")) {
+                    ctx.output(tvf, new BasTvf(json.getIntValue("AI:TAcc"), json.getString("DO:FRes"), json.getString("DO:FireSP"), json.getString("DI:MOvL"), json.getIntValue("AI:FltNo"), json.getString("DO:FST"), json.getString("DI:ByPass"), json.getString("DI:CommOKSt"), json.getString("DI:AFlagSt"), json.getString("stime"), json.getString("DO:SP"), json.getString("DO:sFRestSt"), json.getString("DI:WOvL"), json.getIntValue("AI:PvoltC"), json.getIntValue("AI:PvoltA"), json.getString("DO:FireRST"), json.getIntValue("AI:PvoltB"), json.getIntValue("AI:WindTA"), json.getString("DO:FireFST"), json.getIntValue("AI:WindTB"), json.getIntValue("AI:WindTC"), json.getIntValue("AI:Y_Vibr"), json.getString("DI:Fail"), json.getString("DI:VFFlt"), json.getString("DI:AOvT"), json.getString("DI:SFlagSt"), json.getString("DI:Hang"), json.getString("DI:Vibr"), json.getString("DO:Hang"), json.getString("DO:SFlagSt"), json.getString("DI:SFBas"), json.getIntValue("AI:FAxleT"), json.getIntValue("AI:X_Vibr"), json.getString("DI:FRun"), json.getString("DI:Stp"), json.getString("DO:AFlagSt"), json.getString("DO:NHang"), json.getString("name"), json.getString("DO:sRTRestSt"), json.getString("DO:RST"), json.getString("DI:LR"), json.getIntValue("AI:PcurrA"), json.getIntValue("AI:RAxleT"), json.getIntValue("AI:PcurrC"), json.getIntValue("AI:PcurrB"), json.getString("DI:RRun")
+                    ));
+                } else if (name.contains("UPS_BAS")) {
+                    ctx.output(ups, new UpsBas(
+                            name,
+                            station,
+                            json.getString("stime"),
+                            json.getIntValue("AI:BVP"),
+                            json.getIntValue("AI:OP"),
+                            json.getIntValue("AI:IV"),
+                            json.getIntValue("AI:ROV"),
+                            json.getIntValue("AI:IFV"),
+                            json.getIntValue("AI:OV"),
+                            json.getIntValue("AI:BV"),
+                            json.getIntValue("AI:Temp"),
+                            json.getIntValue("AI:ROFre"),
+                            json.getIntValue("AI:RBV"),
+                            json.getIntValue("AI:ROC"),
+                            json.getIntValue("AI:IFre"),
+                            json.getString("DI:BVLL"),
+                            json.getString("DI:SDActive"),
+                            json.getString("DI:UPSType"),
+                            json.getString("DI:SYSTesting"),
+                            json.getString("DI:CommOK"),
+                            json.getString("DI:UPSFault"),
+                            json.getString("DI:UPSMode"),
+                            json.getString("DI:VoiceOpen"),
+                            json.getString("DI:ESFault")
+                    ));
+                } else if (name.contains("UPS_XJY")) {
+                    ctx.output(ups2,new UpsXjy(
+                            json.getString("stime"),
+                            name,
+                            station,
+                            json.getIntValue("AI:R1"),
+                            json.getIntValue("AI:R2"),
+                            json.getIntValue("AI:R3"),
+                            json.getIntValue("AI:R4"),
+                            json.getIntValue("AI:R5"),
+                            json.getIntValue("AI:R6"),
+                            json.getIntValue("AI:R7"),
+                            json.getIntValue("AI:R8"),
+                            json.getIntValue("AI:R9"),
+                            json.getIntValue("AI:R10"),
+                            json.getIntValue("AI:R11"),
+                            json.getIntValue("AI:R12"),
+                            json.getIntValue("AI:R13"),
+                            json.getIntValue("AI:R14"),
+                            json.getIntValue("AI:R15"),
+                            json.getIntValue("AI:R16"),
+                            json.getIntValue("AI:R17"),
+                            json.getIntValue("AI:R18"),
+                            json.getIntValue("AI:R19"),
+                            json.getIntValue("AI:R20"),
+                            json.getIntValue("AI:R21"),
+                            json.getIntValue("AI:R22"),
+                            json.getIntValue("AI:R23"),
+                            json.getIntValue("AI:R24"),
+                            json.getIntValue("AI:R25"),
+                            json.getIntValue("AI:R26"),
+                            json.getIntValue("AI:R27"),
+                            json.getIntValue("AI:R28"),
+                            json.getIntValue("AI:R29"),
+                            json.getIntValue("AI:R30"),
+                            json.getIntValue("AI:U1"),
+                            json.getIntValue("AI:U2"),
+                            json.getIntValue("AI:U3"),
+                            json.getIntValue("AI:U4"),
+                            json.getIntValue("AI:U5"),
+                            json.getIntValue("AI:U6"),
+                            json.getIntValue("AI:U7"),
+                            json.getIntValue("AI:U8"),
+                            json.getIntValue("AI:U9"),
+                            json.getIntValue("AI:U10"),
+                            json.getIntValue("AI:U11"),
+                            json.getIntValue("AI:U12"),
+                            json.getIntValue("AI:U13"),
+                            json.getIntValue("AI:U14"),
+                            json.getIntValue("AI:U15"),
+                            json.getIntValue("AI:U16"),
+                            json.getIntValue("AI:U17"),
+                            json.getIntValue("AI:U18"),
+                            json.getIntValue("AI:U19"),
+                            json.getIntValue("AI:U20"),
+                            json.getIntValue("AI:U21"),
+                            json.getIntValue("AI:U22"),
+                            json.getIntValue("AI:U23"),
+                            json.getIntValue("AI:U24"),
+                            json.getIntValue("AI:U25"),
+                            json.getIntValue("AI:U26"),
+                            json.getIntValue("AI:U27"),
+                            json.getIntValue("AI:U28"),
+                            json.getIntValue("AI:U29"),
+                            json.getIntValue("AI:U30"),
+                            json.getIntValue("AI:T1"),
+                            json.getIntValue("AI:T2"),
+                            json.getIntValue("AI:T3"),
+                            json.getIntValue("AI:T4"),
+                            json.getIntValue("AI:T5"),
+                            json.getIntValue("AI:T6"),
+                            json.getIntValue("AI:T7"),
+                            json.getIntValue("AI:T8"),
+                            json.getIntValue("AI:T9"),
+                            json.getIntValue("AI:T10"),
+                            json.getIntValue("AI:T11"),
+                            json.getIntValue("AI:T12"),
+                            json.getIntValue("AI:T13"),
+                            json.getIntValue("AI:T14"),
+                            json.getIntValue("AI:T15"),
+                            json.getIntValue("AI:T16"),
+                            json.getIntValue("AI:T17"),
+                            json.getIntValue("AI:T18"),
+                            json.getIntValue("AI:T19"),
+                            json.getIntValue("AI:T20"),
+                            json.getIntValue("AI:T21"),
+                            json.getIntValue("AI:T22"),
+                            json.getIntValue("AI:T23"),
+                            json.getIntValue("AI:T24"),
+                            json.getIntValue("AI:T25"),
+                            json.getIntValue("AI:T26"),
+                            json.getIntValue("AI:T27"),
+                            json.getIntValue("AI:T28"),
+                            json.getIntValue("AI:T29"),
+                            json.getIntValue("AI:T30"),
+                            json.getIntValue("AI:WD"),
+                            json.getIntValue("AI:ZDY"),
+                            json.getIntValue("AI:ZDL")
+                    ) );
+                }else {
+                    ctx.output(ups3,new Ups(
+                            json.getString("stime"),
+                            name,
+                            station,
+                            json.getIntValue("AI:DP17"),
+                            json.getIntValue("AI:DP18"),
+                            json.getIntValue("AI:DP19"),
+                            json.getIntValue("AI:DP20"),
+                            json.getIntValue("AI:DP21"),
+                            json.getIntValue("AI:DP22"),
+                            json.getIntValue("AI:DP23"),
+                            json.getIntValue("AI:DP24"),
+                            json.getIntValue("AI:DP25"),
+                            json.getIntValue("AI:DP26"),
+                            json.getIntValue("AI:DP27"),
+                            json.getIntValue("AI:DP28"),
+                            json.getIntValue("AI:DP29"),
+                            json.getIntValue("AI:DP32"),
+                            json.getIntValue("AI:DP34"),
+                            json.getIntValue("AI:DP35"),
+                            json.getIntValue("AI:DP36"),
+                            json.getString("DI:DP17"),
+                            json.getString("DI:DP18"),
+                            json.getString("DI:DP19"),
+                            json.getString("DI:DP20"),
+                            json.getString("DI:DP21"),
+                            json.getString("DI:DP22"),
+                            json.getString("DI:DP23"),
+                            json.getString("DI:DP24"),
+                            json.getString("DI:DP25"),
+                            json.getString("DI:DP26"),
+                            json.getString("DI:DP27"),
+                            json.getString("DI:DP29"),
+                            json.getString("DI:DP30"),
+                            json.getString("DI:DP31"),
+                            json.getString("DI:DP32"),
+                            json.getString("DI:DP33"),
+                            json.getString("DI:DP34"),
+                            json.getString("DI:DP35"),
+                            json.getString("DI:DP36")
+                            ));
+                }
+            }
+        }
+    );
+        process.getSideOutput(ups).addSink(new KuduSink<UpsBas>("192.168.20.63:7051,192.168.20.64:7051,192.168.20.65:7051", kuduTableInfo4,  UpsBas.class).withStrongConsistency());
+        env.execute();
+}
+}

+ 74 - 0
flink_metro/src/main/java/com/sunwin/metro/start/StartMonitor.java

@@ -0,0 +1,74 @@
+package com.sunwin.metro.start;
+
+
+import com.sunwin.metro.config.ConfigFileHandler;
+import com.sunwin.metro.service.DeviceNormal;
+import com.sunwin.metro.service.DeviceClient;
+import com.sunwin.metro.service.EnergyConsumption;
+import com.sunwin.metro.source.http.HttpMeterAtt;
+import com.sunwin.metro.source.http.HttpMeterMsg;
+import com.sunwin.metro.source.mysql.MysqlSource;
+import com.sunwin.metro.source.mysql.MysqlSourceTime;
+import com.sunwin.metro.utils.DateUtils;
+import com.sunwin.metro.utils.MysqlUtils;
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.commons.io.FileUtils;
+import org.apache.flink.api.common.restartstrategy.RestartStrategies;
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.contrib.streaming.state.RocksDBStateBackend;
+import org.apache.flink.streaming.api.CheckpointingMode;
+import org.apache.flink.streaming.api.TimeCharacteristic;
+import org.apache.flink.streaming.api.datastream.DataStreamSource;
+import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
+import org.apache.flink.streaming.api.environment.CheckpointConfig;
+import org.apache.flink.streaming.api.environment.LocalStreamEnvironment;
+import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
+import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
+import org.apache.flink.streaming.api.functions.sink.SinkFunction;
+import org.apache.flink.streaming.api.functions.source.SourceFunction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author xuYJ
+ * @description: 通讯正常
+ * @create: 2020-08-26 14:10
+ */
+public class StartMonitor {
+    public static final Logger logger = LoggerFactory.getLogger(StartMonitor.class);
+
+    public static void main(String[] args) throws Exception {
+        LocalStreamEnvironment env = StreamExecutionEnvironment.createLocalEnvironment();
+        StreamPro.envPro(env, args[0]);
+        switch (args[0]) {
+            case "device-normal":
+                DataStreamSource<Map<String, List<String>>> source = env.addSource(new MysqlSource(30 * 60 * 1000L));
+                DeviceNormal.process(source);
+                env.execute("device-normal");
+                break;
+            case "device-client":
+                DataStreamSource<Map<String, List<String>>> source2 = env.addSource(new MysqlSourceTime(5 * 1000L));
+                DeviceClient.process(source2);
+                env.execute("device-client");
+                break;
+            case "energy-consumption":
+                SingleOutputStreamOperator<String> source3 = env.setParallelism(1).addSource(new HttpMeterAtt());
+                SingleOutputStreamOperator<Tuple4<String, String, String, String>> source4 = env.addSource(new HttpMeterMsg());
+                EnergyConsumption.process(source3, source4);
+                env.execute("energy-consumption");
+                break;
+            default:
+                break;
+        }
+    }
+}

+ 158 - 0
flink_metro/src/main/java/com/sunwin/metro/start/StartService.java

@@ -0,0 +1,158 @@
+package com.sunwin.metro.start;
+
+
+import com.sunwin.metro.config.ConfigFileHandler;
+import com.sunwin.metro.consumer.CustomKafkaDeserializationSchema;
+import com.sunwin.metro.service.MetroService;
+import com.sunwin.metro.service.WriteMetroTxt;
+import com.sunwin.metro.utils.DateUtils;
+import com.sunwin.metro.utils.MysqlUtils;
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.commons.io.FileUtils;
+import org.apache.flink.api.common.restartstrategy.RestartStrategies;
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.contrib.streaming.state.RocksDBStateBackend;
+import org.apache.flink.streaming.api.CheckpointingMode;
+import org.apache.flink.streaming.api.datastream.DataStreamSource;
+import org.apache.flink.streaming.api.environment.CheckpointConfig;
+import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
+import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
+import org.apache.flink.streaming.api.functions.source.SourceFunction;
+import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author xuYJ
+ * @description: 数据消费者
+ * @create: 2020-08-26 14:10
+ */
+public class StartService {
+    public static final Logger logger = LoggerFactory.getLogger(StartService.class);
+
+    public static void main(String[] args) throws Exception {
+
+        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
+        env.setRestartStrategy(RestartStrategies.fixedDelayRestart(10, org.apache.flink.api.common.time.Time.of(5, TimeUnit.SECONDS)));
+        env.setStateBackend(new RocksDBStateBackend(ConfigFileHandler.getCheckPoint() + args[0] + "/", true).getCheckpointBackend());
+        env.enableCheckpointing(10000 * 6);
+        env.getCheckpointConfig().setMinPauseBetweenCheckpoints(10000 * 3);
+        env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
+        env.getCheckpointConfig().setCheckpointTimeout(60000 * 10);
+        env.getCheckpointConfig().setTolerableCheckpointFailureNumber(100);
+        env.getCheckpointConfig().setMaxConcurrentCheckpoints(1);
+        env.getCheckpointConfig().enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
+        switch (args[0]) {
+            case "metro":
+                new MetroService().process(getInput(env, ConfigFileHandler.getMetroTopicName(), ConfigFileHandler.getMetroId()));
+                env.execute("metro");
+                break;
+            case "writeTxt":
+                new WriteMetroTxt().process(getInput(env, ConfigFileHandler.getMetroTopicName(), ConfigFileHandler.getMetroId()));
+                env.execute("writeTxt");
+                break;
+            case "TCMS-info":
+                DataStreamSource<String> source5 = env.setParallelism(1).addSource(new SourceFunction<String>() {
+                    private Boolean running = true;
+                    @Override
+                    public void run(SourceContext<String> ctx) throws Exception {
+                        List<String> list = FileUtils.readLines(new File("C:\\Users\\daoda\\Desktop\\地铁项目\\TCMS曲线数据4小时.txt"));
+                        while (running) {
+                            for (int i = 0; i < list.size(); i++) {
+                                ctx.collect(list.get(i));
+                                Thread.sleep(500L);
+                            }
+                        }
+                    }
+
+                    @Override
+                    public void cancel() {
+                        running = false;
+                    }
+                });
+                source5.addSink(new RichSinkFunction<String>() {
+                    private PreparedStatement ps;
+                    private Connection connection;
+
+                    @Override
+                    public void open(Configuration parameters) throws Exception {
+                        super.open(parameters);
+                        BasicDataSource dataSource = new BasicDataSource();
+                        connection = MysqlUtils.getMysqlCon(dataSource);
+                    }
+
+                    @Override
+                    public void close() throws Exception {
+                        super.close();
+                        super.close();
+                        if (connection != null) {
+                            connection.close();
+                        }
+                        if (ps != null) {
+                            ps.close();
+                        }
+                    }
+
+                    @Override
+                    public void invoke(String value, Context context) throws Exception {
+                        try {
+                            String sql = "REPLACE into meter_single(collect_id, collect_time, atc_to_signal, atc_pre_arrival_signal, atc_away_signal, atc_next_id, " +
+                                    "atc_current_id, atc_end_id, tmc2_next_id, tmc2_current_id, tmc2_end_id, tmc2_start_id " +
+                                    ") values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
+                            ps = connection.prepareStatement(sql);
+                            String[] result = value.trim().split(",");
+                            ps.setString(1, "result");
+                            ps.setString(2, DateUtils.localDateTimeToStringWithFormat(LocalDateTime.now(), "HH:mm:ss:SSS"));
+                            ps.setDouble(3, Double.parseDouble(result[1]));
+                            ps.setDouble(4, Double.parseDouble(result[2]));
+                            ps.setDouble(5, Double.parseDouble(result[3]));
+                            ps.setDouble(6, Double.parseDouble(result[4]));
+                            ps.setDouble(7, Double.parseDouble(result[5]));
+                            ps.setDouble(8, Double.parseDouble(result[6]));
+                            ps.setDouble(9, Double.parseDouble(result[7]));
+                            ps.setDouble(10, Double.parseDouble(result[8]));
+                            ps.setDouble(11, Double.parseDouble(result[9]));
+                            ps.setDouble(12, Double.parseDouble(result[10]));
+                            ps.addBatch();
+                            ps.executeBatch();
+                            connection.commit();
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                            if (connection != null) {
+                                connection.close();
+                            }
+                            if (ps != null) {
+                                ps.close();
+                            }
+                            BasicDataSource dataSource = new BasicDataSource();
+                            connection = MysqlUtils.getMysqlCon(dataSource);
+                        }
+                    }
+                });
+                env.execute("TCMS-info");
+                break;
+            default:
+                break;
+        }
+    }
+
+    public static DataStreamSource<Tuple4<String, Integer, Long, String>> getInput(StreamExecutionEnvironment env, String topicName, String groupId) {
+        Properties properties = new Properties();
+        properties.setProperty("bootstrap.servers", ConfigFileHandler.getKafkaAddress());
+        properties.setProperty("group.id", groupId);
+        properties.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
+        properties.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
+        FlinkKafkaConsumer<Tuple4<String, Integer, Long, String>> consumer = new FlinkKafkaConsumer<>(topicName, new CustomKafkaDeserializationSchema(), properties);
+        consumer.setStartFromEarliest();
+        return env.addSource(consumer);
+    }
+}

+ 35 - 0
flink_metro/src/main/java/com/sunwin/metro/start/StreamPro.java

@@ -0,0 +1,35 @@
+package com.sunwin.metro.start;
+
+import com.sunwin.metro.config.ConfigFileHandler;
+import org.apache.flink.api.common.restartstrategy.RestartStrategies;
+import org.apache.flink.contrib.streaming.state.RocksDBStateBackend;
+import org.apache.flink.streaming.api.CheckpointingMode;
+import org.apache.flink.streaming.api.TimeCharacteristic;
+import org.apache.flink.streaming.api.environment.CheckpointConfig;
+import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @program: sunwin_metro
+ * @description: 实时流配置
+ * @author: xuYJ
+ * @create: 2021-04-26 17:29
+ **/
+public class StreamPro {
+    public static void envPro (StreamExecutionEnvironment env,String arg) throws IOException {
+        env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
+        env.setParallelism(1);
+        env.setRestartStrategy(RestartStrategies.fixedDelayRestart(10, org.apache.flink.api.common.time.Time.of(5, TimeUnit.SECONDS)));
+        env.setStateBackend(new RocksDBStateBackend(ConfigFileHandler.getCheckPoint() + arg + "/", true).getCheckpointBackend());
+        env.enableCheckpointing(10000 * 6);
+        env.getCheckpointConfig().setMinPauseBetweenCheckpoints(10000 * 3);
+        env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
+        env.getCheckpointConfig().setCheckpointTimeout(60000 * 10);
+        env.getCheckpointConfig().setTolerableCheckpointFailureNumber(100);
+        env.getCheckpointConfig().setMaxConcurrentCheckpoints(1);
+        env.getCheckpointConfig().enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
+
+    }
+}

+ 175 - 0
flink_metro/src/main/java/com/sunwin/metro/utils/DateUtils.java

@@ -0,0 +1,175 @@
+package com.sunwin.metro.utils;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+
+
+public class DateUtils {
+
+    public static Date stringToDateWithFormat(String str, String format) {
+        Date date = null;
+        if (!PerStringUtils.isNullOrEmpty(str)) {
+            try {
+                date = new SimpleDateFormat(format).parse(str);
+            } catch (ParseException e) {
+                date = stringToDate(str);
+            }
+        }
+        return date;
+    }
+
+
+    public static Date stringToDate(String dateStr) {
+        try {
+            return stringToDate(dateStr, getDefaultDateFormats());
+        } catch (ParseException ignored) {
+        }
+        return null;
+    }
+
+
+    public static Date stringToDate(String dateStr, Collection<String> dateFormats) throws ParseException {
+        if (dateStr == null || dateStr.length() == 0) {
+            return null;
+        }
+
+        if (dateFormats == null) {
+            dateFormats = getDefaultDateFormats();
+        }
+        Iterator<String> formatIterator = dateFormats.iterator();
+        SimpleDateFormat dateParser = null;
+        String format;
+        while (formatIterator.hasNext()) {
+            format = formatIterator.next();
+            if (dateParser == null) {
+                dateParser = new SimpleDateFormat(format);
+            } else {
+                dateParser.applyPattern(format);
+            }
+            try {
+                return dateParser.parse(dateStr);
+            } catch (ParseException pe) {
+
+            }
+        }
+        throw new ParseException("Unable to parse the date " + dateStr, 0);
+    }
+
+
+    private static Collection<String> getDefaultDateFormats() {
+        Collection<String> defaultDateFormats = new ArrayList<String>();
+        defaultDateFormats.add("yyyy-MM-dd HH:mm:ss");
+        defaultDateFormats.add("yyyy-MM-dd HH:mm");
+        defaultDateFormats.add("yyyyMMddHHmmss");
+        defaultDateFormats.add("yyyy-MM-dd");
+        defaultDateFormats.add("yyyyMMddHHmm");
+        defaultDateFormats.add("yyyy-MM");
+        defaultDateFormats.add("yyyyMMdd");
+        defaultDateFormats.add("yyyyMM");
+        defaultDateFormats.add("yyyy年MM月dd日 HH时mm分ss秒");
+        defaultDateFormats.add("yyyy年MM月dd日");
+        defaultDateFormats.add("yyyy年MM月");
+        defaultDateFormats.add("yyyy年");
+        defaultDateFormats.add("yyyy");
+        return defaultDateFormats;
+    }
+
+
+    public static Long getTimestamp(String time) {
+        Long timestamp = null;
+        try {
+            timestamp = new SimpleDateFormat("yyyyMMddHHmmssSSS").parse(time).getTime();
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return timestamp;
+    }
+
+    public static String dateToShortStringNoSep(Date date) {
+        return dateToStringWithFormat(date, "yyyyMMdd");
+    }
+
+
+    public static String dateToLongStringNoSep(Date date) {
+        return dateToStringWithFormat(date, "yyyyMMddHHmmss");
+    }
+
+
+    public static String dateToStringWithFormat(Date date, String format) {
+        String str = "";
+        if (date == null || format == null || format.length() == 0) {
+            return str;
+        }
+        try {
+            str = new SimpleDateFormat(format).format(date);
+        } catch (Exception ignored) {
+        }
+        return str;
+    }
+
+
+    public static String localDateTimeToStringWithFormat(LocalDateTime dateTime, String format) {
+        String str = "";
+        if (dateTime == null || format == null || format.length() == 0) {
+            return str;
+        }
+        try {
+            str = DateTimeFormatter.ofPattern(format).format(dateTime);
+        } catch (Exception ignored) {
+        }
+        return str;
+    }
+
+
+    /**
+     * 将一种格式的日期字符转换成目标格式的字符串
+     *
+     * @param str          日期串
+     * @param sourceFormat 原格式,如"yyyyMMddHHmmss"
+     * @param destFormat   目标格式,如"yyyy-MM-dd HH:mm:ss"
+     * @return String 格式化后的日期串
+     * @author yangdong
+     * @date 2015-8-10 下午6:09:41
+     */
+    public static String stringDateFormat(String str, String sourceFormat, String destFormat) {
+        if (PerStringUtils.isNullOrEmpty(str)) {
+            return "";
+        }
+        try {
+            SimpleDateFormat dest = new SimpleDateFormat(destFormat);
+            return dest.format(stringToDateWithFormat(str, sourceFormat));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return "";
+    }
+
+
+    /**
+     * 方法名:stringToTimeStampWithFormat
+     * 作者: kane
+     * 创建时间:2016-9-23 下午02:11:28
+     *
+     * @param dateStr    时间字符串
+     * @param timeFormat 时间字符串格式,如yyyyMMddHHmmss
+     * @return long型时间戳
+     * 描述:将给定格式的字符串转换成时间戳
+     */
+    public static long stringToTimeStampWithFormat(String dateStr, String timeFormat) {
+        try {
+            if (dateStr != null && dateStr.length() > 0) {
+                SimpleDateFormat format = new SimpleDateFormat(timeFormat);
+                Date date = format.parse(dateStr);
+                return date.getTime();
+            }
+        } catch (Exception e) {
+            System.out.println("日期转换出现异常");
+        }
+        return 0;
+    }
+
+
+}

+ 73 - 0
flink_metro/src/main/java/com/sunwin/metro/utils/FileUtil.java

@@ -0,0 +1,73 @@
+package com.sunwin.metro.utils;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.*;
+import org.apache.hadoop.io.IOUtils;
+
+import java.io.IOException;
+
+/**
+ * @program: sunwin_metro
+ * @description: hadoop 工具类
+ * @author: xuYJ
+ * @create: 2021-06-17 09:48
+ **/
+public class FileUtil {
+    private static final Log logger = LogFactory.getLog(FileUtil.class);
+
+
+    public static void mergeFile(Path srcDir, final String srcFileNameExpression, String outFile, boolean overWrite, Configuration conf) throws IOException {
+        FileSystem fs = null;
+        FileStatus[] fileStatuses = new FileStatus[0];
+        FSDataOutputStream outFileOutputStream = null;
+        FSDataInputStream inputStream = null;
+        try {
+            fs = FileSystem.get(conf);
+            fileStatuses = fs.listStatus(srcDir, new PathFilter() {
+                @Override
+                public boolean accept(Path path) {
+                    return path.getName().contains(srcFileNameExpression);
+                }
+            });
+            outFileOutputStream = fs.create(new Path(outFile), overWrite);
+            for (FileStatus st : fileStatuses) {
+                Path temp = st.getPath();
+                inputStream = fs.open(temp);
+                IOUtils.copyBytes(inputStream, outFileOutputStream, 4096, false);
+                inputStream.close();
+                logger.info("merge : " + temp.toString() + " -> " + outFile);
+            }
+
+        } catch (IOException e) {
+            logger.error(e);
+        } finally {
+            if (fs != null) {
+                fs.close();
+            }
+            if (fileStatuses != null) {
+                fileStatuses = null;
+            }
+            if (outFileOutputStream != null) {
+                outFileOutputStream.close();
+            }
+            if (inputStream != null) {
+                inputStream.close();
+            }
+        }
+
+    }
+
+    public static void main(String[] args) throws IOException {
+        if (args.length < 3) {
+            System.out.println("参数错误");
+        }
+        for (String s : args) {
+            System.out.println(s);
+        }
+        Configuration conf = new Configuration();
+        FileUtil.mergeFile(new Path(args[0]), args[1], args[2], true, conf);
+    }
+}
+

+ 117 - 0
flink_metro/src/main/java/com/sunwin/metro/utils/FileUtils.java

@@ -0,0 +1,117 @@
+package com.sunwin.metro.utils;
+
+import org.ahocorasick.trie.Emit;
+import org.ahocorasick.trie.Trie;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * 文件操作工具
+ *
+ * @author kane
+ * @date 2020-02-13 13:42
+ */
+public class FileUtils {
+
+
+    public static boolean containsWords(String inputString, String[] words) {
+        boolean found = false;
+        for (String word : words) {
+            if (inputString.contains(word)) {
+                found = true;
+                break;
+            }
+        }
+        return found;
+    }
+
+
+    public static <T extends Closeable> boolean close(T stream) {
+        if (stream != null) {
+            try {
+                stream.close();
+                return true;
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return false;
+    }
+
+
+    public static boolean isExistFile(String pathFileName) {
+        if (!PerStringUtils.isNullOrEmpty(pathFileName)) {
+            File file = new File(pathFileName);
+            return file.exists() && file.isFile();
+        }
+        return false;
+    }
+
+    public static boolean createFile(String fileName) {
+        if (PerStringUtils.isNullOrEmpty(fileName)) {
+            return false;
+        } else {
+            File file = new File(fileName);
+            try {
+                return file.createNewFile();
+            } catch (IOException e) {
+                return false;
+            }
+        }
+    }
+
+    public static File getFile(String fileName) {
+        if (!isExistFile(fileName)) {
+            createFile(fileName);
+        }
+        return new File(fileName);
+    }
+
+
+    public static String getFileContent(String fileName, String encoding) {
+        if (PerStringUtils.isNullOrEmpty(fileName) || PerStringUtils.isNullOrEmpty(encoding)) {
+            return "";
+        } else {
+            Object[] object = getFileBufferedReader(fileName, encoding);
+            if (object == null) {
+                return null;
+            }
+            try {
+                String line;
+                StringBuilder sb = new StringBuilder();
+                while (null != (line = ((BufferedReader) object[0]).readLine())) {
+                    sb.append(line);
+                }
+                return sb.toString();
+            } catch (Exception ignored) {
+            } finally {
+                close((Closeable) object[0]);
+                close((Closeable) object[1]);
+                close((Closeable) object[2]);
+            }
+            return "";
+        }
+    }
+
+    private static Object[] getFileBufferedReader(String fileName, String encoding) {
+        FileInputStream fileInputStream;
+        InputStreamReader inputStreamReader;
+        BufferedReader bufferedReader;
+        if (PerStringUtils.isNullOrEmpty(fileName) || PerStringUtils.isNullOrEmpty(encoding)) {
+            return null;
+        } else {
+            try {
+                fileInputStream = new FileInputStream(getFile(fileName));
+                inputStreamReader = new InputStreamReader(fileInputStream, encoding);
+                bufferedReader = new BufferedReader(inputStreamReader);
+            } catch (FileNotFoundException | UnsupportedEncodingException e) {
+                e.printStackTrace();
+                return null;
+            }
+        }
+        return new Object[]{bufferedReader, inputStreamReader, fileInputStream};
+    }
+
+
+}

+ 159 - 0
flink_metro/src/main/java/com/sunwin/metro/utils/HBaseUtil.java

@@ -0,0 +1,159 @@
+package com.sunwin.metro.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.*;
+import org.apache.hadoop.hbase.util.Bytes;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @program: sunwin_metro
+ * @description: Hbase工具类
+ * @author: xuYJ
+ * @create: 2021-02-20 14:31
+ **/
+public class HBaseUtil {
+
+    static Connection connection = null;
+    static Admin admin = null;
+
+    static {
+        Configuration conf = HBaseConfiguration.create();
+        conf.set("hbase.zookeeper.quorum", "192.168.20.65:2181,192.168.20.66:2181,192.168.20.67:2181");
+        try {
+            connection = ConnectionFactory.createConnection(conf);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        try {
+            admin = connection.getAdmin();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    public static void sendMessage(String tableName,JSONObject json,String family) {
+        String compName = json.getString("compname");
+        String stationId = json.getString("stationId");
+        String station;
+        String sysName;
+        if (compName.contains("ACS")) {
+            sysName = "001";
+        } else if (compName.contains("BAS")) {
+            sysName = "002";
+        } else if (compName.contains("FAS")) {
+            sysName = "003";
+        } else if (compName.contains("PSD")) {
+            sysName = "004";
+        } else if (compName.contains("UPS")) {
+            sysName = "005";
+        } else if (compName.contains("AFC")) {
+            sysName = "006";
+        } else {
+            sysName = "000";
+        }
+        if (stationId.contains("sw:404")) {
+            station = "001";
+        } else {
+            station = "000";
+        }
+        String deviceTime = DateUtils.stringDateFormat(json.getString("stime"), "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyyMMddHHmmssSSS").substring(0, 8);
+        String dpe = json.getString("dpes");
+        String device = String.valueOf(Math.abs(dpe.hashCode()));
+        String rowKey = station + sysName + deviceTime + device;
+        HashMap<String, Object> map = new HashMap<>();
+        map.put("collectTime", json.getString("collectTime"));
+        map.put("compDes", json.getString("compDes"));
+        map.put("dpe", dpe);
+        map.put("subSys", json.getString("subSys"));
+        map.put("stationName", json.getString("stationName"));
+        map.put("sTime", json.getString("stime"));
+        map.put("compName", json.getString("compname"));
+        map.put("stationId", json.getString("stationId"));
+        putMapDataByRowKey(tableName, family, map, rowKey);
+    }
+
+    public static boolean tableExist(String tableName) throws IOException {
+        return admin.tableExists(TableName.valueOf(tableName));
+    }
+
+    private static void createTable(String tableName, List<String> columnFamily) throws IOException {
+        if (!tableExist(tableName)) {
+            HTableDescriptor hTableDescriptor = new HTableDescriptor(TableName.valueOf(tableName));
+            for (String f : columnFamily) {
+                HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(f);
+                hTableDescriptor.addFamily(hColumnDescriptor);
+            }
+            admin.createTable(hTableDescriptor);
+        }
+    }
+
+    public static Table getTable(String tableName,List<String> familyList) {
+        Table tblName = null;
+        try {
+            createTable(tableName,familyList);
+            tblName = connection.getTable(TableName.valueOf(tableName));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return tblName;
+    }
+
+    public static void putDataByRowKey(String tableName, String family, String colName, String colValue, String rowKey,List<String> familyList) {
+        Table table = getTable(tableName,familyList);
+
+        try {
+            Put put = new Put(rowKey.getBytes());
+            put.addColumn(family.getBytes(), Bytes.toBytes(colName), colValue.getBytes());
+            table.put(put);
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                table.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public static void putMapDataByRowKey(String tableName, String family, Map<String, Object> map, String rowKey) {
+
+        Table table = getTable(tableName, Collections.singletonList(family));
+        try {
+            Put put = new Put(rowKey.getBytes());
+            for (String key : map.keySet()) {
+
+                put.addColumn(family.getBytes(), key.getBytes(), map.get(key).toString().getBytes());
+            }
+            table.put(put);
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                table.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+
+    public static void close(Connection connection, Admin admin) throws IOException {
+        if (connection != null) {
+            connection.close();
+        }
+        if (admin != null) {
+            admin.close();
+        }
+    }
+}

+ 89 - 0
flink_metro/src/main/java/com/sunwin/metro/utils/KafkaUtils.java

@@ -0,0 +1,89 @@
+package com.sunwin.metro.utils;
+
+
+import com.alibaba.fastjson.JSONObject;
+import org.apache.kafka.clients.producer.*;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Random;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Future;
+
+/**
+ * @author xuYJ
+ * @description:kafka工具类
+ * @date 2020/8/17 14:45
+ */
+public class KafkaUtils implements Serializable {
+
+    private static final Map<String, KafkaProducer<String, String>> PRODUCER_CACHE = new ConcurrentHashMap<>();
+
+    /**
+     * 创建生产者
+     */
+    private static KafkaProducer<String, String> createProducer(String brokers) {
+        Properties prop = new Properties();
+        prop.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, brokers);
+        //ACK机制
+        prop.put(ProducerConfig.ACKS_CONFIG, "-1");
+        prop.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
+        prop.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
+        return new KafkaProducer<>(prop);
+    }
+
+    static {
+        Runtime.getRuntime().addShutdownHook(
+                new Thread(() -> PRODUCER_CACHE.forEach(KafkaUtils::accept)
+                )
+        );
+    }
+
+    private static KafkaProducer<String, String> getProducer(String brokers) {
+        return PRODUCER_CACHE.compute(brokers, (k, oldProducer) -> {
+            if (oldProducer == null) {
+                oldProducer = createProducer(brokers);
+            }
+            return oldProducer;
+        });
+    }
+
+
+    public static Future<RecordMetadata> send(String brokers, String topic, String key, String message) {
+        KafkaProducer<String, String> producer = getProducer(brokers);
+        ProducerRecord<String, String> producerRecord = new ProducerRecord<>(topic, key, message);
+        return producer.send(producerRecord);
+    }
+
+
+    public static void send(String brokers, String topic, String message) {
+        KafkaProducer<String, String> producer = getProducer(brokers);
+        ProducerRecord<String, String> producerRecord = new ProducerRecord<String, String>(topic, message);
+        producer.send(producerRecord, new Callback() {
+            @Override
+            public void onCompletion(RecordMetadata recordMetadata, Exception exception) {
+                if (null != exception) {
+                    System.out.println("Send message exception:" + exception);
+                }
+                if (null != recordMetadata) {
+                    System.out.println(String.format("偏移量:%s,分区:%s", recordMetadata.offset(), recordMetadata.partition()));
+                }
+            }
+        });
+    }
+
+
+
+    private static void accept(String key, KafkaProducer<String, String> v) {
+        try {
+            v.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+}
+

+ 33 - 0
flink_metro/src/main/java/com/sunwin/metro/utils/Md5Utils.java

@@ -0,0 +1,33 @@
+package com.sunwin.metro.utils;
+
+import java.util.Date;
+
+/**
+ *生成设备属性id
+ *
+ * @author kane
+ * @date 2019-12-04 17:47
+ */
+public class Md5Utils {
+
+    public static long getDeviceId(String time,String dpe) {
+        if ((dpe == null) || (dpe.length() == 0)) {
+            throw new NullPointerException("生成设备 id的设备属性状态名称不能为空");
+        }
+        if ((time == null) || (time.length() == 0)) {
+            time=DateUtils.dateToLongStringNoSep(new Date());
+        }
+        return Sign.getMd5(dpe+time);
+    }
+
+    public static String getDeviceIdNoTime(String dpe) {
+        if ((dpe == null) || (dpe.length() == 0)) {
+            throw new NullPointerException("生成设备 id的设备属性状态名称不能为空");
+        }
+        return String.valueOf(Sign.getMd5(dpe));
+    }
+
+    public static void main(String[] args) {
+
+    }
+}

+ 50 - 0
flink_metro/src/main/java/com/sunwin/metro/utils/MysqlUtils.java

@@ -0,0 +1,50 @@
+package com.sunwin.metro.utils;
+
+import com.sunwin.metro.config.ConfigFileHandler;
+import org.apache.commons.dbcp2.BasicDataSource;
+
+import java.sql.Connection;
+
+/**
+ * @program: sunwin_metro
+ * @description: mysql连接器
+ * @author: xuYJ
+ * @create: 2021-04-14 14:11
+ **/
+public class MysqlUtils {
+
+    public static Connection getMysqlCon(BasicDataSource dataSource) {
+        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
+        dataSource.setUrl(ConfigFileHandler.getMysqlUrl());
+        dataSource.setUsername(ConfigFileHandler.getMysqlUserName());
+        dataSource.setPassword(ConfigFileHandler.getMysqlPassWord());
+        dataSource.setInitialSize(10);
+        dataSource.setMaxTotal(50);
+        dataSource.setMinIdle(2);
+
+        Connection con = null;
+        try {
+            con = dataSource.getConnection();
+            con.setAutoCommit(false);
+        } catch (Exception ignored) {
+        }
+        return con;
+    }
+
+    public static Connection getImpalaCon(BasicDataSource dataSource) {
+        dataSource.setDriverClassName("com.cloudera.impala.jdbc41.Driver");
+        dataSource.setUrl("jdbc:impala://192.168.20.63:21050/urtdb");
+        dataSource.setInitialSize(10);
+        dataSource.setMaxTotal(50);
+        dataSource.setMinIdle(2);
+
+        Connection con = null;
+        try {
+            con = dataSource.getConnection();
+            con.setAutoCommit(false);
+            System.out.println("创建连接池:" + con);
+        } catch (Exception ignored) {
+        }
+        return con;
+    }
+}

Файловите разлики са ограничени, защото са твърде много
+ 464 - 0
flink_metro/src/main/java/com/sunwin/metro/utils/PerStringUtils.java


+ 93 - 0
flink_metro/src/main/java/com/sunwin/metro/utils/Sign.java

@@ -0,0 +1,93 @@
+/*************************************************
+ Copyright © 2010 boryou. All rights reserved.
+
+ File name: Sign.java
+ Version: 1.0
+ Author: 高威
+ Date: Nov 9, 2010
+ Description:
+ History:
+ 1. Date: Nov 9, 2010
+ Author: 高威
+ Modification:
+ 2. ...
+ *************************************************/
+package com.sunwin.metro.utils;
+
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+
+/**
+ * 签名
+ * @author kane
+ */
+public class Sign {
+
+    private static final int MD5LEN = 16;
+
+    public static byte[] getSign(String text) {
+        byte[] sign = {-44, 29, -116, -39, -113, 0, -78, 4, -23, -128, 9, -104, -20, -8, 66, 126};
+        if (text == null) {
+            return sign;
+        }
+        try {
+            sign = text.getBytes(StandardCharsets.UTF_8);
+        } catch (Exception e1) {
+            e1.printStackTrace();
+        }
+        try {
+            MessageDigest digester = MessageDigest.getInstance("MD5");
+            digester.update(sign);
+            sign = digester.digest();
+            if (sign.length == MD5LEN) {
+                return sign;
+            }
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        return new byte[]{-44, 29, -116, -39, -113, 0, -78, 4, -23, -128, 9, -104, -20, -8, 66, 126};
+    }
+
+
+    public static long getMd5(String text) {
+        return new BigInteger(Sign.getSign(text)).longValue();
+    }
+
+
+    public static String byteToString(byte[] sign) {
+        StringBuilder digestHexStr = new StringBuilder();
+        for (byte b : sign) {
+            digestHexStr.append(byteHex(b));
+        }
+        return digestHexStr.toString();
+    }
+
+    private static String byteHex(int ib) {
+
+        byte[] digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+        byte[] ob = new byte[2];
+        int h;
+        int l;
+        if (ib < 0) {
+
+            ib = -ib;
+            ib = ib - 1;
+            // 补码to原码
+            h = (ib >> 4) & 0x0f;
+            l = ib & 0x0f;
+            h = h | 0x8;
+        } else {
+            h = (ib >> 4) & 0x0f;
+            l = ib & 0x0f;
+        }
+
+        ob[0] = digit[h];
+        ob[1] = digit[l];
+        return new String(ob);
+    }
+
+
+}

+ 104 - 0
flink_metro/src/main/java/com/sunwin/metro/utils/websocket/Client.java

@@ -0,0 +1,104 @@
+package com.sunwin.metro.utils.websocket;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.mysql.cj.util.StringUtils;
+//import com.mysql.jdbc.StringUtils;
+import com.sunwin.metro.source.mysql.MysqlData;
+import com.sunwin.metro.utils.DateUtils;
+import com.sunwin.metro.utils.HBaseUtil;
+import com.sunwin.metro.utils.KafkaUtils;
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.java_websocket.WebSocket;
+import org.java_websocket.client.WebSocketClient;
+import org.java_websocket.handshake.ServerHandshake;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.URI;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @program: sunwin_metro
+ * @description: 自动重启客户端
+ * @author: xuYJ
+ * @create: 2021-02-18 15:57
+ **/
+public class Client {
+    public static final Logger logger = LoggerFactory.getLogger(Client.class);
+    static final String BOOTSTRAP_SERVERS = "192.168.20.65:9092,192.168.20.66:9092,192.168.20.67:9092";
+    private static WebSocketClient client;
+
+    public static void createConnect() throws Exception {
+        client = new WebSocketClient(new URI("ws://127.0.0.1:12108/dpsubSys_websocket")) {
+            @Override
+            public void onOpen(ServerHandshake serverHandshake) {
+                logger.info("webSocket服务端开始启动");
+            }
+
+            @Override
+            public void onMessage(String message) {
+                if (!StringUtils.isNullOrEmpty(message) && !message.contains("errorDes")) {
+                    message = StringEscapeUtils.unescapeJava(message).replace("\"{", "{").replace("}\n\"", "}");
+                    JSONObject object = JSON.parseObject(message);
+                    object.put("collectTime", DateUtils.dateToLongStringNoSep(new Date()));
+                    KafkaUtils.send(BOOTSTRAP_SERVERS, "metro_test", object.toJSONString());
+                    HBaseUtil.sendMessage("metro2", object, "info");
+                } else {
+                    System.out.println(message);
+                }
+            }
+
+            @Override
+            public void onError(Exception arg0) {
+                arg0.printStackTrace();
+            }
+
+            @Override
+            public void onClose(int arg0, String arg1, boolean arg2) {
+                try {
+                    Thread.sleep(40000);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+
+                try {
+                    createConnect();
+                    List<String> results = null;
+                    try {
+                        results = MysqlData.getWords("metro_device_all");
+                    } catch (Exception exception) {
+                        exception.printStackTrace();
+                    }
+                    JSONArray array = new JSONArray();
+                    for (String result : results) {
+                        array.add("sw404:" + result.trim());
+                    }
+                    JSONObject object = new JSONObject();
+                    object.put("dpes", array);
+                    client.send(object.toJSONString());
+
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        };
+        client.connect();
+        client.setConnectionLostTimeout(600000);
+        Thread.sleep(20000);
+        while (!client.getReadyState().equals(WebSocket.READYSTATE.OPEN)) {
+            Thread.sleep(10000);
+        }
+    }
+
+    public static void send(String message) throws Exception {
+        if (null == client || (!client.isOpen())) {
+            createConnect();
+        }
+        client.send(message);
+    }
+
+}

+ 58 - 0
flink_metro/src/main/java/com/sunwin/metro/utils/websocket/ClientManager.java

@@ -0,0 +1,58 @@
+package com.sunwin.metro.utils.websocket;
+
+
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.sunwin.metro.bean.ErrorDevice;
+import com.sunwin.metro.source.mysql.MysqlData;
+import com.sunwin.metro.utils.DateUtils;
+import com.sunwin.metro.utils.Md5Utils;
+import com.sunwin.metro.utils.PerStringUtils;
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.java_websocket.WebSocket;
+import java.io.IOException;
+import java.net.URI;
+import java.util.Collections;
+import java.util.Date;
+
+/**
+ * @program: opcClient
+ * @author: xuYJ
+ * @create: 2020-12-29 13:17
+ **/
+public class ClientManager {
+
+    private ClientSocket socket;
+
+    public void connect(String url, String json) {
+        try {
+            socket = new ClientSocket(this, new URI(url));
+            socket.connect();
+            while (!socket.getReadyState().equals(WebSocket.READYSTATE.OPEN)) {
+                Thread.sleep(10000);
+            }
+            socket.send(json);
+        } catch (Exception e) {
+        }
+    }
+
+    public void receive(String message) throws IOException {
+        if (!PerStringUtils.isNullOrEmpty(message)) {
+            if (message.contains("errorDes")) {
+                System.out.println("message = " + message);
+                JSONObject jsonObject = JSON.parseObject(message);
+                String errorDes = jsonObject.getString("errorDes");
+                String[] split = errorDes.split("--");
+                MysqlData.insertData(Collections.singletonList(new ErrorDevice(Md5Utils.getDeviceIdNoTime(split[0]),split[0], "通讯异常:"+split[1], DateUtils.dateToLongStringNoSep(new Date()))), "metro_device_error");
+            } else {
+                message = StringEscapeUtils.unescapeJava(message).replace("\"{", "{").replace("}\n\"", "}");
+                JSONObject object = JSON.parseObject(message);
+                String deviceName = object.getString("compname");
+                String stationId = object.getString("stationId");
+                String name = stationId + ":" + deviceName;
+                MysqlData.insertData(Collections.singletonList(new ErrorDevice(Md5Utils.getDeviceIdNoTime(name),name, "通讯正常", DateUtils.dateToLongStringNoSep(new Date()))), "metro_device_error");
+            }
+        }
+    }
+}

+ 49 - 0
flink_metro/src/main/java/com/sunwin/metro/utils/websocket/ClientSocket.java

@@ -0,0 +1,49 @@
+package com.sunwin.metro.utils.websocket;
+
+
+import org.java_websocket.client.WebSocketClient;
+import org.java_websocket.handshake.ServerHandshake;
+import java.io.IOException;
+import java.net.URI;
+
+/**
+ * @program: opcClient
+ * @description: 客户端
+ * @author: xuYJ
+ * @create: 2020-12-29 13:15
+ **/
+public class ClientSocket extends WebSocketClient {
+
+    private final ClientManager clientManager;
+
+    public ClientSocket(ClientManager clientManager,URI serverUrl) {
+        super(serverUrl);
+        this.clientManager =clientManager;
+    }
+
+    @Override
+    public void onClose(int arg0, String arg1, boolean arg2) {
+        System.out.println("关闭客户端 ");
+    }
+
+
+    @Override
+    public void onError(Exception arg0) {
+        System.out.println("执行异常...");
+    }
+
+    @Override
+    public void onMessage(String arg0) {
+        try {
+            clientManager.receive(arg0);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void onOpen(ServerHandshake arg0) {
+        System.out.println("成功连接...");
+    }
+}
+

+ 23 - 0
flink_metro/src/main/java/com/sunwin/metro/watermark/DeviceWaterLine.java

@@ -0,0 +1,23 @@
+package com.sunwin.metro.watermark;
+
+import com.sunwin.metro.bean.MetroDevice;
+import com.sunwin.metro.utils.DateUtils;
+import org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor;
+import org.apache.flink.streaming.api.windowing.time.Time;
+
+/**
+ * @program: sunwin_metro
+ * @description: 设置水位线,解析设备源数据中的时间戳字段
+ * @author: xuYJ
+ * @create: 2021-03-08 15:24
+ **/
+public class DeviceWaterLine extends BoundedOutOfOrdernessTimestampExtractor<MetroDevice>{
+    public DeviceWaterLine(Time time) {
+        super(time);
+    }
+
+    @Override
+    public long extractTimestamp(MetroDevice metroDevice) {
+        return DateUtils.getTimestamp(metroDevice.getAttribute_time());
+    }
+}

+ 23 - 0
flink_metro/src/main/java/com/sunwin/metro/watermark/MeterWaterLine.java

@@ -0,0 +1,23 @@
+package com.sunwin.metro.watermark;
+
+
+import org.apache.flink.api.java.tuple.Tuple4;
+import org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor;
+import org.apache.flink.streaming.api.windowing.time.Time;
+
+/**
+ * @program: sunwin_metro
+ * @description: 设置水位线,解析设备源数据中的时间戳字段
+ * @author: xuYJ
+ * @create: 2021-03-08 15:24
+ **/
+public class MeterWaterLine extends BoundedOutOfOrdernessTimestampExtractor<Tuple4<String, String, String, Long>>{
+    public MeterWaterLine(Time time) {
+        super(time);
+    }
+
+    @Override
+    public long extractTimestamp(Tuple4<String, String, String, Long> tuple4) {
+        return tuple4.f3;
+    }
+}

+ 162 - 0
flink_metro/src/main/resources/local/log4j.properties

@@ -0,0 +1,162 @@
+log4j.rootLogger=INFO,CONSOLE
+#DEBUG,CONSOLE,FILE,ROLLING_FILE,MAIL,DATABASE
+#子log日志是否传输到父log内
+log4j.addivity.org.apache=false
+#log4j.logger.org.apache.flink=INFO
+###################
+# 控制台(测试环境)
+###################
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.Threshold=INFO
+log4j.appender.CONSOLE.Target=System.out
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} -%-10p -%m  - %c -%-4r - [%t] %c %x%n
+#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n
+
+
+###################
+# 不滚动。默认生成一个日志文件
+###################
+log4j.logger.akka=INFO
+log4j.logger.org.apache.kafka=INFO
+log4j.logger.org.apache.hadoop=INFO
+log4j.logger.org.apache.zookeeper=INFO
+# Log all infos in the given file
+log4j.appender.file=org.apache.log4j.FileAppender
+log4j.appender.file.file=${log.file}
+log4j.appender.file.append=true
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} -%-10p -%m  - %c -%-4r - [%t] %c %x%n
+# Suppress the irrelevant (wrong) warnings from the Netty channel handler
+#log4j.logger.org.apache.flink.shaded.akka.org.jboss.netty.channel.DefaultChannelPipeline=ERROR,file
+
+########################
+# 按照日志大小滚动
+########################
+log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
+log4j.appender.ROLLING_FILE.Threshold=INFO
+#集群存放地址
+log4j.appender.ROLLING_FILE.File=${log.file}
+#本地存放地址
+#log4j.appender.ROLLING_FILE.File=./logs/${log4j.type}/info.log
+log4j.appender.ROLLING_FILE.Append=true
+log4j.appender.ROLLING_FILE.MaxFileSize=10KB
+log4j.appender.ROLLING_FILE.MaxBackupIndex=1
+log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
+log4j.appender.ROLLING_FILE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} -%-10p -%m  - %c -%-4r - [%t] %c %x%n
+
+########################
+# 按照时间滚动
+########################
+#每一天产生1个日志文件
+log4j.appender.DailyRolling=org.apache.log4j.DailyRollingFileAppender
+#定义日志存放路径
+log4j.appender.DailyRolling.File=${log.file}
+#日志文件是否追加
+log4j.appender.DailyRolling.Append=true
+#定义的时间格式,如果时间定义到分钟(mm)就是每分钟生成一个日志文件,而这里定义的这个格式就是日志名后缀
+#每分钟
+log4j.appender.DailyRolling.DatePattern='_'yyyy-MM-dd-HH
+#log4j.appender.file3.DatePattern='_'yyyy-MM-dd-HH    每小时
+#log4j.appender.file3.DatePattern='_'yyyy-MM-dd	每天
+#log4j.appender.file3.DatePattern='_'yyyy-MM-dd-a	每半天
+#日志输出级别
+log4j.appender.DailyRolling.Threshold=INFO
+#日志编码
+#log4j.appender.DailyRolling.Encoding=UTF-8
+#日志中输出的日志的格式
+log4j.appender.DailyRolling.layout=org.apache.log4j.PatternLayout
+#定义的日志格式
+log4j.appender.DailyRolling.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} -%-10p -%m  - %c -%-4r - [%t] %c %x%n
+#log4j.logger.org.apache.flink.shaded.akka.org.jboss.netty.channel.DefaultChannelPipeline=ERROR,DailyRolling
+
+
+
+#####################################################
+# 输出的日志写入kafka TODO:待完善
+#####################################################
+
+
+
+
+####################
+# Socket Appender
+####################
+log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
+log4j.appender.SOCKET.RemoteHost=localhost
+log4j.appender.SOCKET.Port=5001
+log4j.appender.SOCKET.LocationInfo=true
+# Set up for Log Facter 5
+log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
+log4j.appender.SOCET.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} -%-10p -%m  - %c -%-4r - [%t] %c %x%n
+
+########################
+# Log Factor 5 Appender
+########################
+log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
+log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
+
+
+########################
+# SMTP Appender
+#######################
+log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
+#日志的错误级别
+log4j.appender.MAIL.Threshold=ERROR
+#缓存文件大小,日志达到10K时发送Email
+log4j.appender.MAIL.BufferSize=10
+#发送邮件的服务器
+log4j.appender.MAIL.SMTPHost=smtp.163.com
+#邮件主题
+log4j.appender.MAIL.Subject=solr5Product
+#发送邮件箱的用户
+log4j.appender.MAIL.SMTPUsername=boryoukane@163.com
+#发送邮件箱的密码
+log4j.appender.MAIL.SMTPPassword=QBPBRCJCLWSRJJGF
+#发送邮件箱
+log4j.appender.MAIL.From=boryoukane@163.com
+#接受邮件箱
+log4j.appender.MAIL.To=boryoukane@163.com
+#发送邮件的格式
+log4j.appender.MAIL.layout = org.apache.log4j.HTMLLayout
+log4j.appender.MAIL.layout.LocationInfo = TRUE
+#log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
+#log4j.appender.MAIL.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} -%-10p -%m  - %c -%-4r - [%t] %c %x%n
+########################
+# JDBC Appender
+#######################
+#log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
+#log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
+#log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
+#log4j.appender.DATABASE.user=root
+#log4j.appender.DATABASE.password=
+#log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r
+#[%t] %-5p %c %x - %m%n')
+#log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
+#log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
+
+
+log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.A1.File=SampleMessages.log4j
+log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'
+log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout
+
+
+#注释1:
+#自定义样式
+#   %c     输出所属的类目,通常就是所在类的全名
+#   %C     输出Logger所在类的名称,通常就是所在类的全名
+#   %d     输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss , SSS},%d{ABSOLUTE},%d{DATE}
+#   %F     输出所在类的类名称,只有类名。
+#   %l     输出语句所在的行数,包括类名+方法名+文件名+行数
+#   %L     输出语句所在的行数,只输出数字
+#   %m     输出代码中指定的讯息,如log(message)中的message
+#   %M     输出方法名
+#   %p     输出日志级别,即DEBUG,INFO,WARN,ERROR,FATAL
+#   %r     输出自应用启动到输出该log信息耗费的毫秒数
+#   %t     输出产生该日志事件的线程名
+#   %n     输出一个回车换行符,Windows平台为“/r/n”,Unix平台为“/n”
+#   %%     用来输出百分号“%”
+#          log4j.appender.Linkin.layout.ConversionPattern=%n[%l%d{yy/MM/dd HH:mm:ss:SSS}][%C-%M] %m
+#          log4j.appender.Linkin.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss}[%C]-[%p] %m%n
+#          log4j.appender.Linkin.layout.ConversionPattern = %d{ABSOLUTE} %5p %t %c{2}:%L - %m%n

+ 100 - 0
flink_metro/src/main/resources/local/metro.properties

@@ -0,0 +1,100 @@
+
+# kafka地址
+kafkaAddress5=192.168.20.65:9092,192.168.20.66:9092,192.168.20.67:9092
+# checkPoint地址
+checkPoint5=hdfs://192.168.20.63:8020/flink/flink-checkpoint/
+
+
+
+# groupId
+metro.groupId=impala_metro
+
+
+
+
+# topicName
+metroTopicName=metro_test
+
+
+
+DB_URL=jdbc:mysql://192.168.20.61:3306/URTDB?characterEncoding=utf-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=UTC&rewriteBatchedStatements=true
+#DB_URL=jdbc:mysql://192.168.20.61:3306/swbd?characterEncoding=utf-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=UTC&rewriteBatchedStatements=true
+#DB_URL=jdbc:mysql://192.168.20.61:3306/URTDB?characterEncoding=utf-8
+USER_NAME=root
+#PASSWROD=pass123
+PASSWROD=root
+
+#TODO:数据治理项目
+#imapala
+spring.datasource.impala.driver-class-name=com.cloudera.impala.jdbc41.Driver
+spring.datasource.impala.initial-size=5
+spring.datasource.impala.max-active=10
+spring.datasource.impala.min-idle=1
+spring.datasource.impala.max-wait=60000
+spring.datasource.impala.validation-query=select 1
+spring.datasource.impala.pool-prepared-statements=true
+spring.datasource.impala.max-pool-prepared-statement-per-connection-size=10
+spring.datasource.impala.validation-query-timeout=60000
+spring.datasource.impala.testWhileIdle=true
+spring.datasource.impala.url=jdbc:impala://192.168.20.63:21050/swbd;rewriteBatchedStatements=true;OptimizedInsert=0
+
+
+#kafka
+namespace=mykafka010
+kafkaOffsetRootPath=/consumers/offsets
+
+#kudu
+kudu.master=192.168.20.63:7051,192.168.20.64:7051,192.168.20.65:7051
+#kafka
+bootstrap_servers=192.168.20.65:9092,192.168.20.66:9092,192.168.20.67:9092
+zookeeper_host=192.168.20.65:2181,192.168.20.66:2181,192.168.20.67:2181
+
+#hdfs
+fs.default.home=hdfs://192.168.20.63:8020
+checkpoint.path=hdfs://192.168.20.63:8020/checkPoint/
+tmp.path=hdfs://192.168.20.63:8020/data/es/tmp/
+tmp.listen.stop=hdfs://192.168.20.63:8020/app/tmp/stop/
+#es
+es.nodes=192.168.20.72
+es.port=9200
+
+#参数位置
+rule.namespace=flink_param
+rule.param.path=/apps
+app_name=metro
+
+#监控表
+kudu.monitor.table=t_data_monitor
+es_correct_info=no_correct_record/record
+es_compete_info=no_compete_record_rep/record
+es_heavy_info=no_compete_record_rep/record
+es_consistent_info=no_consistent_record/record
+es_collect_info=collect_intime_record/record
+es_save_info=save_intime_record/record
+
+
+#mysql数据源配置
+spring.datasource.mysql.url=jdbc:mysql://192.168.20.61:3306/swbd?characterEncoding=utf-8&useSSL=false&user=root&password=root
+spring.datasource.mysql.username=root
+spring.datasource.mysql.password=root
+spring.datasource.mysql.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.mysql.initial-size=5
+spring.datasource.mysql.max-active=10
+spring.datasource.mysql.min-idle=1
+spring.datasource.mysql.max-wait=60000
+spring.datasource.mysql.pool-prepared-statements=true
+spring.datasource.mysql.max-pool-prepared-statement-per-connection-size=10
+spring.datasource.mysql.validation-query=select 1
+spring.datasource.mysql.validation-query-timeout=60000
+spring.datasource.mysql.testWhileIdle=true
+
+# 获取当前应用程序的字段集合
+mysql.query.fields=select id,field,data_type from t_data_monitor_fields where app_name = 
+# 添加当前应用程序的字段集合
+mysql.insert.fields=insert into t_data_monitor_fields(app_type,app_name,field,create_time,update_time,data_type) values(?,?,?,?,?,?)
+# 更新当前应用程序的字段集合
+mysql.update.fields=update t_data_monitor_fields set data_type = ? , update_time = ? where field = ?
+# 获取当前应用程序规则记录表各规则类型的最新记录
+mysql.query.rules.newest=SELECT rule_type,rule_comment,start_work_batch FROM t_data_monitor_rules_records  a INNER JOIN ( SELECT  MAX(id) id FROM t_data_monitor_rules_records WHERE app_name='blank'  GROUP BY rule_type ) b ON a.id =b.id 
+# 插入当前应用程序规则的更新记录
+mysql.query.update.rules=insert into t_data_monitor_rules_records(app_type,app_name,rule_type,rule_comment,start_work_batch,create_time,isDefault,isEffective) values(?,?,?,?,?,?,?,?)

+ 162 - 0
flink_metro/src/main/resources/test/log4j.properties

@@ -0,0 +1,162 @@
+log4j.rootLogger=INFO,DailyRolling
+#DEBUG,CONSOLE,FILE,ROLLING_FILE,MAIL,DATABASE
+#子log日志是否传输到父log内
+log4j.addivity.org.apache=false
+#log4j.logger.org.apache.flink=INFO
+###################
+# 控制台(测试环境)
+###################
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.Threshold=INFO
+log4j.appender.CONSOLE.Target=System.out
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} -%-10p -%m  - %c -%-4r - [%t] %c %x%n
+#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n
+
+
+###################
+# 不滚动。默认生成一个日志文件
+###################
+log4j.logger.akka=INFO
+log4j.logger.org.apache.kafka=INFO
+log4j.logger.org.apache.hadoop=INFO
+log4j.logger.org.apache.zookeeper=INFO
+# Log all infos in the given file
+log4j.appender.file=org.apache.log4j.FileAppender
+log4j.appender.file.file=${log.file}
+log4j.appender.file.append=true
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} -%-10p -%m  - %c -%-4r - [%t] %c %x%n
+# Suppress the irrelevant (wrong) warnings from the Netty channel handler
+#log4j.logger.org.apache.flink.shaded.akka.org.jboss.netty.channel.DefaultChannelPipeline=ERROR,file
+
+########################
+# 按照日志大小滚动
+########################
+log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
+log4j.appender.ROLLING_FILE.Threshold=INFO
+#集群存放地址
+log4j.appender.ROLLING_FILE.File=${log.file}
+#本地存放地址
+#log4j.appender.ROLLING_FILE.File=./logs/${log4j.type}/info.log
+log4j.appender.ROLLING_FILE.Append=true
+log4j.appender.ROLLING_FILE.MaxFileSize=10KB
+log4j.appender.ROLLING_FILE.MaxBackupIndex=1
+log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
+log4j.appender.ROLLING_FILE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} -%-10p -%m  - %c -%-4r - [%t] %c %x%n
+
+########################
+# 按照时间滚动
+########################
+#每一天产生1个日志文件
+log4j.appender.DailyRolling=org.apache.log4j.DailyRollingFileAppender
+#定义日志存放路径
+log4j.appender.DailyRolling.File=${log.file}
+#日志文件是否追加
+log4j.appender.DailyRolling.Append=true
+#定义的时间格式,如果时间定义到分钟(mm)就是每分钟生成一个日志文件,而这里定义的这个格式就是日志名后缀
+#每分钟
+log4j.appender.DailyRolling.DatePattern='_'yyyy-MM-dd-HH
+#log4j.appender.file3.DatePattern='_'yyyy-MM-dd-HH    每小时
+#log4j.appender.file3.DatePattern='_'yyyy-MM-dd	每天
+#log4j.appender.file3.DatePattern='_'yyyy-MM-dd-a	每半天
+#日志输出级别
+log4j.appender.DailyRolling.Threshold=INFO
+#日志编码
+#log4j.appender.DailyRolling.Encoding=UTF-8
+#日志中输出的日志的格式
+log4j.appender.DailyRolling.layout=org.apache.log4j.PatternLayout
+#定义的日志格式
+log4j.appender.DailyRolling.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} -%-10p -%m  - %c -%-4r - [%t] %c %x%n
+log4j.logger.org.apache.flink.shaded.akka.org.jboss.netty.channel.DefaultChannelPipeline=ERROR,DailyRolling
+
+
+
+#####################################################
+# 输出的日志写入kafka TODO:待完善
+#####################################################
+
+
+
+
+####################
+# Socket Appender
+####################
+log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
+log4j.appender.SOCKET.RemoteHost=localhost
+log4j.appender.SOCKET.Port=5001
+log4j.appender.SOCKET.LocationInfo=true
+# Set up for Log Facter 5
+log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
+log4j.appender.SOCET.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} -%-10p -%m  - %c -%-4r - [%t] %c %x%n
+
+########################
+# Log Factor 5 Appender
+########################
+log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
+log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
+
+
+########################
+# SMTP Appender
+#######################
+log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
+#日志的错误级别
+log4j.appender.MAIL.Threshold=ERROR
+#缓存文件大小,日志达到10K时发送Email
+log4j.appender.MAIL.BufferSize=10
+#发送邮件的服务器
+log4j.appender.MAIL.SMTPHost=smtp.163.com
+#邮件主题
+log4j.appender.MAIL.Subject=solr5Product
+#发送邮件箱的用户
+log4j.appender.MAIL.SMTPUsername=boryoukane@163.com
+#发送邮件箱的密码
+log4j.appender.MAIL.SMTPPassword=QBPBRCJCLWSRJJGF
+#发送邮件箱
+log4j.appender.MAIL.From=boryoukane@163.com
+#接受邮件箱
+log4j.appender.MAIL.To=boryoukane@163.com
+#发送邮件的格式
+log4j.appender.MAIL.layout = org.apache.log4j.HTMLLayout
+log4j.appender.MAIL.layout.LocationInfo = TRUE
+#log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
+#log4j.appender.MAIL.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} -%-10p -%m  - %c -%-4r - [%t] %c %x%n
+########################
+# JDBC Appender
+#######################
+#log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
+#log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
+#log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
+#log4j.appender.DATABASE.user=root
+#log4j.appender.DATABASE.password=
+#log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r
+#[%t] %-5p %c %x - %m%n')
+#log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
+#log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
+
+
+log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.A1.File=SampleMessages.log4j
+log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'
+log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout
+
+
+#注释1:
+#自定义样式
+#   %c     输出所属的类目,通常就是所在类的全名
+#   %C     输出Logger所在类的名称,通常就是所在类的全名
+#   %d     输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss , SSS},%d{ABSOLUTE},%d{DATE}
+#   %F     输出所在类的类名称,只有类名。
+#   %l     输出语句所在的行数,包括类名+方法名+文件名+行数
+#   %L     输出语句所在的行数,只输出数字
+#   %m     输出代码中指定的讯息,如log(message)中的message
+#   %M     输出方法名
+#   %p     输出日志级别,即DEBUG,INFO,WARN,ERROR,FATAL
+#   %r     输出自应用启动到输出该log信息耗费的毫秒数
+#   %t     输出产生该日志事件的线程名
+#   %n     输出一个回车换行符,Windows平台为“/r/n”,Unix平台为“/n”
+#   %%     用来输出百分号“%”
+#          log4j.appender.Linkin.layout.ConversionPattern=%n[%l%d{yy/MM/dd HH:mm:ss:SSS}][%C-%M] %m
+#          log4j.appender.Linkin.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss}[%C]-[%p] %m%n
+#          log4j.appender.Linkin.layout.ConversionPattern = %d{ABSOLUTE} %5p %t %c{2}:%L - %m%n

+ 100 - 0
flink_metro/src/main/resources/test/metro.properties

@@ -0,0 +1,100 @@
+
+# kafka地址
+kafkaAddress5=192.168.20.65:9092,192.168.20.66:9092,192.168.20.67:9092
+# checkPoint地址
+checkPoint5=hdfs://192.168.20.63:8020/flink/flink-checkpoint/
+
+
+
+# groupId
+metro.groupId=flink_metro
+
+
+
+
+# topicName
+metroTopicName=metro_test
+
+
+
+DB_URL=jdbc:mysql://192.168.20.61:3306/URTDB?characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true
+#DB_URL=jdbc:mysql://192.168.20.61:3306/swbd?characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true
+#DB_URL=jdbc:mysql://192.168.6.247:3306/test
+USER_NAME=root
+#PASSWROD=pass123
+PASSWROD=root
+
+#TODO:数据治理项目
+#imapala
+spring.datasource.impala.driver-class-name=com.cloudera.impala.jdbc41.Driver
+spring.datasource.impala.initial-size=5
+spring.datasource.impala.max-active=10
+spring.datasource.impala.min-idle=1
+spring.datasource.impala.max-wait=60000
+spring.datasource.impala.validation-query=select 1
+spring.datasource.impala.pool-prepared-statements=true
+spring.datasource.impala.max-pool-prepared-statement-per-connection-size=10
+spring.datasource.impala.validation-query-timeout=60000
+spring.datasource.impala.testWhileIdle=true
+spring.datasource.impala.url=jdbc:impala://192.168.20.63:21050/swbd;rewriteBatchedStatements=true;OptimizedInsert=0
+
+
+#kafka
+namespace=mykafka010
+kafkaOffsetRootPath=/consumers/offsets
+
+#kudu
+kudu.master=192.168.20.63:7051,192.168.20.64:7051,192.168.20.65:7051
+#kafka
+bootstrap_servers=192.168.20.65:9092,192.168.20.66:9092,192.168.20.67:9092
+zookeeper_host=192.168.20.65:2181,192.168.20.66:2181,192.168.20.67:2181
+
+#hdfs
+fs.default.home=hdfs://192.168.20.63:8020
+checkpoint.path=hdfs://192.168.20.63:8020/checkPoint/
+tmp.path=hdfs://192.168.20.63:8020/data/es/tmp/
+tmp.listen.stop=hdfs://192.168.20.63:8020/app/tmp/stop/
+#es
+es.nodes=192.168.20.72
+es.port=9200
+
+#参数位置
+rule.namespace=flink_param
+rule.param.path=/apps
+app_name=metro
+
+#监控表
+kudu.monitor.table=t_data_monitor
+es_correct_info=no_correct_record/record
+es_compete_info=no_compete_record_rep/record
+es_heavy_info=no_compete_record_rep/record
+es_consistent_info=no_consistent_record/record
+es_collect_info=collect_intime_record/record
+es_save_info=save_intime_record/record
+
+
+#mysql数据源配置
+spring.datasource.mysql.url=jdbc:mysql://192.168.20.61:3306/swbd?characterEncoding=utf-8&useSSL=false&user=root&password=root
+spring.datasource.mysql.username=root
+spring.datasource.mysql.password=root
+spring.datasource.mysql.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.mysql.initial-size=5
+spring.datasource.mysql.max-active=10
+spring.datasource.mysql.min-idle=1
+spring.datasource.mysql.max-wait=60000
+spring.datasource.mysql.pool-prepared-statements=true
+spring.datasource.mysql.max-pool-prepared-statement-per-connection-size=10
+spring.datasource.mysql.validation-query=select 1
+spring.datasource.mysql.validation-query-timeout=60000
+spring.datasource.mysql.testWhileIdle=true
+
+# 获取当前应用程序的字段集合
+mysql.query.fields=select id,field,data_type from t_data_monitor_fields where app_name = 
+# 添加当前应用程序的字段集合
+mysql.insert.fields=insert into t_data_monitor_fields(app_type,app_name,field,create_time,update_time,data_type) values(?,?,?,?,?,?)
+# 更新当前应用程序的字段集合
+mysql.update.fields=update t_data_monitor_fields set data_type = ? , update_time = ? where field = ?
+# 获取当前应用程序规则记录表各规则类型的最新记录
+mysql.query.rules.newest=SELECT rule_type,rule_comment,start_work_batch FROM t_data_monitor_rules_records  a INNER JOIN ( SELECT  MAX(id) id FROM t_data_monitor_rules_records WHERE app_name='blank'  GROUP BY rule_type ) b ON a.id =b.id 
+# 插入当前应用程序规则的更新记录
+mysql.query.update.rules=insert into t_data_monitor_rules_records(app_type,app_name,rule_type,rule_comment,start_work_batch,create_time,isDefault,isEffective) values(?,?,?,?,?,?,?,?)

+ 113 - 0
pom.xml

@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.sunwin</groupId>
+    <artifactId>sunwin_metro</artifactId>
+    <packaging>pom</packaging>
+    <version>1.0-SNAPSHOT</version>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.3.0.RELEASE</version>
+        <relativePath/>
+    </parent>
+    <modules>
+        <module>flink_metro</module>
+    </modules>
+
+<dependencies>
+    <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-api</artifactId>
+        <version>1.7.25</version>
+    </dependency>
+    <dependency>
+        <groupId>log4j</groupId>
+        <artifactId>log4j</artifactId>
+        <version>1.2.17</version>
+    </dependency>
+    <dependency>
+        <groupId>com.alibaba</groupId>
+        <artifactId>fastjson</artifactId>
+        <version>1.2.73</version>
+    </dependency>
+
+    <dependency>
+        <groupId>commons-lang</groupId>
+        <artifactId>commons-lang</artifactId>
+        <version>2.6</version>
+        <scope>compile</scope>
+    </dependency>
+
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.10</version>
+    </dependency>
+
+    <dependency>
+        <groupId>com.chinaway</groupId>
+        <artifactId>sw-http-client</artifactId>
+        <version>1.1-test</version>
+    </dependency>
+
+</dependencies>
+    <profiles>
+        <profile>
+            <id>local</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+                <property>
+                    <name>env</name>
+                    <value>Env</value>
+                </property>
+            </activation>
+            <build>
+                <resources>
+                    <resource>
+                        <directory>src/main/resources/local</directory>
+                    </resource>
+                </resources>
+            </build>
+        </profile>
+
+        <profile>
+            <id>pro</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+                <property>
+                    <name>pro</name>
+                    <value>Pro</value>
+                </property>
+            </activation>
+            <build>
+                <resources>
+                    <resource>
+                        <directory>src/main/resources/pro</directory>
+                    </resource>
+                </resources>
+            </build>
+        </profile>
+
+        <profile>
+            <id>test</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+                <property>
+                    <name>test</name>
+                    <value>Test</value>
+                </property>
+            </activation>
+            <build>
+                <resources>
+                    <resource>
+                        <directory>src/main/resources/test</directory>
+                    </resource>
+                </resources>
+            </build>
+        </profile>
+    </profiles>
+</project>

Някои файлове не бяха показани, защото твърде много файлове са промени