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 @@ -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