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 0000000..4bb114b Binary files /dev/null and b/img/img_add.png differ diff --git a/img/img_delete.png b/img/img_delete.png new file mode 100644 index 0000000..d6e812f Binary files /dev/null and b/img/img_delete.png differ diff --git a/img/img_update.png b/img/img_update.png new file mode 100644 index 0000000..a501039 Binary files /dev/null and b/img/img_update.png differ 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":[ + ] +}