From 63e8683b67610b788ce665a6b187ffb09d559dcd Mon Sep 17 00:00:00 2001 From: Colin McDonald Date: Fri, 17 Jun 2016 14:58:06 -0400 Subject: [PATCH] Add MaxMind result models, IpIntel model --- .../frozenorb/apiv3/maxmind/MaxMindCity.java | 23 +++++++- .../apiv3/maxmind/MaxMindContinent.java | 21 ++++++- .../apiv3/maxmind/MaxMindCountry.java | 23 +++++++- .../apiv3/maxmind/MaxMindLocation.java | 28 ++++++++- .../apiv3/maxmind/MaxMindPostal.java | 19 +++++- .../maxmind/MaxMindRegisteredCountry.java | 21 ++++++- .../apiv3/maxmind/MaxMindResult.java | 43 ++++++++++---- .../apiv3/maxmind/MaxMindSubdivision.java | 23 +++++++- .../apiv3/maxmind/MaxMindTraits.java | 26 +++++++- .../net/frozenorb/apiv3/model/IpIntel.java | 59 +++++++++++++++++++ .../frozenorb/apiv3/util/MaxMindUtils.java | 10 +++- 11 files changed, 267 insertions(+), 29 deletions(-) create mode 100644 src/main/java/net/frozenorb/apiv3/model/IpIntel.java diff --git a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindCity.java b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindCity.java index 83f3afe..0ad52d0 100644 --- a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindCity.java +++ b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindCity.java @@ -1,4 +1,23 @@ package net.frozenorb.apiv3.maxmind; -public class MaxMindCity { -} +import lombok.Getter; +import net.frozenorb.apiv3.util.MaxMindUtils; +import org.bson.Document; + +import java.util.Map; + +public final class MaxMindCity { + + @Getter private int confidence; + @Getter private int geonameId; + @Getter private String name; + + public MaxMindCity() {} // For Jackson + + public MaxMindCity(Document legacy) { + this.confidence = legacy.getInteger("confidence"); + this.geonameId = legacy.getInteger("geoname_id"); + this.name = MaxMindUtils.getEnglishName(legacy); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindContinent.java b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindContinent.java index 48f1312..c2e50a1 100644 --- a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindContinent.java +++ b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindContinent.java @@ -1,4 +1,21 @@ package net.frozenorb.apiv3.maxmind; -public class MaxMindContinent { -} +import lombok.Getter; +import net.frozenorb.apiv3.util.MaxMindUtils; +import org.bson.Document; + +public final class MaxMindContinent { + + @Getter private String code; + @Getter private int geonameId; + @Getter private String name; + + public MaxMindContinent() {} // For Jackson + + public MaxMindContinent(Document legacy) { + this.code = legacy.getString("code"); + this.geonameId = legacy.getInteger("geoname_id"); + this.name = MaxMindUtils.getEnglishName(legacy); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindCountry.java b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindCountry.java index b6d82c3..66cf4af 100644 --- a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindCountry.java +++ b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindCountry.java @@ -1,4 +1,23 @@ package net.frozenorb.apiv3.maxmind; -public class MaxMindCountry { -} +import lombok.Getter; +import net.frozenorb.apiv3.util.MaxMindUtils; +import org.bson.Document; + +public final class MaxMindCountry { + + @Getter private String isoCode; + @Getter private int confidence; + @Getter private int geonameId; + @Getter private String name; + + public MaxMindCountry() {} // For Jackson + + public MaxMindCountry(Document legacy) { + this.isoCode = legacy.getString("iso_code"); + this.confidence = legacy.getInteger("confidence"); + this.geonameId = legacy.getInteger("geoname_id"); + this.name = MaxMindUtils.getEnglishName(legacy); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindLocation.java b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindLocation.java index 1fc0675..a509c50 100644 --- a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindLocation.java +++ b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindLocation.java @@ -1,4 +1,28 @@ package net.frozenorb.apiv3.maxmind; -public class MaxMindLocation { -} +import lombok.Getter; +import org.bson.Document; + +public final class MaxMindLocation { + + @Getter private double latitude; + @Getter private double longitude; + @Getter private int accuracyRadius; + @Getter private String timeZone; + @Getter private int populationDensity; + @Getter private int metroCode; + @Getter private int averageIncome; + + public MaxMindLocation() {} // For Jackson + + public MaxMindLocation(Document legacy) { + this.latitude = legacy.getDouble("latitude"); + this.longitude = legacy.getDouble("longitude"); + this.accuracyRadius = legacy.getInteger("accuracy_radius"); + this.timeZone = legacy.getString("time_zone"); + this.populationDensity = legacy.getInteger("population_density"); + this.metroCode = legacy.getInteger("metro_code"); + this.averageIncome = legacy.getInteger("average_income"); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindPostal.java b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindPostal.java index d098f9f..96dc5e5 100644 --- a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindPostal.java +++ b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindPostal.java @@ -1,4 +1,19 @@ package net.frozenorb.apiv3.maxmind; -public class MaxMindPostal { -} +import lombok.Getter; +import net.frozenorb.apiv3.util.MaxMindUtils; +import org.bson.Document; + +public final class MaxMindPostal { + + @Getter private String code; + @Getter private int confidence; + + public MaxMindPostal() {} // For Jackson + + public MaxMindPostal(Document legacy) { + this.code = legacy.getString("code"); + this.confidence = legacy.getInteger("confidence"); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindRegisteredCountry.java b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindRegisteredCountry.java index db69f89..07c8b85 100644 --- a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindRegisteredCountry.java +++ b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindRegisteredCountry.java @@ -1,4 +1,21 @@ package net.frozenorb.apiv3.maxmind; -public class MaxMindRegisteredCountry { -} +import lombok.Getter; +import net.frozenorb.apiv3.util.MaxMindUtils; +import org.bson.Document; + +public final class MaxMindRegisteredCountry { + + @Getter private String isoCode; + @Getter private int geonameId; + @Getter private String name; + + public MaxMindRegisteredCountry() {} // For Jackson + + public MaxMindRegisteredCountry(Document legacy) { + this.isoCode = legacy.getString("iso_code"); + this.geonameId = legacy.getInteger("geoname_id"); + this.name = MaxMindUtils.getEnglishName(legacy); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindResult.java b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindResult.java index c5ebce2..81024d2 100644 --- a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindResult.java +++ b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindResult.java @@ -1,20 +1,41 @@ package net.frozenorb.apiv3.maxmind; +import lombok.Getter; +import org.bson.Document; + import java.time.Instant; +import java.util.ArrayList; +import java.util.List; public final class MaxMindResult { - private String ip; - private Instant lastUpdatedAt; - private MaxMindContinent continent; - private MaxMindCity city; - private MaxMindPostal postal; - private MaxMindTraits traits; - private MaxMindLocation location; - private MaxMindSubdivision[] subdivisions; - private MaxMindCountry country; - private MaxMindRegisteredCountry registeredCountry; + @Getter private MaxMindContinent continent; + @Getter private MaxMindCity city; + @Getter private MaxMindPostal postal; + @Getter private MaxMindTraits traits; + @Getter private MaxMindLocation location; + @Getter private MaxMindSubdivision[] subdivisions; + @Getter private MaxMindCountry country; + @Getter private MaxMindRegisteredCountry registeredCountry; - public MaxMindResult() {} + public MaxMindResult() {} // For Jackson + + public MaxMindResult(Document legacy) { + this.continent = new MaxMindContinent((Document) legacy.get("continent")); + this.city = new MaxMindCity((Document) legacy.get("city")); + this.postal = new MaxMindPostal((Document) legacy.get("postal")); + this.traits = new MaxMindTraits((Document) legacy.get("traits")); + this.location = new MaxMindLocation((Document) legacy.get("location")); + this.country = new MaxMindCountry((Document) legacy.get("country")); + this.registeredCountry = new MaxMindRegisteredCountry((Document) legacy.get("registered_country")); + + List subdivisions = new ArrayList<>(); + + for (Object subdivision : (List) legacy.get("subdivisions")) { + subdivisions.add(new MaxMindSubdivision((Document) subdivision)); + } + + this.subdivisions = subdivisions.toArray(new MaxMindSubdivision[subdivisions.size()]); + } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindSubdivision.java b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindSubdivision.java index 7576f98..80185f5 100644 --- a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindSubdivision.java +++ b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindSubdivision.java @@ -1,4 +1,23 @@ package net.frozenorb.apiv3.maxmind; -public class MaxMindSubdivision { -} +import lombok.Getter; +import net.frozenorb.apiv3.util.MaxMindUtils; +import org.bson.Document; + +public final class MaxMindSubdivision { + + @Getter private String isoCode; + @Getter private int confidence; + @Getter private int geonameId; + @Getter private String name; + + public MaxMindSubdivision() {} // For Jackson + + public MaxMindSubdivision(Document legacy) { + this.isoCode = legacy.getString("iso_code"); + this.confidence = legacy.getInteger("confidence"); + this.geonameId = legacy.getInteger("geoname_id"); + this.name = MaxMindUtils.getEnglishName(legacy); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindTraits.java b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindTraits.java index 986b8f2..c8edf7d 100644 --- a/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindTraits.java +++ b/src/main/java/net/frozenorb/apiv3/maxmind/MaxMindTraits.java @@ -1,4 +1,26 @@ package net.frozenorb.apiv3.maxmind; -public class MaxMindTraits { -} +import lombok.Getter; +import org.bson.Document; + +public final class MaxMindTraits { + + @Getter private String isp; + @Getter private String domain; + @Getter private int asn; + @Getter private String asnOrganization; + @Getter private String type; // TODO: MAKE ENUM + @Getter private String organization; + + public MaxMindTraits() {} // For Jackson + + public MaxMindTraits(Document legacy) { + this.isp = legacy.getString("isp"); + this.domain = legacy.getString("domain"); + this.asn = legacy.getInteger("autonomous_system_number"); + this.asnOrganization = legacy.getString("autonomous_system_organization"); + this.type = legacy.getString("user_type"); + this.organization = legacy.getString("organization"); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/model/IpIntel.java b/src/main/java/net/frozenorb/apiv3/model/IpIntel.java new file mode 100644 index 0000000..de83aa9 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/model/IpIntel.java @@ -0,0 +1,59 @@ +package net.frozenorb.apiv3.model; + +import com.mongodb.async.SingleResultCallback; +import com.mongodb.async.client.MongoCollection; +import fr.javatic.mongo.jacksonCodec.Entity; +import fr.javatic.mongo.jacksonCodec.objectId.Id; +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.maxmind.MaxMindResult; +import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.util.SyncUtils; +import org.bson.Document; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +@Entity +@AllArgsConstructor +public final class IpIntel { + + private static final MongoCollection ipIntelCollection = APIv3.getDatabase().getCollection("ipIntel", IpIntel.class); + + @Getter @Id private String id; + @Getter private Instant lastUpdatedAt; + @Getter private MaxMindResult result; + + public static List findAllSync() { + return SyncUtils.blockMulti(ipIntelCollection.find().sort(new Document("lastSeenAt", -1))); + } + + public static IpIntel findByIdSync(String id) { + return SyncUtils.blockOne(ipIntelCollection.find(new Document("_id", id))); + } + + public static void findAll(SingleResultCallback> callback) { + ipIntelCollection.find().sort(new Document("lastSeenAt", -1)).into(new ArrayList<>(), callback); + } + + public static void findById(String id, SingleResultCallback callback) { + ipIntelCollection.find(new Document("_id", id)).first(callback); + } + + public IpIntel() {} // For Jackson + + public IpIntel(String ip, MaxMindResult result) { + this.id = ip; + this.lastUpdatedAt = Instant.now(); + this.result = result; + } + + public void insert() { + BlockingCallback callback = new BlockingCallback<>(); + ipIntelCollection.insertOne(this, callback); + callback.get(); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/util/MaxMindUtils.java b/src/main/java/net/frozenorb/apiv3/util/MaxMindUtils.java index c96e877..80d1464 100644 --- a/src/main/java/net/frozenorb/apiv3/util/MaxMindUtils.java +++ b/src/main/java/net/frozenorb/apiv3/util/MaxMindUtils.java @@ -4,9 +4,11 @@ import com.google.common.base.Charsets; import com.mongodb.async.SingleResultCallback; import lombok.experimental.UtilityClass; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.maxmind.MaxMindResult; import org.bson.Document; import java.util.Base64; +import java.util.Map; @UtilityClass public class MaxMindUtils { @@ -14,12 +16,12 @@ public class MaxMindUtils { private static final String maxMindUserId = APIv3.getConfig().getProperty("maxMind.userId"); private static final String maxMindLicenseKey = APIv3.getConfig().getProperty("maxMind.maxMindLicenseKey"); - public static void getInsights(String ip, SingleResultCallback callback) { + public static void getInsights(String ip, SingleResultCallback callback) { // We have to specifically use getHttpSClient(), vertx's http client is dumb. APIv3.getHttpsClient().get(443, "geoip.maxmind.com", "/geoip/v2.1/insights/" + ip, (response) -> { response.bodyHandler((body) -> { Document resJson = Document.parse(body.toString()); - callback.onResult(resJson, null); + callback.onResult(new MaxMindResult(ip, resJson), null); }); response.exceptionHandler((error) -> { @@ -28,4 +30,8 @@ public class MaxMindUtils { }).putHeader("Authorization", "Basic " + Base64.getEncoder().encodeToString((maxMindUserId + ":" + maxMindLicenseKey).getBytes(Charsets.UTF_8))).end(); } + public static String getEnglishName(Document source) { + return ((Map) source.get("names")).get("en"); + } + } \ No newline at end of file