FUS: add custom validator to compare reported values with a file (for WI-47009)

GitOrigin-RevId: d05528f4bd9338ed6193c49c5b26b2c6aa2912cd
This commit is contained in:
Svetlana.Zemlyanskaya
2019-06-13 03:22:15 +03:00
committed by intellij-monorepo-bot
parent dc741cc225
commit 1b54a11a0b
3 changed files with 168 additions and 0 deletions
@@ -0,0 +1,106 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.eventLog.validator.rules.impl;
import com.intellij.internal.statistic.eventLog.validator.ValidationResultType;
import com.intellij.internal.statistic.eventLog.validator.rules.EventContext;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.reference.SoftReference;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public abstract class LocalFileCustomWhiteListRule extends CustomWhiteListRule {
private static final Logger LOG = Logger.getInstance(LocalFileCustomWhiteListRule.class);
private WeakReference<CachedWhitelistedItems> myWhitelistRef;
private final String myRuleId;
private final Class myResourceHolder;
private final String myRelativePath;
protected LocalFileCustomWhiteListRule(@NotNull String ruleId, @NotNull Class resource, @NotNull String path) {
myRuleId = ruleId;
myResourceHolder = resource;
myRelativePath = path;
}
@Override
public boolean acceptRuleId(@Nullable String ruleId) {
return myRuleId.equals(ruleId);
}
private boolean isWhitelisted(@NotNull String value) {
final CachedWhitelistedItems whitelist = getWhitelist();
return whitelist.contains(value);
}
@NotNull
private synchronized CachedWhitelistedItems getWhitelist() {
final CachedWhitelistedItems whitelist = SoftReference.dereference(myWhitelistRef);
if (whitelist != null) {
return whitelist;
}
final CachedWhitelistedItems items = create();
myWhitelistRef = new WeakReference<>(items);
return items;
}
@NotNull
private CachedWhitelistedItems create() {
try {
final URL stream = myResourceHolder.getResource(myRelativePath);
if (stream == null) {
throw new IOException("Resource " + myRelativePath + " not found");
}
final List<String> values = FileUtil.loadLines(new File(stream.toURI()));
if (!values.isEmpty()) {
return CachedWhitelistedItems.create(ContainerUtil.map2Set(values, value -> value.trim()));
}
}
catch (IOException | URISyntaxException e) {
LOG.info(e);
}
return CachedWhitelistedItems.empty();
}
@NotNull
@Override
final protected ValidationResultType doValidate(@NotNull String data, @NotNull EventContext context) {
if (isThirdPartyValue(data) || isWhitelisted(data)) {
return ValidationResultType.ACCEPTED;
}
return ValidationResultType.REJECTED;
}
private static class CachedWhitelistedItems {
private final Set<String> myValues;
private CachedWhitelistedItems(@NotNull Set<String> values) {
myValues = values;
}
public boolean contains(@NotNull String value) {
return myValues.contains(value);
}
@NotNull
public static CachedWhitelistedItems create(@NotNull Set<String> values) {
return new CachedWhitelistedItems(values);
}
@NotNull
public static CachedWhitelistedItems empty() {
return new CachedWhitelistedItems(Collections.emptySet());
}
}
}
@@ -0,0 +1,60 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistics.validator
import com.intellij.internal.statistic.eventLog.FeatureUsageData
import com.intellij.internal.statistic.eventLog.validator.ValidationResultType
import com.intellij.internal.statistic.eventLog.validator.rules.EventContext
import com.intellij.internal.statistic.eventLog.validator.rules.impl.CustomWhiteListRule
import com.intellij.internal.statistic.eventLog.validator.rules.impl.LocalFileCustomWhiteListRule
import com.intellij.testFramework.LightPlatformTestCase
import junit.framework.TestCase
import org.junit.Test
class LocalFileWhitelistValidatorTest : LightPlatformTestCase() {
private fun doValidateEventId(validator: CustomWhiteListRule, eventId: String, eventData: FeatureUsageData) {
val context = EventContext.create(eventId, eventData.build())
doTest(ValidationResultType.ACCEPTED, validator, eventId, context)
}
private fun doRejectEventId(validator: CustomWhiteListRule, eventId: String, eventData: FeatureUsageData) {
val context = EventContext.create(eventId, eventData.build())
doTest(ValidationResultType.REJECTED, validator, eventId, context)
}
private fun doTest(expected: ValidationResultType, validator: CustomWhiteListRule, data: String, context: EventContext) {
TestCase.assertEquals(expected, validator.validate(data, context))
}
@Test
fun `test validate first allowed value by file`() {
val validator = TestLocalFileWhitelistValidator()
doValidateEventId(validator, "allowed.value", FeatureUsageData())
}
@Test
fun `test validate second allowed value by file`() {
val validator = TestLocalFileWhitelistValidator()
doValidateEventId(validator, "another.allowed.value", FeatureUsageData())
}
@Test
fun `test reject unknown value`() {
val validator = TestLocalFileWhitelistValidator()
doRejectEventId(validator, "unknown.value", FeatureUsageData())
}
@Test
fun `test reject value if file doesn't exist`() {
val validator = EmptyLocalFileWhitelistValidator()
doRejectEventId(validator, "value", FeatureUsageData())
}
}
private class TestLocalFileWhitelistValidator : LocalFileCustomWhiteListRule("local_file",
LocalFileWhitelistValidatorTest::class.java,
"file-with-allowed-values.txt")
private class EmptyLocalFileWhitelistValidator : LocalFileCustomWhiteListRule("local_file",
LocalFileWhitelistValidatorTest::class.java,
"not-existing-file.txt")
@@ -0,0 +1,2 @@
allowed.value
another.allowed.value