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
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.BooleanSupplier;

public class ParamRules {

Expand Down Expand Up @@ -218,6 +219,28 @@ public ParamRules requireAtLeastOne(String[] values, String errorMessage) {
return this;
}

/**
* Add a custom validation rule using a lambda expression.
* <p>
* The validation rule will be executed when {@link #validate()} is called.
* If the condition evaluates to true, an {@link IllegalArgumentException} will be thrown
* with the provided error message.
*
* @param condition a BooleanSupplier that returns true if validation should fail
* @param errorMessage the error message to throw if condition evaluates to true
* @return this ParamRules instance for chaining
*
* @see #validate()
*/
public ParamRules check(BooleanSupplier condition, String errorMessage) {
rules.add(() -> {
if (condition.getAsBoolean()) {
throw new IllegalArgumentException(errorMessage);
}
});
return this;
}


// --------- Utility Methods ----------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ private ParamRules buildRules() {
"glue.access_key and glue.secret_key must be set together")
.requireAtLeastOne(new String[]{glueAccessKey, glueIAMRole},
"At least one of glue.access_key or glue.role_arn must be set")
.require(glueEndpoint, "glue.endpoint must be set");
.require(glueEndpoint, "glue.endpoint must be set")
.check(() -> StringUtils.isNotBlank(glueEndpoint) && !glueEndpoint.startsWith("https://"),
"glue.endpoint must use https protocol,please set glue.endpoint to https://...");
}

private void checkAndInit() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,45 @@ void testAtLeastOne() {
);
Assertions.assertDoesNotThrow(() -> rightRule3.validate());
}

@Test
void testComplexLambdaValidation() {
String username = "alice";
String password = "";
String email = "alice@example.com";
int age = 17;
int maxAge = 100;

ParamRules rules = new ParamRules();

// Add multiple lambda rules
rules.check(() -> username == null || username.isEmpty(), "Username must not be empty")
.check(() -> password == null || password.length() < 6, "Password must be at least 6 characters")
.check(() -> !email.contains("@"), "Email must be valid")
.check(() -> age < 18 || age > maxAge, "Age must be between 18 and 100")
.check(() -> username.equals(email), "Username and email cannot be the same");
// Validate with prefix message
IllegalArgumentException ex = Assertions.assertThrows(IllegalArgumentException.class,
() -> rules.validate("Validation Failed"));
// Check that the error message is prefixed
assert ex.getMessage().startsWith("Validation Failed: ");
}

@Test
void testComplexLambdaValidationSuccess() {
String username = "alice";
String password = "password123";
String email = "alice@example.com";
int age = 25;
int maxAge = 100;
ParamRules rules = new ParamRules();
// Should pass without exception
Assertions.assertDoesNotThrow(() -> {
rules.check(() -> username == null || username.isEmpty(), "Username must not be empty")
.check(() -> password == null || password.length() < 6, "Password must be at least 6 characters")
.check(() -> !email.contains("@"), "Email must be valid")
.check(() -> age < 18 || age > maxAge, "Age must be between 18 and 100")
.check(() -> username.equals(email), "Username and email cannot be the same");
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ private Map<String, String> baseValidProps() {
Map<String, String> props = new HashMap<>();
props.put("glue.access_key", "ak");
props.put("glue.secret_key", "sk");
props.put("glue.endpoint", "glue.us-east-1.amazonaws.com");
props.put("glue.endpoint", "https://glue.us-east-1.amazonaws.com");
return props;
}

Expand Down Expand Up @@ -103,15 +103,28 @@ void testMissingEndpointThrows() {
void testInvalidEndpoint() {
Map<String, String> props = baseValidProps();
props.put("glue.endpoint", "http://invalid-endpoint.com");
Assertions.assertDoesNotThrow(() -> AWSGlueMetaStoreBaseProperties.of(props));
IllegalArgumentException ex = Assertions.assertThrows(
IllegalArgumentException.class,
() -> AWSGlueMetaStoreBaseProperties.of(props)
);
Assertions.assertTrue(ex.getMessage().contains("glue.endpoint must use https protocol,please set glue.endpoint to https://..."));
props.put("glue.endpoint", "http://glue.us-east-1.amazonaws.com");
ex = Assertions.assertThrows(
IllegalArgumentException.class,
() -> AWSGlueMetaStoreBaseProperties.of(props)
);
Assertions.assertTrue(ex.getMessage().contains("glue.endpoint must use https protocol,please set glue.endpoint to https://..."));
}

@Test
void testExtractRegionFailsWhenPatternMatchesButNoRegion() {
Map<String, String> props = baseValidProps();
props.put("glue.endpoint", "glue..amazonaws.com"); // malformed
Assertions.assertDoesNotThrow(() -> AWSGlueMetaStoreBaseProperties.of(props)
IllegalArgumentException ex = Assertions.assertThrows(
IllegalArgumentException.class,
() -> AWSGlueMetaStoreBaseProperties.of(props)
);
Assertions.assertTrue(ex.getMessage().contains("glue.endpoint must use https protocol,please set glue.endpoint to https://..."));
}

@Test
Expand Down
Loading