Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,50 @@ CHANGELOG
* BREAKING: Removed deprecated `TransactionReport.Builder(InetAddress, Tag)`
constructor. Use `Builder(Tag)` and `ipAddress(InetAddress)` instead.
* BREAKING: Removed deprecated `getUrl()` methods from `HttpException` and
`InvalidRequestException`. Use `getUri()` instead.
`InvalidRequestException`. Use `uri()` instead.
* BREAKING: Removed deprecated constructors from `FactorsResponse`,
`InsightsResponse`, and `Phone` classes.
* BREAKING: Removed deprecated `Subscores` class and
`FactorsResponse.getSubscores()` method. Use `getRiskScoreReasons()`
instead.
* BREAKING: Java 17 is now required (previously Java 11).
* BREAKING: Updated `geoip2` dependency to 5.0.0-SNAPSHOT. This introduces
several breaking changes due to changes in the geoip2 library:
* The `IpAddress` class no longer extends `InsightsResponse` from geoip2.
It now uses composition instead. All public methods remain the same, but
code relying on `IpAddress` being an `InsightsResponse` will need to be
updated.
* The `GeoIp2Location` class no longer extends `Location` from geoip2. It
now stores location data directly. All public methods remain the same, but
code relying on `GeoIp2Location` being a `Location` will need to be
updated.
* Removed the `getMaxMind()` method from the `IpAddress` class as this data
is not populated in minFraud responses.
* BREAKING: Converted all response classes to Java records. This change makes
these classes more concise and provides better immutability guarantees.
* All `get*()` accessor methods in response classes are now deprecated and
will be removed in 5.0.0. Use the automatically generated record accessor
methods instead (e.g., use `riskScore()` instead of `getRiskScore()`).
* The response class hierarchy has been flattened. `InsightsResponse` no
longer extends `ScoreResponse`, and `FactorsResponse` no longer extends
`InsightsResponse`. Instead, `InsightsResponse` and `FactorsResponse` now
include all fields from their former parent classes directly.
* All response classes now implement `JsonSerializable` instead of extending
`AbstractModel`. The `toJson()` method remains available for serialization.
* Removed the `AbstractAddress` interface.
* BREAKING: Updated all request classes to use record-style method naming. The
`get` prefix has been removed from all accessor methods (e.g., use `userId()`
instead of `getUserId()`). This applies to all request classes including
`Account`, `Billing`, `CreditCard`, `CustomInputs`, `Device`, `Email`,
`Event`, `Order`, `Payment`, `Shipping`, `ShoppingCartItem`, `Transaction`,
and `TransactionReport`. Unlike response classes, no deprecated helper methods
were added as these methods are primarily used for serialization.
* BREAKING: Updated exception classes to use record-style method naming. The
`get` prefix has been removed from all accessor methods. For `HttpException`,
use `httpStatus()` and `uri()` instead of `getHttpStatus()` and `getUri()`.
For `InvalidRequestException`, use `code()`, `httpStatus()`, and `uri()`
instead of `getCode()`, `getHttpStatus()`, and `getUri()`. No deprecated
helper methods were added.
* Added `CREDIT_APPLICATION` and `FUND_TRANSFER` to the `Event.Type` enum.
* Added the input `/event/party`. This is the party submitting the
transaction. You may provide this using the `party` method on
Expand Down
15 changes: 14 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@
<email>goschwald@maxmind.com</email>
</developer>
</developers>
<repositories>
<repository>
<name>Central Portal Snapshots</name>
<id>central-portal-snapshots</id>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
Expand All @@ -60,7 +73,7 @@
<dependency>
<groupId>com.maxmind.geoip2</groupId>
<artifactId>geoip2</artifactId>
<version>4.4.0</version>
<version>5.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/com/maxmind/minfraud/JsonSerializable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.maxmind.minfraud;

import java.io.IOException;

/**
* Interface for classes that can be serialized to JSON.
* Provides default implementation for toJson() method.
*/
public interface JsonSerializable {

/**
* @return JSON representation of this object.
* @throws IOException if there is an error serializing the object to JSON.
*/
default String toJson() throws IOException {
return Mapper.get().writeValueAsString(this);
}
}
22 changes: 11 additions & 11 deletions src/main/java/com/maxmind/minfraud/WebServiceClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public static final class Builder {
Duration connectTimeout;
Duration requestTimeout;

List<String> locales = Collections.singletonList("en");
List<String> locales = List.of("en");
private ProxySelector proxy;
private HttpClient httpClient;

Expand Down Expand Up @@ -306,8 +306,8 @@ public void reportTransaction(TransactionReport transaction) throws IOException,
if (transaction == null) {
throw new IllegalArgumentException("transaction report must not be null");
}
URI uri = createUri(WebServiceClient.pathBase + "transactions/report");
HttpRequest request = requestFor(transaction, uri);
var uri = createUri(WebServiceClient.pathBase + "transactions/report");
var request = requestFor(transaction, uri);

HttpResponse<InputStream> response = null;
try {
Expand All @@ -328,8 +328,8 @@ private <T> T responseFor(String service, AbstractModel transaction, Class<T> cl
if (transaction == null) {
throw new IllegalArgumentException("transaction must not be null");
}
URI uri = createUri(WebServiceClient.pathBase + service);
HttpRequest request = requestFor(transaction, uri);
var uri = createUri(WebServiceClient.pathBase + service);
var request = requestFor(transaction, uri);

HttpResponse<InputStream> response = null;
try {
Expand All @@ -346,7 +346,7 @@ private <T> T responseFor(String service, AbstractModel transaction, Class<T> cl

private HttpRequest requestFor(AbstractModel transaction, URI uri)
throws MinFraudException, IOException {
HttpRequest.Builder builder = HttpRequest.newBuilder()
var builder = HttpRequest.newBuilder()
.uri(uri)
.header("Accept", "application/json")
.header("Authorization", authHeader)
Expand All @@ -365,7 +365,7 @@ private HttpRequest requestFor(AbstractModel transaction, URI uri)

private void maybeThrowException(HttpResponse<InputStream> response, URI uri)
throws IOException, MinFraudException {
int status = response.statusCode();
var status = response.statusCode();
if (status >= 400 && status < 500) {
this.handle4xxStatus(response, uri);
} else if (status >= 500 && status < 600) {
Expand All @@ -383,7 +383,7 @@ private <T> T handleResponse(HttpResponse<InputStream> response, URI uri, Class<
throws MinFraudException, IOException {
maybeThrowException(response, uri);

InjectableValues inject = new Std().addValue(
var inject = new Std().addValue(
"locales", locales);

try (InputStream stream = response.body()) {
Expand All @@ -398,7 +398,7 @@ private void handle4xxStatus(HttpResponse<InputStream> response, URI uri)
throws IOException, InsufficientFundsException,
InvalidRequestException, AuthenticationException,
PermissionRequiredException {
int status = response.statusCode();
var status = response.statusCode();

String body;
try (InputStream stream = response.body()) {
Expand All @@ -425,8 +425,8 @@ private void handleErrorWithJsonBody(Map<String, String> content,
throws HttpException, InsufficientFundsException,
InvalidRequestException, AuthenticationException,
PermissionRequiredException {
String error = content.get("error");
String code = content.get("code");
var error = content.get("error");
var code = content.get("code");

if (error == null || code == null) {
throw new HttpException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ public HttpException(String message, int httpStatus, URI uri,
/**
* @return the HTTP status of the query that caused the exception.
*/
public int getHttpStatus() {
public int httpStatus() {
return httpStatus;
}

/**
* @return the URI queried.
*/
public URI getUri() {
public URI uri() {
return this.uri;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,22 @@ public InvalidRequestException(String message, String code, int httpStatus,
/**
* @return The error code returned by the MaxMind web service.
*/
public final String getCode() {
public final String code() {
return code;
}

/**
* @return The integer HTTP status returned by the MaxMind web service. Will be 0 if it was not
* set at throw time.
*/
public final int getHttpStatus() {
public final int httpStatus() {
return httpStatus;
}

/**
* @return the URI queried.
*/
public URI getUri() {
public URI uri() {
return this.uri;
}

Expand Down
25 changes: 13 additions & 12 deletions src/main/java/com/maxmind/minfraud/request/AbstractLocation.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
/**
* This class represents the shared location behavior between Billing and Shipping.
*/
public abstract class AbstractLocation extends AbstractModel {
public abstract sealed class AbstractLocation extends AbstractModel
permits Billing, Shipping {
private final String firstName;
private final String lastName;
private final String company;
Expand Down Expand Up @@ -168,23 +169,23 @@ public final T phoneNumber(String number) {
* @return The first name associated with the address
*/
@JsonProperty("first_name")
public final String getFirstName() {
public final String firstName() {
return firstName;
}

/**
* @return The last name associated with the address
*/
@JsonProperty("last_name")
public final String getLastName() {
public final String lastName() {
return lastName;
}

/**
* @return The company name associated with the address
*/
@JsonProperty("company")
public final String getCompany() {
public final String company() {
return company;
}

Expand All @@ -193,7 +194,7 @@ public final String getCompany() {
* @return The first line of the address
*/
@JsonProperty("address")
public final String getAddress() {
public final String address() {
return address;
}

Expand All @@ -202,7 +203,7 @@ public final String getAddress() {
* @return The second line of the address
*/
@JsonProperty("address_2")
public final String getAddress2() {
public final String address2() {
return address2;
}

Expand All @@ -211,7 +212,7 @@ public final String getAddress2() {
* @return The city associated with the address
*/
@JsonProperty("city")
public final String getCity() {
public final String city() {
return city;
}

Expand All @@ -220,7 +221,7 @@ public final String getCity() {
* @return The region code associated with the address
*/
@JsonProperty("region")
public final String getRegion() {
public final String region() {
return region;
}

Expand All @@ -229,31 +230,31 @@ public final String getRegion() {
* @return The country associated with the address
*/
@JsonProperty("country")
public final String getCountry() {
public final String country() {
return country;
}

/**
* @return The postal code associated with the address
*/
@JsonProperty("postal")
public final String getPostal() {
public final String postal() {
return postal;
}

/**
* @return The phone number associated with the address
*/
@JsonProperty("phone_number")
public final String getPhoneNumber() {
public final String phoneNumber() {
return phoneNumber;
}

/**
* @return The phone number country code associated with the address
*/
@JsonProperty("phone_country_code")
public final String getPhoneCountryCode() {
public final String phoneCountryCode() {
return phoneCountryCode;
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/maxmind/minfraud/request/Account.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,15 @@ public Account build() {
* @return The user ID.
*/
@JsonProperty("user_id")
public String getUserId() {
public String userId() {
return userId;
}

/**
* @return The MD5 of the username passed to the builder.
*/
@JsonProperty("username_md5")
public String getUsernameMd5() {
public String usernameMd5() {
return usernameMd5;
}
}
Loading
Loading