Skip to content

Commit

Permalink
allow remote config at loc specified in sys prop
Browse files Browse the repository at this point in the history
Signed-off-by: Andre Dietisheim <[email protected]>
  • Loading branch information
adietish committed Jun 25, 2024
1 parent f9f1344 commit 8a10723
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class EventLimits implements IEventLimits {
static final Duration DEFAULT_REFRESH_PERIOD = Duration.ofHours(6);
private final String pluginId;
private final PluginLimitsFactory factory;
private final Configurations configuration;
private final LimitsConfigurations configuration;
private final EventCounts counts;
private List<PluginLimits> limits;

Expand All @@ -42,13 +42,13 @@ interface PluginLimitsFactory {
}

public EventLimits(String pluginId) {
this(pluginId, null, PluginLimitsDeserialization::create, new Configurations(), EventCounts.getInstance());
this(pluginId, null, PluginLimitsDeserialization::create, new LimitsConfigurations(), EventCounts.getInstance());
}

EventLimits(String pluginId,
List<PluginLimits> limits,
PluginLimitsFactory factory,
Configurations configuration,
LimitsConfigurations configuration,
EventCounts counts) {
this.pluginId = pluginId;
this.limits = limits;
Expand Down Expand Up @@ -98,7 +98,7 @@ List<PluginLimits> getAllLimits() {
FileTime lastModified = configuration.getLocalLastModified();
if (this.limits == null
|| needsRefresh(refreshAfter, lastModified)) {
this.limits = createLimits(Configurations.REMOTE, configuration.getRemote(), factory);
this.limits = createLimits(configuration.getRemote(), factory);
}
return limits;
}
Expand Down Expand Up @@ -144,15 +144,15 @@ private Duration getRefreshAfter(PluginLimits defaults) {
return Duration.ofHours(defaults.getRefresh());
}

private List<PluginLimits> createLimits(String path, String config, PluginLimitsFactory factory) {
private List<PluginLimits> createLimits(String config, PluginLimitsFactory factory) {
try {
if (StringUtil.isEmptyOrSpaces(config)) {
// null to trigger reload upon next #getAllLimits
return null;
}
return factory.create(config);
} catch (Exception e) {
LOGGER.warn("Could not deserialize config " + path, e);
LOGGER.warn("Could not deserialize config", e);
// null to trigger reload upon next #getAllLimits
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,13 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

class Configurations {
class LimitsConfigurations {

private static final Logger LOGGER = Logger.getInstance(Configurations.class);
private static final Logger LOGGER = Logger.getInstance(LimitsConfigurations.class);
static final Path LOCAL = Directories.RED_HAT.resolve("telemetry-config.json");
static final String EMBEDDED = "/telemetry-config.json";
static final String REMOTE = "https://raw.githubusercontent.com/adietish/intellij-redhat-telemetry/issue-82/src/main/resources/telemetry-config.json";
Expand All @@ -42,8 +41,9 @@ class Configurations {
.build();

public String getRemote() {
String url = System.getProperty("REDHAT_TELEMETRY_REMOTE_CONFIG_URL", REMOTE);
Request request = new Request.Builder()
.url(REMOTE)
.url(url)
.addHeader("Content-Type", "application/json")
.build();
try (Response response = client.newCall(request).execute()) {
Expand All @@ -52,15 +52,11 @@ public String getRemote() {
}
return getLocal();
} catch (Throwable e) {
LOGGER.warn("Could not download remote limits configurations.", e);
LOGGER.warn("Could not download remote limits configurations from " + url, e);
return null;
}
}

public boolean localExists() {
return Files.exists(LOCAL);
}

public FileTime getLocalLastModified() {
try {
if (!Files.exists(LOCAL)) {
Expand All @@ -80,16 +76,17 @@ public String getLocal() {
}
}

public String getEmbedded() {
return toString(Configurations.class.getResourceAsStream(EMBEDDED));
public String getEmbedded() throws IOException {
return toString(LimitsConfigurations.class.getResourceAsStream(EMBEDDED));
}

private String toString(InputStream in) {
private String toString(InputStream in) throws IOException {
if (in == null) {
return null;
}
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
return reader.lines().collect(Collectors.joining());
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
return reader.lines().collect(Collectors.joining());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@

class TelemetryConfigurationTest {

private SaveableFileConfiguration file = configuration(new Properties(), SaveableFileConfiguration.class);
private IConfiguration defaults = mock(IConfiguration.class);
private IConfiguration overrides = mock(IConfiguration.class);
private List<IConfiguration> configurations = Arrays.asList(overrides, file, defaults);
private ConfigurationChangedListener listener = mock(ConfigurationChangedListener.class);
private TelemetryConfiguration config = new TestableTelemetryConfiguration(file, configurations, listener);
private final SaveableFileConfiguration file = configuration(new Properties(), SaveableFileConfiguration.class);
private final IConfiguration defaults = mock(IConfiguration.class);
private final IConfiguration overrides = mock(IConfiguration.class);
private final List<IConfiguration> configurations = Arrays.asList(overrides, file, defaults);
private final ConfigurationChangedListener listener = mock(ConfigurationChangedListener.class);
private final TelemetryConfiguration config = new TestableTelemetryConfiguration(file, configurations, listener);

@Test
void get_should_return_overridden_value() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void getAllLimits_returns_null_if_deserialization_throws() throws IOExcep
PluginLimitsFactory factory = mock(PluginLimitsFactory.class);
doThrow(new IOException())
.when(factory).create(any());
Configurations configurations = mock(Configurations.class);
LimitsConfigurations configurations = mock(LimitsConfigurations.class);
doReturn("bogus") // needs to return non-null for factory to be invoked
.when(configurations).getRemote();
EventCounts counts = mock(EventCounts.class);
Expand All @@ -55,7 +55,7 @@ public void getAllLimits_returns_null_if_deserialization_throws() throws IOExcep
public void getAllLimits_downloads_remote_if_local_file_has_no_modification_timestamp() {
// given
List<PluginLimits> allLimits = List.of(createDefaultPluginLimits(Integer.MAX_VALUE));
Configurations configurations = mock(Configurations.class);
LimitsConfigurations configurations = mock(LimitsConfigurations.class);
doReturn(null) // no modification timestamp, file does not exist
.when(configurations).getLocalLastModified();
EventCounts counts = mock(EventCounts.class);
Expand All @@ -71,7 +71,7 @@ public void getAllLimits_downloads_remote_if_local_file_was_modified_7h_ago_and_
// given
List<PluginLimits> noDefaultLimits = Collections.emptyList();
PluginLimitsFactory factory = mock(PluginLimitsFactory.class);
Configurations configurations = mock(Configurations.class);
LimitsConfigurations configurations = mock(LimitsConfigurations.class);
EventCounts counts = mock(EventCounts.class);
// default refresh (without existing plugin limits) is 6h
doReturn(createFileTime(7)) // 7h ago
Expand All @@ -88,7 +88,7 @@ public void getAllLimits_downloads_remote_if_local_file_was_modified_7h_ago_and_
// given
List<PluginLimits> allLimits = List.of(createDefaultPluginLimits(-1));
PluginLimitsFactory factory = mock(PluginLimitsFactory.class);
Configurations configurations = mock(Configurations.class);
LimitsConfigurations configurations = mock(LimitsConfigurations.class);
// default refresh (with plugin limits without refresh) is 6h
doReturn(createFileTime(7)) // 7h ago
.when(configurations).getLocalLastModified();
Expand All @@ -105,7 +105,7 @@ public void getAllLimits_does_NOT_download_remote_if_local_file_was_modified_wit
// given
List<PluginLimits> allLimits = List.of(createDefaultPluginLimits(2));
PluginLimitsFactory factory = mock(PluginLimitsFactory.class);
Configurations configurations = mock(Configurations.class);
LimitsConfigurations configurations = mock(LimitsConfigurations.class);
doReturn(createFileTime(1)) // 1h ago
.when(configurations).getLocalLastModified();
EventCounts counts = mock(EventCounts.class);
Expand All @@ -120,7 +120,7 @@ public void getAllLimits_does_NOT_download_remote_if_local_file_was_modified_wit
public void getAllLimits_returns_null_if_downloadRemote_returns_null() {
// given
PluginLimitsFactory factory = mock(PluginLimitsFactory.class);
Configurations configurations = createConfigurations(LocalDateTime.now());
LimitsConfigurations configurations = createConfigurations(LocalDateTime.now());
doReturn(null)
.when(configurations).getRemote();
EventCounts counts = mock(EventCounts.class);
Expand All @@ -134,7 +134,7 @@ public void getAllLimits_returns_null_if_downloadRemote_returns_null() {
@Test
public void canSend_returns_true_if_default_allows() {
// given
Configurations configurations = createConfigurations(LocalDateTime.now()); // local file up-to-date, no refresh
LimitsConfigurations configurations = createConfigurations(LocalDateTime.now()); // local file up-to-date, no refresh
List<PluginLimits> pluginLimits = List.of(createDefaultPluginLimits(true));
EventLimits limits = new EventLimits(
"bogus",
Expand All @@ -153,7 +153,7 @@ public void canSend_returns_true_if_default_allows() {
public void canSend_returns_true_if_default_cannotSend_but_pluginLimit_canSend() {
// given
String pluginId = "jedis";
Configurations configurations = createConfigurations(LocalDateTime.now()); // local file up-to-date, no refresh
LimitsConfigurations configurations = createConfigurations(LocalDateTime.now()); // local file up-to-date, no refresh
List<PluginLimits> pluginLimits = List.of(
createDefaultPluginLimits(Integer.MAX_VALUE, false),
createPluginLimits(pluginId, Integer.MAX_VALUE, true)
Expand All @@ -175,7 +175,7 @@ public void canSend_returns_true_if_default_cannotSend_but_pluginLimit_canSend()
public void canSend_returns_true_if_there_is_no_default_nor_pluginLimit() {
// given
String pluginId = "jedis";
Configurations configurations = createConfigurations(LocalDateTime.now()); // local file up-to-date, no refresh
LimitsConfigurations configurations = createConfigurations(LocalDateTime.now()); // local file up-to-date, no refresh
List<PluginLimits> pluginLimits = Collections.emptyList();
EventLimits limits = new EventLimits(
pluginId,
Expand All @@ -194,7 +194,7 @@ public void canSend_returns_true_if_there_is_no_default_nor_pluginLimit() {
public void wasSent_puts_event_to_eventCount() {
// given
String pluginId = "jedis";
Configurations configurations = createConfigurations(LocalDateTime.now()); // local file up-to-date, no refresh
LimitsConfigurations configurations = createConfigurations(LocalDateTime.now()); // local file up-to-date, no refresh
List<PluginLimits> pluginLimits = Collections.emptyList();
EventCounts eventCounts = mock(EventCounts.class);
EventLimits limits = new EventLimits(
Expand Down Expand Up @@ -241,8 +241,8 @@ private static PluginLimits createPluginLimits(String pluginId, int refresh, boo
return mock;
}

private static Configurations createConfigurations(@NotNull LocalDateTime localModificationTimestamp) {
Configurations configurations = mock(Configurations.class);
private static LimitsConfigurations createConfigurations(@NotNull LocalDateTime localModificationTimestamp) {
LimitsConfigurations configurations = mock(LimitsConfigurations.class);
int localCreatedHoursAgo = (int) ChronoUnit.HOURS.between(localModificationTimestamp, LocalDateTime.now());
doReturn(createFileTime(localCreatedHoursAgo))
.when(configurations).getLocalLastModified();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,48 +27,48 @@

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

public class ConfigurationsIntegrationTest {
public class LimitsConfigurationsIntegrationTest {

private Path backup = null;

@BeforeEach
void beforeEach() throws IOException {
this.backup = backup(Configurations.LOCAL);
this.backup = backup(LimitsConfigurations.LOCAL);
}

@AfterEach
void afterEach() throws IOException {
restore(backup, Configurations.LOCAL);
void afterEach() {
restore(backup, LimitsConfigurations.LOCAL);
}

@Test
public void getRemote_can_download_remote_config() {
// given
Configurations configurations = new Configurations();
LimitsConfigurations configurations = new LimitsConfigurations();
// when
String remote = configurations.getRemote();
// then
assertThat(remote).isNotEmpty();
}

@Test
public void getRemote_writes_remote_to_local_file() throws IOException {
public void getRemote_writes_remote_to_local_file() {
// given
Configurations configurations = new Configurations();
LimitsConfigurations configurations = new LimitsConfigurations();
// when
configurations.getRemote();
// then
assertThat(Files.exists(Configurations.LOCAL)).isTrue();
assertThat(Files.exists(LimitsConfigurations.LOCAL)).isTrue();
}

@Test
public void getRemote_returns_content_that_is_equal_to_local_file() throws IOException {
// given
Configurations configurations = new Configurations();
LimitsConfigurations configurations = new LimitsConfigurations();
String remote = null;
// when
remote = configurations.getRemote();
String file = toString(Configurations.LOCAL);
String file = toString(LimitsConfigurations.LOCAL);
// then
assertThat(remote).isEqualTo(file);
}
Expand All @@ -77,8 +77,8 @@ public void getRemote_returns_content_that_is_equal_to_local_file() throws IOExc
public void getLocal_returns_content_of_local_file() throws IOException {
// given
String expected = "yoda";
Files.write(Configurations.LOCAL, expected.getBytes(), StandardOpenOption.CREATE);
Configurations configurations = new Configurations();
Files.write(LimitsConfigurations.LOCAL, expected.getBytes(), StandardOpenOption.CREATE);
LimitsConfigurations configurations = new LimitsConfigurations();
// when
String local = configurations.getLocal();
// then
Expand All @@ -88,9 +88,9 @@ public void getLocal_returns_content_of_local_file() throws IOException {
@Test
public void getLocalLastModified_returns_time_when_file_was_created() throws IOException {
// given
Files.write(Configurations.LOCAL, "obiwan".getBytes(), StandardOpenOption.CREATE);
FileTime whenCreated = Files.getLastModifiedTime(Configurations.LOCAL);
Configurations configurations = new Configurations();
Files.write(LimitsConfigurations.LOCAL, "obiwan".getBytes(), StandardOpenOption.CREATE);
FileTime whenCreated = Files.getLastModifiedTime(LimitsConfigurations.LOCAL);
LimitsConfigurations configurations = new LimitsConfigurations();
// when
FileTime whenChecked = configurations.getLocalLastModified();
// then
Expand All @@ -100,11 +100,11 @@ public void getLocalLastModified_returns_time_when_file_was_created() throws IOE
@Test
public void getLocalLastModified_returns_time_when_file_was_downloaded() throws IOException {
// given
Files.write(Configurations.LOCAL, "obiwan".getBytes(), StandardOpenOption.CREATE);
FileTime whenCreated = Files.getLastModifiedTime(Configurations.LOCAL);
Configurations configurations = new Configurations();
Files.write(LimitsConfigurations.LOCAL, "obiwan".getBytes(), StandardOpenOption.CREATE);
FileTime whenCreated = Files.getLastModifiedTime(LimitsConfigurations.LOCAL);
LimitsConfigurations configurations = new LimitsConfigurations();
configurations.getRemote();
FileTime whenDownloaded = Files.getLastModifiedTime(Configurations.LOCAL);
FileTime whenDownloaded = Files.getLastModifiedTime(LimitsConfigurations.LOCAL);
// when
FileTime whenChecked = configurations.getLocalLastModified();
// then
Expand All @@ -113,9 +113,9 @@ public void getLocalLastModified_returns_time_when_file_was_downloaded() throws
}

@Test
public void getLocalLastModified_returns_null_if_local_file_does_not_exist() throws IOException {
public void getLocalLastModified_returns_null_if_local_file_does_not_exist() {
// given
Configurations configurations = new Configurations();
LimitsConfigurations configurations = new LimitsConfigurations();
// when
FileTime whenChecked = configurations.getLocalLastModified();
// then
Expand All @@ -126,9 +126,9 @@ public void getLocalLastModified_returns_null_if_local_file_does_not_exist() thr
public void getEmbedded_returns_content_of_embedded_file() throws IOException {
// given
BufferedReader reader = new BufferedReader(new InputStreamReader(Objects.requireNonNull(
ConfigurationsIntegrationTest.class.getResourceAsStream(Configurations.EMBEDDED))));
LimitsConfigurationsIntegrationTest.class.getResourceAsStream(LimitsConfigurations.EMBEDDED))));
String expected = reader.lines().collect(Collectors.joining());
Configurations configurations = new Configurations();
LimitsConfigurations configurations = new LimitsConfigurations();
// when
String local = configurations.getEmbedded();
// then
Expand Down Expand Up @@ -166,13 +166,4 @@ private boolean safeMove(Path source, Path destination) {
return false;
}
}

private void safeDelete(Path toDelete) {
try {
Files.delete(toDelete);
} catch (IOException e) {
// swallow
}
}

}

0 comments on commit 8a10723

Please sign in to comment.