Skip to content

Commit

Permalink
RecordCountVarianceValidator- support dynamic threshold
Browse files Browse the repository at this point in the history
  • Loading branch information
Sunjeet committed Aug 16, 2024
1 parent a55ca71 commit 9a9a05d
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.netflix.hollow.api.producer.HollowProducer.ReadState;
import com.netflix.hollow.core.read.engine.HollowTypeReadState;
import java.util.function.Supplier;

/**
* Used to validate if the cardinality change in current cycle is with in the allowed percent for a given typeName.
Expand All @@ -36,6 +37,9 @@ public class RecordCountVarianceValidator implements ValidatorListener {
"Record count validation for type %s has failed as actual change percent %s "
+ "is greater than allowed change percent %s.";

private static final String NULL_THRESHOLD =
"Record count validation for type %s has failed because the variance threshold was null.";

private static final String DATA_TYPE_NAME = "Typename";
private static final String ALLOWABLE_VARIANCE_PERCENT_NAME = "AllowableVariancePercent";
private static final String LATEST_CARDINALITY_NAME = "LatestRecordCount";
Expand All @@ -46,7 +50,7 @@ public class RecordCountVarianceValidator implements ValidatorListener {

private final String typeName;

private final float allowableVariancePercent;
private final Supplier<Float> allowableVariancePercentSupplier;

/**
* @param typeName type name
Expand All @@ -58,13 +62,27 @@ public class RecordCountVarianceValidator implements ValidatorListener {
* Anything more results in failure of validation.
*/
public RecordCountVarianceValidator(String typeName, float allowableVariancePercent) {
this(typeName, () -> allowableVariancePercent);
}

/**
* @param typeName type name
* @param allowableVariancePercentSupplier: Used to validate if the cardinality change in current cycle is with in the
* allowed percent, and changes to this threshold are applied in the next invocation of validation.
* Ex: 0% allowableVariancePercent ensures type cardinality does not vary at all for cycle to cycle.
* Ex: Number of state in United States.
* 10% allowableVariancePercent: from previous cycle any addition or removal within 10% cardinality is valid.
* Anything more results in failure of validation.
*/
public RecordCountVarianceValidator(String typeName, Supplier<Float> allowableVariancePercentSupplier) {
this.typeName = typeName;
if (allowableVariancePercent < 0) {
this.allowableVariancePercentSupplier = allowableVariancePercentSupplier;
Float allowableVariancePercent = allowableVariancePercentSupplier.get();
if (allowableVariancePercent == null || allowableVariancePercent < 0) {
throw new IllegalArgumentException("RecordCountVarianceValidator for type " + typeName
+ ": cannot have allowableVariancePercent less than 0. Value provided: "
+ ": cannot have allowableVariancePercent be null or less than 0. Value provided: "
+ allowableVariancePercent);
}
this.allowableVariancePercent = allowableVariancePercent;
}

@Override
Expand All @@ -75,6 +93,13 @@ public String getName() {
@Override
public ValidationResult onValidate(ReadState readState) {
ValidationResult.ValidationResultBuilder vrb = ValidationResult.from(this);

Float allowableVariancePercent = allowableVariancePercentSupplier.get();
if (allowableVariancePercent == null) {
String message = String.format(NULL_THRESHOLD, typeName);
return vrb.failed(message);
}

vrb.detail(ALLOWABLE_VARIANCE_PERCENT_NAME, allowableVariancePercent)
.detail(DATA_TYPE_NAME, typeName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void testValidationListenerWithOnlyRecordCountValidator() {

private void createHollowProducerAndRunCycle(final String typeName, boolean addPrimaryKeyValidator) {
ValidatorListener dupeValidator = new DuplicateDataDetectionValidator(typeName);
ValidatorListener countValidator = new RecordCountVarianceValidator(typeName, 3.0f);
ValidatorListener countValidator = new RecordCountVarianceValidator(typeName, () -> 3.0f);
validationListener = new TestValidationStatusListener();
cycleAndValidationListener = new TestCycleAndValidationStatusListener();
Builder builder = HollowProducer.withPublisher(publisher).withAnnouncer(announcer)
Expand Down

0 comments on commit 9a9a05d

Please sign in to comment.