Skip to content

Commit

Permalink
Merge pull request #385 from maxmind/greg/is-anycast
Browse files Browse the repository at this point in the history
Add support for is_anycast
  • Loading branch information
horgh authored Dec 4, 2023
2 parents 1426b67 + 44e39b9 commit c7c6701
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 6 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ CHANGELOG
the `JsonCreator` annotation so that it is used when deserializing.
This will prevent new additions in the future from causing a
deserialization error.
* The `isAnycast()` method was added to `com.maxmind.geoip2.record.Traits`.
This returns `true` if the IP address belongs to an [anycast
network](https://en.wikipedia.org/wiki/Anycast). This is available for the
GeoIP2 Country, City Plus, and Insights web services and the GeoIP2 Country,
City, and Enterprise databases.

4.1.0 (2023-07-28)
------------------
Expand Down
124 changes: 122 additions & 2 deletions src/main/java/com/maxmind/geoip2/record/Traits.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public final class Traits extends AbstractRecord {
private final boolean isAnonymous;
private final boolean isAnonymousProxy;
private final boolean isAnonymousVpn;
private final boolean isAnycast;
private final boolean isHostingProvider;
private final boolean isLegitimateProxy;
private final boolean isPublicProxy;
Expand All @@ -41,14 +42,14 @@ public final class Traits extends AbstractRecord {

public Traits() {
this(null, null, null, null,
null, false, false, false, false,
null, false, false, false, false, false,
false, false, false, false, false, null,
null, null, null, null, null, null, null);
}

public Traits(String ipAddress, Network network) {
this(null, null, null, null,
ipAddress, false, false, false, false,
ipAddress, false, false, false, false, false,
false, false, false, false, false, null,
null, null, network, null, null, null, null);
}
Expand All @@ -62,6 +63,7 @@ public Traits(
@JsonProperty("is_anonymous") boolean isAnonymous,
@JsonProperty("is_anonymous_proxy") boolean isAnonymousProxy,
@JsonProperty("is_anonymous_vpn") boolean isAnonymousVpn,
@JsonProperty("is_anycast") boolean isAnycast,
@JsonProperty("is_hosting_provider") boolean isHostingProvider,
@JsonProperty("is_legitimate_proxy") boolean isLegitimateProxy,
@JsonProperty("is_public_proxy") boolean isPublicProxy,
Expand All @@ -86,6 +88,7 @@ public Traits(
this.isAnonymous = isAnonymous;
this.isAnonymousProxy = isAnonymousProxy;
this.isAnonymousVpn = isAnonymousVpn;
this.isAnycast = isAnycast;
this.isHostingProvider = isHostingProvider;
this.isLegitimateProxy = isLegitimateProxy;
this.isPublicProxy = isPublicProxy;
Expand Down Expand Up @@ -113,6 +116,7 @@ public Traits(
@MaxMindDbParameter(name = "is_anonymous") Boolean isAnonymous,
@MaxMindDbParameter(name = "is_anonymous_proxy") Boolean isAnonymousProxy,
@MaxMindDbParameter(name = "is_anonymous_vpn") Boolean isAnonymousVpn,
@MaxMindDbParameter(name = "is_anycast") Boolean isAnycast,
@MaxMindDbParameter(name = "is_hosting_provider") Boolean isHostingProvider,
@MaxMindDbParameter(name = "is_legitimate_proxy") Boolean isLegitimateProxy,
@MaxMindDbParameter(name = "is_public_proxy") Boolean isPublicProxy,
Expand All @@ -136,6 +140,7 @@ public Traits(
this.isAnonymous = isAnonymous != null ? isAnonymous : false;
this.isAnonymousProxy = isAnonymousProxy != null ? isAnonymousProxy : false;
this.isAnonymousVpn = isAnonymousVpn != null ? isAnonymousVpn : false;
this.isAnycast = isAnycast != null ? isAnycast : false;
this.isHostingProvider = isHostingProvider != null ? isHostingProvider : false;
this.isLegitimateProxy = isLegitimateProxy != null ? isLegitimateProxy : false;
this.isPublicProxy = isPublicProxy != null ? isPublicProxy : false;
Expand All @@ -152,6 +157,110 @@ public Traits(
this.staticIpScore = staticIpScore;
}

@Deprecated
public Traits(
Long autonomousSystemNumber,
String autonomousSystemOrganization,
ConnectionType connectionType,
String domain,
String ipAddress,
boolean isAnonymous,
boolean isAnonymousProxy,
boolean isAnonymousVpn,
boolean isHostingProvider,
boolean isLegitimateProxy,
boolean isPublicProxy,
boolean isResidentialProxy,
boolean isSatelliteProvider,
boolean isTorExitNode,
String isp,
String mobileCountryCode,
String mobileNetworkCode,
Network network,
String organization,
String userType,
Integer userCount,
Double staticIpScore
) {
this(
autonomousSystemNumber,
autonomousSystemOrganization,
connectionType,
domain,
ipAddress,
isAnonymous,
isAnonymousProxy,
isAnonymousVpn,
false, // isAnycast
isHostingProvider,
isLegitimateProxy,
isPublicProxy,
isResidentialProxy,
isSatelliteProvider,
isTorExitNode,
isp,
mobileCountryCode,
mobileNetworkCode,
network,
organization,
userType,
userCount,
staticIpScore
);
}

@Deprecated
public Traits(
Long autonomousSystemNumber,
String autonomousSystemOrganization,
String connectionType,
String domain,
String ipAddress,
Boolean isAnonymous,
Boolean isAnonymousProxy,
Boolean isAnonymousVpn,
Boolean isHostingProvider,
Boolean isLegitimateProxy,
Boolean isPublicProxy,
Boolean isResidentialProxy,
Boolean isSatelliteProvider,
Boolean isTorExitNode,
String isp,
String mobileCountryCode,
String mobileNetworkCode,
Network network,
String organization,
String userType,
Integer userCount,
Double staticIpScore
) {
this(
autonomousSystemNumber,
autonomousSystemOrganization,
connectionType,
domain,
ipAddress,
isAnonymous,
isAnonymousProxy,
isAnonymousVpn,
false, // isAnycast
isHostingProvider,
isLegitimateProxy,
isPublicProxy,
isResidentialProxy,
isSatelliteProvider,
isTorExitNode,
isp,
mobileCountryCode,
mobileNetworkCode,
network,
organization,
userType,
userCount,
staticIpScore
);
}

public Traits(
Traits traits,
String ipAddress,
Expand All @@ -166,6 +275,7 @@ public Traits(
traits.isAnonymous(),
traits.isAnonymousProxy(),
traits.isAnonymousVpn(),
traits.isAnycast(),
traits.isHostingProvider(),
traits.isLegitimateProxy(),
traits.isPublicProxy(),
Expand Down Expand Up @@ -303,6 +413,16 @@ public boolean isAnonymousVpn() {
return this.isAnonymousVpn;
}

/**
* @return This is true if the IP address belongs to an <a
* href="https://en.wikipedia.org/wiki/Anycast">anycast network</a>.
* This is not available from GeoLite databases or web services.
*/
@JsonProperty("is_anycast")
public boolean isAnycast() {
return this.isAnycast;
}

/**
* @return This is true if the IP address belongs to a hosting or
* VPN provider (see description of isAnonymousVpn). This is only
Expand Down
12 changes: 12 additions & 0 deletions src/test/java/com/maxmind/geoip2/DatabaseReaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,10 @@ public void testCity() throws Exception {
CityResponse tryResponse = reader.tryCity(ipAddress).get();
assertEquals(response.toJson(), tryResponse.toJson());

// This IP has is_anycast
response = reader.city(InetAddress.getByName("214.1.1.0"));
assertTrue(response.getTraits().isAnycast());

// Test that the methods can be called on DB without
// an exception
reader.country(ipAddress);
Expand Down Expand Up @@ -313,6 +317,10 @@ public void testCountry() throws Exception {

CountryResponse tryResponse = reader.tryCountry(ipAddress).get();
assertEquals(response.toJson(), tryResponse.toJson());

// This IP has is_anycast
response = reader.country(InetAddress.getByName("214.1.1.0"));
assertTrue(response.getTraits().isAnycast());
}
}

Expand Down Expand Up @@ -357,6 +365,10 @@ public void testEnterprise() throws Exception {
assertEquals("310", response.getTraits().getMobileCountryCode());
assertEquals("004", response.getTraits().getMobileNetworkCode());

// This IP has is_anycast
response = reader.enterprise(InetAddress.getByName("214.1.1.0"));
assertTrue(response.getTraits().isAnycast());

// Test that the city and country methods can be called without
// an exception
reader.city(ipAddress);
Expand Down
1 change: 1 addition & 0 deletions src/test/java/com/maxmind/geoip2/WebServiceClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ public void test200WithDefaultValues() throws Exception {
assertNull(traits.getStaticIpScore());
assertNull(traits.getUserCount());
assertFalse(traits.isAnonymousProxy());
assertFalse(traits.isAnycast());
assertFalse(traits.isSatelliteProvider());

for (Country c : new Country[] {country, registeredCountry,
Expand Down
4 changes: 3 additions & 1 deletion src/test/java/com/maxmind/geoip2/model/JsonTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public void testInsightsSerialization() throws IOException {
.put("is_anonymous", true)
.put("is_anonymous_proxy", true)
.put("is_anonymous_vpn", true)
.put("is_anycast", true)
.put("is_hosting_provider", true)
.put("is_legitimate_proxy", true)
.put("is_public_proxy", true)
Expand Down Expand Up @@ -144,6 +145,7 @@ public void testCitySerialization() throws IOException {
// difference
.put("is_anonymous", false)
.put("is_anonymous_vpn", false)
.put("is_anycast", true)
.put("is_hosting_provider", false)
.put("is_legitimate_proxy", false)
.put("is_public_proxy", false)
Expand Down Expand Up @@ -232,6 +234,7 @@ public void testCountrySerialization() throws IOException {
// difference
.put("is_anonymous", false)
.put("is_anonymous_vpn", false)
.put("is_anycast", true)
.put("is_hosting_provider", false)
.put("is_legitimate_proxy", false)
.put("is_public_proxy", false)
Expand Down Expand Up @@ -349,5 +352,4 @@ public void testIspSerialization() throws Exception {

assertEquals(expectedNode, actualNode);
}

}
2 changes: 1 addition & 1 deletion src/test/resources/maxmind-db
Submodule maxmind-db updated 62 files
+11 −0 .github/dependabot.yml
+52 −0 .github/workflows/codeql-analysis.yml
+38 −0 .github/workflows/go.yml
+21 −0 .github/workflows/golangci-lint.yml
+1 −0 .gitignore
+708 −0 .golangci.toml
+68 −0 cmd/write-test-data/main.go
+13 −0 go.mod
+16 −0 go.sum
+6 −0 perltidyrc
+178 −0 pkg/writer/decoder.go
+182 −0 pkg/writer/geoip2.go
+39 −0 pkg/writer/ip.go
+245 −0 pkg/writer/maxmind.go
+73 −0 pkg/writer/nestedstructures.go
+58 −0 pkg/writer/writer.go
+175 −1 source-data/GeoIP2-City-Test.json
+5 −0 source-data/GeoIP2-Connection-Type-Test.json
+99 −0 source-data/GeoIP2-Country-Test.json
+5 −0 source-data/GeoIP2-Domain-Test.json
+294 −0 source-data/GeoIP2-Enterprise-Test.json
+0 −26 source-data/GeoIP2-IP-Risk-Test.json
+301 −0 source-data/GeoIP2-Precision-Enterprise-Test.json
+168 −0 source-data/GeoLite2-City-Test.json
+92 −0 source-data/GeoLite2-Country-Test.json
+ test-data/GeoIP2-Anonymous-IP-Test.mmdb
+ test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb
+ test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb
+ test-data/GeoIP2-City-Test.mmdb
+ test-data/GeoIP2-Connection-Type-Test.mmdb
+ test-data/GeoIP2-Country-Test.mmdb
+ test-data/GeoIP2-DensityIncome-Test.mmdb
+ test-data/GeoIP2-Domain-Test.mmdb
+ test-data/GeoIP2-Enterprise-Test.mmdb
+ test-data/GeoIP2-IP-Risk-Test.mmdb
+ test-data/GeoIP2-ISP-Test.mmdb
+ test-data/GeoIP2-Precision-Enterprise-Sandbox-Test.mmdb
+ test-data/GeoIP2-Precision-Enterprise-Test.mmdb
+ test-data/GeoIP2-Static-IP-Score-Test.mmdb
+ test-data/GeoIP2-User-Count-Test.mmdb
+ test-data/GeoLite2-ASN-Test.mmdb
+ test-data/GeoLite2-City-Test.mmdb
+ test-data/GeoLite2-Country-Test.mmdb
+ test-data/MaxMind-DB-no-ipv4-search-tree.mmdb
+ test-data/MaxMind-DB-string-value-entries.mmdb
+ test-data/MaxMind-DB-test-broken-pointers-24.mmdb
+ test-data/MaxMind-DB-test-broken-search-tree-24.mmdb
+ test-data/MaxMind-DB-test-decoder.mmdb
+ test-data/MaxMind-DB-test-ipv4-24.mmdb
+ test-data/MaxMind-DB-test-ipv4-28.mmdb
+ test-data/MaxMind-DB-test-ipv4-32.mmdb
+ test-data/MaxMind-DB-test-ipv6-24.mmdb
+ test-data/MaxMind-DB-test-ipv6-28.mmdb
+ test-data/MaxMind-DB-test-ipv6-32.mmdb
+ test-data/MaxMind-DB-test-metadata-pointers.mmdb
+ test-data/MaxMind-DB-test-mixed-24.mmdb
+ test-data/MaxMind-DB-test-mixed-28.mmdb
+ test-data/MaxMind-DB-test-mixed-32.mmdb
+ test-data/MaxMind-DB-test-nested.mmdb
+ test-data/MaxMind-DB-test-pointer-decoder.mmdb
+28 −14 test-data/README.md
+0 −667 test-data/write-test-data.pl
3 changes: 2 additions & 1 deletion src/test/resources/test-data/insights0.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"is_anonymous": true,
"is_anonymous_proxy": true,
"is_anonymous_vpn": true,
"is_anycast": true,
"is_hosting_provider": true,
"is_public_proxy": true,
"is_residential_proxy": true,
Expand All @@ -86,4 +87,4 @@
"user_count": 2,
"user_type": "college"
}
}
}
3 changes: 2 additions & 1 deletion src/test/resources/test-data/insights1.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"is_anonymous": true,
"is_anonymous_proxy": true,
"is_anonymous_vpn": true,
"is_anycast": true,
"is_hosting_provider": true,
"is_public_proxy": true,
"is_satellite_provider": true,
Expand All @@ -101,4 +102,4 @@
"user_count": 2,
"user_type": "college"
}
}
}

0 comments on commit c7c6701

Please sign in to comment.