Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow message limits (#82) #85

Merged
merged 4 commits into from
Jul 18, 2024
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
10 changes: 10 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ dependencies {
}

test {
// Discover and execute all other JUnit5-based tests
useJUnitPlatform()
afterSuite { desc, result ->
if (!desc.parent)
Expand All @@ -64,6 +65,15 @@ test {
}
}

tasks.register('platformTests', Test) {
// Discover and execute JUnit4-based EventCountsTest
useJUnit()
description = 'Runs the platform tests.'
group = 'verification'
outputs.upToDateWhen { false }
mustRunAfter test
}

configurations {
implementation {
exclude group: 'org.slf4j', module: 'slf4j-api'
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ideaVersion = IC-2020.3
ideaVersion = IC-2022.1
# build number ranges
# https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html
sinceIdeaBuild=203
sinceIdeaBuild=211
projectVersion=1.2.0-SNAPSHOT
intellijPluginVersion=1.16.1
jetBrainsToken=invalid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
******************************************************************************/
package com.redhat.devtools.intellij.telemetry.core.configuration;

import java.io.FileNotFoundException;
import java.io.InputStream;
import java.nio.file.Path;

Expand All @@ -28,7 +27,7 @@ public ClasspathConfiguration(Path file, ClassLoader classLoader) {
}

@Override
protected InputStream createInputStream(Path path) throws FileNotFoundException {
protected InputStream createInputStream(Path path) {
if (path == null) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@
******************************************************************************/
package com.redhat.devtools.intellij.telemetry.core.configuration;

import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Objects;

public abstract class CompositeConfiguration implements IConfiguration {

@Nullable
@Override
public String get(final String key) {
List<IConfiguration> configurations = getConfigurations();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class TelemetryConfiguration extends CompositeConfiguration {
private static final SaveableFileConfiguration FILE = new SaveableFileConfiguration(
Directories.RED_HAT.resolve("com.redhat.devtools.intellij.telemetry"));

private static TelemetryConfiguration INSTANCE = new TelemetryConfiguration();
private static final TelemetryConfiguration INSTANCE = new TelemetryConfiguration();

public static TelemetryConfiguration getInstance() {
return INSTANCE;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package com.redhat.devtools.intellij.telemetry.core.configuration.limits;

import com.intellij.openapi.util.text.StringUtil;

import java.util.Arrays;

public enum Enabled {
ALL("all"),
ERROR("error"),
CRASH("crash"),
OFF("off");

private final String value;

Enabled(String value) {
this.value = value;
}

private boolean hasValue(String value) {
if (StringUtil.isEmptyOrSpaces(value)) {
return this.value == null;
}
return value.equals(this.value);
}

public static Enabled safeValueOf(String value) {
return Arrays.stream(values())
.filter(instance -> instance.hasValue(value))
.findAny()
.orElse(ALL);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package com.redhat.devtools.intellij.telemetry.core.configuration.limits;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.Service;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.util.xmlb.XmlSerializerUtil;
import com.redhat.devtools.intellij.telemetry.core.service.Event;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import static com.redhat.devtools.intellij.telemetry.core.util.TimeUtils.isToday;

/**
* A counter that stores daily occurrences of events.
* The state is persisted and loaded by the IDEA platform
*
* @see PersistentStateComponent
*/
@Service
@State(
name = " com.redhat.devtools.intellij.telemetry.core.configuration.limits.EventCounts",
storages = @Storage(value = "eventCounts.xml")
)
public final class EventCounts implements PersistentStateComponent<EventCounts> {

public static EventCounts getInstance() {
return ApplicationManager.getApplication().getService(EventCounts.class);
}

private static final String COUNT_VALUES_SEPARATOR = ",";

EventCounts() {}

public final Map<String, String> counts = new HashMap<>();

@Override
public EventCounts getState() {
return this;
}

@Override
public void loadState(@NotNull EventCounts state) {
XmlSerializerUtil.copyBean(state, this);
}

@Override
public void noStateLoaded() {
PersistentStateComponent.super.noStateLoaded();
}

@Override
public void initializeComponent() {
PersistentStateComponent.super.initializeComponent();
}

@Nullable
public Count get(Event event) {
if (event == null) {
return null;
}
String countString = counts.get(event.getName());
return toCount(countString);
}

public void put(Event event) {
Count count = createOrUpdateCount(event);
put(event, count);
}

EventCounts put(Event event, Count count) {
if (event == null) {
return this;
}
counts.put(event.getName(), toString(count));
return this;
}

private Count createOrUpdateCount(Event event) {
Count count = get(event);
if (count != null) {
// update existing
count = count.newOccurrence();
} else {
// create new
count = new Count();
}
return count;
}

private Count toCount(String string) {
if (StringUtils.isEmpty(string)) {
return null;
}
String[] split = string.split(COUNT_VALUES_SEPARATOR);
LocalDateTime lastOccurrence = toLastOccurrence(split[0]);
int total = toTotal(split[1]);
return new Count(lastOccurrence, total);
}

private LocalDateTime toLastOccurrence(String value) {
try {
long epochSeconds = Long.parseLong(value);
return LocalDateTime.ofEpochSecond(epochSeconds, 0, ZonedDateTime.now().getOffset());
} catch (NumberFormatException e) {
return null;
}
}

private int toTotal(String value) {
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
return 0;
}
}

String toString(@NotNull Count count) {
long epochSecond = count.lastOccurrence.toEpochSecond(ZonedDateTime.now().getOffset());
return epochSecond + COUNT_VALUES_SEPARATOR + count.dailyTotal;
}

public static class Count {
private final LocalDateTime lastOccurrence;
private final int dailyTotal;

Count() {
this(LocalDateTime.now(), 1);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Count)) return false;
Count count = (Count) o;
return dailyTotal == count.dailyTotal && Objects.equals(lastOccurrence, count.lastOccurrence);
}

@Override
public int hashCode() {
return Objects.hash(lastOccurrence, dailyTotal);
}

Count(LocalDateTime lastOccurrence, int dailyTotal) {
this.lastOccurrence = lastOccurrence;
this.dailyTotal = dailyTotal;
}

public LocalDateTime getLastOccurrence() {
return lastOccurrence;
}

public int getDailyTotal() {
if (isToday(lastOccurrence)) {
return dailyTotal;
} else {
return 0;
}
}

public Count newOccurrence() {
return new Count(LocalDateTime.now(), getDailyTotal() + 1);
}
}
}
Loading
Loading