diff options
| author | doufenghu <[email protected]> | 2023-08-24 21:05:36 +0800 |
|---|---|---|
| committer | doufenghu <[email protected]> | 2023-08-24 21:05:36 +0800 |
| commit | 8d8cb9997e314f1a6b0660fd92372679860f612f (patch) | |
| tree | a977bfb1b6b0adb5c79a014cadcb2b0f38d53e10 | |
| parent | f599767054c7591d6ed4b9128c5b074d8103c0b6 (diff) | |
[Release][All] Galaxy Tools 1.2
- 重命名包com.geedgenetworks
- 改善IPLookupV2 查询性能
- 升级maxmind-db版本至2.1.0,去除JACKSON的依赖
- infoLookup方法支持更多返回结果方式,包括CSV,JSON,Object
- 重构处理逻辑,减少对象之间的转换
- IPV4 与 IPv6 校验基于InetAddress
- 完善单元测试和Benchmark测试工具
- 删除过期类和部分方法
| -rw-r--r-- | README.md | 4 | ||||
| -rw-r--r-- | pom.xml | 42 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/crypt/AESUtil.java (renamed from src/main/java/com/zdjizhi/crypt/AESUtil.java) | 2 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/crypt/BCrypt.java (renamed from src/main/java/com/zdjizhi/crypt/BCrypt.java) | 2 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/crypt/CertificateCoder.java (renamed from src/main/java/com/zdjizhi/crypt/CertificateCoder.java) | 2 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/crypt/Cryptos.java (renamed from src/main/java/com/zdjizhi/crypt/Cryptos.java) | 6 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/crypt/DesFileUtil.java (renamed from src/main/java/com/zdjizhi/crypt/DesFileUtil.java) | 2 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/crypt/DesUtil.java (renamed from src/main/java/com/zdjizhi/crypt/DesUtil.java) | 2 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/crypt/Digests.java (renamed from src/main/java/com/zdjizhi/crypt/Digests.java) | 4 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/crypt/RSACoder.java (renamed from src/main/java/com/zdjizhi/crypt/RSACoder.java) | 2 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/crypt/package.html (renamed from src/main/java/com/zdjizhi/crypt/package.html) | 0 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/domain/LocationResponse.java (renamed from src/main/java/com/zdjizhi/domain/LocationResponseV2.java) | 36 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/domain/Nets.java (renamed from src/main/java/com/zdjizhi/domain/Nets.java) | 2 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/exception/Exceptions.java (renamed from src/main/java/com/zdjizhi/exception/Exceptions.java) | 2 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/file/FileApplication.java (renamed from src/main/java/com/zdjizhi/file/FileApplication.java) | 8 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/file/FileFilterExtension.java (renamed from src/main/java/com/zdjizhi/file/FileFilterExtension.java) | 2 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/AbstractIpLookup.java (renamed from src/main/java/com/zdjizhi/utils/AbstractIpLookup.java) | 52 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/AsnLookup.java | 428 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/CIDRUtils.java (renamed from src/main/java/com/zdjizhi/utils/CIDRUtils.java) | 2 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/CommonUtil.java (renamed from src/main/java/com/zdjizhi/utils/CommonUtil.java) | 6 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/CookieUtil.java (renamed from src/main/java/com/zdjizhi/utils/CookieUtil.java) | 2 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/DateUtils.java (renamed from src/main/java/com/zdjizhi/utils/DateUtils.java) | 3 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/Encodes.java (renamed from src/main/java/com/zdjizhi/utils/Encodes.java) | 4 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/FormatUtils.java (renamed from src/main/java/com/zdjizhi/utils/FormatUtils.java) | 7 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/GalaxyDataBaseReader.java (renamed from src/main/java/com/zdjizhi/utils/GalaxyDataBaseReader.java) | 89 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/IPUtil.java (renamed from src/main/java/com/zdjizhi/utils/IPUtil.java) | 19 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/IpLookupV2.java | 760 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/JsonMapper.java (renamed from src/main/java/com/zdjizhi/utils/JsonMapper.java) | 2 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/MathUtils.java (renamed from src/main/java/com/zdjizhi/utils/MathUtils.java) | 2 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/SnowflakeId.java (renamed from src/main/java/com/zdjizhi/utils/SnowflakeId.java) | 466 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/StringUtil.java (renamed from src/main/java/com/zdjizhi/utils/StringUtil.java) | 2 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/TimeConstants.java (renamed from src/main/java/com/zdjizhi/utils/TimeConstants.java) | 2 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/ZooKeeperLock.java (renamed from src/main/java/com/zdjizhi/utils/ZooKeeperLock.java) | 280 | ||||
| -rw-r--r-- | src/main/java/com/geedgenetworks/utils/ZookeeperUtils.java (renamed from src/main/java/com/zdjizhi/utils/ZookeeperUtils.java) | 278 | ||||
| -rw-r--r-- | src/main/java/com/zdjizhi/domain/JsonInjector.java | 44 | ||||
| -rw-r--r-- | src/main/java/com/zdjizhi/domain/LocationResponse.java | 157 | ||||
| -rw-r--r-- | src/main/java/com/zdjizhi/utils/AsnLookup.java | 554 | ||||
| -rw-r--r-- | src/main/java/com/zdjizhi/utils/IpLookupV2.java | 894 | ||||
| -rw-r--r-- | src/test/java/com/geedgenetworks/test/DateUtilTest.java (renamed from src/test/java/com/zdjizhi/test/DateUtilTest.java) | 6 | ||||
| -rw-r--r-- | src/test/java/com/geedgenetworks/test/FormatUtilTest.java (renamed from src/test/java/com/zdjizhi/test/FormatUtilTest.java) | 10 | ||||
| -rw-r--r-- | src/test/java/com/geedgenetworks/test/IPBenchMark.java (renamed from src/test/java/com/zdjizhi/test/IPBenchMarkTest.java) | 40 | ||||
| -rw-r--r-- | src/test/java/com/geedgenetworks/test/IpLookupV2Test.java | 179 | ||||
| -rw-r--r-- | src/test/java/com/geedgenetworks/test/JsonMapperTest.java (renamed from src/test/java/com/zdjizhi/test/JsonMapperTest.java) | 6 | ||||
| -rw-r--r-- | src/test/java/com/zdjizhi/test/HllSketchTest.java | 94 | ||||
| -rw-r--r-- | src/test/java/com/zdjizhi/test/IpLookupV2Test.java | 110 |
45 files changed, 2022 insertions, 2594 deletions
@@ -10,11 +10,11 @@ Galaxy Tools 是中电积至关于java的核心工具类库,主要包括文件 **增加Galaxy Tools 到你的应用中** *** -Galaxy 的 Maven group ID 是 `com.zdjizhi` 并且 artifactId 是 `galaxy`。增加maven依赖,如下所示: +Galaxy 的 Maven group ID 是 `com.geedgenetworks` 并且 artifactId 是 `galaxy`。增加maven依赖,如下所示: ``` <dependency> - <groupId>com.zdjizhi</groupId> + <groupId>com.geedgenetworks</groupId> <artifactId>galaxy</artifactId> <version>1.1.1/version> </dependency> @@ -3,42 +3,22 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> - <groupId>com.zdjizhi</groupId> + <groupId>com.geedgenetworks</groupId> <artifactId>galaxy</artifactId> <packaging>jar</packaging> <name>galaxy</name> - <version>1.1.3</version> + <version>1.2</version> <description>galaxy tools for common</description> <url>http://www.zdjizhi.com/galaxy-tool</url> <licenses> <license> - <name>The zdjizhi Software License, Version 21.0</name> + <name>The geedge networks Software License, Version 21.0</name> <url>http://www.apache.org/licenses/LICENSE-1.0.txt</url> <distribution>repo</distribution> </license> </licenses> - <developers> - <developer> - <id>galaxy tools</id> - <name>darnell</name> - <roles> - <role>Project Leader</role> - </roles> - <timezone>+8</timezone> - <url>http://</url> - </developer> - - </developers> - - <contributors> - <contributor> - <name>XX</name> - <url>https://</url> - </contributor> - </contributors> - <!-- 仓库地址构建 --> <repositories> @@ -56,13 +36,8 @@ <url>http://192.168.40.153:8099/content/repositories/galaxy-tool</url> <uniqueVersion>true</uniqueVersion> </repository> -<!-- <snapshotRepository> --> -<!-- <id>nexus</id> --> -<!-- <name>snapshots</name> --> -<!-- <url>http://192.168.40.125:8099/content/repositories/snapshots/</url> --> -<!-- </snapshotRepository> --> </distributionManagement> - + <properties> <java.version>1.8</java.version> @@ -203,7 +178,7 @@ <dependency> <groupId>com.maxmind.db</groupId> <artifactId>maxmind-db</artifactId> - <version>1.4.0</version> + <version>2.1.0</version> </dependency> <dependency> @@ -242,13 +217,6 @@ </dependency> <dependency> - <groupId>org.apache.datasketches</groupId> - <artifactId>datasketches-java</artifactId> - <version>3.3.0</version> - <scope>provided</scope> - </dependency> - - <dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.32</version> diff --git a/src/main/java/com/zdjizhi/crypt/AESUtil.java b/src/main/java/com/geedgenetworks/crypt/AESUtil.java index aae56a2..160da6c 100644 --- a/src/main/java/com/zdjizhi/crypt/AESUtil.java +++ b/src/main/java/com/geedgenetworks/crypt/AESUtil.java @@ -4,7 +4,7 @@ * Copyright 2010 NIS, Inc. All rights reserved. * */ -package com.zdjizhi.crypt; +package com.geedgenetworks.crypt; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.digest.DigestUtils; diff --git a/src/main/java/com/zdjizhi/crypt/BCrypt.java b/src/main/java/com/geedgenetworks/crypt/BCrypt.java index 797274e..18d9e67 100644 --- a/src/main/java/com/zdjizhi/crypt/BCrypt.java +++ b/src/main/java/com/geedgenetworks/crypt/BCrypt.java @@ -1,4 +1,4 @@ -package com.zdjizhi.crypt; +package com.geedgenetworks.crypt; import java.io.UnsupportedEncodingException; import java.security.SecureRandom; diff --git a/src/main/java/com/zdjizhi/crypt/CertificateCoder.java b/src/main/java/com/geedgenetworks/crypt/CertificateCoder.java index 74e1834..dd41a05 100644 --- a/src/main/java/com/zdjizhi/crypt/CertificateCoder.java +++ b/src/main/java/com/geedgenetworks/crypt/CertificateCoder.java @@ -1,5 +1,5 @@ - package com.zdjizhi.crypt; + package com.geedgenetworks.crypt; import java.io.FileInputStream; import java.security.KeyStore; diff --git a/src/main/java/com/zdjizhi/crypt/Cryptos.java b/src/main/java/com/geedgenetworks/crypt/Cryptos.java index 7b7f3f3..dbbed2c 100644 --- a/src/main/java/com/zdjizhi/crypt/Cryptos.java +++ b/src/main/java/com/geedgenetworks/crypt/Cryptos.java @@ -1,7 +1,7 @@ -package com.zdjizhi.crypt; +package com.geedgenetworks.crypt; -import com.zdjizhi.exception.Exceptions; -import com.zdjizhi.utils.Encodes; +import com.geedgenetworks.exception.Exceptions; +import com.geedgenetworks.utils.Encodes; import java.io.UnsupportedEncodingException; import java.security.GeneralSecurityException; diff --git a/src/main/java/com/zdjizhi/crypt/DesFileUtil.java b/src/main/java/com/geedgenetworks/crypt/DesFileUtil.java index 1b61584..7bea334 100644 --- a/src/main/java/com/zdjizhi/crypt/DesFileUtil.java +++ b/src/main/java/com/geedgenetworks/crypt/DesFileUtil.java @@ -1,4 +1,4 @@ -package com.zdjizhi.crypt; +package com.geedgenetworks.crypt; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; diff --git a/src/main/java/com/zdjizhi/crypt/DesUtil.java b/src/main/java/com/geedgenetworks/crypt/DesUtil.java index a99e4c1..8b15a9e 100644 --- a/src/main/java/com/zdjizhi/crypt/DesUtil.java +++ b/src/main/java/com/geedgenetworks/crypt/DesUtil.java @@ -1,4 +1,4 @@ -package com.zdjizhi.crypt; +package com.geedgenetworks.crypt; import java.security.NoSuchAlgorithmException; import java.security.Security; diff --git a/src/main/java/com/zdjizhi/crypt/Digests.java b/src/main/java/com/geedgenetworks/crypt/Digests.java index 02b4148..3996615 100644 --- a/src/main/java/com/zdjizhi/crypt/Digests.java +++ b/src/main/java/com/geedgenetworks/crypt/Digests.java @@ -1,7 +1,7 @@ /** * Copyright (c) 2005-2012 springside.org.cn */ -package com.zdjizhi.crypt; +package com.geedgenetworks.crypt; import java.io.IOException; import java.io.InputStream; @@ -9,7 +9,7 @@ import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.security.SecureRandom; -import com.zdjizhi.exception.Exceptions; +import com.geedgenetworks.exception.Exceptions; /** diff --git a/src/main/java/com/zdjizhi/crypt/RSACoder.java b/src/main/java/com/geedgenetworks/crypt/RSACoder.java index 6d928a0..45219f5 100644 --- a/src/main/java/com/zdjizhi/crypt/RSACoder.java +++ b/src/main/java/com/geedgenetworks/crypt/RSACoder.java @@ -1,4 +1,4 @@ -package com.zdjizhi.crypt; +package com.geedgenetworks.crypt; import java.security.Key; diff --git a/src/main/java/com/zdjizhi/crypt/package.html b/src/main/java/com/geedgenetworks/crypt/package.html index 84c081f..84c081f 100644 --- a/src/main/java/com/zdjizhi/crypt/package.html +++ b/src/main/java/com/geedgenetworks/crypt/package.html diff --git a/src/main/java/com/zdjizhi/domain/LocationResponseV2.java b/src/main/java/com/geedgenetworks/domain/LocationResponse.java index cf858ca..8d9256a 100644 --- a/src/main/java/com/zdjizhi/domain/LocationResponseV2.java +++ b/src/main/java/com/geedgenetworks/domain/LocationResponse.java @@ -1,9 +1,10 @@ -package com.zdjizhi.domain;/** +package com.geedgenetworks.domain;/** * Created by dell on 2018-10-8. */ -import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.base.MoreObjects; +import com.maxmind.db.MaxMindDbConstructor; +import com.maxmind.db.MaxMindDbParameter; /** * @ClassName CountryResponse @@ -12,8 +13,7 @@ import com.google.common.base.MoreObjects; * @Date 2018-10-8 18:56 * @Version 1.0 **/ -public class LocationResponseV2 { - +public class LocationResponse implements java.io.Serializable { private String areaCode; private String asn; @@ -42,21 +42,24 @@ public class LocationResponseV2 { private String countryCode; - private boolean privateIP; - + private boolean isPrivateIP; - public LocationResponseV2() { + public LocationResponse() { this("", "", "", "", "", "", "", "", "", "", "", "", "", ""); } - public LocationResponseV2(@JsonProperty("AREA_CODE") String areaCode, @JsonProperty("ASN") String asn, - @JsonProperty("ISP") String isp, @JsonProperty("LATITUDE") String latitude, - @JsonProperty("LONGITUDE") String longitude, @JsonProperty("COUNTRY") String country, - @JsonProperty("SUPER_ADMINISTRATIVE_AREA") String superAdministrativeArea, @JsonProperty("ADMINISTRATIVE_AREA") String administrativeArea, - @JsonProperty("SUB_ADMINISTRATIVE_AREA") String subAdministrativeArea, @JsonProperty("LOCALITY") String locality, - @JsonProperty("DEPENDENT_LOCALITY") String dependentLocality, @JsonProperty("DOUBLE_DEPENDENT_LOCALITY") String doubleDependentLocality, - @JsonProperty("ORGANIZATION") String organization, @JsonProperty("COUNTRY_CODE") String countryCode) { + public LocationResponse(boolean isPrivateIP) { + this.setPrivateIP(isPrivateIP); + } + @MaxMindDbConstructor + public LocationResponse(@MaxMindDbParameter(name="AREA_CODE") String areaCode, @MaxMindDbParameter(name= "ASN") String asn, + @MaxMindDbParameter(name= "ISP") String isp, @MaxMindDbParameter(name= "LATITUDE") String latitude, + @MaxMindDbParameter(name= "LONGITUDE") String longitude, @MaxMindDbParameter(name= "COUNTRY") String country, + @MaxMindDbParameter(name= "SUPER_ADMINISTRATIVE_AREA") String superAdministrativeArea, @MaxMindDbParameter(name= "ADMINISTRATIVE_AREA") String administrativeArea, + @MaxMindDbParameter(name= "SUB_ADMINISTRATIVE_AREA") String subAdministrativeArea, @MaxMindDbParameter(name= "LOCALITY") String locality, + @MaxMindDbParameter(name= "DEPENDENT_LOCALITY") String dependentLocality, @MaxMindDbParameter(name="DOUBLE_DEPENDENT_LOCALITY") String doubleDependentLocality, + @MaxMindDbParameter(name= "ORGANIZATION") String organization, @MaxMindDbParameter(name="COUNTRY_CODE") String countryCode) { this.areaCode = areaCode; this.asn = asn; this.isp = isp; @@ -71,7 +74,6 @@ public class LocationResponseV2 { this.doubleDependentLocality = doubleDependentLocality; this.organization = organization; this.countryCode = countryCode; - } public String getAreaCode() { @@ -187,11 +189,11 @@ public class LocationResponseV2 { } public boolean isPrivateIP() { - return privateIP; + return isPrivateIP; } public void setPrivateIP(boolean privateIP) { - this.privateIP = privateIP; + isPrivateIP = privateIP; } @Override diff --git a/src/main/java/com/zdjizhi/domain/Nets.java b/src/main/java/com/geedgenetworks/domain/Nets.java index bad78d8..0f83bed 100644 --- a/src/main/java/com/zdjizhi/domain/Nets.java +++ b/src/main/java/com/geedgenetworks/domain/Nets.java @@ -1,4 +1,4 @@ -package com.zdjizhi.domain; +package com.geedgenetworks.domain; /** * Created by dell on 2018-8-30. diff --git a/src/main/java/com/zdjizhi/exception/Exceptions.java b/src/main/java/com/geedgenetworks/exception/Exceptions.java index 04ba794..fdf187f 100644 --- a/src/main/java/com/zdjizhi/exception/Exceptions.java +++ b/src/main/java/com/geedgenetworks/exception/Exceptions.java @@ -1,7 +1,7 @@ /** * Copyright (c) 2005-2012 springside.org.cn */ -package com.zdjizhi.exception; +package com.geedgenetworks.exception; import java.io.PrintWriter; import java.io.StringWriter; diff --git a/src/main/java/com/zdjizhi/file/FileApplication.java b/src/main/java/com/geedgenetworks/file/FileApplication.java index 6e3db66..245f228 100644 --- a/src/main/java/com/zdjizhi/file/FileApplication.java +++ b/src/main/java/com/geedgenetworks/file/FileApplication.java @@ -1,8 +1,8 @@ -package com.zdjizhi.file; +package com.geedgenetworks.file; -import com.zdjizhi.utils.DateUtils; -import com.zdjizhi.utils.StringUtil; -import com.zdjizhi.utils.TimeConstants; +import com.geedgenetworks.utils.DateUtils; +import com.geedgenetworks.utils.StringUtil; +import com.geedgenetworks.utils.TimeConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/com/zdjizhi/file/FileFilterExtension.java b/src/main/java/com/geedgenetworks/file/FileFilterExtension.java index bff24e2..9561594 100644 --- a/src/main/java/com/zdjizhi/file/FileFilterExtension.java +++ b/src/main/java/com/geedgenetworks/file/FileFilterExtension.java @@ -1,4 +1,4 @@ -package com.zdjizhi.file; +package com.geedgenetworks.file; import java.io.File; import java.io.FileFilter; diff --git a/src/main/java/com/zdjizhi/utils/AbstractIpLookup.java b/src/main/java/com/geedgenetworks/utils/AbstractIpLookup.java index 7639d72..1762bfa 100644 --- a/src/main/java/com/zdjizhi/utils/AbstractIpLookup.java +++ b/src/main/java/com/geedgenetworks/utils/AbstractIpLookup.java @@ -1,8 +1,12 @@ -package com.zdjizhi.utils; +package com.geedgenetworks.utils; +import com.google.common.collect.Maps; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.List; +import java.util.Map; + /** * @ClassName AbstractIpLookup * @Description 对IP定位查找抽象类,规定可执行方法 @@ -12,11 +16,25 @@ import org.slf4j.LoggerFactory; **/ public abstract class AbstractIpLookup { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); - protected static final String UNKNOWN = ""; - protected static final String LOCATION_SEPARATOR = "."; - protected static final String LATLNG_SEPARATOR = ","; - protected static final String OBJECT_SEPARATOR = "\t"; - protected static final String PRIVATE_IP = "Private IP"; + public static final String UNKNOWN = ""; + public static final String LOCATION_SEPARATOR = "."; + public static final String LAT_LNG_SEPARATOR = ","; + public static final String OBJECT_SEPARATOR = "\t"; + public static final String PRIVATE_IP = "Private IP"; + + protected static final String DEFAULT_DATABASE_PATH = "dat"; + protected static final String DEFAULT_DB_IP_PUBLIC = "ip.mmdb"; + protected static final String DEFAULT_DB_IP_PUBLIC_V4 = "ip_v4_built_in.mmdb"; + protected static final String DEFAULT_DB_IP_PUBLIC_V6 = "ip_v6.mmdb"; + protected static final String DEFAULT_DB_IP_PRIVATE = "ip_private.mmdb"; + protected static final String DEFAULT_DB_IP_PRIVATE_V4 = "ip_private_v4.mmdb"; + protected static final String DEFAULT_DB_IP_PRIVATE_V6 = "ip_private_v6.mmdb"; + public enum Type { + PRIVATE, PUBLIC + } + public enum IpVersion { + IPv4, IPv6 + } /** * 给定IP库文件路径,获取国家代码 @@ -130,8 +148,6 @@ public abstract class AbstractIpLookup { */ public abstract String asnLookupInfo(String ip); - - /** * * 获取AS号与组织信息 @@ -165,17 +181,25 @@ public abstract class AbstractIpLookup { public abstract String infoLookupToCSV(String ip); /** - * This method to return all fields for JSON. + * This method to return all fields for JSON String. * @param ip * @return */ - public abstract String infoLookupToJson(String ip); - - - - + public abstract String infoLookupToJSONString(String ip); + /** + * This method to return all fields for JSON Object. + * @param ip + * @return + */ + public abstract Object infoLookupToJSON(String ip); + /** + * This method returns all fields for the MMDB Response Object.. + * @param ip + * @return + */ + public abstract Object infoLookup(String ip); } diff --git a/src/main/java/com/geedgenetworks/utils/AsnLookup.java b/src/main/java/com/geedgenetworks/utils/AsnLookup.java new file mode 100644 index 0000000..bf7bba7 --- /dev/null +++ b/src/main/java/com/geedgenetworks/utils/AsnLookup.java @@ -0,0 +1,428 @@ +package com.geedgenetworks.utils; + +import com.google.common.base.Joiner; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.ObjectArrays; +import com.maxmind.db.CHMCache; +import com.geedgenetworks.domain.LocationResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.URL; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static com.geedgenetworks.utils.AbstractIpLookup.UNKNOWN; + +/** + * @ClassName AsnLookup + * @Description IP查询AS号 + * @Author 中电积至有限公司 darnell + * @Date 2020-05-09 13:45 + * @Version 1.0.3 + **/ +public class AsnLookup { + + public enum Type { + PRIVATE, PUBLIC + } + protected static final String SEPARATOR = ","; + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + public final static String DEFAULT_DATABASE_PATH = "dat"; + private final static String DEFAULT_DB_ASN_PUBLIC = "asn.mmdb"; + private final static String DEFAULT_DB_ASN_PUBLIC_V4 = "asn_v4.mmdb"; + private final static String DEFAULT_DB_ASN_PUBLIC_V6 = "asn_v6.mmdb"; + private final static String DEFAULT_DB_ASN_PRIVATE = "asn_private.mmdb"; + private final static String DEFAULT_DB_ASN_PRIVATE_V4 = "asn_private_v4.mmdb"; + private final static String DEFAULT_DB_ASN_PRIVATE_V6 = "asn_private_v6.mmdb"; + private final Map<String, List<GalaxyDataBaseReader>> availableDBReaders = Maps.newHashMap(); + private static GalaxyDataBaseReader publicDatabaseReader; + private static GalaxyDataBaseReader publicV4DatabaseReader; + private static GalaxyDataBaseReader publicV6DatabaseReader; + + private static GalaxyDataBaseReader privateDatabaseReader; + private static GalaxyDataBaseReader privateV4DatabaseReader; + private static GalaxyDataBaseReader privateV6DatabaseReader; + + synchronized void init(Builder builder) { + initializeDatabaseReaders(builder); + initializeAvailableDatabaseReaders(); + } + private void initializeDatabaseReaders(Builder builder) { + try { + if (builder.isDefaultDB) { + //Initialize IP MMDBs using default paths + File[] publicDatabaseFiles = buildMMDBFilesUseWorkDirectory(DEFAULT_DB_ASN_PUBLIC, DEFAULT_DB_ASN_PUBLIC_V4, DEFAULT_DB_ASN_PUBLIC_V6); + File[] privateDatabaseFiles = buildMMDBFilesUseWorkDirectory(DEFAULT_DB_ASN_PRIVATE, DEFAULT_DB_ASN_PRIVATE_V4, DEFAULT_DB_ASN_PRIVATE_V6); + updateFileIfNotExists(publicDatabaseFiles); + updateFileIfNotExists(privateDatabaseFiles); + publicDatabaseReader = constructDatabaseReader(publicDatabaseFiles[0]); + publicV4DatabaseReader = constructDatabaseReader(publicDatabaseFiles[1]); + publicV6DatabaseReader = constructDatabaseReader(publicDatabaseFiles[2]); + privateDatabaseReader = constructDatabaseReader(privateDatabaseFiles[0]); + privateV4DatabaseReader = constructDatabaseReader(privateDatabaseFiles[1]); + privateV6DatabaseReader = constructDatabaseReader(privateDatabaseFiles[2]); + } else { + //Initialize IP MMDBs using custom paths/streams + publicDatabaseReader = constructDatabaseReader(builder.publicAsnDatabaseFile, builder.publicAsnDatabaseStream); + publicV4DatabaseReader = constructDatabaseReader(builder.publicAsnV4DatabaseFile, builder.publicAsnV4DatabaseStream); + publicV6DatabaseReader = constructDatabaseReader(builder.publicAsnV6DatabaseFile, builder.publicAsnV6DatabaseStream); + privateDatabaseReader = constructDatabaseReader(builder.privateAsnDatabaseFile, builder.privateAsnDatabaseStream); + privateV4DatabaseReader = constructDatabaseReader(builder.privateAsnV4DatabaseFile, builder.privateAsnV4DatabaseStream); + privateV6DatabaseReader = constructDatabaseReader(builder.privateAsnV6DatabaseFile, builder.privateAsnV6DatabaseStream); + } + } catch (Exception e) { + logger.error("Unsupported GeoIP2 *.mmdb database: expected either File path or Stream. " + e); + } + } + + private File[] buildMMDBFilesUseWorkDirectory(String... files) { + File[] dbFiles = ObjectArrays.newArray(File.class, files.length); + for (int i = 0; i < files.length; i++) { + dbFiles[i] = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator + files[i]); + } + return dbFiles; + } + + private void updateFileIfNotExists(File[] files) { + for (File file : files) { + if (!file.exists()) { + URL url = IpLookupV2.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + file.getName()); + if (url != null) { + file = new File(url.getPath()); + } + } + } + + } + + + private GalaxyDataBaseReader constructDatabaseReader(String filePath, InputStream stream) { + try { + if (StringUtil.isNotBlank(filePath) && new File(filePath).exists()) { + return constructDatabaseReader(new File(filePath)); + } else if (stream != null) { + return constructDatabaseReader(stream); + } else { + return null; + } + } catch (IOException ie) { + logger.error("Unsupported GeoIP2 *.mmdb database: expected either File path or Stream. " + ie); + } + throw new UnsupportedOperationException("Unsupported GeoIP2 *.mmdb database: expected either File path or Stream. " ); + } + + private GalaxyDataBaseReader constructDatabaseReader(File file) throws IOException { + return file.exists() ? new GalaxyDataBaseReader.Builder(file).withCache(new CHMCache()).build() : null; + } + + private GalaxyDataBaseReader constructDatabaseReader(InputStream stream) throws IOException { + return stream != null ? new GalaxyDataBaseReader.Builder(stream).withCache(new CHMCache()).build() : null; + } + + private void initializeAvailableDatabaseReaders() { + List<GalaxyDataBaseReader> ipv4DbReaders = Lists.newArrayList(); + List<GalaxyDataBaseReader> ipv6DbReaders = Lists.newArrayList(); + + addIfNotEmpty(ipv4DbReaders, privateV4DatabaseReader); + addIfNotEmpty(ipv6DbReaders, privateV6DatabaseReader); + //Add Private IP library + addIfNotEmpty(ipv4DbReaders, privateDatabaseReader); + addIfNotEmpty(ipv6DbReaders, privateDatabaseReader); + + addIfNotEmpty(ipv4DbReaders, publicV4DatabaseReader); + addIfNotEmpty(ipv6DbReaders, publicV6DatabaseReader); + //Add Public IP library + addIfNotEmpty(ipv4DbReaders, publicDatabaseReader); + addIfNotEmpty(ipv6DbReaders, publicDatabaseReader); + + availableDBReaders.put(AbstractIpLookup.IpVersion.IPv4.name(), ipv4DbReaders); + availableDBReaders.put(AbstractIpLookup.IpVersion.IPv6.name(), ipv6DbReaders); + } + + private void addIfNotEmpty(List<GalaxyDataBaseReader> dbReaders, GalaxyDataBaseReader dbReader) { + if (StringUtil.isNotEmpty(dbReader)) { + dbReaders.add(dbReader); + } + + } + + + private AsnLookup(AsnLookup.Builder builder) { + init(builder); + } + private GalaxyDataBaseReader buildDataReader(File database) throws IOException { + if (database.exists()) { + return new GalaxyDataBaseReader.Builder(database).withCache(new CHMCache()).build(); + } else { + return null; + } + } + + private GalaxyDataBaseReader buildDataReader(InputStream stream) throws IOException { + if (stream != null) { + return new GalaxyDataBaseReader.Builder(stream).withCache(new CHMCache()).build(); + } else { + return null; + } + } + + /** + * 加载mmdb数据字典文件,内部生成mmdb动态库。 + * + * 1.默认记载ASN库,使用方式如下: + * AsnLookup asnLookup = new AsnLookup.Builder(true).build(); + * 自动加载应用dat目录下的库文件,命名为:asn_v4.asn_v6.mmdb库。 + * + * 2.手动加载IP库,使用方式如下: + * <p> + * AsnLookup asnLookup = new AsnLookup.Builder(false).loadDataFileV4("D:\\galaxy-tool\\dat\\asn_v4_201901.mmdb"). + * loadDataFileV6("D:\\galaxy-tool\\dat\\asn_v6_201901.mmdb").build(); + * + * </p> + */ + public static final class Builder { + String publicAsnDatabaseFile; + String publicAsnV4DatabaseFile; + String publicAsnV6DatabaseFile; + + InputStream publicAsnDatabaseStream; + InputStream publicAsnV4DatabaseStream; + InputStream publicAsnV6DatabaseStream; + + String privateAsnDatabaseFile; + String privateAsnV4DatabaseFile; + String privateAsnV6DatabaseFile; + + InputStream privateAsnDatabaseStream; + InputStream privateAsnV4DatabaseStream; + InputStream privateAsnV6DatabaseStream; + boolean isDefaultDB; + + + /** + * + * @param isDefaultDB <code>false</code> 手动指定IP库路径 <code>true</code> 使用默认路径 + */ + public Builder(boolean isDefaultDB) { + this.isDefaultDB = isDefaultDB; + } + + /** + * + * @param publicAsnDatabaseFile 加载ASN database文件,不区分IPv4/6 + * @return + */ + public Builder loadDataFile(String publicAsnDatabaseFile) { + this.publicAsnDatabaseFile = publicAsnDatabaseFile; + return this; + } + + /** + * + * @param publicAsnDatabaseStream 加载ASN database流,不区分IPv4/6 + * @return + */ + public Builder loadDataFile(InputStream publicAsnDatabaseStream) { + this.publicAsnDatabaseStream = publicAsnDatabaseStream; + return this; + } + + /** + * + * @param publicAsnV4DatabaseFile 加载ASN IPv4 database文件 + * @return + */ + public Builder loadDataFileV4(String publicAsnV4DatabaseFile) { + this.publicAsnV4DatabaseFile = publicAsnV4DatabaseFile; + return this; + } + + /** + * + * @param publicAsnV4DatabaseStream 加载ASN IPv4 database流 + * @return + */ + public Builder loadDataFileV4(InputStream publicAsnV4DatabaseStream) { + this.publicAsnV4DatabaseStream = publicAsnV4DatabaseStream; + return this; + } + + + + /** + * + * @param publicAsnV6DatabaseFile 加载ASN IPv6 database文件 + * @return + */ + public Builder loadDataFileV6(String publicAsnV6DatabaseFile) { + this.publicAsnV6DatabaseFile = publicAsnV6DatabaseFile; + return this; + } + + /** + * + * @param publicAsnV6DatabaseStream 加载ASN IPv6 database流 + * @return + */ + public Builder loadDataFileV6(InputStream publicAsnV6DatabaseStream) { + this.publicAsnV6DatabaseStream = publicAsnV6DatabaseStream; + return this; + } + + /** + * + * @param privateAsnDatabaseFile 加载ASN database文件,不区分IPv4/6 + * @return + */ + public Builder loadDataFilePrivate(String privateAsnDatabaseFile) { + this.privateAsnDatabaseFile = privateAsnDatabaseFile; + return this; + } + + /** + * + * @param privateAsnDatabaseStream 加载ASN database流,不区分IPv4/6 + * @return + */ + public Builder loadDataFilePrivate(InputStream privateAsnDatabaseStream) { + this.privateAsnDatabaseStream = privateAsnDatabaseStream; + return this; + } + + + + /** + * + * @param privateAsnV4DatabaseFile 加载ASN IPv4 database文件 + * @return + */ + public Builder loadDataFilePrivateV4(String privateAsnV4DatabaseFile) { + this.privateAsnV4DatabaseFile = privateAsnV4DatabaseFile; + return this; + } + + /** + * + * @param privateAsnV4DatabaseStream 加载ASN IPv4 database流 + * @return + */ + public Builder loadDataFilePrivateV4(InputStream privateAsnV4DatabaseStream) { + this.privateAsnV4DatabaseStream = privateAsnV4DatabaseStream; + return this; + } + + /** + * + * @param privateAsnV6DatabaseFile 加载ASN IPv6 database文件 + * @return + */ + public Builder loadDataFilePrivateV6(String privateAsnV6DatabaseFile) { + this.privateAsnV6DatabaseFile = privateAsnV6DatabaseFile; + return this; + } + /** + * + * @param privateAsnV6DatabaseStream 加载ASN IPv6 database流 + * @return + */ + public Builder loadDataFilePrivateV6(InputStream privateAsnV6DatabaseStream) { + this.privateAsnV6DatabaseStream = privateAsnV6DatabaseStream; + return this; + } + + /** + * 构建对象 + * @return + * @throws IOException + */ + public AsnLookup build() { + return new AsnLookup(this); + } + + + } + + + public String asnLookup(String ip) { + + LocationResponse response = getResponse(ip); + + if (StringUtil.isEmpty(response) || response.isPrivateIP()) { + return UNKNOWN; + } + + return StringUtil.setDefaultIfEmpty(response.getAsn(), UNKNOWN).toString() ; + + + } + + public String asnLookupOrganization(String ip) { + LocationResponse response = getResponse(ip); + if (StringUtil.isEmpty(response) || response.isPrivateIP()) { + return UNKNOWN; + } + return response.getOrganization(); + } + + public String asnLookupInfo(String ip) { + LocationResponse response = getResponse(ip); + if (StringUtil.isEmpty(response) || response.isPrivateIP()) { + return UNKNOWN; + } + return Joiner.on(SEPARATOR).useForNull("").join(response.getCountryCode(), response.getOrganization()); + + } + + + + + public String asnLookupDetail(String ip) { + LocationResponse response = getResponse(ip); + + if (StringUtil.isEmpty(response) || response.isPrivateIP()) { + return UNKNOWN; + } + return Joiner.on(SEPARATOR).useForNull("").join(response.getAsn(), response.getCountryCode(), response.getOrganization()); + } + + + private LocationResponse getResponse(String ip) { + try { + ip = Optional.ofNullable(ip).orElse("").trim(); + InetAddress ipAddress = InetAddress.getByName(ip); + if (ipAddress instanceof Inet4Address) { + //Iterate through each 'dbReader' and execute them in the following order: private v4 -> private -> public v4 -> public. + for (GalaxyDataBaseReader reader : availableDBReaders.get(AbstractIpLookup.IpVersion.IPv4.name())) { + LocationResponse response = reader.locationV2(ipAddress); + if(StringUtil.isNotEmpty(response)) { + return response; + } + } + } else if (ipAddress instanceof Inet6Address) { + //Iterate through each 'dbReader' and execute them in the following order: private v6 -> private -> public v6 -> public. + for(GalaxyDataBaseReader reader : availableDBReaders.get(AbstractIpLookup.IpVersion.IPv6.name())) { + LocationResponse response = reader.locationV2(ipAddress); + if(StringUtil.isNotEmpty(response)) { + return response; + } + } + } else { + throw new IllegalArgumentException("IP address <" + ip +">. "); + } + return null; + } catch (Exception e) { + throw new IllegalArgumentException("IP address <" + ip +">. " + e); + } + + + } +} diff --git a/src/main/java/com/zdjizhi/utils/CIDRUtils.java b/src/main/java/com/geedgenetworks/utils/CIDRUtils.java index 2fbd939..70ef217 100644 --- a/src/main/java/com/zdjizhi/utils/CIDRUtils.java +++ b/src/main/java/com/geedgenetworks/utils/CIDRUtils.java @@ -1,4 +1,4 @@ -package com.zdjizhi.utils; +package com.geedgenetworks.utils; import java.math.BigInteger; import java.net.InetAddress; diff --git a/src/main/java/com/zdjizhi/utils/CommonUtil.java b/src/main/java/com/geedgenetworks/utils/CommonUtil.java index 987678c..49391db 100644 --- a/src/main/java/com/zdjizhi/utils/CommonUtil.java +++ b/src/main/java/com/geedgenetworks/utils/CommonUtil.java @@ -1,6 +1,5 @@ -package com.zdjizhi.utils; +package com.geedgenetworks.utils; -import java.io.File; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; @@ -9,9 +8,6 @@ import java.util.Iterator; import java.util.List; import java.util.Set; - - - /** * * <p>项目开发中常用公共类.通过类方法进行访问.</p> diff --git a/src/main/java/com/zdjizhi/utils/CookieUtil.java b/src/main/java/com/geedgenetworks/utils/CookieUtil.java index da49a78..6707a6b 100644 --- a/src/main/java/com/zdjizhi/utils/CookieUtil.java +++ b/src/main/java/com/geedgenetworks/utils/CookieUtil.java @@ -4,7 +4,7 @@ * Copyright 2010 NIS, Inc. All rights reserved. * */ -package com.zdjizhi.utils; +package com.geedgenetworks.utils; import javax.servlet.ServletRequest; import javax.servlet.http.Cookie; diff --git a/src/main/java/com/zdjizhi/utils/DateUtils.java b/src/main/java/com/geedgenetworks/utils/DateUtils.java index 22a49db..a8b8321 100644 --- a/src/main/java/com/zdjizhi/utils/DateUtils.java +++ b/src/main/java/com/geedgenetworks/utils/DateUtils.java @@ -1,6 +1,5 @@ -package com.zdjizhi.utils; +package com.geedgenetworks.utils; -import com.google.common.base.Stopwatch; import com.google.common.collect.Lists; import org.joda.time.*; import org.joda.time.format.DateTimeFormat; diff --git a/src/main/java/com/zdjizhi/utils/Encodes.java b/src/main/java/com/geedgenetworks/utils/Encodes.java index 92dd3cf..87aead2 100644 --- a/src/main/java/com/zdjizhi/utils/Encodes.java +++ b/src/main/java/com/geedgenetworks/utils/Encodes.java @@ -1,9 +1,9 @@ /** * Copyright (c) 2005-2012 springside.org.cn */ -package com.zdjizhi.utils; +package com.geedgenetworks.utils; -import com.zdjizhi.exception.Exceptions; +import com.geedgenetworks.exception.Exceptions; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Hex; diff --git a/src/main/java/com/zdjizhi/utils/FormatUtils.java b/src/main/java/com/geedgenetworks/utils/FormatUtils.java index 1f55840..35d1c8a 100644 --- a/src/main/java/com/zdjizhi/utils/FormatUtils.java +++ b/src/main/java/com/geedgenetworks/utils/FormatUtils.java @@ -1,15 +1,10 @@ -package com.zdjizhi.utils; +package com.geedgenetworks.utils; -import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Base64; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; import java.util.Set; -import java.util.StringTokenizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/com/zdjizhi/utils/GalaxyDataBaseReader.java b/src/main/java/com/geedgenetworks/utils/GalaxyDataBaseReader.java index e9b5f1d..47f16fb 100644 --- a/src/main/java/com/zdjizhi/utils/GalaxyDataBaseReader.java +++ b/src/main/java/com/geedgenetworks/utils/GalaxyDataBaseReader.java @@ -1,16 +1,9 @@ -package com.zdjizhi.utils;/** - * Created by dell on 2018-10-8. - */ +package com.geedgenetworks.utils; -import com.fasterxml.jackson.databind.*; -import com.fasterxml.jackson.databind.node.ObjectNode; import com.maxmind.db.*; -import com.maxmind.geoip2.exception.AddressNotFoundException; -import com.maxmind.geoip2.exception.GeoIp2Exception; -import com.zdjizhi.domain.LocationResponse; -import com.zdjizhi.domain.JsonInjector; -import com.zdjizhi.domain.LocationResponseV2; - +import com.geedgenetworks.domain.LocationResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -26,31 +19,17 @@ import java.util.List; * @Version 1.0 **/ public class GalaxyDataBaseReader { - + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); private final Reader reader; - - private final ObjectMapper om; - - private final List<String> locales; - private GalaxyDataBaseReader(Builder builder) throws IOException { if (builder.stream != null) { this.reader = new Reader(builder.stream, builder.cache); } else if (builder.database != null) { this.reader = new Reader(builder.database, builder.mode, builder.cache); } else { - // This should never happen. If it does, review the Builder class - // constructors for errors. throw new IllegalArgumentException( "Unsupported Builder configuration: expected either File or URL"); } - this.om = new ObjectMapper(); - this.om.configure(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS, false); - this.om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, - false); - this.om.configure( - DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true); - this.locales = builder.locales; } /** @@ -135,63 +114,15 @@ public class GalaxyDataBaseReader { } } + public LocationResponse locationV2(InetAddress ipAddress) throws IOException { + return reader.get(ipAddress, LocationResponse.class); - /** - * @param ipAddress IPv4 or IPv6 address to lookup. - * @return A <T> object with the data for the IP address - * @throws IOException if there is an error opening or reading from the file. - * @throws AddressNotFoundException if the IP address is not in our database - */ - private <T> T get(InetAddress ipAddress, Class<T> cls, - String type) throws IOException, AddressNotFoundException { - - String databaseType = this.getMetadata().getDatabaseType(); - if (!databaseType.contains(type)) { - String caller = Thread.currentThread().getStackTrace()[2] - .getMethodName(); - throw new UnsupportedOperationException( - "Invalid attempt to open a " + databaseType - + " database using the " + caller + " method"); - } - - ObjectNode node = jsonNodeToObjectNode(reader.get(ipAddress)); - - // We throw the same exception as the web service when an IP is not in - // the database - if (node == null) { - throw new AddressNotFoundException("The address " - + ipAddress.getHostAddress() + " is not in the database."); - } - - InjectableValues inject = new JsonInjector(locales, ipAddress.getHostAddress()); - return this.om.reader(inject).treeToValue(node, cls); } - private ObjectNode jsonNodeToObjectNode(JsonNode node) - throws InvalidDatabaseException { - if (node == null || node instanceof ObjectNode) { - return (ObjectNode) node; - } - throw new InvalidDatabaseException( - "Unexpected data type returned. The GeoIP2 database may be corrupt."); - } - - - - public LocationResponse location(InetAddress ipAddress) throws IOException, GeoIp2Exception { - return this.get(ipAddress, LocationResponse.class, ""); - - } - - public LocationResponseV2 locationV2(InetAddress ipAddress) throws IOException, GeoIp2Exception { - return this.get(ipAddress, LocationResponseV2.class, ""); - - } - - - public void close() throws IOException { - this.reader.close(); + if (this.reader != null) { + this.reader.close(); + } } diff --git a/src/main/java/com/zdjizhi/utils/IPUtil.java b/src/main/java/com/geedgenetworks/utils/IPUtil.java index 8f80fe5..5c33273 100644 --- a/src/main/java/com/zdjizhi/utils/IPUtil.java +++ b/src/main/java/com/geedgenetworks/utils/IPUtil.java @@ -1,13 +1,14 @@ -package com.zdjizhi.utils; +package com.geedgenetworks.utils; -import com.zdjizhi.domain.Nets; +import com.geedgenetworks.domain.Nets; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; import java.io.StringWriter; import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; @@ -161,8 +162,8 @@ public class IPUtil { try{ - long start = getIpHostDesimal(startIp); - long end = getIpHostDesimal(endIp); + long start = getIpHostDecimal(startIp); + long end = getIpHostDecimal(endIp); for (long i = start; i <= end; i++) { list.add(getIpHostString(String.valueOf(i))); @@ -299,6 +300,8 @@ public class IPUtil { } + + /** * 将IPv4形式掩码形式转为,整型掩码位数 * @param netmarks @@ -555,7 +558,6 @@ public class IPUtil { return str; } - /** * @deprecated * <p> Use {@link IPUtil#isIPv4Address(String)} instead. @@ -573,10 +575,9 @@ public class IPUtil { */ public static boolean isIPAddress(String ip) { return isIPv4Address(ip) || isIPv6Address(ip); - } - /** + /** * * <p>验证Ip是否符合规则.给定字符串,判断是否符合正则验证的ip格式.</p> * <pre>例子说明:</pre> @@ -737,7 +738,7 @@ public class IPUtil { * @return <code>-1</code> 验证ip不合法,<code>ip</code> 计算ip返回长整型. */ - public static long getIpHostDesimal(String ip) { + public static long getIpHostDecimal(String ip) { long ip10 = 0; if (!isIP(ip)) { return -1; // ip 不合法 @@ -772,7 +773,7 @@ public class IPUtil { if (isIP(ip)) { String endIp = getEndIP(ip, mask); - num = getIpHostDesimal(endIp) - getIpHostDesimal(ip) +1; + num = getIpHostDecimal(endIp) - getIpHostDecimal(ip) +1; } else { throw new IllegalArgumentException("所传入的IP地址不符合IPV4规范"); diff --git a/src/main/java/com/geedgenetworks/utils/IpLookupV2.java b/src/main/java/com/geedgenetworks/utils/IpLookupV2.java new file mode 100644 index 0000000..f63cfbb --- /dev/null +++ b/src/main/java/com/geedgenetworks/utils/IpLookupV2.java @@ -0,0 +1,760 @@ +package com.geedgenetworks.utils; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.alibaba.fastjson2.JSONWriter; +import com.google.common.base.Joiner; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.ObjectArrays; +import com.maxmind.db.CHMCache; +import com.geedgenetworks.domain.LocationResponse; + + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.URL; +import java.util.*; + + +/** + * @ClassName IpLookupV2 + * @Description The IPLookupv2 class enriches information with geographic fields, given an ip address. It works with User-defined Maxmind's GeoIP binary database. + * @Author darnell + * @Date 2023-08-22 20:00 Geedge Networks + * @Version 1.2 + **/ +public final class IpLookupV2 extends AbstractIpLookup { + private AsnLookup asnLookup; + private final Map<String, List<GalaxyDataBaseReader>> availableDBReaders = Maps.newHashMap(); + + private GalaxyDataBaseReader publicDatabaseReader; + private GalaxyDataBaseReader publicV4DatabaseReader;; + private GalaxyDataBaseReader publicV6DatabaseReader;; + private GalaxyDataBaseReader privateDatabaseReader;; + private GalaxyDataBaseReader privateV4DatabaseReader;; + private GalaxyDataBaseReader privateV6DatabaseReader;; + + private IpLookupV2(Builder builder) { + init(builder); + } + + // Initialization of variables + synchronized void init(Builder builder) { + initializeDatabaseReaders(builder); + initializeAsnLookup(builder); + initializeAvailableDatabaseReaders(); + } + + private void initializeDatabaseReaders(Builder builder) { + try { + if (builder.isDefaultDB) { + //Initialize IP MMDBs using default paths + File[] publicDatabaseFiles = buildMMDBFilesUseWorkDirectory(DEFAULT_DB_IP_PUBLIC, DEFAULT_DB_IP_PUBLIC_V4, DEFAULT_DB_IP_PUBLIC_V6); + File[] privateDatabaseFiles = buildMMDBFilesUseWorkDirectory(DEFAULT_DB_IP_PRIVATE, DEFAULT_DB_IP_PRIVATE_V4, DEFAULT_DB_IP_PRIVATE_V6); + updateFileIfNotExists(publicDatabaseFiles); + updateFileIfNotExists(privateDatabaseFiles); + publicDatabaseReader = constructDatabaseReader(publicDatabaseFiles[0]); + publicV4DatabaseReader = constructDatabaseReader(publicDatabaseFiles[1]); + publicV6DatabaseReader = constructDatabaseReader(publicDatabaseFiles[2]); + privateDatabaseReader = constructDatabaseReader(privateDatabaseFiles[0]); + privateV4DatabaseReader = constructDatabaseReader(privateDatabaseFiles[1]); + privateV6DatabaseReader = constructDatabaseReader(privateDatabaseFiles[2]); + } else { + //Initialize IP MMDBs using custom paths/streams + publicDatabaseReader = constructDatabaseReader(builder.publicDatabaseFile, builder.publicDatabaseStream); + publicV4DatabaseReader = constructDatabaseReader(builder.publicV4DatabaseFile, builder.publicV4DatabaseStream); + publicV6DatabaseReader = constructDatabaseReader(builder.publicV6DatabaseFile, builder.publicV6DatabaseStream); + privateDatabaseReader = constructDatabaseReader(builder.privateDatabaseFile, builder.privateDatabaseStream); + privateV4DatabaseReader = constructDatabaseReader(builder.privateV4DatabaseFile, builder.privateV4DatabaseStream); + privateV6DatabaseReader = constructDatabaseReader(builder.privateV6DatabaseFile, builder.privateV6DatabaseStream); + } + } catch (Exception e) { + logger.error("Unsupported GeoIP2 *.mmdb database: expected either File path or Stream. " + e); + } + } + private void initializeAsnLookup(Builder builder) { + if (builder.isDefaultDB) { + asnLookup = new AsnLookup.Builder(true).build(); + } else { + // Initialize ASN MMDBs using custom paths/streams + asnLookup = new AsnLookup.Builder(false) + .loadDataFile(builder.publicAsnDatabaseFile) + .loadDataFile(builder.publicAsnDatabaseStream) + .loadDataFileV4(builder.publicAsnV4DatabaseFile) + .loadDataFileV4(builder.publicAsnV4DatabaseStream) + .loadDataFileV6(builder.publicAsnV6DatabaseFile) + .loadDataFileV6(builder.publicAsnV6DatabaseStream) + .loadDataFilePrivate(builder.privateAsnDatabaseFile) + .loadDataFilePrivate(builder.privateAsnDatabaseStream) + .loadDataFilePrivateV4(builder.privateAsnV4DatabaseFile) + .loadDataFilePrivateV4(builder.privateAsnV4DatabaseStream) + .loadDataFilePrivateV6(builder.privateAsnV6DatabaseFile) + .loadDataFilePrivateV6(builder.privateAsnV6DatabaseStream) + .build(); + } + + } + + private void initializeAvailableDatabaseReaders() { + List<GalaxyDataBaseReader> ipv4DbReaders = Lists.newArrayList(); + List<GalaxyDataBaseReader> ipv6DbReaders = Lists.newArrayList(); + + addIfNotEmpty(ipv4DbReaders, privateV4DatabaseReader); + addIfNotEmpty(ipv6DbReaders, privateV6DatabaseReader); + //Add Private IP library + addIfNotEmpty(ipv4DbReaders, privateDatabaseReader); + addIfNotEmpty(ipv6DbReaders, privateDatabaseReader); + + addIfNotEmpty(ipv4DbReaders, publicV4DatabaseReader); + addIfNotEmpty(ipv6DbReaders, publicV6DatabaseReader); + //Add Public IP library + addIfNotEmpty(ipv4DbReaders, publicDatabaseReader); + addIfNotEmpty(ipv6DbReaders, publicDatabaseReader); + + availableDBReaders.put(IpVersion.IPv4.name(), ipv4DbReaders); + availableDBReaders.put(IpVersion.IPv6.name(), ipv6DbReaders); + } + + + private void addIfNotEmpty(List<GalaxyDataBaseReader> dbReaders, GalaxyDataBaseReader dbReader) { + if (StringUtil.isNotEmpty(dbReader)) { + dbReaders.add(dbReader); + } + + } + + private File[] buildMMDBFilesUseWorkDirectory(String... files) { + File[] dbFiles = ObjectArrays.newArray(File.class, files.length); + for (int i = 0; i < files.length; i++) { + dbFiles[i] = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator + files[i]); + } + return dbFiles; + } + + private void updateFileIfNotExists(File[] files) { + for (File file : files) { + if (!file.exists()) { + URL url = IpLookupV2.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + file.getName()); + if (url != null) { + file = new File(url.getPath()); + } + } + } + + } + + + private GalaxyDataBaseReader constructDatabaseReader(String filePath, InputStream stream) { + try { + if (StringUtil.isNotBlank(filePath) && new File(filePath).exists()) { + return constructDatabaseReader(new File(filePath)); + } else if (stream != null) { + return constructDatabaseReader(stream); + } else { + return null; + } + } catch (IOException ie) { + logger.error("Unsupported GeoIP2 *.mmdb database: expected either File path or Stream. " + ie); + } + throw new UnsupportedOperationException("Unsupported GeoIP2 *.mmdb database: expected either File path or Stream. " ); + } + + private GalaxyDataBaseReader constructDatabaseReader(File file) throws IOException { + return file.exists() ? new GalaxyDataBaseReader.Builder(file).withCache(new CHMCache()).build() : null; + } + + private GalaxyDataBaseReader constructDatabaseReader(InputStream stream) throws IOException { + return stream != null ? new GalaxyDataBaseReader.Builder(stream).withCache(new CHMCache()).build() : null; + } + + + + /** + * 加载mmdb数据字典文件,内部生成mmdb动态库。 + * + * 1.默认记载IP库,使用方式如下: + * IpLookup ipLookup = new IpLookup.Builder(true).build(); + * 自动加载应用dat目录下的库文件,命名为:all_ip_info_v4.mmdb与all_ip_info_v6.mmdb库。 + * + * 2.手动加载IP库,使用方式如下: + * <p> + * IpLookup ipLookup = new IpLookup.Builder(false).loadDataFileV4("D:\\galaxy-tool\\dat\\ip.mmdb"). + * loadDataFileV6("D:\\galaxy-tool\\dat\\all_ip_info_v6.mmdb").build(); + * + * </p> + */ + public static final class Builder { + String publicDatabaseFile; + String publicV4DatabaseFile; + String publicV6DatabaseFile; + + InputStream publicDatabaseStream; + InputStream publicV4DatabaseStream; + InputStream publicV6DatabaseStream; + + String privateDatabaseFile; + String privateV4DatabaseFile; + String privateV6DatabaseFile; + + InputStream privateDatabaseStream; + InputStream privateV4DatabaseStream; + InputStream privateV6DatabaseStream; + + String publicAsnDatabaseFile; + String publicAsnV4DatabaseFile; + String publicAsnV6DatabaseFile; + + InputStream publicAsnDatabaseStream; + InputStream publicAsnV4DatabaseStream; + InputStream publicAsnV6DatabaseStream; + + String privateAsnDatabaseFile; + String privateAsnV4DatabaseFile; + String privateAsnV6DatabaseFile; + + InputStream privateAsnDatabaseStream; + InputStream privateAsnV4DatabaseStream; + InputStream privateAsnV6DatabaseStream; + + boolean isDefaultDB; + + /** + * + * @param isDefaultDB <code>false</code> 手动指定IP库路径 <code>true</code> 使用默认路径 + * @return Builder + */ + public Builder(boolean isDefaultDB) { + this.isDefaultDB = isDefaultDB; + } + + /** + * @param databaseFile 加载GeoIP2 database 文件,不区分IPv4/6 + * @return + */ + public Builder loadDataFile(String databaseFile) { + this.publicDatabaseFile = databaseFile; + return this; + } + + /** + * @param databaseStream 加载GeoIP2流,不区分IPv4/6 + * @return + */ + public Builder loadDataFile(InputStream databaseStream) { + this.publicDatabaseStream = databaseStream; + return this; + } + + /** + * + * @param databaseFile 加载第三方内置GeoIP2 IPv4 database 文件 + * @return + */ + public Builder loadDataFileV4(String databaseFile) { + this.publicV4DatabaseFile = databaseFile; + return this; + } + + /** + * @param databaseStream 加载第三方内置GeoIP2 IPv4流 + * @return + */ + public Builder loadDataFileV4(InputStream databaseStream) { + this.publicV4DatabaseStream = databaseStream; + return this; + } + + + /** + * + * @param databaseFile 加载第三方内置GeoIP2 IPv6 database 文件 + * @return + */ + public Builder loadDataFileV6(String databaseFile) { + this.publicV6DatabaseFile = databaseFile; + return this; + } + + /** + * @param databaseStream 加载第三方内置GeoIP2 IPv6流 + * @return + */ + public Builder loadDataFileV6(InputStream databaseStream) { + this.publicV6DatabaseStream = databaseStream; + return this; + } + + + /** + * + * @param databaseFile 加载自定义GeoIP2 database 文件,不区分IPv4/6 + * @return + */ + public Builder loadDataFilePrivate(String databaseFile) { + this.privateDatabaseFile = databaseFile; + return this; + } + + /** + * + * @param databaseStream 加载自定义GeoIP2 流文件,不区分IPv4/6 + * @return + */ + public Builder loadDataFilePrivate(InputStream databaseStream) { + this.privateDatabaseStream = databaseStream; + return this; + } + + /** + * + * @param databaseFile 加载自定义GeoIP2 IPv4 database 文件 + * @return + */ + public Builder loadDataFilePrivateV4(String databaseFile) { + this.privateV4DatabaseFile = databaseFile; + return this; + } + + /** + * + * @param databaseStream 加载自定义GeoIP2 IPv4 流 + * @return + */ + public Builder loadDataFilePrivateV4(InputStream databaseStream) { + this.privateV4DatabaseStream = databaseStream; + return this; + } + + /** + * + * @param databaseFile 加载自定义GeoIP2 IPv6 database 文件 + * @return + */ + public Builder loadDataFilePrivateV6(String databaseFile) { + this.privateV6DatabaseFile = databaseFile; + return this; + } + + /** + * + * @param databaseStream 加载自定义GeoIP2 IPv6流 + * @return + */ + public Builder loadDataFilePrivateV6(InputStream databaseStream) { + this.privateV6DatabaseStream = databaseStream; + return this; + } + + + + /** + * + * @param asnDatabaseFile 加载ASN database文件,不区分IPv4/6 + * @return + */ + public Builder loadAsnDataFile(String asnDatabaseFile) { + this.publicAsnDatabaseFile = asnDatabaseFile; + return this; + } + + /** + * + * @param asnDatabaseStream 加载ASN database流,不区分IPv4/6 + * @return + */ + public Builder loadAsnDataFile(InputStream asnDatabaseStream) { + this.publicAsnDatabaseStream = asnDatabaseStream; + return this; + } + + + /** + * + * @param asnDatabaseFile 加载ASN IPv4 database文件 + * @return + */ + public Builder loadAsnDataFileV4(String asnDatabaseFile) { + this.publicAsnV4DatabaseFile = asnDatabaseFile; + return this; + } + + /** + * + * @param asnDatabaseStream 加载ASN IPv4 database流 + * @return + */ + public Builder loadAsnDataFileV4(InputStream asnDatabaseStream) { + this.publicAsnV4DatabaseStream = asnDatabaseStream; + return this; + } + + + /** + * + * @param asnDatabaseFile 加载ASN IPv6 database文件 + * @return + */ + public Builder loadAsnDataFileV6(String asnDatabaseFile) { + this.publicAsnV6DatabaseFile = asnDatabaseFile; + return this; + } + + /** + * + * @param asnDatabaseStream 加载ASN IPv6 database流 + * @return + */ + public Builder loadAsnDataFileV6(InputStream asnDatabaseStream) { + this.publicAsnV6DatabaseStream = asnDatabaseStream; + return this; + } + + + /** + * + * @param asnDatabaseFile 加载ASN database文件,不区分IPv4/6 + * @return + */ + public Builder loadAsnDataFilePrivate(String asnDatabaseFile) { + this.privateAsnDatabaseFile = asnDatabaseFile; + return this; + } + + /** + * + * @param asnDatabaseStream 加载ASN database流,不区分IPv4/6 + * @return + */ + public Builder loadAsnDataFilePrivate(InputStream asnDatabaseStream) { + this.privateAsnDatabaseStream = asnDatabaseStream; + return this; + } + + /** + * + * @param asnDatabaseFile 加载ASN IPv4 database文件 + * @return + */ + public Builder loadAsnDataFilePrivateV4(String asnDatabaseFile) { + this.privateAsnV4DatabaseFile = asnDatabaseFile; + return this; + } + + /** + * + * @param asnDatabaseStream 加载ASN IPv4 database流 + * @return + */ + public Builder loadAsnDataFilePrivateV4(InputStream asnDatabaseStream) { + this.privateAsnV4DatabaseStream = asnDatabaseStream; + return this; + } + + + /** + * + * @param asnDatabaseFile 加载ASN IPv6 database文件 + * @return Builder + */ + public Builder loadAsnDataFilePrivateV6(String asnDatabaseFile) { + this.privateAsnV6DatabaseFile = asnDatabaseFile; + return this; + } + + /** + * + * @param asnDatabaseStream 加载ASN IPv6 database流 + * @return + */ + public Builder loadAsnDataFilePrivateV6(InputStream asnDatabaseStream) { + this.privateAsnV6DatabaseStream = asnDatabaseStream; + return this; + } + + /** + * Build IPLookupV2 instance + * @return + * @throws IOException + */ + public IpLookupV2 build() { + return new IpLookupV2(this); + } + + } + + public Map<String, List<GalaxyDataBaseReader>> getDbReaders() { + return availableDBReaders; + } + + @Override + public String countryLookup(String ip) { + LocationResponse response = getResponse(ip); + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + if (response.isPrivateIP()) { + return PRIVATE_IP; + } + + return StringUtil.setDefaultIfEmpty(response.getCountry(), UNKNOWN).toString() ; + } + + @Override + public String cityLookupDetail(String ip) { + + LocationResponse response = getResponse(ip); + + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + if (response.isPrivateIP()) { + return PRIVATE_IP; + } + + return Joiner.on(LOCATION_SEPARATOR).useForNull("").join(response.getCountry(), + response.getSuperAdministrativeArea(), response.getAdministrativeArea()); + } + + @Override + public String administrativeAreaLookupDetail(String ip) { + LocationResponse response = getResponse(ip); + + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + if (response.isPrivateIP()) { + return PRIVATE_IP; + } + + return Joiner.on(LOCATION_SEPARATOR).useForNull("").join(response.getCountry(), + response.getSuperAdministrativeArea(), response.getAdministrativeArea(), + response.getSubAdministrativeArea()); + } + + @Override + public String locationLookupDetail(String ip) { + LocationResponse response = getResponse(ip); + + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + if (response.isPrivateIP()) { + return PRIVATE_IP; + } + + return Joiner.on(LOCATION_SEPARATOR).useForNull("").join(response.getCountry(), + response.getSuperAdministrativeArea(), response.getAdministrativeArea(), + response.getSubAdministrativeArea(), response.getLocality(), + response.getDependentLocality(), response.getDoubleDependentLocality()); + } + + @Override + public String cityLookup(String ip) { + LocationResponse response = getResponse(ip); + + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + if (response.isPrivateIP()) { + return PRIVATE_IP; + } + + return StringUtil.setDefaultIfEmpty(response.getAdministrativeArea(), UNKNOWN).toString() ; + + } + + @Override + public String countryCodeLookup(String ip) { + LocationResponse response = getResponse(ip); + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + return StringUtil.setDefaultIfEmpty(response.getCountryCode(), UNKNOWN).toString() ; + } + + @Override + public String regionCodeLookup(String ip) { + LocationResponse response = getResponse(ip); + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + return StringUtil.setDefaultIfEmpty(response.getAreaCode(), UNKNOWN).toString() ; + } + + @Override + public String infoLookupToCSV(String ip) { + LocationResponse response = getResponse(ip); + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + StringBuilder ipInfo = new StringBuilder(); + ipInfo.append( + Joiner.on(LOCATION_SEPARATOR).useForNull("").join(response.getCountry(), + response.getSuperAdministrativeArea(), response.getAdministrativeArea(), + response.getSubAdministrativeArea(), response.getLocality(), + response.getDependentLocality(), response.getDoubleDependentLocality())) + .append(OBJECT_SEPARATOR).append( + StringUtil.setDefaultIfEmpty(response.getIsp(), UNKNOWN).toString() + ).append(OBJECT_SEPARATOR).append( + StringUtil.setDefaultIfEmpty(response.getOrganization(), UNKNOWN).toString() + ).append(OBJECT_SEPARATOR).append( + asnLookup.asnLookup(ip) + ).append(OBJECT_SEPARATOR).append( + Joiner.on(LAT_LNG_SEPARATOR).skipNulls().join(response.getLatitude(), response.getLongitude()) + ); + return ipInfo.toString(); + } + + @Override + public String infoLookupToJSONString(String ip) { + LocationResponse response = getResponse(ip); + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + return JSON.toJSONString(response, JSONWriter.Feature.WriteNullStringAsEmpty); + } + + @Override + public Object infoLookupToJSON(String ip) { + LocationResponse response = getResponse(ip); + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + return JSONObject.from(response); + } + + @Override + public Object infoLookup(String ip) { + LocationResponse response = getResponse(ip); + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + return response; + } + + @Override + public String provinceLookup(String ip) { + LocationResponse response = getResponse(ip); + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + if (response.isPrivateIP()) { + return PRIVATE_IP; + } + return StringUtil.setDefaultIfEmpty(response.getSuperAdministrativeArea(), UNKNOWN).toString() ; + } + + @Override + public String ispLookup(String ip) { + LocationResponse response = getResponse(ip); + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + if (response.isPrivateIP()) { + return PRIVATE_IP; + } + return StringUtil.setDefaultIfEmpty(response.getIsp(), UNKNOWN).toString() ; + } + + @Override + public String organizationLookup(String ip) { + LocationResponse response = getResponse(ip); + if (StringUtil.isEmpty(response)) { + return UNKNOWN; + } + if (response.isPrivateIP()) { + return PRIVATE_IP; + } + return StringUtil.setDefaultIfEmpty(response.getOrganization(), UNKNOWN).toString() ; + } + + + @Override + public String latLngLookup(String ip) { + LocationResponse response = getResponse(ip); + if (StringUtil.isEmpty(response) || response.isPrivateIP()) { + return UNKNOWN; + } + + return Joiner.on(LAT_LNG_SEPARATOR).skipNulls().join(response.getLatitude(), response.getLongitude()); + + } + + @Override + public String cityLatLngLookup(String ip) { + return Joiner.on(OBJECT_SEPARATOR).skipNulls().join(cityLookup(ip), latLngLookup(ip)); + } + + @Override + public String asnLookup(String ip) { + return asnLookup.asnLookup(ip); + } + + @Override + public String asnLookupOrganization(String ip) { + return asnLookup.asnLookupOrganization(ip); + } + @Override + public String asnLookupInfo(String ip) { + return asnLookup.asnLookupInfo(ip); + } + + @Override + public String asnLookupDetail(String ip) { + return asnLookup.asnLookupDetail(ip); + } + + + private LocationResponse getResponse(String ip) { + try { + ip = Optional.ofNullable(ip).orElse("").trim(); + InetAddress ipAddress = InetAddress.getByName(ip); + if (ipAddress instanceof Inet4Address) { + + //Iterate through each 'dbReader' and execute them in the following order: private v4 -> private -> public v4 -> public. + for (GalaxyDataBaseReader reader : availableDBReaders.get(IpVersion.IPv4.name())) { + LocationResponse response = reader.locationV2(ipAddress); + if(StringUtil.isNotEmpty(response)) { + return response; + } + } + //Is it a private IP + if (IPUtil.internalIp(ip)) { + return new LocationResponse(true); + } + + } else if (ipAddress instanceof Inet6Address) { + //Iterate through each 'dbReader' and execute them in the following order: private v6 -> private -> public v6 -> public. + for(GalaxyDataBaseReader reader : availableDBReaders.get(IpVersion.IPv6.name())) { + LocationResponse response = reader.locationV2(ipAddress); + if(StringUtil.isNotEmpty(response)) { + return response; + } + } + } else { + throw new IllegalArgumentException("IP address <" + ip +">. "); + } + return null; + } catch (Exception e) { + throw new IllegalArgumentException("IP address <" + ip +">. " + e); + } + } + + +} + + + + + + + + + + + diff --git a/src/main/java/com/zdjizhi/utils/JsonMapper.java b/src/main/java/com/geedgenetworks/utils/JsonMapper.java index adb11fa..22bfe77 100644 --- a/src/main/java/com/zdjizhi/utils/JsonMapper.java +++ b/src/main/java/com/geedgenetworks/utils/JsonMapper.java @@ -1,4 +1,4 @@ -package com.zdjizhi.utils; +package com.geedgenetworks.utils; import java.io.IOException; import java.text.SimpleDateFormat; diff --git a/src/main/java/com/zdjizhi/utils/MathUtils.java b/src/main/java/com/geedgenetworks/utils/MathUtils.java index 06be39d..09288d7 100644 --- a/src/main/java/com/zdjizhi/utils/MathUtils.java +++ b/src/main/java/com/geedgenetworks/utils/MathUtils.java @@ -1,4 +1,4 @@ -package com.zdjizhi.utils; +package com.geedgenetworks.utils; import java.text.DecimalFormat; import java.util.Arrays; diff --git a/src/main/java/com/zdjizhi/utils/SnowflakeId.java b/src/main/java/com/geedgenetworks/utils/SnowflakeId.java index afae296..d73c012 100644 --- a/src/main/java/com/zdjizhi/utils/SnowflakeId.java +++ b/src/main/java/com/geedgenetworks/utils/SnowflakeId.java @@ -1,234 +1,234 @@ -package com.zdjizhi.utils;
-
-import org.apache.log4j.Logger;
-
-
-public class SnowflakeId {
- private static Logger logger = Logger.getLogger(SnowflakeId.class);
-
- /**
- * 共64位 第一位为符号位 默认0
- * 时间戳 39位(17 year), centerId:(关联每个环境或任务数) :7位(0-127),
- * workerId(关联进程):6(0-63) ,序列号:11位(2047/ms)
- *
- * 序列号 /ms = (-1L ^ (-1L << 11))
- * 最大使用年 = (1L << 39) / (1000L * 60 * 60 * 24 * 365)
- */
- /**
- * 开始时间截 (2020-02-28 00:00:00) max 17years
- */
- private final long twepoch = 1582819200000L;
-
- /**
- * 机器id所占的位数
- */
- private final long workerIdBits = 6L;
-
- /**
- * 数据标识id所占的位数
- */
- private final long dataCenterIdBits = 7L;
-
- /**
- * 支持的最大机器id,结果是63 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数)
- * M << n = M * 2^n
- */
- private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
-
- /**
- * 支持的最大数据标识id,结果是127
- */
- private final long maxDataCenterId = -1L ^ (-1L << dataCenterIdBits);
-
- /**
- * 序列在id中占的位数
- */
- private final long sequenceBits = 11L;
-
- /**
- * 机器ID向左移12位
- */
- private final long workerIdShift = sequenceBits;
-
- /**
- * 数据标识id向左移17位(14+6)
- */
- private final long dataCenterIdShift = sequenceBits + workerIdBits;
-
- /**
- * 时间截向左移22位(4+6+14)
- */
- private final long timestampLeftShift = sequenceBits + workerIdBits + dataCenterIdBits;
-
- /**
- * 生成序列的掩码,这里为2047
- */
- private final long sequenceMask = -1L ^ (-1L << sequenceBits);
-
- /**
- * 工作机器ID(0~63)
- */
- private long workerId;
-
- /**
- * 数据中心ID(0~127)
- */
- private long dataCenterId;
-
- /**
- * 毫秒内序列(0~2047)
- */
- private long sequence = 0L;
-
- /**
- * 上次生成ID的时间截
- */
- private long lastTimestamp = -1L;
-
-
- private static SnowflakeId idWorker;
-
- private static ZookeeperUtils zookeeperUtils = new ZookeeperUtils();
- /**
- * 设置允许时间回拨的最大限制10s
- */
- private static final long rollBackTime = 10000L;
-
- /**
- * @param workerId
- * @param dataCenterId
- */
- private static void getSnowflakeldInstance(long workerId, long dataCenterId) {
- idWorker = new SnowflakeId(workerId, dataCenterId);
- }
- /**
- * 依赖于zookeeper
- * @param zookeeperIp
- * @param kafkaTopic
- * @param dataCenterId
- */
- private static void getSnowflakeldInstance(String zookeeperIp, long dataCenterId) {
- idWorker = new SnowflakeId(zookeeperIp, dataCenterId);
- }
-
- /**
- * 构造函数
- */
- private SnowflakeId(long tmpWorkerId, long dataCenterIdNum) {
- if (tmpWorkerId > maxWorkerId || tmpWorkerId < 0) {
- throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
- }
- if (dataCenterIdNum > maxDataCenterId || dataCenterIdNum < 0) {
- throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than ", maxDataCenterId));
- }
- this.workerId = tmpWorkerId;
- this.dataCenterId = dataCenterIdNum;
-
- }
-
- private SnowflakeId(String zookeeperIp, long dataCenterIdNum) {
- ZooKeeperLock lock = new ZooKeeperLock(zookeeperIp, "/locks", "disLocks1");
- if (lock.lock()) {
- int tmpWorkerId = zookeeperUtils.modifyNode("/Snowflake/" + "worker" + dataCenterIdNum, zookeeperIp);
- if (tmpWorkerId > maxWorkerId || tmpWorkerId < 0) {
- throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
- }
- if (dataCenterIdNum > maxDataCenterId || dataCenterIdNum < 0) {
- throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than ", maxDataCenterId));
- }
- this.workerId = tmpWorkerId;
- this.dataCenterId = dataCenterIdNum;
- try {
- lock.unlock();
- } catch (InterruptedException ie) {
- ie.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- logger.error("This is not usual error!!!===>>>" + e + "<<<===");
- }
- }
- }
- /**
- * 获得下一个ID (该方法是线程安全的)
- *
- * @return SnowflakeId
- */
- private synchronized long nextId() {
- long timestamp = timeGen();
- //设置一个允许回拨限制时间,系统时间回拨范围在rollBackTime内可以等待校准
- if (lastTimestamp - timestamp > 0 && lastTimestamp - timestamp < rollBackTime) {
- timestamp = tilNextMillis(lastTimestamp);
- }
- //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
- if (timestamp < lastTimestamp) {
- throw new RuntimeException(
- String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
- }
-
- //如果是同一时间生成的,则进行毫秒内序列
- if (lastTimestamp == timestamp) {
- sequence = (sequence + 1) & sequenceMask;
- //毫秒内序列溢出
- if (sequence == 0) {
- //阻塞到下一个毫秒,获得新的时间戳
- timestamp = tilNextMillis(lastTimestamp);
- }
- }
- //时间戳改变,毫秒内序列重置
- else {
- sequence = 0L;
- }
-
- //上次生成ID的时间截
- lastTimestamp = timestamp;
-
- //移位并通过或运算拼到一起组成64位的ID
- return ((timestamp - twepoch) << timestampLeftShift)
- | (dataCenterId << dataCenterIdShift)
- | (workerId << workerIdShift)
- | sequence;
- }
-
- /**
- * 阻塞到下一个毫秒,直到获得新的时间戳
- *
- * @param lastTimestamp 上次生成ID的时间截
- * @return 当前时间戳
- */
- protected long tilNextMillis(long lastTimestamp) {
- long timestamp = timeGen();
- while (timestamp <= lastTimestamp) {
- timestamp = timeGen();
- }
- return timestamp;
- }
-
- /**
- * 返回以毫秒为单位的当前时间
- *
- * @return 当前时间(毫秒)
- */
- protected long timeGen() {
- return System.currentTimeMillis();
- }
-
- public static Long generateId(long workerId, long dataCenterIdNum) {
- if (idWorker == null) {
- getSnowflakeldInstance(workerId, dataCenterIdNum);
- }
- return idWorker.nextId();
- }
-
- /**
- * 静态工具类
- *
- * @return
- */
- public synchronized static Long generateId(String zookeeperIp, long dataCenterIdNum) {
- if (idWorker == null) {
- getSnowflakeldInstance(zookeeperIp, dataCenterIdNum);
- }
- return idWorker.nextId();
- }
-
+package com.geedgenetworks.utils; + +import org.apache.log4j.Logger; + + +public class SnowflakeId { + private static Logger logger = Logger.getLogger(SnowflakeId.class); + + /** + * 共64位 第一位为符号位 默认0 + * 时间戳 39位(17 year), centerId:(关联每个环境或任务数) :7位(0-127), + * workerId(关联进程):6(0-63) ,序列号:11位(2047/ms) + * + * 序列号 /ms = (-1L ^ (-1L << 11)) + * 最大使用年 = (1L << 39) / (1000L * 60 * 60 * 24 * 365) + */ + /** + * 开始时间截 (2020-02-28 00:00:00) max 17years + */ + private final long twepoch = 1582819200000L; + + /** + * 机器id所占的位数 + */ + private final long workerIdBits = 6L; + + /** + * 数据标识id所占的位数 + */ + private final long dataCenterIdBits = 7L; + + /** + * 支持的最大机器id,结果是63 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) + * M << n = M * 2^n + */ + private final long maxWorkerId = -1L ^ (-1L << workerIdBits); + + /** + * 支持的最大数据标识id,结果是127 + */ + private final long maxDataCenterId = -1L ^ (-1L << dataCenterIdBits); + + /** + * 序列在id中占的位数 + */ + private final long sequenceBits = 11L; + + /** + * 机器ID向左移12位 + */ + private final long workerIdShift = sequenceBits; + + /** + * 数据标识id向左移17位(14+6) + */ + private final long dataCenterIdShift = sequenceBits + workerIdBits; + + /** + * 时间截向左移22位(4+6+14) + */ + private final long timestampLeftShift = sequenceBits + workerIdBits + dataCenterIdBits; + + /** + * 生成序列的掩码,这里为2047 + */ + private final long sequenceMask = -1L ^ (-1L << sequenceBits); + + /** + * 工作机器ID(0~63) + */ + private long workerId; + + /** + * 数据中心ID(0~127) + */ + private long dataCenterId; + + /** + * 毫秒内序列(0~2047) + */ + private long sequence = 0L; + + /** + * 上次生成ID的时间截 + */ + private long lastTimestamp = -1L; + + + private static SnowflakeId idWorker; + + private static ZookeeperUtils zookeeperUtils = new ZookeeperUtils(); + /** + * 设置允许时间回拨的最大限制10s + */ + private static final long rollBackTime = 10000L; + + /** + * @param workerId + * @param dataCenterId + */ + private static void getSnowflakeldInstance(long workerId, long dataCenterId) { + idWorker = new SnowflakeId(workerId, dataCenterId); + } + /** + * 依赖于zookeeper + * @param zookeeperIp + * @param kafkaTopic + * @param dataCenterId + */ + private static void getSnowflakeldInstance(String zookeeperIp, long dataCenterId) { + idWorker = new SnowflakeId(zookeeperIp, dataCenterId); + } + + /** + * 构造函数 + */ + private SnowflakeId(long tmpWorkerId, long dataCenterIdNum) { + if (tmpWorkerId > maxWorkerId || tmpWorkerId < 0) { + throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); + } + if (dataCenterIdNum > maxDataCenterId || dataCenterIdNum < 0) { + throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than ", maxDataCenterId)); + } + this.workerId = tmpWorkerId; + this.dataCenterId = dataCenterIdNum; + + } + + private SnowflakeId(String zookeeperIp, long dataCenterIdNum) { + ZooKeeperLock lock = new ZooKeeperLock(zookeeperIp, "/locks", "disLocks1"); + if (lock.lock()) { + int tmpWorkerId = zookeeperUtils.modifyNode("/Snowflake/" + "worker" + dataCenterIdNum, zookeeperIp); + if (tmpWorkerId > maxWorkerId || tmpWorkerId < 0) { + throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); + } + if (dataCenterIdNum > maxDataCenterId || dataCenterIdNum < 0) { + throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than ", maxDataCenterId)); + } + this.workerId = tmpWorkerId; + this.dataCenterId = dataCenterIdNum; + try { + lock.unlock(); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + logger.error("This is not usual error!!!===>>>" + e + "<<<==="); + } + } + } + /** + * 获得下一个ID (该方法是线程安全的) + * + * @return SnowflakeId + */ + private synchronized long nextId() { + long timestamp = timeGen(); + //设置一个允许回拨限制时间,系统时间回拨范围在rollBackTime内可以等待校准 + if (lastTimestamp - timestamp > 0 && lastTimestamp - timestamp < rollBackTime) { + timestamp = tilNextMillis(lastTimestamp); + } + //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常 + if (timestamp < lastTimestamp) { + throw new RuntimeException( + String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); + } + + //如果是同一时间生成的,则进行毫秒内序列 + if (lastTimestamp == timestamp) { + sequence = (sequence + 1) & sequenceMask; + //毫秒内序列溢出 + if (sequence == 0) { + //阻塞到下一个毫秒,获得新的时间戳 + timestamp = tilNextMillis(lastTimestamp); + } + } + //时间戳改变,毫秒内序列重置 + else { + sequence = 0L; + } + + //上次生成ID的时间截 + lastTimestamp = timestamp; + + //移位并通过或运算拼到一起组成64位的ID + return ((timestamp - twepoch) << timestampLeftShift) + | (dataCenterId << dataCenterIdShift) + | (workerId << workerIdShift) + | sequence; + } + + /** + * 阻塞到下一个毫秒,直到获得新的时间戳 + * + * @param lastTimestamp 上次生成ID的时间截 + * @return 当前时间戳 + */ + protected long tilNextMillis(long lastTimestamp) { + long timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } + + /** + * 返回以毫秒为单位的当前时间 + * + * @return 当前时间(毫秒) + */ + protected long timeGen() { + return System.currentTimeMillis(); + } + + public static Long generateId(long workerId, long dataCenterIdNum) { + if (idWorker == null) { + getSnowflakeldInstance(workerId, dataCenterIdNum); + } + return idWorker.nextId(); + } + + /** + * 静态工具类 + * + * @return + */ + public synchronized static Long generateId(String zookeeperIp, long dataCenterIdNum) { + if (idWorker == null) { + getSnowflakeldInstance(zookeeperIp, dataCenterIdNum); + } + return idWorker.nextId(); + } + }
\ No newline at end of file diff --git a/src/main/java/com/zdjizhi/utils/StringUtil.java b/src/main/java/com/geedgenetworks/utils/StringUtil.java index 8896538..b449082 100644 --- a/src/main/java/com/zdjizhi/utils/StringUtil.java +++ b/src/main/java/com/geedgenetworks/utils/StringUtil.java @@ -1,4 +1,4 @@ -package com.zdjizhi.utils; +package com.geedgenetworks.utils; import org.apache.commons.lang3.StringUtils; diff --git a/src/main/java/com/zdjizhi/utils/TimeConstants.java b/src/main/java/com/geedgenetworks/utils/TimeConstants.java index a3a30e4..f662106 100644 --- a/src/main/java/com/zdjizhi/utils/TimeConstants.java +++ b/src/main/java/com/geedgenetworks/utils/TimeConstants.java @@ -1,4 +1,4 @@ -package com.zdjizhi.utils; +package com.geedgenetworks.utils; /** * diff --git a/src/main/java/com/zdjizhi/utils/ZooKeeperLock.java b/src/main/java/com/geedgenetworks/utils/ZooKeeperLock.java index ed11eb4..7a0a21b 100644 --- a/src/main/java/com/zdjizhi/utils/ZooKeeperLock.java +++ b/src/main/java/com/geedgenetworks/utils/ZooKeeperLock.java @@ -1,140 +1,140 @@ -package com.zdjizhi.utils;
-
-import org.apache.log4j.Logger;
-import org.apache.zookeeper.*;
-import org.apache.zookeeper.data.Stat;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-public class ZooKeeperLock implements Watcher {
- private static Logger logger = Logger.getLogger(ZooKeeperLock.class);
-
- private ZooKeeper zk = null;
- private String rootLockNode; // 锁的根节点
- private String lockName; // 竞争资源,用来生成子节点名称
- private String currentLock; // 当前锁
- private String waitLock; // 等待的锁(前一个锁)
- private CountDownLatch countDownLatch; // 计数器(用来在加锁失败时阻塞加锁线程)
- private int sessionTimeout = 30000; // 超时时间
-
- // 1. 构造器中创建ZK链接,创建锁的根节点
- public ZooKeeperLock(String zkAddress, String rootLockNode, String lockName) {
- this.rootLockNode = rootLockNode;
- this.lockName = lockName;
- try {
- // 创建连接,zkAddress格式为:IP:PORT
- zk = new ZooKeeper(zkAddress, this.sessionTimeout, this);
- // 检测锁的根节点是否存在,不存在则创建
- Stat stat = zk.exists(rootLockNode, false);
- if (null == stat) {
- zk.create(rootLockNode, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
- }
- } catch (IOException | InterruptedException | KeeperException e) {
- e.printStackTrace();
- logger.error("ZooKeeperLock Constructors ===>>>Node already exists!");
- }
- }
-
- // 2. 加锁方法,先尝试加锁,不能加锁则等待上一个锁的释放
- public boolean lock() {
- if (this.tryLock()) {
- logger.warn("ZooKeeperLock method lock() ===>>> zkLockProcess[[[" + Thread.currentThread().getName() + "]]] addZkLock(" + this.currentLock + ")success!");
- return true;
- } else {
- return waitOtherLock(this.waitLock, this.sessionTimeout);
- }
- }
-
- public boolean tryLock() {
- // 分隔符
- String split = "_lock_";
- if (this.lockName.contains("_lock_")) {
- throw new RuntimeException("lockName can't contains '_lock_' ");
- }
- try {
- // 创建锁节点(临时有序节点)
- this.currentLock = zk.create(this.rootLockNode + "/" + this.lockName + split, new byte[0],
- ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
- logger.warn("ZooKeeperLock method tryLock() ===>>> zkLockProcess[[[" + Thread.currentThread().getName() + "]]] create zkLockNode(" + this.currentLock + ")success,begin to election...");
- // 取所有子节点
- List<String> nodes = zk.getChildren(this.rootLockNode, false);
- // 取所有竞争lockName的锁
- List<String> lockNodes = new ArrayList<String>();
- for (String nodeName : nodes) {
- if (nodeName.split(split)[0].equals(this.lockName)) {
- lockNodes.add(nodeName);
- }
- }
- Collections.sort(lockNodes);
- // 取最小节点与当前锁节点比对加锁
- String currentLockPath = this.rootLockNode + "/" + lockNodes.get(0);
- if (this.currentLock.equals(currentLockPath)) {
- return true;
- }
- // 加锁失败,设置前一节点为等待锁节点
- String currentLockNode = this.currentLock.substring(this.currentLock.lastIndexOf("/") + 1);
- int preNodeIndex = Collections.binarySearch(lockNodes, currentLockNode) - 1;
- this.waitLock = lockNodes.get(preNodeIndex);
- } catch (KeeperException | InterruptedException e) {
- e.printStackTrace();
- }
- return false;
- }
-
- private boolean waitOtherLock(String waitLock, int sessionTimeout) {
- boolean islock = false;
- try {
- // 监听等待锁节点
- String waitLockNode = this.rootLockNode + "/" + waitLock;
- Stat stat = zk.exists(waitLockNode, true);
- if (null != stat) {
- logger.error("ZooKeeperLock method waitOtherLock() ===>>> zkLockProcess[[[" + Thread.currentThread().getName() + "]]] zkLock(" + this.currentLock + ")addZkLock fail,wait lock(" + waitLockNode + ")release...");
- // 设置计数器,使用计数器阻塞线程
- this.countDownLatch = new CountDownLatch(1);
- islock = this.countDownLatch.await(sessionTimeout, TimeUnit.MILLISECONDS);
- this.countDownLatch = null;
- if (islock) {
- logger.warn("ZooKeeperLock method waitOtherLock() ===>>> zkLockProcess[[[" + Thread.currentThread().getName() + "]]] zkLock(" + this.currentLock + ")addZkLock success,lock(" + waitLockNode + ")release over.");
- } else {
- logger.error("ZooKeeperLock method waitOtherLock() ===>>> zkLockProcess[[[" + Thread.currentThread().getName() + "]]] zkLock(" + this.currentLock + "addZkLock fail...");
- }
- } else {
- islock = true;
- }
- } catch (KeeperException | InterruptedException e) {
- e.printStackTrace();
- }
- return islock;
- }
-
- // 3. 释放锁
- public void unlock() throws InterruptedException {
- try {
- Stat stat = zk.exists(this.currentLock, false);
- if (null != stat) {
- logger.warn("ZooKeeperLock method unlock() ===>>> zkLockProcess[[[" + Thread.currentThread().getName() + "]]] free zkLock " + this.currentLock);
- zk.delete(this.currentLock, -1);
- this.currentLock = null;
- }
- } catch (InterruptedException | KeeperException e) {
- e.printStackTrace();
- } finally {
- zk.close();
- }
- }
-
- // 4. 监听器回调
- @Override
- public void process(WatchedEvent watchedEvent) {
- if (null != this.countDownLatch && watchedEvent.getType() == Event.EventType.NodeDeleted) {
- // 计数器减一,恢复线程操作
- this.countDownLatch.countDown();
- }
- }
-
-}
+package com.geedgenetworks.utils; + +import org.apache.log4j.Logger; +import org.apache.zookeeper.*; +import org.apache.zookeeper.data.Stat; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class ZooKeeperLock implements Watcher { + private static Logger logger = Logger.getLogger(ZooKeeperLock.class); + + private ZooKeeper zk = null; + private String rootLockNode; // 锁的根节点 + private String lockName; // 竞争资源,用来生成子节点名称 + private String currentLock; // 当前锁 + private String waitLock; // 等待的锁(前一个锁) + private CountDownLatch countDownLatch; // 计数器(用来在加锁失败时阻塞加锁线程) + private int sessionTimeout = 30000; // 超时时间 + + // 1. 构造器中创建ZK链接,创建锁的根节点 + public ZooKeeperLock(String zkAddress, String rootLockNode, String lockName) { + this.rootLockNode = rootLockNode; + this.lockName = lockName; + try { + // 创建连接,zkAddress格式为:IP:PORT + zk = new ZooKeeper(zkAddress, this.sessionTimeout, this); + // 检测锁的根节点是否存在,不存在则创建 + Stat stat = zk.exists(rootLockNode, false); + if (null == stat) { + zk.create(rootLockNode, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); + } + } catch (IOException | InterruptedException | KeeperException e) { + e.printStackTrace(); + logger.error("ZooKeeperLock Constructors ===>>>Node already exists!"); + } + } + + // 2. 加锁方法,先尝试加锁,不能加锁则等待上一个锁的释放 + public boolean lock() { + if (this.tryLock()) { + logger.warn("ZooKeeperLock method lock() ===>>> zkLockProcess[[[" + Thread.currentThread().getName() + "]]] addZkLock(" + this.currentLock + ")success!"); + return true; + } else { + return waitOtherLock(this.waitLock, this.sessionTimeout); + } + } + + public boolean tryLock() { + // 分隔符 + String split = "_lock_"; + if (this.lockName.contains("_lock_")) { + throw new RuntimeException("lockName can't contains '_lock_' "); + } + try { + // 创建锁节点(临时有序节点) + this.currentLock = zk.create(this.rootLockNode + "/" + this.lockName + split, new byte[0], + ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); + logger.warn("ZooKeeperLock method tryLock() ===>>> zkLockProcess[[[" + Thread.currentThread().getName() + "]]] create zkLockNode(" + this.currentLock + ")success,begin to election..."); + // 取所有子节点 + List<String> nodes = zk.getChildren(this.rootLockNode, false); + // 取所有竞争lockName的锁 + List<String> lockNodes = new ArrayList<String>(); + for (String nodeName : nodes) { + if (nodeName.split(split)[0].equals(this.lockName)) { + lockNodes.add(nodeName); + } + } + Collections.sort(lockNodes); + // 取最小节点与当前锁节点比对加锁 + String currentLockPath = this.rootLockNode + "/" + lockNodes.get(0); + if (this.currentLock.equals(currentLockPath)) { + return true; + } + // 加锁失败,设置前一节点为等待锁节点 + String currentLockNode = this.currentLock.substring(this.currentLock.lastIndexOf("/") + 1); + int preNodeIndex = Collections.binarySearch(lockNodes, currentLockNode) - 1; + this.waitLock = lockNodes.get(preNodeIndex); + } catch (KeeperException | InterruptedException e) { + e.printStackTrace(); + } + return false; + } + + private boolean waitOtherLock(String waitLock, int sessionTimeout) { + boolean islock = false; + try { + // 监听等待锁节点 + String waitLockNode = this.rootLockNode + "/" + waitLock; + Stat stat = zk.exists(waitLockNode, true); + if (null != stat) { + logger.error("ZooKeeperLock method waitOtherLock() ===>>> zkLockProcess[[[" + Thread.currentThread().getName() + "]]] zkLock(" + this.currentLock + ")addZkLock fail,wait lock(" + waitLockNode + ")release..."); + // 设置计数器,使用计数器阻塞线程 + this.countDownLatch = new CountDownLatch(1); + islock = this.countDownLatch.await(sessionTimeout, TimeUnit.MILLISECONDS); + this.countDownLatch = null; + if (islock) { + logger.warn("ZooKeeperLock method waitOtherLock() ===>>> zkLockProcess[[[" + Thread.currentThread().getName() + "]]] zkLock(" + this.currentLock + ")addZkLock success,lock(" + waitLockNode + ")release over."); + } else { + logger.error("ZooKeeperLock method waitOtherLock() ===>>> zkLockProcess[[[" + Thread.currentThread().getName() + "]]] zkLock(" + this.currentLock + "addZkLock fail..."); + } + } else { + islock = true; + } + } catch (KeeperException | InterruptedException e) { + e.printStackTrace(); + } + return islock; + } + + // 3. 释放锁 + public void unlock() throws InterruptedException { + try { + Stat stat = zk.exists(this.currentLock, false); + if (null != stat) { + logger.warn("ZooKeeperLock method unlock() ===>>> zkLockProcess[[[" + Thread.currentThread().getName() + "]]] free zkLock " + this.currentLock); + zk.delete(this.currentLock, -1); + this.currentLock = null; + } + } catch (InterruptedException | KeeperException e) { + e.printStackTrace(); + } finally { + zk.close(); + } + } + + // 4. 监听器回调 + @Override + public void process(WatchedEvent watchedEvent) { + if (null != this.countDownLatch && watchedEvent.getType() == Event.EventType.NodeDeleted) { + // 计数器减一,恢复线程操作 + this.countDownLatch.countDown(); + } + } + +} diff --git a/src/main/java/com/zdjizhi/utils/ZookeeperUtils.java b/src/main/java/com/geedgenetworks/utils/ZookeeperUtils.java index 3142fff..380b55f 100644 --- a/src/main/java/com/zdjizhi/utils/ZookeeperUtils.java +++ b/src/main/java/com/geedgenetworks/utils/ZookeeperUtils.java @@ -1,139 +1,139 @@ -package com.zdjizhi.utils;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-import org.apache.log4j.Logger;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Stat;
-
-
-public class ZookeeperUtils implements Watcher {
- private static Logger logger = Logger.getLogger(ZookeeperUtils.class);
-
- private ZooKeeper zookeeper;
-
- private static final int SESSION_TIME_OUT = 20000;
-
- private CountDownLatch countDownLatch = new CountDownLatch(1);
-
- @Override
- public void process(WatchedEvent event) {
- if (event.getState() == Event.KeeperState.SyncConnected) {
- countDownLatch.countDown();
- }
- }
-
-
- /**
- * 修改节点信息
- *
- * @param path 节点路径
- */
- public int modifyNode(String path, String zookeeperIp) {
- createNode(path, "0".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, zookeeperIp);
- int workerId = 0;
- try {
- connectZookeeper(zookeeperIp);
- Stat stat = zookeeper.exists(path, true);
- workerId = Integer.parseInt(getNodeDate(path));
- if (workerId > 63) {
- workerId = 0;
- zookeeper.setData(path, "1".getBytes(), stat.getVersion());
- } else {
- String result = String.valueOf(workerId + 1);
- if (stat != null) {
- zookeeper.setData(path, result.getBytes(), stat.getVersion());
- } else {
- logger.error("Node does not exist!,Can't modify");
- }
- }
- } catch (KeeperException | InterruptedException e) {
- logger.error("modify error Can't modify,"+e.getMessage());
- }
- finally {
- closeConn();
- }
- logger.warn("workerID is:" + workerId);
- return workerId;
- }
-
- /**
- * 连接zookeeper
- *
- * @param host 地址
- */
- public void connectZookeeper(String host) {
- try {
- zookeeper = new ZooKeeper(host, SESSION_TIME_OUT, this);
- countDownLatch.await();
- } catch (IOException | InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * 关闭连接
- */
- public void closeConn() {
- try {
- if (zookeeper != null) {
- zookeeper.close();
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * 获取节点内容
- *
- * @param path 节点路径
- * @return 内容/异常null
- */
- public String getNodeDate(String path) {
- String result = null;
- Stat stat = new Stat();
- try {
- byte[] resByte = zookeeper.getData(path, true, stat);
- result = new String(resByte);
- } catch (KeeperException | InterruptedException e) {
- logger.error("Get node information exception");
- e.printStackTrace();
- }
- return result;
- }
-
- /**
- * @param path 节点创建的路径
- * @param date 节点所存储的数据的byte[]
- * @param acls 控制权限策略
- */
- public void createNode(String path, byte[] date, List<ACL> acls, String zookeeperIp) {
- try {
- connectZookeeper(zookeeperIp);
- Stat exists = zookeeper.exists(path, true);
- if (exists == null) {
- Stat existsSnowflakeld = zookeeper.exists("/Snowflake", true);
- if (existsSnowflakeld == null) {
- zookeeper.create("/Snowflake", null, acls, CreateMode.PERSISTENT);
- }
- zookeeper.create(path, date, acls, CreateMode.PERSISTENT);
- } else {
- logger.warn("Node already exists ! Don't need to create");
- }
- } catch (KeeperException | InterruptedException e) {
- e.printStackTrace();
- } finally {
- closeConn();
- }
- }
-
-}
+package com.geedgenetworks.utils; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.CountDownLatch; + +import org.apache.log4j.Logger; +import org.apache.zookeeper.CreateMode; +import org.apache.zookeeper.KeeperException; +import org.apache.zookeeper.WatchedEvent; +import org.apache.zookeeper.Watcher; +import org.apache.zookeeper.ZooDefs; +import org.apache.zookeeper.ZooKeeper; +import org.apache.zookeeper.data.ACL; +import org.apache.zookeeper.data.Stat; + + +public class ZookeeperUtils implements Watcher { + private static Logger logger = Logger.getLogger(ZookeeperUtils.class); + + private ZooKeeper zookeeper; + + private static final int SESSION_TIME_OUT = 20000; + + private CountDownLatch countDownLatch = new CountDownLatch(1); + + @Override + public void process(WatchedEvent event) { + if (event.getState() == Event.KeeperState.SyncConnected) { + countDownLatch.countDown(); + } + } + + + /** + * 修改节点信息 + * + * @param path 节点路径 + */ + public int modifyNode(String path, String zookeeperIp) { + createNode(path, "0".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, zookeeperIp); + int workerId = 0; + try { + connectZookeeper(zookeeperIp); + Stat stat = zookeeper.exists(path, true); + workerId = Integer.parseInt(getNodeDate(path)); + if (workerId > 63) { + workerId = 0; + zookeeper.setData(path, "1".getBytes(), stat.getVersion()); + } else { + String result = String.valueOf(workerId + 1); + if (stat != null) { + zookeeper.setData(path, result.getBytes(), stat.getVersion()); + } else { + logger.error("Node does not exist!,Can't modify"); + } + } + } catch (KeeperException | InterruptedException e) { + logger.error("modify error Can't modify,"+e.getMessage()); + } + finally { + closeConn(); + } + logger.warn("workerID is:" + workerId); + return workerId; + } + + /** + * 连接zookeeper + * + * @param host 地址 + */ + public void connectZookeeper(String host) { + try { + zookeeper = new ZooKeeper(host, SESSION_TIME_OUT, this); + countDownLatch.await(); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * 关闭连接 + */ + public void closeConn() { + try { + if (zookeeper != null) { + zookeeper.close(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * 获取节点内容 + * + * @param path 节点路径 + * @return 内容/异常null + */ + public String getNodeDate(String path) { + String result = null; + Stat stat = new Stat(); + try { + byte[] resByte = zookeeper.getData(path, true, stat); + result = new String(resByte); + } catch (KeeperException | InterruptedException e) { + logger.error("Get node information exception"); + e.printStackTrace(); + } + return result; + } + + /** + * @param path 节点创建的路径 + * @param date 节点所存储的数据的byte[] + * @param acls 控制权限策略 + */ + public void createNode(String path, byte[] date, List<ACL> acls, String zookeeperIp) { + try { + connectZookeeper(zookeeperIp); + Stat exists = zookeeper.exists(path, true); + if (exists == null) { + Stat existsSnowflakeld = zookeeper.exists("/Snowflake", true); + if (existsSnowflakeld == null) { + zookeeper.create("/Snowflake", null, acls, CreateMode.PERSISTENT); + } + zookeeper.create(path, date, acls, CreateMode.PERSISTENT); + } else { + logger.warn("Node already exists ! Don't need to create"); + } + } catch (KeeperException | InterruptedException e) { + e.printStackTrace(); + } finally { + closeConn(); + } + } + +} diff --git a/src/main/java/com/zdjizhi/domain/JsonInjector.java b/src/main/java/com/zdjizhi/domain/JsonInjector.java deleted file mode 100644 index cd19e7c..0000000 --- a/src/main/java/com/zdjizhi/domain/JsonInjector.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.zdjizhi.domain;/** - * Created by dell on 2018-10-8. - */ - -import com.fasterxml.jackson.databind.BeanProperty; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.InjectableValues; -import com.maxmind.geoip2.record.Traits; - -import java.util.List; - -/** - * @ClassName JsonInjector - * @Description TODO - * @Author dell - * @Date 2018-10-8 18:38 - * @Version 1.0 - **/ -public class JsonInjector extends InjectableValues { - - private final List<String> locales; - private final String ip; - - public JsonInjector(List<String> locales, String ip) { - this.locales = locales; - this.ip = ip; - } - - @Override - public Object findInjectableValue(Object valueId, DeserializationContext ctxt, - BeanProperty forProperty, Object beanInstance) { - if ("locales".equals(valueId)) { - return locales; - } - if ("ip_address".equals(valueId)) { - return ip; - } - if ("traits".equals(valueId)) { - return new Traits(ip); - } - return null; - } - -} diff --git a/src/main/java/com/zdjizhi/domain/LocationResponse.java b/src/main/java/com/zdjizhi/domain/LocationResponse.java deleted file mode 100644 index db042be..0000000 --- a/src/main/java/com/zdjizhi/domain/LocationResponse.java +++ /dev/null @@ -1,157 +0,0 @@ -package com.zdjizhi.domain;/** - * Created by dell on 2018-10-8. - */ - -import com.fasterxml.jackson.annotation.JsonProperty; - - -/** - * @ClassName CountryResponse - * @Description TODO - * @Author dell - * @Date 2018-10-8 18:56 - * @Version 1.0 - * * @deprecated - * *<p> Use {@link LocationResponseV2} instead. - **/ -@Deprecated -public class LocationResponse { - - private String areaCode; - - private String asn; - - private String city; - - private String country; - - private String isp; - - private String latitude; - - private String longitude; - - private String province; - - private String organization; - - private String countryCode; - - private boolean privateIP; - - - - public LocationResponse() { - - this("", "", "", "", "", "", "", "", "", ""); - } - - public LocationResponse(@JsonProperty("AREA_CODE") String areaCode, @JsonProperty("ASN") String asn, - @JsonProperty("CITY") String city, @JsonProperty("COUNTRY") String country, - @JsonProperty("ISP") String isp, @JsonProperty("LATITUDE") String latitude, - @JsonProperty("LONGITUDE") String longitude, @JsonProperty("PROVINCE") String province, - @JsonProperty("ORGANIZATION") String organization, @JsonProperty("COUNTRY_CODE") String countryCode) { - this.areaCode = areaCode; - this.asn = asn; - this.city = city; - this.isp = isp; - this.latitude = latitude; - this.longitude = longitude; - this.province = province; - this.country = country; - this.organization = organization; - this.countryCode = countryCode; - - } - - public String getAreaCode() { - return areaCode; - } - - public void setAreaCode(String areaCode) { - this.areaCode = areaCode; - } - - public String getAsn() { - return asn; - } - - public void setAsn(String asn) { - this.asn = asn; - } - - public String getCity() { - return city; - } - - public void setCity(String city) { - this.city = city; - } - - - public String getCountry() { - return country; - } - - - public void setCountry(String country) { - this.country = country; - } - - public String getIsp() { - return isp; - } - - public void setIsp(String isp) { - this.isp = isp; - } - - public String getLatitude() { - return latitude; - } - - public void setLatitude(String latitude) { - this.latitude = latitude; - } - - public String getLongitude() { - return longitude; - } - - public void setLongitude(String longitude) { - this.longitude = longitude; - } - - public String getProvince() { - return province; - } - - public void setProvince(String province) { - this.province = province; - } - - public String getOrganization() { - return organization; - } - - public void setOrganization(String organization) { - this.organization = organization; - } - - public String getCountryCode() { - return countryCode; - } - - public void setCountryCode(String countryCode) { - this.countryCode = countryCode; - } - - public boolean isPrivateIP() { - return privateIP; - } - - public void setPrivateIP(boolean privateIP) { - this.privateIP = privateIP; - } -} - diff --git a/src/main/java/com/zdjizhi/utils/AsnLookup.java b/src/main/java/com/zdjizhi/utils/AsnLookup.java deleted file mode 100644 index 6b7f21b..0000000 --- a/src/main/java/com/zdjizhi/utils/AsnLookup.java +++ /dev/null @@ -1,554 +0,0 @@ -package com.zdjizhi.utils; - -import com.google.common.base.Joiner; -import com.maxmind.db.CHMCache; -import com.maxmind.geoip2.exception.AddressNotFoundException; -import com.zdjizhi.domain.LocationResponseV2; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.InetAddress; -import java.net.URL; - -/** - * @ClassName AsnLookup - * @Description IP查询AS号 - * @Author 中电积至有限公司 darnell - * @Date 2020-05-09 13:45 - * @Version 1.0.3 - **/ -public class AsnLookup { - enum ServiceEnum { - PRIVATE, PUBLIC - } - protected static final String UNKNOWN = ""; - protected static final String SEPARATOR = ","; - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - public final static String DEFAULT_DATABASE_PATH = "dat"; - private final static String DEFAULT_DB_ASN_PUBLIC = "asn.mmdb"; - private final static String DEFAULT_DB_ASN_PUBLIC_V4 = "asn_v4.mmdb"; - private final static String DEFAULT_DB_ASN_PUBLIC_V6 = "asn_v6.mmdb"; - private final static String DEFAULT_DB_ASN_PRIVATE = "asn_private.mmdb"; - private final static String DEFAULT_DB_ASN_PRIVATE_V4 = "asn_private_v4.mmdb"; - private final static String DEFAULT_DB_ASN_PRIVATE_V6 = "asn_private_v6.mmdb"; - - private static GalaxyDataBaseReader publicDatabaseReader; - private static GalaxyDataBaseReader publicV4DatabaseReader; - private static GalaxyDataBaseReader publicV6DatabaseReader; - - private static GalaxyDataBaseReader privateDatabaseReader; - private static GalaxyDataBaseReader privateV4DatabaseReader; - private static GalaxyDataBaseReader privateV6DatabaseReader; - - - synchronized void init(AsnLookup.Builder builder) { - try { - - if (builder.isDefaultDB) { - - File publicDatabaseFile = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator - + DEFAULT_DB_ASN_PUBLIC); - if (!publicDatabaseFile.exists()) { - URL url = AsnLookup.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_ASN_PUBLIC); - if (url != null) { - publicDatabaseFile = new File(url.getPath()); - } - - } - - - File asnDbPublicV4File = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator - + DEFAULT_DB_ASN_PUBLIC_V4); - if (!asnDbPublicV4File.exists()) { - URL url = AsnLookup.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_ASN_PUBLIC_V4); - if (url != null) { - asnDbPublicV4File = new File(url.getPath()); - } - - } - - File asnDbPublicV6File = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator - + DEFAULT_DB_ASN_PUBLIC_V6); - if (!asnDbPublicV6File.exists()) { - URL url = AsnLookup.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_ASN_PUBLIC_V6); - if (url != null) { - asnDbPublicV6File = new File(url.getPath()); - } - } - - File asnDbPrivateFile = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator - + DEFAULT_DB_ASN_PRIVATE); - if (!asnDbPrivateFile.exists()) { - URL url = AsnLookup.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_ASN_PRIVATE); - if (url != null) { - asnDbPrivateFile = new File(url.getPath()); - } - - } - - File asnDbPrivateV4File = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator - + DEFAULT_DB_ASN_PRIVATE_V4); - if (!asnDbPrivateV4File.exists()) { - URL url = AsnLookup.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_ASN_PRIVATE_V4); - if (url != null) { - asnDbPrivateV4File = new File(url.getPath()); - } - - } - - - File asnDbPrivateV6File = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator - + DEFAULT_DB_ASN_PRIVATE_V6); - if (!asnDbPrivateV6File.exists()) { - URL url = AsnLookup.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_ASN_PRIVATE_V6); - if (url != null) { - asnDbPrivateV6File = new File(url.getPath()); - } - } - - publicDatabaseReader = buildDataReader(publicDatabaseFile); - publicV4DatabaseReader = buildDataReader(asnDbPublicV4File); - publicV6DatabaseReader = buildDataReader(asnDbPublicV6File); - privateDatabaseReader = buildDataReader(asnDbPrivateFile); - privateV4DatabaseReader = buildDataReader(asnDbPrivateV4File); - privateV6DatabaseReader = buildDataReader(asnDbPrivateV6File); - - } else { - - if (StringUtil.isNotBlank(builder.publicAsnDatabaseFile)) { - publicDatabaseReader = buildDataReader(new File(builder.publicAsnDatabaseFile)); - } else if (builder.publicAsnDatabaseStream != null) { - publicDatabaseReader = buildDataReader(builder.publicAsnDatabaseStream); - } - - if (StringUtil.isNotBlank(builder.publicAsnV4DatabaseFile)) { - publicV4DatabaseReader = buildDataReader((new File(builder.publicAsnV4DatabaseFile))); - } else if (builder.publicAsnV4DatabaseStream != null) { - publicV4DatabaseReader = buildDataReader(builder.publicAsnV4DatabaseStream); - } - - if (StringUtil.isNotBlank(builder.publicAsnV6DatabaseFile)) { - publicV6DatabaseReader = buildDataReader(new File(builder.publicAsnV6DatabaseFile)); - } else if (builder.publicAsnV6DatabaseStream != null) { - publicV6DatabaseReader = buildDataReader(builder.publicAsnV6DatabaseStream); - } - - if (StringUtil.isNotBlank(builder.privateAsnDatabaseFile)) { - privateDatabaseReader = buildDataReader(new File(builder.privateAsnDatabaseFile)); - } else if (builder.privateAsnDatabaseStream != null) { - privateDatabaseReader = buildDataReader(builder.privateAsnDatabaseStream); - } - - if (StringUtil.isNotBlank(builder.privateAsnV4DatabaseFile)) { - privateV4DatabaseReader = buildDataReader(new File(builder.privateAsnV4DatabaseFile)); - } else if (builder.privateAsnV4DatabaseStream != null) { - privateV4DatabaseReader = buildDataReader(builder.privateAsnV4DatabaseStream); - } - - if (StringUtil.isNotBlank(builder.privateAsnV6DatabaseFile)) { - privateV6DatabaseReader = buildDataReader(new File(builder.privateAsnV6DatabaseFile)); - } else if (builder.privateAsnV6DatabaseStream != null) { - privateV6DatabaseReader = buildDataReader(builder.privateAsnV6DatabaseStream); - } - } - - } catch (Exception e) { - e.printStackTrace(); - logger.error("Unsupported GeoIP2 *.mmdb database: expected either File path or Stream."); - } - - - } - - - - private AsnLookup(AsnLookup.Builder builder) { - init(builder); - } - private GalaxyDataBaseReader buildDataReader(File database) throws IOException { - if (database.exists()) { - return new GalaxyDataBaseReader.Builder(database).withCache(new CHMCache()).build(); - } else { - return null; - } - } - - private GalaxyDataBaseReader buildDataReader(InputStream stream) throws IOException { - if (stream != null) { - return new GalaxyDataBaseReader.Builder(stream).withCache(new CHMCache()).build(); - } else { - return null; - } - } - - /** - * 加载mmdb数据字典文件,内部生成mmdb动态库。 - * - * 1.默认记载ASN库,使用方式如下: - * AsnLookup asnLookup = new AsnLookup.Builder(true).build(); - * 自动加载应用dat目录下的库文件,命名为:asn_v4.asn_v6.mmdb库。 - * - * 2.手动加载IP库,使用方式如下: - * <p> - * AsnLookup asnLookup = new AsnLookup.Builder(false).loadDataFileV4("D:\\galaxy-tool\\dat\\asn_v4_201901.mmdb"). - * loadDataFileV6("D:\\galaxy-tool\\dat\\asn_v6_201901.mmdb").build(); - * - * </p> - */ - public static final class Builder { - String publicAsnDatabaseFile; - String publicAsnV4DatabaseFile; - String publicAsnV6DatabaseFile; - - InputStream publicAsnDatabaseStream; - InputStream publicAsnV4DatabaseStream; - InputStream publicAsnV6DatabaseStream; - - String privateAsnDatabaseFile; - String privateAsnV4DatabaseFile; - String privateAsnV6DatabaseFile; - - InputStream privateAsnDatabaseStream; - InputStream privateAsnV4DatabaseStream; - InputStream privateAsnV6DatabaseStream; - boolean isDefaultDB; - - - /** - * - * @param isDefaultDB <code>false</code> 手动指定IP库路径 <code>true</code> 使用默认路径 - */ - public Builder(boolean isDefaultDB) { - this.isDefaultDB = isDefaultDB; - } - - /** - * - * @param publicAsnDatabaseFile 加载ASN database文件,不区分IPv4/6 - * @return - */ - public Builder loadDataFile(String publicAsnDatabaseFile) { - this.publicAsnDatabaseFile = publicAsnDatabaseFile; - return this; - } - - /** - * - * @param publicAsnDatabaseStream 加载ASN database流,不区分IPv4/6 - * @return - */ - public Builder loadDataFile(InputStream publicAsnDatabaseStream) { - this.publicAsnDatabaseStream = publicAsnDatabaseStream; - return this; - } - - /** - * - * @param publicAsnV4DatabaseFile 加载ASN IPv4 database文件 - * @return - */ - public Builder loadDataFileV4(String publicAsnV4DatabaseFile) { - this.publicAsnV4DatabaseFile = publicAsnV4DatabaseFile; - return this; - } - - /** - * - * @param publicAsnV4DatabaseStream 加载ASN IPv4 database流 - * @return - */ - public Builder loadDataFileV4(InputStream publicAsnV4DatabaseStream) { - this.publicAsnV4DatabaseStream = publicAsnV4DatabaseStream; - return this; - } - - - - /** - * - * @param publicAsnV6DatabaseFile 加载ASN IPv6 database文件 - * @return - */ - public Builder loadDataFileV6(String publicAsnV6DatabaseFile) { - this.publicAsnV6DatabaseFile = publicAsnV6DatabaseFile; - return this; - } - - /** - * - * @param publicAsnV6DatabaseStream 加载ASN IPv6 database流 - * @return - */ - public Builder loadDataFileV6(InputStream publicAsnV6DatabaseStream) { - this.publicAsnV6DatabaseStream = publicAsnV6DatabaseStream; - return this; - } - - /** - * - * @param privateAsnDatabaseFile 加载ASN database文件,不区分IPv4/6 - * @return - */ - public Builder loadDataFilePrivate(String privateAsnDatabaseFile) { - this.privateAsnDatabaseFile = privateAsnDatabaseFile; - return this; - } - - /** - * - * @param privateAsnDatabaseStream 加载ASN database流,不区分IPv4/6 - * @return - */ - public Builder loadDataFilePrivate(InputStream privateAsnDatabaseStream) { - this.privateAsnDatabaseStream = privateAsnDatabaseStream; - return this; - } - - - - /** - * - * @param privateAsnV4DatabaseFile 加载ASN IPv4 database文件 - * @return - */ - public Builder loadDataFilePrivateV4(String privateAsnV4DatabaseFile) { - this.privateAsnV4DatabaseFile = privateAsnV4DatabaseFile; - return this; - } - - /** - * - * @param privateAsnV4DatabaseStream 加载ASN IPv4 database流 - * @return - */ - public Builder loadDataFilePrivateV4(InputStream privateAsnV4DatabaseStream) { - this.privateAsnV4DatabaseStream = privateAsnV4DatabaseStream; - return this; - } - - /** - * - * @param privateAsnV6DatabaseFile 加载ASN IPv6 database文件 - * @return - */ - public Builder loadDataFilePrivateV6(String privateAsnV6DatabaseFile) { - this.privateAsnV6DatabaseFile = privateAsnV6DatabaseFile; - return this; - } - /** - * - * @param privateAsnV6DatabaseStream 加载ASN IPv6 database流 - * @return - */ - public Builder loadDataFilePrivateV6(InputStream privateAsnV6DatabaseStream) { - this.privateAsnV6DatabaseStream = privateAsnV6DatabaseStream; - return this; - } - - - /** - * 构建对象 - * @return - * @throws IOException - */ - public AsnLookup build() { - return new AsnLookup(this); - } - - - - } - - - public String asnLookup(String ip) { - - LocationResponseV2 response = getResponse(ip); - - if (StringUtil.isEmpty(response) || response.isPrivateIP()) { - return UNKNOWN; - } - - return StringUtil.setDefaultIfEmpty(response.getAsn(), UNKNOWN).toString() ; - - - } - - public String asnLookupOrganization(String ip) { - LocationResponseV2 response = getResponse(ip); - if (StringUtil.isEmpty(response) || response.isPrivateIP()) { - return UNKNOWN; - } - return response.getOrganization(); - } - - public String asnLookupInfo(String ip) { - LocationResponseV2 response = getResponse(ip); - if (StringUtil.isEmpty(response) || response.isPrivateIP()) { - return UNKNOWN; - } - return Joiner.on(SEPARATOR).useForNull("").join(response.getCountryCode(), response.getOrganization()); - - } - - - - - public String asnLookupDetail(String ip) { - LocationResponseV2 response = getResponse(ip); - - if (StringUtil.isEmpty(response) || response.isPrivateIP()) { - return UNKNOWN; - } - return Joiner.on(SEPARATOR).useForNull("").join(response.getAsn(), response.getCountryCode(), response.getOrganization()); - } - - - - - - - private LocationResponseV2 getResponse(String ip) { - LocationResponseV2 response = null; - if (IPUtil.isIPv4Address(ip) || IPUtil.isIPv6Address(ip)) { - response = new Context(new PrivateReader()).executeStragey(ip); - if (StringUtil.isEmpty(response)) { - response = new Context(new PublicReader()).executeStragey(ip); - } - } else { - throw new IllegalArgumentException("Unknown IP format :" + ip ); - } - return response; - } - - - - - private GalaxyDataBaseReader getAsnDataBaseReaderV4(String service) { - - if (service.equalsIgnoreCase(ServiceEnum.PRIVATE.name())) { - if (StringUtil.isNotEmpty(privateV4DatabaseReader)) { - return privateV4DatabaseReader; - } else { - return privateDatabaseReader; - } - } else { - if (StringUtil.isNotEmpty(publicV4DatabaseReader)) { - return publicV4DatabaseReader; - } else{ - return publicDatabaseReader; - } - } - } - - private GalaxyDataBaseReader getAsnDataBaseReaderV6(String service) { - - if (service.equalsIgnoreCase(ServiceEnum.PRIVATE.name())) { - if (StringUtil.isNotEmpty(privateV6DatabaseReader)) { - return privateV6DatabaseReader; - } else { - return privateDatabaseReader; - } - } else { - if (StringUtil.isNotEmpty(publicV6DatabaseReader)) { - return publicV6DatabaseReader; - } else{ - return publicDatabaseReader; - } - } - } - - - - interface Strategy { - LocationResponseV2 getResponse(String ip); - } - - /** - * 用户自定义IP库的执行策略 - */ - class PrivateReader implements Strategy { - @Override - public LocationResponseV2 getResponse(String ip) { - GalaxyDataBaseReader dataBaseReader = null; - LocationResponseV2 response = null; - try { - InetAddress ipAddress = InetAddress.getByName(ip); - - if (IPUtil.isIPv4Address(ip)) { - dataBaseReader = getAsnDataBaseReaderV4(ServiceEnum.PRIVATE.name()); - } else if (IPUtil.isIPv6Address(ip)) { - dataBaseReader = getAsnDataBaseReaderV6(ServiceEnum.PRIVATE.name()); - } - - if (StringUtil.isNotEmpty(dataBaseReader)) { - response = dataBaseReader.locationV2(ipAddress); - } - - } catch(AddressNotFoundException addressNotFoundException) { - logger.debug("Address not found ,ip is :" + ip); - } catch (Exception e) { - throw new IllegalArgumentException("ip address :" + ip +", parser error " + e); - } - return response; - } - } - /** - * 第三方服务库的执行策略,例如maxmind、IPDAT - */ - class PublicReader implements Strategy { - @Override - public LocationResponseV2 getResponse(String ip) { - GalaxyDataBaseReader dataBaseReader = null; - LocationResponseV2 response = null; - - try { - InetAddress ipAddress = InetAddress.getByName(ip); - - if (IPUtil.isIPv4Address(ip)) { - dataBaseReader = getAsnDataBaseReaderV4(ServiceEnum.PUBLIC.name()); - - } else if (IPUtil.isIPv6Address(ip)) { - dataBaseReader = getAsnDataBaseReaderV6(ServiceEnum.PUBLIC.name()); - - } - - if (StringUtil.isNotEmpty(dataBaseReader)) { - response = dataBaseReader.locationV2(ipAddress); - } - - } catch(AddressNotFoundException addressNotFoundException) { - logger.debug("Address not found ,ip is :" + ip); - } catch (Exception e) { - throw new IllegalArgumentException("ip address :" + ip +", parser error " + e); - } - return response; - - - } - } - - - - class Context { - private Strategy strategy; - - public Context(Strategy strategy) { - this.strategy = strategy; - } - - public LocationResponseV2 executeStragey(String ip) { - - return strategy.getResponse(ip); - } - - } - - - - - - -} diff --git a/src/main/java/com/zdjizhi/utils/IpLookupV2.java b/src/main/java/com/zdjizhi/utils/IpLookupV2.java deleted file mode 100644 index 8ef1225..0000000 --- a/src/main/java/com/zdjizhi/utils/IpLookupV2.java +++ /dev/null @@ -1,894 +0,0 @@ -package com.zdjizhi.utils; - -import com.alibaba.fastjson2.JSON; -import com.google.common.base.Joiner; -import com.maxmind.db.CHMCache; -import com.maxmind.geoip2.exception.AddressNotFoundException; -import com.zdjizhi.domain.LocationResponseV2; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.InetAddress; -import java.net.URL; -import java.util.Optional; - -/** - * @ClassName IpLookupV2 - * @Description IP定位库与TSG四级IP定位库命名体系保持一致 - * @Author 中电积至有限公司 darnell - * @Date 2022-01-27 15:01 - * @Version 1.0.8 - **/ -public final class IpLookupV2 extends AbstractIpLookup{ - - enum ServiceEnum { - PRIVATE, PUBLIC - } - public final static String DEFAULT_DATABASE_PATH = "dat"; - private final static String DEFAULT_DB_IP_PUBLIC = "ip.mmdb"; - private final static String DEFAULT_DB_IP_PUBLIC_V4 = "ip_v4.mmdb"; - private final static String DEFAULT_DB_IP_PUBLIC_V6 = "ip_v6.mmdb"; - private final static String DEFAULT_DB_IP_PRIVATE = "ip_private.mmdb"; - private final static String DEFAULT_DB_IP_PRIVATE_V4 = "ip_private_v4.mmdb"; - private final static String DEFAULT_DB_IP_PRIVATE_V6 = "ip_private_v6.mmdb"; - - private AsnLookup asnLookup; - - private static GalaxyDataBaseReader publicDatabaseReader; - private static GalaxyDataBaseReader publicV4DatabaseReader; - private static GalaxyDataBaseReader publicV6DatabaseReader; - - private static GalaxyDataBaseReader privateDatabaseReader; - private static GalaxyDataBaseReader privateV4DatabaseReader; - private static GalaxyDataBaseReader privateV6DatabaseReader; - - synchronized void init(Builder builder) { - try { - - if (builder.isDefaultDB) { - - File publicDatabaseFile = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator - + DEFAULT_DB_IP_PUBLIC); - - if (!publicDatabaseFile.exists()) { - URL url = IpLookupV2.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_IP_PUBLIC); - if (url != null) { - publicDatabaseFile = new File(url.getPath()); - } - } - - File dbPublicV4File = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator - + DEFAULT_DB_IP_PUBLIC_V4); - - if (!dbPublicV4File.exists()) { - URL url = IpLookupV2.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_IP_PUBLIC_V4); - if (url != null) { - dbPublicV4File = new File(url.getPath()); - } - } - - File dbPublicV6File = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator - + DEFAULT_DB_IP_PUBLIC_V6); - if (!dbPublicV6File.exists()) { - URL url = IpLookupV2.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_IP_PUBLIC_V6); - if (url != null) { - dbPublicV6File = new File(url.getPath()); - } - } - - File dbPrivateFile = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator - +DEFAULT_DB_IP_PRIVATE); - - if (!dbPrivateFile.exists()) { - URL url = IpLookupV2.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_IP_PRIVATE); - if (url != null) { - dbPrivateFile = new File(url.getPath()); - } - } - - - File dbPrivateV4File = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator - + DEFAULT_DB_IP_PRIVATE_V4); - - if (!dbPrivateV4File.exists()) { - URL url = IpLookupV2.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_IP_PRIVATE_V4); - if (url != null) { - dbPrivateV4File = new File(url.getPath()); - } - } - - File dbPrivateV6File = new File(System.getProperty("user.dir") + File.separator + DEFAULT_DATABASE_PATH + File.separator - + DEFAULT_DB_IP_PRIVATE_V6); - if (!dbPrivateV6File.exists()) { - URL url = IpLookupV2.class.getResource("/"+ DEFAULT_DATABASE_PATH + "/" + DEFAULT_DB_IP_PRIVATE_V6); - if (url != null) { - dbPrivateV6File = new File(url.getPath()); - } - } - - - publicDatabaseReader = buildDataReader(publicDatabaseFile); - publicV4DatabaseReader = buildDataReader(dbPublicV4File); - publicV6DatabaseReader = buildDataReader(dbPublicV6File); - privateDatabaseReader = buildDataReader(dbPrivateFile); - privateV4DatabaseReader = buildDataReader(dbPrivateV4File); - privateV6DatabaseReader = buildDataReader(dbPrivateV6File); - - asnLookup = new AsnLookup.Builder(true).build(); - - } else { - - if (StringUtil.isNotBlank(builder.publicDatabaseFile)) { - publicDatabaseReader = buildDataReader(new File(builder.publicDatabaseFile)); - } else if (builder.publicDatabaseStream != null) { - publicDatabaseReader = buildDataReader(builder.publicDatabaseStream); - } - - if (StringUtil.isNotBlank(builder.publicV4DatabaseFile)) { - publicV4DatabaseReader = buildDataReader(new File(builder.publicV4DatabaseFile)); - } else if (builder.publicV4DatabaseStream != null) { - publicV4DatabaseReader = buildDataReader(builder.publicV4DatabaseStream); - } - - if (StringUtil.isNotBlank(builder.publicV6DatabaseFile)) { - publicV6DatabaseReader = buildDataReader(new File(builder.publicV6DatabaseFile)); - } else if (builder.publicV6DatabaseStream != null) { - publicV6DatabaseReader = buildDataReader(builder.publicV6DatabaseStream); - } - - if (StringUtil.isNotBlank(builder.privateDatabaseFile)) { - privateDatabaseReader = buildDataReader(new File(builder.privateDatabaseFile)); - } else if (builder.privateDatabaseStream != null) { - privateDatabaseReader = buildDataReader(builder.privateDatabaseStream); - - } - - if (StringUtil.isNotBlank(builder.privateV4DatabaseFile)) { - privateV4DatabaseReader = buildDataReader(new File(builder.privateV4DatabaseFile)); - } else if (builder.privateV4DatabaseStream != null) { - privateV4DatabaseReader = buildDataReader(builder.privateV4DatabaseStream); - } - - if (StringUtil.isNotBlank(builder.privateV6DatabaseFile)) { - privateV6DatabaseReader = buildDataReader(new File(builder.privateV6DatabaseFile)); - } else if (builder.privateV6DatabaseStream != null) { - privateV6DatabaseReader = buildDataReader(builder.privateV6DatabaseStream); - } - - asnLookup = new AsnLookup.Builder(false) - .loadDataFile(builder.publicAsnDatabaseFile) - .loadDataFile(builder.publicAsnDatabaseStream) - .loadDataFileV4(builder.publicAsnV4DatabaseFile) - .loadDataFileV4(builder.publicAsnV4DatabaseStream) - .loadDataFileV6(builder.publicAsnV6DatabaseFile) - .loadDataFileV6(builder.publicAsnV6DatabaseStream) - .loadDataFilePrivate(builder.privateAsnDatabaseFile) - .loadDataFilePrivate(builder.privateAsnDatabaseStream) - .loadDataFilePrivateV4(builder.privateAsnV4DatabaseFile) - .loadDataFilePrivateV4(builder.privateAsnV4DatabaseStream) - .loadDataFilePrivateV6(builder.privateAsnV6DatabaseFile) - .loadDataFilePrivateV6(builder.privateAsnV6DatabaseStream) - .build(); - } - - } catch (Exception e) { - logger.error("Unsupported GeoIP2 *.mmdb database: expected either File path or Stream. " + e); - } - - - } - - - private IpLookupV2(Builder builder) { - init(builder); - } - - private GalaxyDataBaseReader buildDataReader(File database) throws IOException { - if (database.exists()) { - return new GalaxyDataBaseReader.Builder(database).withCache(new CHMCache()).build(); - } else { - return null; - } - } - - private GalaxyDataBaseReader buildDataReader(InputStream stream) throws IOException { - if (stream != null) { - return new GalaxyDataBaseReader.Builder(stream).withCache(new CHMCache()).build(); - } else { - return null; - } - } - - - - /** - * 加载mmdb数据字典文件,内部生成mmdb动态库。 - * - * 1.默认记载IP库,使用方式如下: - * IpLookup ipLookup = new IpLookup.Builder(true).build(); - * 自动加载应用dat目录下的库文件,命名为:all_ip_info_v4.mmdb与all_ip_info_v6.mmdb库。 - * - * 2.手动加载IP库,使用方式如下: - * <p> - * IpLookup ipLookup = new IpLookup.Builder(false).loadDataFileV4("D:\\galaxy-tool\\dat\\ip.mmdb"). - * loadDataFileV6("D:\\galaxy-tool\\dat\\all_ip_info_v6.mmdb").build(); - * - * </p> - */ - public static final class Builder { - String publicDatabaseFile; - String publicV4DatabaseFile; - String publicV6DatabaseFile; - - InputStream publicDatabaseStream; - InputStream publicV4DatabaseStream; - InputStream publicV6DatabaseStream; - - String privateDatabaseFile; - String privateV4DatabaseFile; - String privateV6DatabaseFile; - - InputStream privateDatabaseStream; - InputStream privateV4DatabaseStream; - InputStream privateV6DatabaseStream; - - String publicAsnDatabaseFile; - String publicAsnV4DatabaseFile; - String publicAsnV6DatabaseFile; - - InputStream publicAsnDatabaseStream; - InputStream publicAsnV4DatabaseStream; - InputStream publicAsnV6DatabaseStream; - - String privateAsnDatabaseFile; - String privateAsnV4DatabaseFile; - String privateAsnV6DatabaseFile; - - InputStream privateAsnDatabaseStream; - InputStream privateAsnV4DatabaseStream; - InputStream privateAsnV6DatabaseStream; - - boolean isDefaultDB; - - /** - * - * @param isDefaultDB <code>false</code> 手动指定IP库路径 <code>true</code> 使用默认路径 - */ - public Builder(boolean isDefaultDB) { - this.isDefaultDB = isDefaultDB; - } - - /** - * @param publicDatabaseFile 加载GeoIP2 database 文件,不区分IPv4/6 - * @return - */ - public Builder loadDataFile(String publicDatabaseFile) { - this.publicDatabaseFile = publicDatabaseFile; - return this; - } - - /** - * @param publicDatabaseStream 加载GeoIP2流,不区分IPv4/6 - * @return - */ - public Builder loadDataFile(InputStream publicDatabaseStream) { - this.publicDatabaseStream = publicDatabaseStream; - return this; - } - - /** - * - * @param publicV4DatabaseFile 加载第三方内置GeoIP2 IPv4 database 文件 - * @return - */ - public Builder loadDataFileV4(String publicV4DatabaseFile) { - this.publicV4DatabaseFile = publicV4DatabaseFile; - return this; - } - - /** - * @param publicV4DatabaseStream 加载第三方内置GeoIP2 IPv4流 - * @return - */ - public Builder loadDataFileV4(InputStream publicV4DatabaseStream) { - this.publicV4DatabaseStream = publicV4DatabaseStream; - return this; - } - - - /** - * - * @param publicV6DatabaseFile 加载第三方内置GeoIP2 IPv6 database 文件 - * @return - */ - public Builder loadDataFileV6(String publicV6DatabaseFile) { - this.publicV6DatabaseFile = publicV6DatabaseFile; - return this; - } - - /** - * @param publicV6DatabaseStream 加载第三方内置GeoIP2 IPv6流 - * @return - */ - public Builder loadDataFileV6(InputStream publicV6DatabaseStream) { - this.publicV6DatabaseStream = publicV6DatabaseStream; - return this; - } - - - /** - * - * @param privateDatabaseFile 加载自定义GeoIP2 database 文件,不区分IPv4/6 - * @return - */ - public Builder loadDataFilePrivate(String privateDatabaseFile) { - this.privateDatabaseFile = privateDatabaseFile; - return this; - } - - /** - * - * @param privateDatabaseStream 加载自定义GeoIP2 流,不区分IPv4/6 - * @return - */ - public Builder loadDataFilePrivate(InputStream privateDatabaseStream) { - this.privateDatabaseStream = privateDatabaseStream; - return this; - } - - /** - * - * @param privateV4DatabaseFile 加载自定义GeoIP2 IPv4 database 文件 - * @return - */ - public Builder loadDataFilePrivateV4(String privateV4DatabaseFile) { - this.privateV4DatabaseFile = privateV4DatabaseFile; - return this; - } - - /** - * - * @param privateV4DatabaseStream 加载自定义GeoIP2 IPv4 流 - * @return - */ - public Builder loadDataFilePrivateV4(InputStream privateV4DatabaseStream) { - this.privateV4DatabaseStream = privateV4DatabaseStream; - return this; - } - - /** - * - * @param privateV6DatabaseFile 加载自定义GeoIP2 IPv6 database 文件 - * @return - */ - public Builder loadDataFilePrivateV6(String privateV6DatabaseFile) { - this.privateV6DatabaseFile = privateV6DatabaseFile; - return this; - } - - /** - * - * @param privateV6DatabaseStream 加载自定义GeoIP2 IPv6流 - * @return - */ - public Builder loadDataFilePrivateV6(InputStream privateV6DatabaseStream) { - this.privateV6DatabaseStream = privateV6DatabaseStream; - return this; - } - - - - /** - * - * @param publicAsnDatabaseFile 加载ASN database文件,不区分IPv4/6 - * @return - */ - public Builder loadAsnDataFile(String publicAsnDatabaseFile) { - this.publicAsnDatabaseFile = publicAsnDatabaseFile; - return this; - } - - /** - * - * @param publicAsnDatabaseStream 加载ASN database流,不区分IPv4/6 - * @return - */ - public Builder loadAsnDataFile(InputStream publicAsnDatabaseStream) { - this.publicAsnDatabaseStream = publicAsnDatabaseStream; - return this; - } - - - /** - * - * @param publicAsnV4DatabaseFile 加载ASN IPv4 database文件 - * @return - */ - public Builder loadAsnDataFileV4(String publicAsnV4DatabaseFile) { - this.publicAsnV4DatabaseFile = publicAsnV4DatabaseFile; - return this; - } - - /** - * - * @param publicAsnV4DatabaseStream 加载ASN IPv4 database流 - * @return - */ - public Builder loadAsnDataFileV4(InputStream publicAsnV4DatabaseStream) { - this.publicAsnV4DatabaseStream = publicAsnV4DatabaseStream; - return this; - } - - - /** - * - * @param publicAsnV6DatabaseFile 加载ASN IPv6 database文件 - * @return - */ - public Builder loadAsnDataFileV6(String publicAsnV6DatabaseFile) { - this.publicAsnV6DatabaseFile = publicAsnV6DatabaseFile; - return this; - } - - /** - * - * @param publicAsnV6DatabaseStream 加载ASN IPv6 database流 - * @return - */ - public Builder loadAsnDataFileV6(InputStream publicAsnV6DatabaseStream) { - this.publicAsnV6DatabaseStream = publicAsnV6DatabaseStream; - return this; - } - - - /** - * - * @param privateAsnDatabaseFile 加载ASN database文件,不区分IPv4/6 - * @return - */ - public Builder loadAsnDataFilePrivate(String privateAsnDatabaseFile) { - this.privateAsnDatabaseFile = privateAsnDatabaseFile; - return this; - } - - /** - * - * @param privateAsnDatabaseStream 加载ASN database流,不区分IPv4/6 - * @return - */ - public Builder loadAsnDataFilePrivate(InputStream privateAsnDatabaseStream) { - this.privateAsnDatabaseStream = privateAsnDatabaseStream; - return this; - } - - /** - * - * @param privateAsnV4DatabaseFile 加载ASN IPv4 database文件 - * @return - */ - public Builder loadAsnDataFilePrivateV4(String privateAsnV4DatabaseFile) { - this.privateAsnV4DatabaseFile = privateAsnV4DatabaseFile; - return this; - } - - /** - * - * @param privateAsnV4DatabaseStream 加载ASN IPv4 database流 - * @return - */ - public Builder loadAsnDataFilePrivateV4(InputStream privateAsnV4DatabaseStream) { - this.privateAsnV4DatabaseStream = privateAsnV4DatabaseStream; - return this; - } - - - /** - * - * @param privateAsnV6DatabaseFile 加载ASN IPv6 database文件 - * @return - */ - public Builder loadAsnDataFilePrivateV6(String privateAsnV6DatabaseFile) { - this.privateAsnV6DatabaseFile = privateAsnV6DatabaseFile; - return this; - } - - /** - * - * @param privateAsnV6DatabaseStream 加载ASN IPv6 database流 - * @return - */ - public Builder loadAsnDataFilePrivateV6(InputStream privateAsnV6DatabaseStream) { - this.privateAsnV6DatabaseStream = privateAsnV6DatabaseStream; - return this; - } - - /** - * 构建对象 - * @return - * @throws IOException - */ - public IpLookupV2 build() { - return new IpLookupV2(this); - } - - } - - @Override - public String countryLookup(String ip) { - - LocationResponseV2 response = getResponse(ip); - if (StringUtil.isEmpty(response)) { - return UNKNOWN; - } - if (response.isPrivateIP()) { - return PRIVATE_IP; - } - - return StringUtil.setDefaultIfEmpty(response.getCountry(), UNKNOWN).toString() ; - } - - @Override - public String cityLookupDetail(String ip) { - - LocationResponseV2 response = getResponse(ip); - - if (StringUtil.isEmpty(response)) { - return UNKNOWN; - } - if (response.isPrivateIP()) { - return PRIVATE_IP; - } - - return - Joiner.on(LOCATION_SEPARATOR).useForNull("").join(response.getCountry(), - response.getSuperAdministrativeArea(), response.getAdministrativeArea()); - } - - @Override - public String administrativeAreaLookupDetail(String ip) { - LocationResponseV2 response = getResponse(ip); - - if (StringUtil.isEmpty(response)) { - return UNKNOWN; - } - if (response.isPrivateIP()) { - return PRIVATE_IP; - } - - return Joiner.on(LOCATION_SEPARATOR).useForNull("").join(response.getCountry(), - response.getSuperAdministrativeArea(), response.getAdministrativeArea(), - response.getSubAdministrativeArea()); - - } - - @Override - public String locationLookupDetail(String ip) { - LocationResponseV2 response = getResponse(ip); - - if (StringUtil.isEmpty(response)) { - return UNKNOWN; - } - if (response.isPrivateIP()) { - return PRIVATE_IP; - } - - return Joiner.on(LOCATION_SEPARATOR).useForNull("").join(response.getCountry(), - response.getSuperAdministrativeArea(), response.getAdministrativeArea(), - response.getSubAdministrativeArea(), response.getLocality(), - response.getDependentLocality(), response.getDoubleDependentLocality()); - } - - @Override - public String cityLookup(String ip) { - LocationResponseV2 response = getResponse(ip); - - if (StringUtil.isEmpty(response)) { - return UNKNOWN; - } - if (response.isPrivateIP()) { - return PRIVATE_IP; - } - - return StringUtil.setDefaultIfEmpty(response.getAdministrativeArea(), UNKNOWN).toString() ; - - } - - @Override - public String countryCodeLookup(String ip) { - LocationResponseV2 response = getResponse(ip); - if (StringUtil.isEmpty(response)) { - return UNKNOWN; - } - return StringUtil.setDefaultIfEmpty(response.getCountryCode(), UNKNOWN).toString() ; - } - - @Override - public String regionCodeLookup(String ip) { - LocationResponseV2 response = getResponse(ip); - if (StringUtil.isEmpty(response)) { - return UNKNOWN; - } - return StringUtil.setDefaultIfEmpty(response.getAreaCode(), UNKNOWN).toString() ; - } - - @Override - public String infoLookupToCSV(String ip) { - LocationResponseV2 response = getResponse(ip); - if (StringUtil.isEmpty(response)) { - return UNKNOWN; - } - StringBuilder ipInfo = new StringBuilder(); - ipInfo.append( - Joiner.on(LOCATION_SEPARATOR).useForNull("").join(response.getCountry(), - response.getSuperAdministrativeArea(), response.getAdministrativeArea(), - response.getSubAdministrativeArea(), response.getLocality(), - response.getDependentLocality(), response.getDoubleDependentLocality())) - .append(OBJECT_SEPARATOR).append( - StringUtil.setDefaultIfEmpty(response.getIsp(), UNKNOWN).toString() - ).append(OBJECT_SEPARATOR).append( - StringUtil.setDefaultIfEmpty(response.getOrganization(), UNKNOWN).toString() - ).append(OBJECT_SEPARATOR).append( - asnLookup.asnLookup(ip) - ).append(OBJECT_SEPARATOR).append( - Joiner.on(LATLNG_SEPARATOR).skipNulls().join(response.getLatitude(), response.getLongitude()) - ); - - return ipInfo.toString(); - } - @Override - public String infoLookupToJson(String ip) { - LocationResponseV2 response = getResponse(ip); - if (StringUtil.isEmpty(response)) { - response = new LocationResponseV2(); - } - response.setAsn(asnLookup(ip)); - - return JSON.toJSONString(response); - } - - - @Override - public String provinceLookup(String ip) { - LocationResponseV2 response = getResponse(ip); - if (StringUtil.isEmpty(response)) { - return UNKNOWN; - } - if (response.isPrivateIP()) { - return PRIVATE_IP; - } - return StringUtil.setDefaultIfEmpty(response.getSuperAdministrativeArea(), UNKNOWN).toString() ; - } - - @Override - public String ispLookup(String ip) { - LocationResponseV2 response = getResponse(ip); - if (StringUtil.isEmpty(response)) { - return UNKNOWN; - } - if (response.isPrivateIP()) { - return PRIVATE_IP; - } - return StringUtil.setDefaultIfEmpty(response.getIsp(), UNKNOWN).toString() ; - } - - @Override - public String organizationLookup(String ip) { - LocationResponseV2 response = getResponse(ip); - if (StringUtil.isEmpty(response)) { - return UNKNOWN; - } - if (response.isPrivateIP()) { - return PRIVATE_IP; - } - return StringUtil.setDefaultIfEmpty(response.getOrganization(), UNKNOWN).toString() ; - } - - - - - @Override - public String latLngLookup(String ip) { - LocationResponseV2 response = getResponse(ip); - if (StringUtil.isEmpty(response) || response.isPrivateIP()) { - return UNKNOWN; - } - - return Joiner.on(LATLNG_SEPARATOR).skipNulls().join(response.getLatitude(), response.getLongitude()); - - } - - @Override - public String cityLatLngLookup(String ip) { - return Joiner.on(OBJECT_SEPARATOR).skipNulls().join(cityLookup(ip), latLngLookup(ip)); - } - - @Override - public String asnLookup(String ip) { - return asnLookup.asnLookup(ip); - } - - @Override - public String asnLookupOrganization(String ip) { - return asnLookup.asnLookupOrganization(ip); - } - @Override - public String asnLookupInfo(String ip) { - return asnLookup.asnLookupInfo(ip); - } - - @Override - public String asnLookupDetail(String ip) { - return asnLookup.asnLookupDetail(ip); - } - - private LocationResponseV2 getResponse(String ip) { - - ip = Optional.ofNullable(ip).orElse("").trim(); - - if (!IPUtil.isIPAddress(ip)) { - throw new IllegalArgumentException("Unknown IP format :" + ip ); - } - - LocationResponseV2 response = new Context(new PrivateReader()).executeStrategy(ip); - - if (StringUtil.isEmpty(response)) { - response = new Context(new PublicReader()).executeStrategy(ip); - } - - if (StringUtil.isEmpty(response)) { - response = new Context(new InnerReader()).executeStrategy(ip); - } - - return response; - } - - - - private GalaxyDataBaseReader getIpDataBaseReaderV4(String service) { - - if (service.equalsIgnoreCase(ServiceEnum.PRIVATE.name())) { - if (StringUtil.isNotEmpty(privateV4DatabaseReader)) { - return privateV4DatabaseReader; - } else { - return privateDatabaseReader; - } - } else { - if (StringUtil.isNotEmpty(publicV4DatabaseReader)) { - return publicV4DatabaseReader; - } else { - return publicDatabaseReader; - } - } - - } - - private GalaxyDataBaseReader getIpDataBaseReaderV6(String service) { - - if (service.equalsIgnoreCase(ServiceEnum.PRIVATE.name())) { - if (StringUtil.isNotEmpty(privateV6DatabaseReader)) { - return privateV6DatabaseReader; - } else { - return privateDatabaseReader; - } - } else { - if (StringUtil.isNotEmpty(publicV6DatabaseReader)) { - return publicV6DatabaseReader; - } else { - return publicDatabaseReader; - } - } - - } - - interface Strategy { - LocationResponseV2 getResponse(String ip); - } - - /** - * 用户自定义库的执行策略 - */ - class PrivateReader implements Strategy { - @Override - public LocationResponseV2 getResponse(String ip) { - GalaxyDataBaseReader dataBaseReader = null; - LocationResponseV2 response = null; - try { - InetAddress ipAddress = InetAddress.getByName(ip); - - if (IPUtil.isIPv4Address(ip)) { - dataBaseReader = getIpDataBaseReaderV4(ServiceEnum.PRIVATE.name()); - } else if (IPUtil.isIPv6Address(ip)) { - dataBaseReader = getIpDataBaseReaderV6(ServiceEnum.PRIVATE.name()); - } - - if (StringUtil.isNotEmpty(dataBaseReader)) { - response = dataBaseReader.locationV2(ipAddress); - } - - } catch(AddressNotFoundException addressNotFoundException) { - logger.debug("Address not found ,ip is :" + ip); - } catch (Exception e) { - throw new IllegalArgumentException("IP address :" + ip +", parser error " + e); - } - return response; - } - } - /** - * 公共库(系统内置)库执行策略 - */ - class PublicReader implements Strategy { - @Override - public LocationResponseV2 getResponse(String ip) { - GalaxyDataBaseReader dataBaseReader = null; - LocationResponseV2 response = null; - try { - InetAddress ipAddress = InetAddress.getByName(ip); - - if (IPUtil.isIPv4Address(ip)) { - dataBaseReader = getIpDataBaseReaderV4(ServiceEnum.PUBLIC.name()); - - } else if (IPUtil.isIPv6Address(ip)) { - dataBaseReader = getIpDataBaseReaderV6(ServiceEnum.PUBLIC.name()); - - } - - if (StringUtil.isNotEmpty(dataBaseReader)) { - response = dataBaseReader.locationV2(ipAddress); - } - - } catch(AddressNotFoundException addressNotFoundException) { - logger.debug("Address not found ,ip is :" + ip); - } catch (Exception e) { - throw new IllegalArgumentException("ip address :" + ip +", parser error " + e); - } - return response; - - - } - } - - /** - * 私有IP执行策略 - */ - class InnerReader implements Strategy { - @Override - public LocationResponseV2 getResponse(String ip) { - LocationResponseV2 response = null; - if(IPUtil.isIPv4Address(ip) && IPUtil.internalIp(ip)) { - response = new LocationResponseV2(); - response.setPrivateIP(true); - } - return response; - } - } - - - class Context { - private Strategy strategy; - - public Context(Strategy strategy) { - this.strategy = strategy; - } - - public LocationResponseV2 executeStrategy(String ip) { - return strategy.getResponse(ip); - } - - } - - - - -} - - - - - - - - - - - diff --git a/src/test/java/com/zdjizhi/test/DateUtilTest.java b/src/test/java/com/geedgenetworks/test/DateUtilTest.java index 7c08212..ab38f73 100644 --- a/src/test/java/com/zdjizhi/test/DateUtilTest.java +++ b/src/test/java/com/geedgenetworks/test/DateUtilTest.java @@ -1,4 +1,4 @@ -package com.zdjizhi.test; +package com.geedgenetworks.test; import java.util.Collections; import java.util.Date; @@ -6,8 +6,8 @@ import java.util.List; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; -import com.zdjizhi.utils.DateUtils; -import com.zdjizhi.utils.TimeConstants; +import com.geedgenetworks.utils.DateUtils; +import com.geedgenetworks.utils.TimeConstants; import org.apache.log4j.Logger; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/com/zdjizhi/test/FormatUtilTest.java b/src/test/java/com/geedgenetworks/test/FormatUtilTest.java index 6b822de..fddc4f0 100644 --- a/src/test/java/com/zdjizhi/test/FormatUtilTest.java +++ b/src/test/java/com/geedgenetworks/test/FormatUtilTest.java @@ -1,9 +1,7 @@ -package com.zdjizhi.test; +package com.geedgenetworks.test; -import com.google.common.net.InternetDomainName; -import com.zdjizhi.utils.Encodes; -import com.zdjizhi.utils.FormatUtils; -import com.zdjizhi.utils.StringUtil; +import com.geedgenetworks.utils.Encodes; +import com.geedgenetworks.utils.FormatUtils; import org.apache.commons.io.FileUtils; import org.junit.Assert; @@ -11,9 +9,7 @@ import org.junit.Test; import java.io.File; import java.io.IOException; -import java.net.URI; import java.util.ArrayList; -import java.util.Base64; import java.util.HashSet; import java.util.List; import java.util.Set; diff --git a/src/test/java/com/zdjizhi/test/IPBenchMarkTest.java b/src/test/java/com/geedgenetworks/test/IPBenchMark.java index e1cb266..8a34e89 100644 --- a/src/test/java/com/zdjizhi/test/IPBenchMarkTest.java +++ b/src/test/java/com/geedgenetworks/test/IPBenchMark.java @@ -1,7 +1,6 @@ -package com.zdjizhi.test; +package com.geedgenetworks.test; -import com.zdjizhi.utils.AsnLookup; -import com.zdjizhi.utils.IpLookupV2; +import com.geedgenetworks.utils.IpLookupV2; import org.apache.log4j.Logger; import java.io.File; @@ -11,21 +10,22 @@ import java.io.IOException; import java.net.InetAddress; import java.util.Random; -public class IPBenchMarkTest { +public class IPBenchMark { private final static Logger logger = Logger.getLogger(IpLookupV2Test.class); private final static boolean TRACE = false; - private final static int COUNT = 1000000; + private final static int BENCHMARKS = 10; - private final static int SEED = 5; - + enum SourceType{ + FILE, STREAM + } - private IpLookupV2 ipLookup = getIpLookupByDatabase(); + private static final String defaultSourceType = SourceType.STREAM.name(); - private IpLookupV2 ipLookupA = getIpLookupByStream(); + private static IpLookupV2 ipLookup; - private IpLookupV2 getIpLookupByDatabase() { + private static IpLookupV2 getIpLookupByDatabase() { return new IpLookupV2.Builder(false) .loadDataFileV4("dat/ip_v4_built_in.mmdb") .loadDataFilePrivateV6("dat/ip_v4_user_defined.mmdb") @@ -36,7 +36,7 @@ public class IPBenchMarkTest { .build(); } - private IpLookupV2 getIpLookupByStream() { + private static IpLookupV2 getIpLookupByStream() { IpLookupV2 ipLookupV2 = null; try { ipLookupV2 = new IpLookupV2.Builder(false) @@ -53,14 +53,16 @@ public class IPBenchMarkTest { return ipLookupV2; } - private static AsnLookup asnLookup = new AsnLookup.Builder(false) - .loadDataFileV4("dat/asn_v4.mmdb") - .loadDataFileV6("dat/asn_v6.mmdb") - .build(); - public static void main(String[] args) throws IOException{ - for(int i=0; i< SEED; i++) { - new IPBenchMarkTest().benchMark(COUNT, i); + if (defaultSourceType.equals(SourceType.FILE.name())) { + ipLookup = getIpLookupByDatabase(); + } else if (defaultSourceType.equals(SourceType.STREAM.name())) { + ipLookup = getIpLookupByStream(); + } else { + throw new IllegalArgumentException("Unknown Source Type"); + } + for(int i=0; i< BENCHMARKS; i++) { + new IPBenchMark().benchMark(COUNT, i); } } @@ -71,7 +73,7 @@ public class IPBenchMarkTest { for (int i = 0; i < count; i++) { random.nextBytes(address); InetAddress ip = InetAddress.getByAddress(address); - String ipInfo = ipLookup.infoLookupToCSV(ip.getHostAddress()); + Object ipInfo = ipLookup.infoLookup(ip.getHostAddress()); if (TRACE) { if (i % 50000 == 0) { logger.info(i + " " + ip); diff --git a/src/test/java/com/geedgenetworks/test/IpLookupV2Test.java b/src/test/java/com/geedgenetworks/test/IpLookupV2Test.java new file mode 100644 index 0000000..8ff7d93 --- /dev/null +++ b/src/test/java/com/geedgenetworks/test/IpLookupV2Test.java @@ -0,0 +1,179 @@ +package com.geedgenetworks.test; + +import com.alibaba.fastjson2.JSONObject; +import com.geedgenetworks.utils.AbstractIpLookup; +import com.geedgenetworks.utils.IpLookupV2; +import com.maxmind.db.Network; +import org.apache.log4j.Logger; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.net.InetAddress; +import java.net.UnknownHostException; + +import static org.junit.Assert.assertEquals; + + +public class IpLookupV2Test { + Logger logger = Logger.getLogger(IpLookupV2Test.class); + @Rule + public ExpectedException expectedEx = ExpectedException.none(); + + IpLookupV2 ipLookupA = getIpLookupByDatabase(); + IpLookupV2 ipLookup = getIpLookupByStream(); + + private IpLookupV2 getIpLookupByDatabase() { + return new IpLookupV2.Builder(false) + .loadDataFileV4("dat/ip_v4_built_in.mmdb") + .loadDataFilePrivateV6("dat/ip_v4_user_defined.mmdb") + .loadDataFileV6("dat/ip_v6_built_in.mmdb") + .loadDataFilePrivateV6("dat/ip_v6_user_defined.mmdb") + .loadAsnDataFile("dat/asn_v4.mmdb") + .loadAsnDataFileV6("dat/asn_v6.mmdb") + .build(); + } + + private IpLookupV2 getIpLookupByStream() { + IpLookupV2 ipLookupV2 = null; + try { + ipLookupV2 = new IpLookupV2.Builder(true) + .loadDataFileV4(new FileInputStream(new File("dat/ip_v4_built_in.mmdb"))) + .loadDataFilePrivateV4(new FileInputStream(new File("dat/ip_v4_user_defined.mmdb"))) + .loadDataFileV6(new FileInputStream(new File("dat/ip_v6_built_in.mmdb"))) + .loadDataFilePrivateV6(new FileInputStream(new File("dat/ip_v6_user_defined.mmdb"))) + .loadAsnDataFile(new FileInputStream(new File("dat/asn_v4.mmdb"))) + .loadAsnDataFileV6(new FileInputStream(new File("dat/asn_v6.mmdb"))) + .build(); + }catch (FileNotFoundException e) { + logger.error(" File is not found:", e); + } + return ipLookupV2; + } + + @Test + public void testLoadPrivateIPv4MMDBFiles() { + try { + IpLookupV2 ipLookupV4 = new IpLookupV2.Builder(false) + .loadDataFilePrivateV4(new FileInputStream(new File("dat/ip_v4_user_defined.mmdb"))) + .build(); + assertEquals(ipLookupV4.getDbReaders().get(AbstractIpLookup.IpVersion.IPv4.name()).size(), 1); + }catch (FileNotFoundException e) { + logger.error(" File is not found:", e); + } + + } + + @Test + public void testLoadAllPrivateIPv4MMDBFiles() { + try { + IpLookupV2 ipLookupV4 = new IpLookupV2.Builder(false) + .loadDataFilePrivateV4(new FileInputStream(new File("dat/ip_v4_user_defined.mmdb"))) + .loadDataFileV4(new FileInputStream(new File("dat/ip_v4_built_in.mmdb"))) + .build(); + assertEquals(ipLookupV4.getDbReaders().get(AbstractIpLookup.IpVersion.IPv4.name()).size(), 2); + } catch (FileNotFoundException e) { + logger.error(" File is not found:", e); + } + + } + + @Test + public void testLoadDefaultMMDBFiles() { + + IpLookupV2 tmpIpLookup = new IpLookupV2.Builder(true).build(); + logger.info(tmpIpLookup.cityLookup("120.221.155.223")); + + } + + @Test + public void testPrivateIP() { + assertEquals(ipLookupA.countryLookup("192.168.10.123"), "Private IP"); + Object jsonObject = ipLookupA.infoLookupToJSON("120.221.155.223"); + logger.info(jsonObject); + } + + @Test(expected=IllegalArgumentException.class) + public void testIpLookupIllegalArguments(){ + ipLookup.countryLookup("116.178.179.336"); + } + + @Test(expected=IllegalArgumentException.class) + public void testIPIsBlank() { + ipLookup.countryLookup(""); + } + @Test(expected=IllegalArgumentException.class) + public void testIPIsNull() { + ipLookup.countryLookup(null); + } + + @Test + public void testIpLookupOutput() { + assertEquals(ipLookup.countryLookup("120.221.155.223"), "China"); + assertEquals(ipLookup.provinceLookup("120.221.155.223"), "Shandong"); + assertEquals(ipLookup.cityLookup("120.221.155.223"), "Other"); + assertEquals(ipLookup.cityLookupDetail("120.221.155.223").split("\\" + AbstractIpLookup.LOCATION_SEPARATOR).length, 3); + assertEquals(ipLookup.locationLookupDetail("120.221.155.223").split("\\" + AbstractIpLookup.LOCATION_SEPARATOR).length, 7); + assertEquals(ipLookup.administrativeAreaLookupDetail("120.221.155.223").split("\\" + AbstractIpLookup.LOCATION_SEPARATOR).length, 4); + assertEquals(ipLookup.latLngLookup("120.221.155.223"), "36.0986,120.3719"); + assertEquals(ipLookup.cityLatLngLookup("120.221.155.223").split( AbstractIpLookup.OBJECT_SEPARATOR).length, 2); + assertEquals(ipLookup.ispLookup("120.221.155.223"), "-"); + assertEquals(ipLookup.organizationLookup("120.221.155.223"), ""); + assertEquals(ipLookup.infoLookupToCSV("120.221.155.223").split( AbstractIpLookup.OBJECT_SEPARATOR).length, 5); + assertEquals(JSONObject.from(ipLookup.infoLookupToJSON("120.221.155.223")).get("country"),"China"); + } + + @Test + public void testOutputJson() { + logger.info(ipLookup.infoLookupToJSON("120.221.155.223")); + logger.info(ipLookup.infoLookupToJSON("2001:db8:3333:4444:5555:6666:7777:8888")); + logger.info(ipLookup.infoLookupToJSON("2001:db8::")); + logger.info(ipLookup.infoLookupToJSON("120.221.155.223")); + + } + + @Test + public void testIPv6() throws UnknownHostException { + Network network = new Network( + InetAddress.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), + 28 + ); + + assertEquals("2001:db0:0:0:0:0:0:0", network.getNetworkAddress().getHostAddress()); + assertEquals(28, network.getPrefixLength()); + assertEquals("2001:db0:0:0:0:0:0:0/28", network.toString()); + } + + + @Test + public void testUnknownIP() { + logger.info(ipLookup.infoLookupToJSON("255.244.255.254")); + logger.info(ipLookup.infoLookupToJSON("8.8.8.8")); + } + + + @Test + public void testAsnLookupOutput() { + logger.info(ipLookup.asnLookupOrganization("8.8.8.8")); + logger.info(ipLookup.asnLookupDetail("8.8.8.8")); + logger.info(ipLookup.asnLookupOrganization("8.8.8.8")); + + + + } + + + + + + + + + + + +} + diff --git a/src/test/java/com/zdjizhi/test/JsonMapperTest.java b/src/test/java/com/geedgenetworks/test/JsonMapperTest.java index bd8c5bd..a5dd0d8 100644 --- a/src/test/java/com/zdjizhi/test/JsonMapperTest.java +++ b/src/test/java/com/geedgenetworks/test/JsonMapperTest.java @@ -1,8 +1,8 @@ -package com.zdjizhi.test; +package com.geedgenetworks.test; import com.google.common.collect.Maps; -import com.zdjizhi.utils.CommonUtil; -import com.zdjizhi.utils.JsonMapper; +import com.geedgenetworks.utils.CommonUtil; +import com.geedgenetworks.utils.JsonMapper; import org.junit.Test; import java.util.Map; diff --git a/src/test/java/com/zdjizhi/test/HllSketchTest.java b/src/test/java/com/zdjizhi/test/HllSketchTest.java deleted file mode 100644 index 3821724..0000000 --- a/src/test/java/com/zdjizhi/test/HllSketchTest.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.zdjizhi.test; - -import com.zdjizhi.utils.IPUtil; -import org.apache.commons.lang3.RandomUtils; -import org.apache.datasketches.frequencies.ErrorType; -import org.apache.datasketches.frequencies.ItemsSketch; -import org.apache.datasketches.hll.HllSketch; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.List; - -public class HllSketchTest { - @Test - public void testHllSketch() { - HllSketch sketch = new HllSketch(); - long ipaddr = IPUtil.getIpDesimal("1.1.1.1"); - long n = 10000000; - List<String> ipSets = new ArrayList<String>(); - for (int i = 0; i < n; i++) { - String ip = String.valueOf(ipaddr + RandomUtils.nextInt(1, 100000000)); - ipSets.add(ip); - sketch.update(IPUtil.getIpString(ip)); - } - - long startTime = System.nanoTime(); - System.out.println("Unique IPs: " + ipSets.stream().distinct().count()); - System.out.println((System.nanoTime() - startTime) / 1000 / 1000 + "s"); - - startTime = System.nanoTime(); - System.out.println("Estimated IPs:" + sketch.getEstimate()); - System.out.println(sketch.toString()); - System.out.println((System.nanoTime() - startTime) / 1000 / 1000 + "s"); - - } - - @Test - public void testFrequentItems() { - ItemsSketch<String> sketch = new ItemsSketch<String>(67108864); - sketch.update("abc.com", 10); - sketch.update("bcd.com", 5); - sketch.update("def.com", 5); - sketch.update("efg.com", 8); - sketch.update("abc.com", 5); - sketch.update("121.com", 5); - sketch.update("bcd1.com", 5); - sketch.update("def2.com", 5); - sketch.update("ef3.com", 8); - sketch.update("abc4.com", 5); - - for (ItemsSketch.Row<String> item : sketch.getFrequentItems(ErrorType.NO_FALSE_POSITIVES)) { - System.out.println(item.getItem() + "-" + item.getEstimate()); - - } - } - - - @Test - public void topK() { - ItemsSketch<String> sk = new ItemsSketch<>(16); - sk.update("1.1.1.1", 1020); - sk.update("1.1.1.2", 21020); - sk.update("1.1.1.1", 100); - sk.update("1.1.1.3", 100); - sk.update("1.1.1.3", 100); - sk.update("1.1.1.4", 100); - sk.update("1.1.1.5", 100); - sk.update("1.1.1.6", 100); - sk.update("1.1.1.10", 100); - sk.update("1.1.1.5", 100000); - sk.update("1.1.1.9", 100); - sk.update("1.1.1.234", 100); - sk.update("1.1.2.234", 100); - sk.update("2.1.2.234", 100); - sk.update("2.2.2.234", 100); - sk.update("10.1.2.234", 100); - sk.update("102.1.2.234", 100); - - - ItemsSketch.Row<String>[] items = sk.getFrequentItems(10, ErrorType.NO_FALSE_POSITIVES); - System.out.println(sk.getNumActiveItems()); - for (ItemsSketch.Row<String> item : items) { - - System.out.println(item.getItem() - + " - " + item.getEstimate() - + " - " + item.getLowerBound() - + " - " + item.getUpperBound()); - - - } - } - - -} diff --git a/src/test/java/com/zdjizhi/test/IpLookupV2Test.java b/src/test/java/com/zdjizhi/test/IpLookupV2Test.java deleted file mode 100644 index 8dafc73..0000000 --- a/src/test/java/com/zdjizhi/test/IpLookupV2Test.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.zdjizhi.test; - -import com.zdjizhi.utils.IpLookupV2; -import org.apache.log4j.Logger; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; - - -public class IpLookupV2Test { - Logger logger = Logger.getLogger(IpLookupV2Test.class); - @Rule - public ExpectedException expectedEx = ExpectedException.none(); - - IpLookupV2 ipLookupA = getIpLookupByDatabase(); - - IpLookupV2 ipLookup = getIpLookupByStream(); - - - private IpLookupV2 getIpLookupByDatabase() { - return new IpLookupV2.Builder(false) - .loadDataFileV4("dat/ip_v4_built_in.mmdb") - .loadDataFilePrivateV6("dat/ip_v4_user_defined.mmdb") - .loadDataFileV6("dat/ip_v6_built_in.mmdb") - .loadDataFilePrivateV6("dat/ip_v6_user_defined.mmdb") - .loadAsnDataFile("dat/asn_v4.mmdb") - .loadAsnDataFileV6("dat/asn_v6.mmdb") - .build(); - } - - private IpLookupV2 getIpLookupByStream() { - IpLookupV2 ipLookupV2 = null; - try { - ipLookupV2 = new IpLookupV2.Builder(false) - .loadDataFileV4(new FileInputStream(new File("dat/ip_v4_built_in.mmdb"))) - .loadDataFilePrivateV4(new FileInputStream(new File("dat/ip_v4_user_defined.mmdb"))) - .loadDataFileV6(new FileInputStream(new File("dat/ip_v6_built_in.mmdb"))) - .loadDataFilePrivateV6(new FileInputStream(new File("dat/ip_v6_user_defined.mmdb"))) - .loadAsnDataFile(new FileInputStream(new File("dat/asn_v4.mmdb"))) - .loadAsnDataFileV6(new FileInputStream(new File("dat/asn_v6.mmdb"))) - .build(); - }catch (FileNotFoundException e) { - logger.error(" File is not found:", e); - } - return ipLookupV2; - } - @Test - public void testPrivateIP() { - Assert.assertEquals(ipLookup.countryLookup("192.168.10.123"), "Private IP"); - } - - @Test(expected=IllegalArgumentException.class) - public void testIpLookupIllegalArguments(){ - ipLookup.countryLookup("116.178.179.336"); - } - - @Test - public void testIpLookupOutput() { - logger.info(ipLookup.countryLookup("120.221.155.223")); - logger.info(ipLookup.provinceLookup("120.221.155.223")); - logger.info(ipLookup.cityLookup("120.221.155.223")); - logger.info(ipLookup.cityLookupDetail("120.221.155.223")); - logger.info(ipLookup.administrativeAreaLookupDetail("120.221.155.223")); - logger.info(ipLookup.locationLookupDetail("120.221.155.223")); - logger.info(ipLookup.latLngLookup("120.221.155.223")); - logger.info(ipLookup.cityLatLngLookup("120.221.155.223")); - logger.info(ipLookup.ispLookup("120.221.155.223")); - logger.info(ipLookup.organizationLookup("120.221.155.223")); - logger.info(ipLookup.asnLookup("120.221.155.223")); - logger.info(ipLookup.infoLookupToCSV("120.221.155.223")); - logger.info(ipLookup.infoLookupToJson("120.221.155.223")); - - } - - @Test - public void testOutputJson() { - logger.info(ipLookup.infoLookupToJson("120.221.155.223")); - - } - - - @Test - public void testAsnLookupOutput() { - - - logger.info(ipLookup.asnLookupOrganization("8.8.8.8")); - logger.info(ipLookup.asnLookupDetail("8.8.8.8")); - logger.info(ipLookup.asnLookupOrganization("8.8.8.8")); - - - - } - - - - - - - - - - - -} - |
