From 7d16e5a54ccea39bb0f5ee38b1f1496f10d58c0a Mon Sep 17 00:00:00 2001 From: wangzhengzhen Date: Mon, 1 Jul 2024 09:39:16 +0800 Subject: [PATCH] ddns --- .gitignore | 76 ++-- README.md | 111 +++++- img/img_add.png | Bin 0 -> 37731 bytes img/img_delete.png | Bin 0 -> 20081 bytes img/img_update.png | Bin 0 -> 36645 bytes pom.xml | 147 ++++++++ src/main/java/com/z/toys/dns/Main.java | 140 +++++++ .../java/com/z/toys/dns/model/ParamModel.java | 37 ++ .../z/toys/dns/provider/AliDnsProvider.java | 175 +++++++++ .../com/z/toys/dns/provider/DnsProvider.java | 45 +++ .../toys/dns/provider/DnsProviderManage.java | 25 ++ .../java/com/z/toys/dns/util/BeanUtil.java | 74 ++++ .../toys/dns/util/Okhttp3_Internal_Util.java | 50 +++ .../java/com/z/toys/dns/util/StrUtil.java | 35 ++ .../META-INF/native-image/fix_okhttp3.json | 12 + .../META-INF/native-image/jni-config.json | 6 + .../predefined-classes-config.json | 8 + .../META-INF/native-image/proxy-config.json | 2 + .../META-INF/native-image/reflect-config.json | 344 ++++++++++++++++++ .../native-image/resource-config.json | 13 + .../native-image/serialization-config.json | 8 + 21 files changed, 1266 insertions(+), 42 deletions(-) create mode 100644 img/img_add.png create mode 100644 img/img_delete.png create mode 100644 img/img_update.png create mode 100644 pom.xml create mode 100644 src/main/java/com/z/toys/dns/Main.java create mode 100644 src/main/java/com/z/toys/dns/model/ParamModel.java create mode 100644 src/main/java/com/z/toys/dns/provider/AliDnsProvider.java create mode 100644 src/main/java/com/z/toys/dns/provider/DnsProvider.java create mode 100644 src/main/java/com/z/toys/dns/provider/DnsProviderManage.java create mode 100644 src/main/java/com/z/toys/dns/util/BeanUtil.java create mode 100644 src/main/java/com/z/toys/dns/util/Okhttp3_Internal_Util.java create mode 100644 src/main/java/com/z/toys/dns/util/StrUtil.java create mode 100644 src/main/resources/META-INF/native-image/fix_okhttp3.json create mode 100644 src/main/resources/META-INF/native-image/jni-config.json create mode 100644 src/main/resources/META-INF/native-image/predefined-classes-config.json create mode 100644 src/main/resources/META-INF/native-image/proxy-config.json create mode 100644 src/main/resources/META-INF/native-image/reflect-config.json create mode 100644 src/main/resources/META-INF/native-image/resource-config.json create mode 100644 src/main/resources/META-INF/native-image/serialization-config.json diff --git a/.gitignore b/.gitignore index a7e4258..a87e6df 100644 --- a/.gitignore +++ b/.gitignore @@ -1,45 +1,39 @@ -# ---> Java -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* -replay_pid* - -# ---> Maven target/ -pom.xml.tag -pom.xml.releaseBackup -pom.xml.versionsBackup -pom.xml.next -release.properties -dependency-reduced-pom.xml -buildNumber.properties -.mvn/timing.properties -# https://github.com/takari/maven-wrapper#usage-without-binary-jar -.mvn/wrapper/maven-wrapper.jar +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ -# Eclipse m2e generated files -# Eclipse Core -.project -# JDT-specific (Eclipse Java Development Tools) +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +.idea/ + +### Eclipse ### +.apt_generated .classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index 6b87d8b..6fa9d23 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,111 @@ -# ddns +# DNS域名解析工具 +## 说明 + +该项目通过云服务商提供的API,实现对账号下的域名进行添加,查询,更新,删除操作。 + +目前仅接入阿里云DNS,可以通过实现 `DnsProvider` 类,扩展其他云服务商。 + +### 配置 + +在云服务商后台配置生成授权信息,把 key 和 secret 配置到系统环境变量。 + +也可以在启动前设置临时变量 + +- windows + +``` +set ALIYUN_ACCESS_KEY_ID=阿里云ACCESS_KEY_ID + +set ALIYUN_ACCESS_KEY_SECRET=阿里云ACCESS_KEY_SECRET +``` + +- linux + +``` +export ALIYUN_ACCESS_KEY_ID=阿里云 ACCESS_KEY_ID + +export ALIYUN_ACCESS_KEY_SECRET=阿里云 ACCESS_KEY_SECRET +``` + +## 运行 + +编译完成后会生成可运行的jar包和原生应用 + +jar包运行(需安装java环境): + +``` +java -jar 生成的jar包 [参数1] [值1] [参数2] [值2] 操作 +``` + +使用原生应用运行不需要单独安装java环境: + +```java +编译后的可执行文件 [参数1] [值1] [参数2] [值2] 操作 +``` + +参数说明 + +| 参数 | 备注 | +| --------------- |---------------------------| +| provider | 服务提供商,如:aliyun | +| domain | 域名,如:baidu.com | +| rr | 记录,和域拼接在一起为完整域名,如:www | +| type | 解析类型,如:A/AAAA/TXT/CNAME 等 | +| value | 记录值,如果是A类型则对应IP地址,以此类推 | + +操作说明: + +| 操作 | 备注 | +|--------|------| +| add | 添加域名 | +| view | 查看域名 | +| update | 更新域名 | +| delete | 域除域名 | + +## 示例 + +- 设置临时环境变量 + +``` +set ALIYUN_ACCESS_KEY_ID=阿里云ACCESS_KEY_ID + +set ALIYUN_ACCESS_KEY_SECRET=阿里云ACCESS_KEY_SECRET + +set ALIYU_REGION_ID=区域id +``` + +> ALIYUN_REGION_ID 非密填,默认 cn-hangzhou +> 其他区域可参考:https://api.aliyun.com/product/Alidns ,如:cn-shenzhen + +- 新增域名 + +``` +dns.exe -provider aliyun -domain engr-z.com -rr test -type A -value 8.8.8.8 add +``` + +![img.png](img/img_add.png) + +> ipv4是A记录,ipv6是AAAA记录 + +- 查看域名 + +``` +dns.exe -provider aliyun -domain engr-z.com -rr test show +``` + +- 更新域名 + +``` +dns.exe -provider aliyun -domain engr-z.com -rr test -type A -value 8.8.4.4 update +``` + +![img_1.png](img/img_update.png) + +- 删除域名 + +``` +dns.exe -provider aliyun -domain engr-z.com -rr test delete +``` + +![img_2.png](img/img_delete.png) diff --git a/img/img_add.png b/img/img_add.png new file mode 100644 index 0000000000000000000000000000000000000000..4bb114b122977fd207970e48b7a46a0eba991fdd GIT binary patch literal 37731 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 lDkcb*={oARrLv%`2IgMIw6M{~x%~y|e%T literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..3ca1f45 --- /dev/null +++ b/pom.xml @@ -0,0 +1,147 @@ + + + 4.0.0 + + com.z.toys + z-dns + 1.0-SNAPSHOT + + + 17 + ${java.version} + ${java.version} + com.z.toys.dns.Main + 1.18.34 + 2.0.13 + 1.8.0 + 3.4.0 + 0.3.3 + 24.0.1 + + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + org.slf4j + slf4j-simple + ${slf4j.version} + + + commons-cli + commons-cli + ${commons-cli.version} + + + com.aliyun + alidns20150109 + ${alidns.version} + + + com.aliyun + credentials-java + ${aliyun-credentials-java.version} + + + org.graalvm.nativeimage + svm + ${svm.version} + provided + + + + + + native + + true + + + + + org.graalvm.buildtools + native-maven-plugin + + + + compile + + package + + + + false + ${project.artifactId}-${project.version}-native + + --no-fallback + --initialize-at-build-time=org.slf4j + --enable-http + --enable-https + -H:+ReportExceptionStackTraces + -H:+ReportUnsupportedElementsAtRuntime + -H:+AddAllCharsets + + ${start-class} + + + + + + + single + + false + + + + + org.apache.maven.plugins + maven-assembly-plugin + + ${project.artifactId}-${project.version}-single + + + ${start-class} + + + + jar-with-dependencies + + false + + + + make-assembly + package + + single + + + + + + + + + + + ${artifactId}-${project.version} + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + \ No newline at end of file diff --git a/src/main/java/com/z/toys/dns/Main.java b/src/main/java/com/z/toys/dns/Main.java new file mode 100644 index 0000000..09bbd04 --- /dev/null +++ b/src/main/java/com/z/toys/dns/Main.java @@ -0,0 +1,140 @@ +package com.z.toys.dns; + +import com.aliyun.tea.TeaException; +import com.z.toys.dns.model.ParamModel; +import com.z.toys.dns.provider.DnsProvider; +import com.z.toys.dns.provider.DnsProviderManage; +import com.z.toys.dns.util.BeanUtil; +import com.z.toys.dns.util.StrUtil; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.cli.*; + +import java.util.Arrays; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @author wangzz + * @since 2024/3/26 + **/ +@Slf4j(topic = "DnsMain") +public class Main { + + /** + * + * @param args + * @author wangzz + * @since 2024/3/26 + */ + @SneakyThrows + public static void main(String[] args) { + + try { + + CommandLineParser parser = new DefaultParser(); + CommandLine cmd = parser.parse(getOptions(), args); + + String op = args[args.length - 1]; + if (StrUtil.isEmpty(op)) { + log.error("操作参数不能为空,add(新增)/show(查询显示)/update(更新)/delete(删除)"); + return; + } + + Map map = Arrays.stream(cmd.getOptions()).collect(Collectors.toMap(opt -> opt.getOpt(), opt -> opt.getValue())); + log.debug("参数:{}", map); + + ParamModel paramModel = BeanUtil.map2Bean(map, ParamModel.class); + + DnsProvider dnsProvider = DnsProviderManage.getProvider(paramModel.getProvider()); + if (Objects.isNull(dnsProvider)) { + log.error("provider无效:{}", paramModel.getProvider()); + return; + } + + switch (op) { + case "show": { + dnsProvider.printDomainInfo(paramModel); + break; + } + case "add": { + dnsProvider.addDomain(paramModel); + break; + } + case "update": { + dnsProvider.updateDomain(paramModel); + break; + } + case "delete": { + dnsProvider.deleteDomain(paramModel); + break; + } + default: + log.error("操作参数错误:{}", op); + } + + } catch (ParseException e) { + log.error("参数解析错误", e); + + } catch (TeaException e) { + log.error("TeaException", e); + } + + } + + + /** + * 参数 + * @return + * @author wangzz + * @since 2024/3/26 + */ + public static Options getOptions() { + + Options options = new Options(); + + Option provider = Option.builder() + .option("provider") + .hasArg() + .required(true) + .desc("dns提供商,如:aliyun") + .build(); + options.addOption(provider); + + Option domain = Option.builder() + .option("domain") + .hasArg() + .required(true) + .desc("域名,如:engr-z.com") + .build(); + options.addOption(domain); + + Option rr = Option.builder() + .option("rr") + .hasArg() + .required(true) + .desc("记录/子域名") + .build(); + options.addOption(rr); + + Option type = Option.builder() + .option("type") + .hasArg() + .required(false) + .desc("记录类型,如:A/AAAA") + .build(); + options.addOption(type); + + Option value = Option.builder() + .option("value") + .hasArg() + .required(false) + .desc("记录值") + .build(); + options.addOption(value); + + return options; + } + +} diff --git a/src/main/java/com/z/toys/dns/model/ParamModel.java b/src/main/java/com/z/toys/dns/model/ParamModel.java new file mode 100644 index 0000000..6b88e03 --- /dev/null +++ b/src/main/java/com/z/toys/dns/model/ParamModel.java @@ -0,0 +1,37 @@ +package com.z.toys.dns.model; + +import lombok.Data; + +/** + * @author wangzz + * @since 2024/3/26 + **/ +@Data +public class ParamModel { + + /** + * dns供应商 + */ + private String provider; + + /** + * 域名 + */ + private String domain; + + /** + * 记录/子域名 + */ + private String rr; + + /** + * 类型 + */ + private String type; + + /** + * 记录值 + */ + private String value; + +} diff --git a/src/main/java/com/z/toys/dns/provider/AliDnsProvider.java b/src/main/java/com/z/toys/dns/provider/AliDnsProvider.java new file mode 100644 index 0000000..95b471f --- /dev/null +++ b/src/main/java/com/z/toys/dns/provider/AliDnsProvider.java @@ -0,0 +1,175 @@ +package com.z.toys.dns.provider; + +import com.aliyun.alidns20150109.Client; +import com.aliyun.alidns20150109.models.*; +import com.aliyun.tea.TeaModel; +import com.z.toys.dns.model.ParamModel; +import com.z.toys.dns.util.StrUtil; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; +import java.util.Objects; + +/** + * @author wangzz + * @since 2024/3/26 + **/ +@Slf4j(topic = "AliDnsProvider") +public class AliDnsProvider implements DnsProvider { + + /** + * 初使化账号 + * @return + * @throws Exception + * @author wangzz + * @since 2024/3/26 + */ + public static Client createClient() throws Exception { + String accessKeyId = System.getenv("ALIYUN_ACCESS_KEY_ID"); + String keySecret = System.getenv("ALIYUN_ACCESS_KEY_SECRET"); + if (StrUtil.isEmpty(accessKeyId) || StrUtil.isEmpty(keySecret)) { + throw new RuntimeException("阿里云 accessKeyId 或 keySecret 未配置"); + } + + // Endpoint 规则为:[product_code].[regionid].aliyuncs.com + // 请参考 https://api.aliyun.com/product/Alidns + String endpoint = String.format("alidns.%s.aliyuncs.com", Objects.toString(System.getenv("ALIYUN_REGION_ID"), "cn-hangzhou")); + com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config() + .setAccessKeyId(accessKeyId) + .setAccessKeySecret(keySecret) + .setEndpoint(endpoint); + + return new Client(config); + } + + @SneakyThrows + public DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecordsRecord getDomainInfo(ParamModel param) { + + Client client = createClient(); + DescribeDomainRecordsRequest req = new DescribeDomainRecordsRequest(); + req.setDomainName(param.getDomain()); + req.setRRKeyWord(param.getRr()); + + log.debug("查询域名解析记录请求:{}", com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(req))); + DescribeDomainRecordsResponse resp = client.describeDomainRecords(req); + log.debug("查询域名解析记录返回:{}", com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(resp))); + + List records = resp.getBody().getDomainRecords().getRecord(); + if (Objects.nonNull(records) && !records.isEmpty()) { + return records.get(0); + } + + return null; + } + + @SneakyThrows + @Override + public void printDomainInfo(ParamModel param) { + + if (StrUtil.isEmpty(param.getDomain()) || StrUtil.isEmpty(param.getRr())) { + log.error("必要参数不能为空"); + return; + } + + DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecordsRecord record = this.getDomainInfo(param); + if (Objects.nonNull(record)) { + log.info("查询域名结果↓"); + log.info("\t recordId: {}", record.getRecordId()); + log.info("\tdomainName: {}", record.getDomainName()); + log.info("\t rr: {}", record.getRR()); + log.info("\t type: {}", record.getType()); + log.info("\t value: {}", record.getValue()); + log.info("\t ttl: {}", record.getTTL()); + log.info("\t remark: {}", Objects.toString(record.getRemark(), "")); + } else { + log.info("域名未找到"); + } + + } + + @SneakyThrows + @Override + public void addDomain(ParamModel param) { + + if (StrUtil.isEmpty(param.getDomain()) || StrUtil.isEmpty(param.getRr()) || StrUtil.isEmpty(param.getType()) || StrUtil.isEmpty(param.getValue())) { + log.error("必要参数不能为空"); + return; + } + + DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecordsRecord record = this.getDomainInfo(param); + if (Objects.isNull(record)) { + AddDomainRecordRequest req = new AddDomainRecordRequest(); + req.setDomainName(param.getDomain()); + req.setRR(param.getRr()); + req.setType(param.getType()); + req.setValue(param.getValue()); + log.debug("添加域名解析记录请求:{}", com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(req))); + AddDomainRecordResponse resp = createClient().addDomainRecord(req); + log.debug("添加域名解析记录返回:{}", com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(resp))); + + log.info("添加域名解析记录成功:recordId={}", resp.getBody().getRecordId()); + + } else { + log.info("域名记录已存在", param.getRr()); + } + } + + @SneakyThrows + @Override + public void updateDomain(ParamModel param) { + + if (StrUtil.isEmpty(param.getDomain()) || StrUtil.isEmpty(param.getRr()) || StrUtil.isEmpty(param.getType()) || StrUtil.isEmpty(param.getValue())) { + log.error("必要参数不能为空"); + return; + } + + DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecordsRecord record = this.getDomainInfo(param); + if (Objects.nonNull(record)) { + + if (Objects.equals(param.getValue(), record.getValue())) { + log.info("域名解析记录值相同,不更新"); + return; + } + + UpdateDomainRecordRequest req = new UpdateDomainRecordRequest(); + req.setRecordId(record.getRecordId()); + req.setRR(param.getRr()); + req.setType(param.getType()); + req.setValue(param.getValue()); + log.debug("更新域名解析记录请求:{}", com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(req))); + UpdateDomainRecordResponse resp = createClient().updateDomainRecord(req); + log.debug("更新域名解析记录返回:{}", com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(resp))); + + log.info("更新域名解析记录成功"); + + } else { + log.info("域名未找到"); + } + } + + @SneakyThrows + @Override + public void deleteDomain(ParamModel param) { + + if (StrUtil.isEmpty(param.getDomain()) || StrUtil.isEmpty(param.getRr())) { + log.error("必要参数不能为空"); + return; + } + + DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecordsRecord record = this.getDomainInfo(param); + if (Objects.nonNull(record)) { + + DeleteDomainRecordRequest req = new DeleteDomainRecordRequest(); + req.setRecordId(record.getRecordId()); + log.debug("删除域名解析记录请求:{}", com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(req))); + DeleteDomainRecordResponse resp = createClient().deleteDomainRecord(req); + log.debug("删除域名解析记录返回:{}", com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(resp))); + + log.info("删除域名解析记录成功:recordId={},domain={},rr={}", record.getRecordId(), param.getDomain(), param.getRr()); + + } else { + log.info("域名未找到"); + } + } +} diff --git a/src/main/java/com/z/toys/dns/provider/DnsProvider.java b/src/main/java/com/z/toys/dns/provider/DnsProvider.java new file mode 100644 index 0000000..034c631 --- /dev/null +++ b/src/main/java/com/z/toys/dns/provider/DnsProvider.java @@ -0,0 +1,45 @@ +package com.z.toys.dns.provider; + +import com.z.toys.dns.model.ParamModel; + +/** + * @author wangzz + * @since 2024/3/26 + **/ +public interface DnsProvider { + + String ALIYUN = "aliyun"; + + /** + * 打印域名信息 + * @param param + * @author wangzz + * @since 2024/3/26 + */ + void printDomainInfo(ParamModel param); + + /** + * 添加域名 + * @param param + * @author wangzz + * @since 2024/3/26 + */ + void addDomain(ParamModel param); + + /** + * 更新域名 + * @param param + * @author wangzz + * @since 2024/3/26 + */ + void updateDomain(ParamModel param); + + /** + * 删除域名 + * @param param + * @author wangzz + * @since 2024/3/26 + */ + void deleteDomain(ParamModel param); + +} diff --git a/src/main/java/com/z/toys/dns/provider/DnsProviderManage.java b/src/main/java/com/z/toys/dns/provider/DnsProviderManage.java new file mode 100644 index 0000000..220c727 --- /dev/null +++ b/src/main/java/com/z/toys/dns/provider/DnsProviderManage.java @@ -0,0 +1,25 @@ +package com.z.toys.dns.provider; + +/** + * @author wangzz + * @since 2024/3/26 + **/ +public class DnsProviderManage { + + /** + * 获取dns内容提供者 + * @param provider + * @return + * @author wangzz + * @since 2024/3/26 + */ + public static DnsProvider getProvider(String provider) { + + switch (provider) { + case DnsProvider.ALIYUN: + return new AliDnsProvider(); + } + return null; + } + +} diff --git a/src/main/java/com/z/toys/dns/util/BeanUtil.java b/src/main/java/com/z/toys/dns/util/BeanUtil.java new file mode 100644 index 0000000..acf7181 --- /dev/null +++ b/src/main/java/com/z/toys/dns/util/BeanUtil.java @@ -0,0 +1,74 @@ +package com.z.toys.dns.util; + +import lombok.SneakyThrows; + +import java.beans.BeanInfo; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.util.HashMap; +import java.util.Map; + +/** + * @author wangzz + * @since 2024/3/26 + **/ +public class BeanUtil { + + /** + * 将 Bean 转换为 Map + * @param bean + * @return + * @author wangzz + * @since 2024/3/26 + */ + @SneakyThrows + public static Map bean2Map(Object bean) { + + Map map = new HashMap<>(); + BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass()); + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { + map.put(propertyDescriptor.getName(), propertyDescriptor.getReadMethod().invoke(bean)); + } + + return map; + } + + /** + * 将 Map 转换为 Bean + * @param map + * @param clazz + * @return + * @param + * @author wangzz + * @since 2024/3/26 + */ + @SneakyThrows + public static T map2Bean(Map map, Class clazz) { + + // 获取 Bean 的类信息 + BeanInfo beanInfo = Introspector.getBeanInfo(clazz); + + // 获取 Bean 的属性描述符 + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + + // 创建 Bean 实例 + T bean = clazz.newInstance(); + + // 遍历属性描述符 + for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { + // 获取属性名称 + String name = propertyDescriptor.getName(); + // 获取属性值 + Object value = map.get(name); + // 如果属性值不为空,则将属性值设置到 Bean 中 + if (value != null) { + propertyDescriptor.getWriteMethod().invoke(bean, value); + } + } + + return bean; + } + + +} diff --git a/src/main/java/com/z/toys/dns/util/Okhttp3_Internal_Util.java b/src/main/java/com/z/toys/dns/util/Okhttp3_Internal_Util.java new file mode 100644 index 0000000..518f669 --- /dev/null +++ b/src/main/java/com/z/toys/dns/util/Okhttp3_Internal_Util.java @@ -0,0 +1,50 @@ +package com.z.toys.dns.util; + +import com.oracle.svm.core.annotate.Alias; +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; +import okhttp3.internal.Util; +import okio.BufferedSource; +import okio.ByteString; + +import java.io.IOException; +import java.nio.charset.Charset; + +/** + * @author wangzz + * @since 2024/3/26 + **/ +@TargetClass(Util.class) +public final class Okhttp3_Internal_Util { + + @Alias + private static ByteString UTF_8_BOM; + @Alias + private static ByteString UTF_16_BE_BOM; + @Alias + private static ByteString UTF_16_LE_BOM; + @Alias + public static Charset UTF_8; + @Alias + private static Charset UTF_16_BE; + @Alias + private static Charset UTF_16_LE; + + @Substitute + public static Charset bomAwareCharset(BufferedSource source, Charset charset) throws IOException { + + if (source.rangeEquals(0, UTF_8_BOM)) { + source.skip(UTF_8_BOM.size()); + return UTF_8; + } + if (source.rangeEquals(0, UTF_16_BE_BOM)) { + source.skip(UTF_16_BE_BOM.size()); + return UTF_16_BE; + } + if (source.rangeEquals(0, UTF_16_LE_BOM)) { + source.skip(UTF_16_LE_BOM.size()); + return UTF_16_LE; + } + return charset; + } +} diff --git a/src/main/java/com/z/toys/dns/util/StrUtil.java b/src/main/java/com/z/toys/dns/util/StrUtil.java new file mode 100644 index 0000000..c1cc68b --- /dev/null +++ b/src/main/java/com/z/toys/dns/util/StrUtil.java @@ -0,0 +1,35 @@ +package com.z.toys.dns.util; + +import java.util.Objects; + +/** + * @author wangzz + * @since 2024/3/26 + **/ +public class StrUtil { + + /** + * + * @param str + * @return + * @author wangzz + * @since 2024/3/26 + */ + public static boolean isEmpty(String str) { + + return Objects.isNull(str) || "".equals(str); + } + + /** + * + * @param str + * @return + * @author wangzz + * @since 2024/3/26 + */ + public static boolean isNotEmpty(String str) { + + return !isEmpty(str); + } + +} diff --git a/src/main/resources/META-INF/native-image/fix_okhttp3.json b/src/main/resources/META-INF/native-image/fix_okhttp3.json new file mode 100644 index 0000000..a893bc8 --- /dev/null +++ b/src/main/resources/META-INF/native-image/fix_okhttp3.json @@ -0,0 +1,12 @@ +[ + { + "annotatedClass": "com.z.toys.dns.util.Okhttp3_Internal_Util", + "originalClass": "okhttp3.internal.Util", + "methods": [ + { + "annotatedName": "bomAwareCharset", + "substitute": true + } + ] + } +] \ No newline at end of file diff --git a/src/main/resources/META-INF/native-image/jni-config.json b/src/main/resources/META-INF/native-image/jni-config.json new file mode 100644 index 0000000..8b4e417 --- /dev/null +++ b/src/main/resources/META-INF/native-image/jni-config.json @@ -0,0 +1,6 @@ +[ +{ + "name":"java.lang.Boolean", + "methods":[{"name":"getBoolean","parameterTypes":["java.lang.String"] }] +} +] diff --git a/src/main/resources/META-INF/native-image/predefined-classes-config.json b/src/main/resources/META-INF/native-image/predefined-classes-config.json new file mode 100644 index 0000000..0e79b2c --- /dev/null +++ b/src/main/resources/META-INF/native-image/predefined-classes-config.json @@ -0,0 +1,8 @@ +[ + { + "type":"agent-extracted", + "classes":[ + ] + } +] + diff --git a/src/main/resources/META-INF/native-image/proxy-config.json b/src/main/resources/META-INF/native-image/proxy-config.json new file mode 100644 index 0000000..0d4f101 --- /dev/null +++ b/src/main/resources/META-INF/native-image/proxy-config.json @@ -0,0 +1,2 @@ +[ +] diff --git a/src/main/resources/META-INF/native-image/reflect-config.json b/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 0000000..5451f2d --- /dev/null +++ b/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,344 @@ +[ +{ + "name":"[B" +}, +{ + "name":"[Ljava.lang.String;" +}, +{ + "name":"[Lsun.security.pkcs.SignerInfo;" +}, +{ + "name":"com.aliyun.alidns20150109.models.AddDomainRecordRequest", + "allPublicFields":true +}, +{ + "name":"com.aliyun.alidns20150109.models.AddDomainRecordResponse", + "allPublicFields":true +}, +{ + "name":"com.aliyun.alidns20150109.models.AddDomainRecordResponseBody", + "allPublicFields":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.aliyun.alidns20150109.models.DescribeDomainRecordsRequest", + "allPublicFields":true +}, +{ + "name":"com.aliyun.alidns20150109.models.DescribeDomainRecordsResponse", + "allPublicFields":true +}, +{ + "name":"com.aliyun.alidns20150109.models.DescribeDomainRecordsResponseBody", + "allPublicFields":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.aliyun.alidns20150109.models.UpdateDomainRecordRequest", + "allPublicFields":true +}, +{ + "name":"com.aliyun.alidns20150109.models.UpdateDomainRecordResponse", + "allPublicFields":true +}, +{ + "name":"com.aliyun.alidns20150109.models.UpdateDomainRecordResponseBody", + "allPublicFields":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.aliyun.alidns20150109.models.DeleteDomainRecordRequest", + "allPublicFields":true +}, +{ + "name":"com.aliyun.alidns20150109.models.DeleteDomainRecordResponse", + "allPublicFields":true +}, +{ + "name":"com.aliyun.alidns20150109.models.DeleteDomainRecordResponseBody", + "allPublicFields":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.aliyun.alidns20150109.models.DescribeDomainRecordsResponseBody$DescribeDomainRecordsResponseBodyDomainRecords", + "allPublicFields":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.aliyun.alidns20150109.models.DescribeDomainRecordsResponseBody$DescribeDomainRecordsResponseBodyDomainRecordsRecord", + "allPublicFields":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.aliyun.credentials.models.Config", + "allPublicFields":true +}, +{ + "name":"com.aliyun.teaopenapi.models.OpenApiRequest", + "allPublicFields":true +}, +{ + "name":"com.aliyun.teaopenapi.models.Params", + "allPublicFields":true +}, +{ + "name":"com.z.toys.dns.model.ParamModel", + "queryAllPublicMethods":true, + "methods":[{"name":"","parameterTypes":[] }, {"name":"setDomain","parameterTypes":["java.lang.String"] }, {"name":"setProvider","parameterTypes":["java.lang.String"] }, {"name":"setRr","parameterTypes":["java.lang.String"] }, {"name":"setType","parameterTypes":["java.lang.String"] }, {"name":"setValue","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"com.z.toys.dns.model.ParamModelBeanInfo" +}, +{ + "name":"com.z.toys.dns.model.ParamModelCustomizer" +}, +{ + "name":"com.sun.crypto.provider.AESCipher$General", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.ARCFOURCipher", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.DESCipher", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.DESedeCipher", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.DHParameters", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.GaloisCounterMode$AESGCM", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.HmacCore$HmacSHA256", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.HmacCore$HmacSHA384", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.TlsMasterSecretGenerator", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"java.beans.PropertyVetoException" +}, +{ + "name":"java.lang.Object", + "queryAllPublicMethods":true +}, +{ + "name":"java.lang.ObjectBeanInfo" +}, +{ + "name":"java.lang.ObjectCustomizer" +}, +{ + "name":"java.lang.String" +}, +{ + "name":"java.lang.Thread", + "fields":[{"name":"threadLocalRandomProbe"}] +}, +{ + "name":"java.lang.Throwable", + "methods":[{"name":"addSuppressed","parameterTypes":["java.lang.Throwable"] }] +}, +{ + "name":"java.lang.reflect.AccessibleObject", + "fields":[{"name":"override"}] +}, +{ + "name":"java.security.AlgorithmParametersSpi" +}, +{ + "name":"java.security.KeyStoreSpi" +}, +{ + "name":"java.security.SecureRandomParameters" +}, +{ + "name":"java.security.interfaces.ECPrivateKey" +}, +{ + "name":"java.security.interfaces.ECPublicKey" +}, +{ + "name":"java.sql.Date" +}, +{ + "name":"java.util.ArrayList", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"java.util.Date" +}, +{ + "name":"java.util.HashMap", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"java.util.concurrent.atomic.Striped64", + "fields":[{"name":"base"}, {"name":"cellsBusy"}] +}, +{ + "name":"javax.net.ssl.SSLParameters", + "methods":[{"name":"setApplicationProtocols","parameterTypes":["java.lang.String[]"] }] +}, +{ + "name":"javax.net.ssl.SSLSocket", + "methods":[{"name":"getApplicationProtocol","parameterTypes":[] }] +}, +{ + "name":"javax.security.auth.x500.X500Principal", + "fields":[{"name":"thisX500Name"}], + "methods":[{"name":"","parameterTypes":["sun.security.x509.X500Name"] }] +}, +{ + "name":"sun.misc.Unsafe", + "fields":[{"name":"theUnsafe"}] +}, +{ + "name":"sun.security.pkcs12.PKCS12KeyStore", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.DRBG", + "methods":[{"name":"","parameterTypes":["java.security.SecureRandomParameters"] }] +}, +{ + "name":"sun.security.provider.DSA$SHA224withDSA", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.DSA$SHA256withDSA", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.JavaKeyStore$JKS", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.MD5", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.SHA", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.SHA2$SHA224", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.SHA2$SHA256", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.SHA5$SHA384", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.SHA5$SHA512", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.X509Factory", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.rsa.PSSParameters", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.rsa.RSAKeyFactory$Legacy", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.rsa.RSAPSSSignature", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.rsa.RSASignature$SHA224withRSA", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.ssl.SSLContextImpl$TLSContext", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.util.ObjectIdentifier" +}, +{ + "name":"sun.security.x509.AuthorityInfoAccessExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.AuthorityKeyIdentifierExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.BasicConstraintsExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.CRLDistributionPointsExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.CertificateExtensions" +}, +{ + "name":"sun.security.x509.CertificatePoliciesExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.ExtendedKeyUsageExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.IssuerAlternativeNameExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.KeyUsageExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.NetscapeCertTypeExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.PrivateKeyUsageExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.SubjectAlternativeNameExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.SubjectKeyIdentifierExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +} +] diff --git a/src/main/resources/META-INF/native-image/resource-config.json b/src/main/resources/META-INF/native-image/resource-config.json new file mode 100644 index 0000000..b643d8d --- /dev/null +++ b/src/main/resources/META-INF/native-image/resource-config.json @@ -0,0 +1,13 @@ +{ + "resources":{ + "includes":[{ + "pattern":"\\QMETA-INF/services/org.slf4j.spi.SLF4JServiceProvider\\E" + }, { + "pattern":"java.base:\\Qjdk/internal/icu/impl/data/icudt67b/nfkc.nrm\\E" + }, { + "pattern":"java.base:\\Qjdk/internal/icu/impl/data/icudt67b/uprops.icu\\E" + }, { + "pattern":"java.base:\\Qsun/net/idn/uidna.spp\\E" + }]}, + "bundles":[] +} diff --git a/src/main/resources/META-INF/native-image/serialization-config.json b/src/main/resources/META-INF/native-image/serialization-config.json new file mode 100644 index 0000000..f3d7e06 --- /dev/null +++ b/src/main/resources/META-INF/native-image/serialization-config.json @@ -0,0 +1,8 @@ +{ + "types":[ + ], + "lambdaCapturingTypes":[ + ], + "proxies":[ + ] +}