Browse Source

feat: 实现工参更新

weijianghai 2 years ago
parent
commit
61e4ef74a5

+ 24 - 0
build-dir/gpload/cfm.cfg_0_4g_siteinfo.yml

@@ -0,0 +1,24 @@
+VERSION: 1.0.0.1
+DATABASE: sqmmt
+USER: sqmdb
+HOST: 192.168.50.5
+PORT: 5432
+GPLOAD:
+  PRELOAD:
+    - TRUNCATE: false
+    - REUSE_TABLES: false
+  INPUT:
+    - SOURCE:
+        LOCAL_HOSTNAME:
+          - 192.168.50.3
+        PORT: 54331
+        FILE:
+          - /data1/site_info/cfm.cfg_0_4g_siteinfo.csv
+    - FORMAT: csv
+    - DELIMITER: ','
+    - ENCODING: utf-8
+    - ERROR_LIMIT: 20000000
+    - LOG_ERRORS: true
+  OUTPUT:
+    - TABLE: cfm.cfg_0_4g_siteinfo
+    - MODE: insert

+ 24 - 0
build-dir/gpload/cfm.cfg_0_5g_siteinfo.yml

@@ -0,0 +1,24 @@
+VERSION: 1.0.0.1
+DATABASE: sqmmt
+USER: sqmdb
+HOST: 192.168.50.5
+PORT: 5432
+GPLOAD:
+  PRELOAD:
+    - TRUNCATE: false
+    - REUSE_TABLES: false
+  INPUT:
+    - SOURCE:
+        LOCAL_HOSTNAME:
+          - 192.168.50.3
+        PORT: 54331
+        FILE:
+          - /data1/site_info/cfm.cfg_0_5g_siteinfo.csv
+    - FORMAT: csv
+    - DELIMITER: ','
+    - ENCODING: utf-8
+    - ERROR_LIMIT: 20000000
+    - LOG_ERRORS: true
+  OUTPUT:
+    - TABLE: cfm.cfg_0_5g_siteinfo
+    - MODE: insert

+ 24 - 0
build-dir/gpload/customer_service.cfg_cell_info.yml

@@ -0,0 +1,24 @@
+VERSION: 1.0.0.1
+DATABASE: sqmmt
+USER: sqmdb
+HOST: 192.168.50.5
+PORT: 5432
+GPLOAD:
+  PRELOAD:
+    - TRUNCATE: false
+    - REUSE_TABLES: false
+  INPUT:
+    - SOURCE:
+        LOCAL_HOSTNAME:
+          - 192.168.50.3
+        PORT: 54331
+        FILE:
+          - /data1/site_info/customer_service.cfg_cell_info.csv
+    - FORMAT: csv
+    - DELIMITER: ','
+    - ENCODING: utf-8
+    - ERROR_LIMIT: 20000000
+    - LOG_ERRORS: true
+  OUTPUT:
+    - TABLE: customer_service.cfg_cell_info
+    - MODE: insert

+ 24 - 0
build-dir/gpload/customer_service.cfg_p_netconf_std.yml

@@ -0,0 +1,24 @@
+VERSION: 1.0.0.1
+DATABASE: sqmmt
+USER: sqmdb
+HOST: 192.168.50.5
+PORT: 5432
+GPLOAD:
+  PRELOAD:
+    - TRUNCATE: false
+    - REUSE_TABLES: false
+  INPUT:
+    - SOURCE:
+        LOCAL_HOSTNAME:
+          - 192.168.50.3
+        PORT: 54331
+        FILE:
+          - /data1/site_info/customer_service.cfg_p_netconf_std.csv
+    - FORMAT: csv
+    - DELIMITER: ','
+    - ENCODING: utf-8
+    - ERROR_LIMIT: 20000000
+    - LOG_ERRORS: true
+  OUTPUT:
+    - TABLE: customer_service.cfg_p_netconf_std
+    - MODE: insert

+ 15 - 0
build-dir/gpload/gpload.sh

@@ -0,0 +1,15 @@
+#!/bin/bash
+
+source /usr/local/greenplum-db-clients/greenplum_loaders_path.sh
+table=$1
+# 由于gpload需要输入密码,这里需要使用expect执行
+password=sqmdb_1QAZ
+expect -c "
+set timeout 300
+spawn gpload -f /data1/site_info/gpload/${table}.yml
+expect {
+\"connecting (yes/no)?\" { send \"yes\n\";exp_continue }
+\"Password:\" { send \"${password}\n\"; exp_continue}
+timeout { puts \"超时\" exit 2}
+}
+"

+ 1 - 0
build-dir/run.sh

@@ -0,0 +1 @@
+nohup java -jar /data1/site_info/site_info.jar >/dev/null 2>&1 &

+ 5 - 0
build-dir/stop.sh

@@ -0,0 +1,5 @@
+#!/bin/bash
+
+for i in $(ps -ef | grep site_info.jar | grep -v grep | awk '{print $2}'); do
+  kill -9 "$i"
+done

+ 73 - 0
pom.xml

@@ -0,0 +1,73 @@
+<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.nokia</groupId>
+        <artifactId>hb_springboot_parent</artifactId>
+        <version>1.0</version>
+        <relativePath/>
+    </parent>
+    <artifactId>siteinfo</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>siteinfo_update</name>
+    <description>siteinfo_update</description>
+    <properties>
+        <java.version>8</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <skipTests>true</skipTests>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.junit.vintage</groupId>
+                    <artifactId>junit-vintage-engine</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.xuxueli</groupId>
+            <artifactId>xxl-job-core</artifactId>
+            <version>2.3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-csv</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-jdbc</artifactId>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
+        <dependency>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+            <version>42.4.1</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>site_info</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 91 - 0
src/main/java/com/nokia/common/gpload/GploadUtil.java

@@ -0,0 +1,91 @@
+package com.nokia.common.gpload;
+
+import com.nokia.common.gpload.entity.GploadResult;
+import com.xxl.job.core.context.XxlJobHelper;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@Slf4j
+public class GploadUtil {
+    public static final Pattern PATTERN = Pattern.compile("= (\\d+)");
+    private static Process process = null;
+    private static BufferedReader reader = null;
+
+    public static GploadResult gpload(String gploadCommand) {
+        GploadResult result = new GploadResult();
+        result.setTaskStatus(true);
+        try {
+            process = Runtime.getRuntime().exec(gploadCommand);
+            reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+            List<String> lines = new ArrayList<>();
+            String line;
+            while ((line = reader.readLine()) != null) {
+                lines.add(line);
+            }
+            log.info("gpload result: " + lines);
+            XxlJobHelper.log("gpload result: " + lines);
+            for (String s : lines) {
+                if (s.contains("|rows Inserted")) {
+                    result.setInsertedCount(getNum(s));
+                }
+                if (s.contains("|rows Updated")) {
+                    result.setUpdatedCount(getNum(s));
+                }
+                if (s.contains("|data formatting errors")) {
+                    result.setErrorCount(getNum(s));
+                }
+                if (s.contains("ERROR") || s.contains("gpload failed")) {
+                    result.setTaskStatus(false);
+                }
+                if (s.contains("ERROR")) {
+                    result.setMessage(s);
+                }
+            }
+        } catch (IOException e) {
+            log.error("gpload发生异常: {}", e.getMessage(), e);
+            XxlJobHelper.log("gpload发生异常: {}", e.getMessage(), e);
+            result.setTaskStatus(false);
+            result.setMessage(e.getMessage());
+        } finally {
+            log.info("gpload的结果为: {}", result);
+            XxlJobHelper.log("gpload的结果为: {}", result);
+            destroy();
+        }
+        return result;
+    }
+
+    private static void destroy() {
+        if (reader != null) {
+            try {
+                reader.close();
+            } catch (IOException e) {
+                log.error("close reader error: {}", e.getMessage(), e);
+                XxlJobHelper.log("close reader error: {}", e.getMessage(), e);
+            }
+            reader = null;
+        }
+        if (process != null) {
+            process.destroy();
+            process = null;
+        }
+    }
+
+    /**
+     * 获取gpload统计条数
+     */
+    private static int getNum(String s) {
+        Matcher matcher = PATTERN.matcher(s);
+        if (matcher.find()) {
+            return Integer.parseInt(matcher.group(1));
+        }
+
+        return 0;
+    }
+}

+ 12 - 0
src/main/java/com/nokia/common/gpload/entity/GploadResult.java

@@ -0,0 +1,12 @@
+package com.nokia.common.gpload.entity;
+
+import lombok.Data;
+
+@Data
+public class GploadResult {
+    private Boolean taskStatus;
+    private Integer insertedCount;
+    private Integer updatedCount;
+    private Integer errorCount;
+    private String message;
+}

+ 13 - 0
src/main/java/com/nokia/siteinfo/SiteinfoUpdateApplication.java

@@ -0,0 +1,13 @@
+package com.nokia.siteinfo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+//@ComponentScan("com.nokia")
+@SpringBootApplication
+public class SiteinfoUpdateApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(SiteinfoUpdateApplication.class, args);
+    }
+}

+ 25 - 0
src/main/java/com/nokia/siteinfo/config/DataSourceConfig.java

@@ -0,0 +1,25 @@
+package com.nokia.siteinfo.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Component;
+
+import javax.sql.DataSource;
+
+@Component
+public class DataSourceConfig {
+    @Bean
+    @ConfigurationProperties(prefix = "spring.datasource.input")
+    public DataSource inputDataSource()
+    {
+        return DataSourceBuilder.create().build();
+    }
+
+    @Bean
+    @ConfigurationProperties(prefix = "spring.datasource.output")
+    public DataSource outputDataSource()
+    {
+        return DataSourceBuilder.create().build();
+    }
+}

+ 20 - 0
src/main/java/com/nokia/siteinfo/config/JdbcTemplateConfig.java

@@ -0,0 +1,20 @@
+package com.nokia.siteinfo.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Component;
+
+import javax.sql.DataSource;
+
+@Component
+public class JdbcTemplateConfig {
+    @Bean
+    public JdbcTemplate inputJdbcTemplate(DataSource inputDataSource) {
+        return new JdbcTemplate(inputDataSource);
+    }
+
+    @Bean
+    public JdbcTemplate outputJdbcTemplate(DataSource outputDataSource) {
+        return new JdbcTemplate(outputDataSource);
+    }
+}

+ 76 - 0
src/main/java/com/nokia/siteinfo/config/XxlJobConfig.java

@@ -0,0 +1,76 @@
+package com.nokia.siteinfo.config;
+
+import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * xxl-job config
+ *
+ * @author xuxueli 2017-04-28
+ */
+@Slf4j
+@Configuration
+public class XxlJobConfig {
+    @Value("${xxl.job.admin.addresses}")
+    private String adminAddresses;
+
+    @Value("${xxl.job.accessToken}")
+    private String accessToken;
+
+    @Value("${xxl.job.executor.appname}")
+    private String appname;
+
+    @Value("${xxl.job.executor.address}")
+    private String address;
+
+    @Value("${xxl.job.executor.ip}")
+    private String ip;
+
+    @Value("${xxl.job.executor.port}")
+    private int port;
+
+    @Value("${xxl.job.executor.logpath}")
+    private String logPath;
+
+    @Value("${xxl.job.executor.logretentiondays}")
+    private int logRetentionDays;
+
+
+    @Bean
+    public XxlJobSpringExecutor xxlJobExecutor() {
+        log.info(">>>>>>>>>>> xxl-job config init.");
+        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
+        xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
+        xxlJobSpringExecutor.setAppname(appname);
+        xxlJobSpringExecutor.setAddress(address);
+        xxlJobSpringExecutor.setIp(ip);
+        xxlJobSpringExecutor.setPort(port);
+        xxlJobSpringExecutor.setAccessToken(accessToken);
+        xxlJobSpringExecutor.setLogPath(logPath);
+        xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
+
+        return xxlJobSpringExecutor;
+    }
+
+    /**
+     * 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;
+     *
+     *      1、引入依赖:
+     *          <dependency>
+     *             <groupId>org.springframework.cloud</groupId>
+     *             <artifactId>spring-cloud-commons</artifactId>
+     *             <version>${version}</version>
+     *         </dependency>
+     *
+     *      2、配置文件,或者容器启动变量
+     *          spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
+     *
+     *      3、获取IP
+     *          String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
+     */
+
+
+}

+ 309 - 0
src/main/java/com/nokia/siteinfo/task/UpdateTask.java

@@ -0,0 +1,309 @@
+package com.nokia.siteinfo.task;
+
+import com.nokia.common.gpload.GploadUtil;
+import com.nokia.common.gpload.entity.GploadResult;
+import com.xxl.job.core.context.XxlJobHelper;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVPrinter;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Component
+@Slf4j
+public class UpdateTask {
+    private final JdbcTemplate inputJdbcTemplate;
+    private final JdbcTemplate outputJdbcTemplate;
+
+    public UpdateTask(JdbcTemplate inputJdbcTemplate, JdbcTemplate outputJdbcTemplate) {
+        this.inputJdbcTemplate = inputJdbcTemplate;
+        this.outputJdbcTemplate = outputJdbcTemplate;
+    }
+
+//    0 0 1 ? * 2
+    @XxlJob("siteInfoJobHandler")
+    public void siteInfoJobHandler() {
+        try {
+            Map<String, Map<String, Object>> map = new HashMap<>();
+            update4g(map);
+            update5g(map);
+            writeCsvs(map);
+            backup("customer_service.cfg_p_netconf_std");
+            gpload("customer_service.cfg_p_netconf_std");
+            backup("customer_service.cfg_cell_info");
+            gpload("customer_service.cfg_cell_info");
+        } catch (Exception e) {
+            log.error("发生异常了: {}", e.getMessage(), e);
+            XxlJobHelper.log("发生异常了: {}", e.getMessage(), e);
+            XxlJobHelper.handleFail(e.getMessage());
+        }
+    }
+
+    public void update4g(Map<String, Map<String, Object>> map) throws IOException {
+        // 查询o2p.cfg_0_4g_siteinfo
+        String sql = "select * from o2p.cfg_0_4g_siteinfo";
+        List<Map<String, Object>> list = inputJdbcTemplate.queryForList(sql);
+        Map<String, Map<String, Object>> temp = new HashMap<>();
+        // 去重
+        list.forEach(t -> {
+            map.put((String) t.get("cgi"), t);
+            temp.put((String) t.get("cgi"), t);
+        });
+        log.info("cfg_0_4g_siteinfo: {} -> {}", list.size(), temp.size());
+        XxlJobHelper.log("cfg_0_4g_siteinfo: {} -> {}", list.size(), temp.size());
+        String table = "cfm.cfg_0_4g_siteinfo";
+        writeCsv(temp, table);
+        backup(table);
+        // o2p.cfg_0_4g_siteinfo -> cfm.cfg_0_4g_siteinfo
+        gpload(table);
+        // 查询cfm.cfg_0_4g_siteinfo_gx
+        sql = "select * from cfm.cfg_0_4g_siteinfo_gx";
+        list = outputJdbcTemplate.queryForList(sql);
+        // 添加新元素
+        list.forEach(t -> map.putIfAbsent((String) t.get("cgi"), t));
+        log.info("cfg_0_4g_siteinfo_gx: {} -> {}", list.size(), map.size());
+        XxlJobHelper.log("cfg_0_4g_siteinfo_gx: {} -> {}", list.size(), map.size());
+    }
+
+    public void update5g(Map<String, Map<String, Object>> map) throws IOException {
+        // 查询o2p.cfg_0_5g_siteinfo
+        String sql = "select * from o2p.cfg_0_5g_siteinfo";
+        List<Map<String, Object>> list = inputJdbcTemplate.queryForList(sql);
+        Map<String, Map<String, Object>> temp = new HashMap<>();
+        // 去重
+        list.forEach(t -> {
+            map.put((String) t.get("cgisai"), t);
+            temp.put((String) t.get("cgisai"), t);
+        });
+        log.info("cfg_0_5g_siteinfo: {} -> {}", list.size(), temp.size());
+        XxlJobHelper.log("cfg_0_5g_siteinfo: {} -> {}", list.size(), temp.size());
+        String table = "cfm.cfg_0_5g_siteinfo";
+        writeCsv(temp, table);
+        backup(table);
+        // o2p.cfg_0_5g_siteinfo -> cfm.cfg_0_5g_siteinfo
+        gpload(table);
+        // 查询cfm.cfg_0_5g_siteinfo_gx
+        sql = "select * from cfm.cfg_0_5g_siteinfo_gx";
+        list = outputJdbcTemplate.queryForList(sql);
+        // 添加新元素
+        list.forEach(t -> map.putIfAbsent((String) t.get("cgisai"), t));
+        log.info("cfg_0_5g_siteinfo_gx: {} -> {}", list.size(), map.size());
+        XxlJobHelper.log("cfg_0_5g_siteinfo_gx: {} -> {}", list.size(), map.size());
+    }
+
+    public void writeCsvs(Map<String, Map<String, Object>> map) throws IOException {
+        try (OutputStreamWriter osw1 = new OutputStreamWriter(
+                Files.newOutputStream(Paths.get("customer_service.cfg_p_netconf_std.csv")),
+                StandardCharsets.UTF_8);
+             CSVPrinter printer1 = new CSVPrinter(osw1, CSVFormat.DEFAULT);
+             OutputStreamWriter osw2 = new OutputStreamWriter(
+                     Files.newOutputStream(Paths.get("customer_service.cfg_cell_info.csv")),
+                     StandardCharsets.UTF_8);
+             CSVPrinter printer2 = new CSVPrinter(osw2, CSVFormat.DEFAULT);) {
+            for (Map<String, Object> t : map.values()) {
+                boolean isFourG = "4G".equals(t.get("network_name"));
+                if (isFourG) {
+                    BigDecimal id = print4gCfgPNetconfStd(printer1, t);
+                    String siteName = (String) t.get("bbu_name");
+                    printCfgCellInfo(printer2, t, id, siteName);
+                } else {
+                    BigDecimal id = print5gCfgPNetconfStd(printer1, t);
+                    String siteName = (String) t.get("station_name");
+                    printCfgCellInfo(printer2, t, id, siteName);
+                }
+            }
+        }
+    }
+
+    public void writeCsv(Map<String, Map<String, Object>> map, String table) throws IOException {
+        log.info("writeCsv: {}", table);
+        XxlJobHelper.log("writeCsv: {}", table);
+        try (OutputStreamWriter osw = new OutputStreamWriter(Files.newOutputStream(Paths.get(table + ".csv")),
+                StandardCharsets.UTF_8);
+             CSVPrinter printer = new CSVPrinter(osw, CSVFormat.DEFAULT);) {
+            for (Map<String, Object> t : map.values()) {
+                printer.printRecord(t.values());
+            }
+        }
+    }
+
+    /**
+     * 备份
+     *
+     * @param table 表
+     */
+    public void backup(String table) {
+        log.info("备份: {}", table);
+        XxlJobHelper.log("备份: {}", table);
+        LocalDate now = LocalDate.now();
+        String nowString = dateFormat(now);
+        // 备份
+        String sql = "create table " + table + "_bak_" + nowString + " as select * from " + table;
+        outputJdbcTemplate.execute(sql);
+        // 删除之前的备份
+        sql = "DO $$\n" +
+                "DECLARE t varchar(255);\n" +
+                "BEGIN FOR t IN\n" +
+                "select 'drop table ' || schemaname || '.' || tablename || ';'\n" +
+                "from pg_tables\n" +
+                "where schemaname || '.' || tablename like '" + table + "_bak_%' " +
+                "and schemaname || '.' || tablename != '" + table + "_bak_" + nowString + "' loop EXECUTE t;\n" +
+                "END LOOP;\n" +
+                "END;\n" +
+                "$$";
+        outputJdbcTemplate.execute(sql);
+        // 清空表
+        sql = "truncate table " + table;
+        outputJdbcTemplate.execute(sql);
+    }
+
+    /**
+     * 日期格式
+     *
+     * @param localDate 当地日期
+     * @return {@link String}
+     */
+    public String dateFormat(LocalDate localDate) {
+        return localDate.format(DateTimeFormatter.ofPattern("MMdd"));
+    }
+
+    public void gpload(String table) throws IOException {
+        String gploadCommand = "sh /data1/site_info/gpload/gpload.sh " + table;
+        GploadResult gpload = GploadUtil.gpload(gploadCommand);
+        if (Boolean.TRUE.equals(gpload.getTaskStatus())) {
+            log.info("gpload {} 完成: {}", table, gpload);
+            XxlJobHelper.log("gpload {} 完成: {}", table, gpload);
+            // 删除文件
+            Files.deleteIfExists(Paths.get(table + ".csv"));
+        } else {
+            log.error("gpload {} 失败: {}", table, gpload.getMessage());
+            XxlJobHelper.log("gpload {} 失败: {}", table, gpload.getMessage());
+        }
+    }
+
+    private BigDecimal print4gCfgPNetconfStd(CSVPrinter p, Map<String, Object> t) throws IOException {
+        BigDecimal enbid = (BigDecimal) t.get("enbid");
+        BigDecimal cell_id = (BigDecimal) t.get("cell_id");
+        BigDecimal cellId = enbid.multiply(new BigDecimal(256)).add(cell_id);
+        BigDecimal id = cellId.add(new BigDecimal(46001000000000L));
+        p.printRecord(
+                "",
+                t.get("city_code"),
+                t.get("city_name"),
+                t.get("district_name"),
+                "",
+                "",
+                t.get("bbu_name"),
+                enbid,
+                cell_id,
+                t.get("cell_name"),
+                id,
+                cellId,
+                "",
+                "",
+                "",
+                4,
+                "",
+                "",
+                "宏站".equals(t.get("station_type")) ? "室外" : "室内",
+                "",
+                "",
+                "",
+                "",
+                t.get("scene"),
+                "",
+                "",
+                t.get("lon"),
+                t.get("lat"),
+                t.get("vender"),
+                t.get("height"),
+                ((BigDecimal) t.get("m_downtilt")).add((BigDecimal) t.get("e_downtilt")),
+                t.get("direction"),
+                t.get("down_freq"),
+                "",
+                "河北省",
+                "",
+                "",
+                "",
+                t.get("construction"),
+                "",
+                ""
+        );
+        return id;
+    }
+
+    private BigDecimal print5gCfgPNetconfStd(CSVPrinter p, Map<String, Object> t) throws IOException {
+        BigDecimal gnbid = (BigDecimal) t.get("gnbid");
+        BigDecimal cell_id = (BigDecimal) t.get("cell_id");
+        BigDecimal cellId = gnbid.multiply(new BigDecimal(4096)).add(cell_id);
+        BigDecimal id = cellId.add(new BigDecimal(4600100000000000L));
+        p.printRecord(
+                "",
+                t.get("city_code"),
+                t.get("city_name"),
+                t.get("district_name"),
+                "",
+                "",
+                t.get("station_name"),
+                gnbid,
+                cell_id,
+                t.get("cell_name"),
+                id,
+                cellId,
+                "",
+                "",
+                "",
+                4,
+                "",
+                "",
+                "宏站".equals(t.get("station_type")) ? "室外" : "室内",
+                "",
+                "",
+                "",
+                "",
+                t.get("scene"),
+                "",
+                "",
+                t.get("lon"),
+                t.get("lat"),
+                t.get("vender"),
+                t.get("height"),
+                ((BigDecimal) t.get("m_downtilt")).add((BigDecimal) t.get("e_downtilt")),
+                t.get("direction"),
+                t.get("down_freq"),
+                "",
+                "河北省",
+                "",
+                "",
+                "",
+                t.get("construction"),
+                "",
+                ""
+        );
+        return id;
+    }
+
+    private void printCfgCellInfo(CSVPrinter p, Map<String, Object> t, BigDecimal id, String siteName) throws IOException {
+        p.printRecord(
+                id,
+                siteName,
+                t.get("city_name"),
+                t.get("lon"),
+                t.get("lat"),
+                ""
+        );
+    }
+}

+ 27 - 0
src/main/resources/application.properties

@@ -0,0 +1,27 @@
+server.port=12093
+spring.application.name=siteinfo_update
+spring.datasource.input.jdbc-url=jdbc:postgresql://192.168.10.9:5432/sqmmt
+spring.datasource.input.username=pmparse
+spring.datasource.input.password=Richr00t#
+spring.datasource.input.driverClassName=org.postgresql.Driver
+
+spring.datasource.output.jdbc-url=jdbc:postgresql://192.168.50.5:5432/sqmmt
+spring.datasource.output.username=sqmdb
+spring.datasource.output.password=sqmdb_1QAZ
+spring.datasource.output.driverClassName=org.postgresql.Driver
+### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"
+xxl.job.admin.addresses=http://192.168.10.7:8087/xxl-job-admin
+### xxl-job, access token
+xxl.job.accessToken=
+### xxl-job executor appname
+xxl.job.executor.appname=site-info
+### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is null
+xxl.job.executor.address=
+### xxl-job executor server-info
+xxl.job.executor.ip=
+xxl.job.executor.port=9999
+### xxl-job executor log-path
+xxl.job.executor.logpath=/data1/site_info/xxl/
+### xxl-job executor log-retention-days
+xxl.job.executor.logretentiondays=30
+logging.level.root=info

+ 51 - 0
src/main/resources/logback-spring.xml

@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <property name="PATH" value="./log"/>
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <Pattern>%d{HH:mm:ss.SSS} %highlight(%-5level) %blue(%logger:%line) %msg%n</Pattern>
+        </encoder>
+    </appender>
+    <appender name="TRACE_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${PATH}/trace.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- rollover daily -->
+            <fileNamePattern>${PATH}/trace.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
+            <maxFileSize>10MB</maxFileSize>
+            <maxHistory>60</maxHistory>
+            <totalSizeCap>20GB</totalSizeCap>
+        </rollingPolicy>
+        <encoder>
+            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %blue(%logger:%line) %msg%n</Pattern>
+        </encoder>
+    </appender>
+    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${PATH}/error.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- rollover daily -->
+            <fileNamePattern>${PATH}/error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
+            <maxFileSize>10MB</maxFileSize>
+            <maxHistory>60</maxHistory>
+            <totalSizeCap>20GB</totalSizeCap>
+        </rollingPolicy>
+        <encoder>
+            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %blue(%logger:%line) %msg%n</Pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>ERROR</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+    <root level="INFO">
+        <appender-ref ref="STDOUT"/>
+    </root>
+    <root level="INFO">
+        <appender-ref ref="TRACE_FILE"/>
+    </root>
+    <root level="ERROR">
+        <appender-ref ref="ERROR_FILE"/>
+    </root>
+</configuration>

+ 19 - 0
src/test/java/com/nokia/siteinfo/SiteinfoUpdateApplicationTests.java

@@ -0,0 +1,19 @@
+package com.nokia.siteinfo;
+
+import com.nokia.siteinfo.task.UpdateTask;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@Slf4j
+@SpringBootTest
+class SiteinfoUpdateApplicationTests {
+    @Autowired
+    private UpdateTask updateTask;
+
+    @Test
+    void test() {
+        updateTask.siteInfoJobHandler();
+    }
+}