Skip to content

Commit 920b439

Browse files
authored
feat: allow message limits (#82) (#85)
feat: allow message limits (#82) Signed-off-by: Andre Dietisheim <[email protected]>
1 parent a46bf55 commit 920b439

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+4219
-104
lines changed

build.gradle

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ dependencies {
5353
}
5454

5555
test {
56+
// Discover and execute all other JUnit5-based tests
5657
useJUnitPlatform()
5758
afterSuite { desc, result ->
5859
if (!desc.parent)
@@ -64,6 +65,15 @@ test {
6465
}
6566
}
6667

68+
tasks.register('platformTests', Test) {
69+
// Discover and execute JUnit4-based EventCountsTest
70+
useJUnit()
71+
description = 'Runs the platform tests.'
72+
group = 'verification'
73+
outputs.upToDateWhen { false }
74+
mustRunAfter test
75+
}
76+
6777
configurations {
6878
implementation {
6979
exclude group: 'org.slf4j', module: 'slf4j-api'

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
ideaVersion = IC-2020.3
1+
ideaVersion = IC-2022.1
22
# build number ranges
33
# https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html
4-
sinceIdeaBuild=203
4+
sinceIdeaBuild=211
55
projectVersion=1.2.0-SNAPSHOT
66
intellijPluginVersion=1.16.1
77
jetBrainsToken=invalid

src/main/java/com/redhat/devtools/intellij/telemetry/core/configuration/ClasspathConfiguration.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
******************************************************************************/
1111
package com.redhat.devtools.intellij.telemetry.core.configuration;
1212

13-
import java.io.FileNotFoundException;
1413
import java.io.InputStream;
1514
import java.nio.file.Path;
1615

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

3029
@Override
31-
protected InputStream createInputStream(Path path) throws FileNotFoundException {
30+
protected InputStream createInputStream(Path path) {
3231
if (path == null) {
3332
return null;
3433
}

src/main/java/com/redhat/devtools/intellij/telemetry/core/configuration/CompositeConfiguration.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,14 @@
1010
******************************************************************************/
1111
package com.redhat.devtools.intellij.telemetry.core.configuration;
1212

13+
import org.jetbrains.annotations.Nullable;
14+
1315
import java.util.List;
1416
import java.util.Objects;
1517

1618
public abstract class CompositeConfiguration implements IConfiguration {
1719

20+
@Nullable
1821
@Override
1922
public String get(final String key) {
2023
List<IConfiguration> configurations = getConfigurations();

src/main/java/com/redhat/devtools/intellij/telemetry/core/configuration/TelemetryConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public class TelemetryConfiguration extends CompositeConfiguration {
2525
private static final SaveableFileConfiguration FILE = new SaveableFileConfiguration(
2626
Directories.RED_HAT.resolve("com.redhat.devtools.intellij.telemetry"));
2727

28-
private static TelemetryConfiguration INSTANCE = new TelemetryConfiguration();
28+
private static final TelemetryConfiguration INSTANCE = new TelemetryConfiguration();
2929

3030
public static TelemetryConfiguration getInstance() {
3131
return INSTANCE;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 Red Hat, Inc.
3+
* Distributed under license by Red Hat, Inc. All rights reserved.
4+
* This program is made available under the terms of the
5+
* Eclipse Public License v2.0 which accompanies this distribution,
6+
* and is available at http://www.eclipse.org/legal/epl-v20.html
7+
*
8+
* Contributors:
9+
* Red Hat, Inc. - initial API and implementation
10+
******************************************************************************/
11+
package com.redhat.devtools.intellij.telemetry.core.configuration.limits;
12+
13+
import com.intellij.openapi.util.text.StringUtil;
14+
15+
import java.util.Arrays;
16+
17+
public enum Enabled {
18+
ALL("all"),
19+
ERROR("error"),
20+
CRASH("crash"),
21+
OFF("off");
22+
23+
private final String value;
24+
25+
Enabled(String value) {
26+
this.value = value;
27+
}
28+
29+
private boolean hasValue(String value) {
30+
if (StringUtil.isEmptyOrSpaces(value)) {
31+
return this.value == null;
32+
}
33+
return value.equals(this.value);
34+
}
35+
36+
public static Enabled safeValueOf(String value) {
37+
return Arrays.stream(values())
38+
.filter(instance -> instance.hasValue(value))
39+
.findAny()
40+
.orElse(ALL);
41+
}
42+
}
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 Red Hat, Inc.
3+
* Distributed under license by Red Hat, Inc. All rights reserved.
4+
* This program is made available under the terms of the
5+
* Eclipse Public License v2.0 which accompanies this distribution,
6+
* and is available at http://www.eclipse.org/legal/epl-v20.html
7+
*
8+
* Contributors:
9+
* Red Hat, Inc. - initial API and implementation
10+
******************************************************************************/
11+
package com.redhat.devtools.intellij.telemetry.core.configuration.limits;
12+
13+
import com.intellij.openapi.application.ApplicationManager;
14+
import com.intellij.openapi.components.PersistentStateComponent;
15+
import com.intellij.openapi.components.Service;
16+
import com.intellij.openapi.components.State;
17+
import com.intellij.openapi.components.Storage;
18+
import com.intellij.util.xmlb.XmlSerializerUtil;
19+
import com.redhat.devtools.intellij.telemetry.core.service.Event;
20+
import org.apache.commons.lang.StringUtils;
21+
import org.jetbrains.annotations.NotNull;
22+
import org.jetbrains.annotations.Nullable;
23+
24+
import java.time.LocalDateTime;
25+
import java.time.ZonedDateTime;
26+
import java.util.HashMap;
27+
import java.util.Map;
28+
import java.util.Objects;
29+
30+
import static com.redhat.devtools.intellij.telemetry.core.util.TimeUtils.isToday;
31+
32+
/**
33+
* A counter that stores daily occurrences of events.
34+
* The state is persisted and loaded by the IDEA platform
35+
*
36+
* @see PersistentStateComponent
37+
*/
38+
@Service
39+
@State(
40+
name = " com.redhat.devtools.intellij.telemetry.core.configuration.limits.EventCounts",
41+
storages = @Storage(value = "eventCounts.xml")
42+
)
43+
public final class EventCounts implements PersistentStateComponent<EventCounts> {
44+
45+
public static EventCounts getInstance() {
46+
return ApplicationManager.getApplication().getService(EventCounts.class);
47+
}
48+
49+
private static final String COUNT_VALUES_SEPARATOR = ",";
50+
51+
EventCounts() {}
52+
53+
public final Map<String, String> counts = new HashMap<>();
54+
55+
@Override
56+
public EventCounts getState() {
57+
return this;
58+
}
59+
60+
@Override
61+
public void loadState(@NotNull EventCounts state) {
62+
XmlSerializerUtil.copyBean(state, this);
63+
}
64+
65+
@Override
66+
public void noStateLoaded() {
67+
PersistentStateComponent.super.noStateLoaded();
68+
}
69+
70+
@Override
71+
public void initializeComponent() {
72+
PersistentStateComponent.super.initializeComponent();
73+
}
74+
75+
@Nullable
76+
public Count get(Event event) {
77+
if (event == null) {
78+
return null;
79+
}
80+
String countString = counts.get(event.getName());
81+
return toCount(countString);
82+
}
83+
84+
public void put(Event event) {
85+
Count count = createOrUpdateCount(event);
86+
put(event, count);
87+
}
88+
89+
EventCounts put(Event event, Count count) {
90+
if (event == null) {
91+
return this;
92+
}
93+
counts.put(event.getName(), toString(count));
94+
return this;
95+
}
96+
97+
private Count createOrUpdateCount(Event event) {
98+
Count count = get(event);
99+
if (count != null) {
100+
// update existing
101+
count = count.newOccurrence();
102+
} else {
103+
// create new
104+
count = new Count();
105+
}
106+
return count;
107+
}
108+
109+
private Count toCount(String string) {
110+
if (StringUtils.isEmpty(string)) {
111+
return null;
112+
}
113+
String[] split = string.split(COUNT_VALUES_SEPARATOR);
114+
LocalDateTime lastOccurrence = toLastOccurrence(split[0]);
115+
int total = toTotal(split[1]);
116+
return new Count(lastOccurrence, total);
117+
}
118+
119+
private LocalDateTime toLastOccurrence(String value) {
120+
try {
121+
long epochSeconds = Long.parseLong(value);
122+
return LocalDateTime.ofEpochSecond(epochSeconds, 0, ZonedDateTime.now().getOffset());
123+
} catch (NumberFormatException e) {
124+
return null;
125+
}
126+
}
127+
128+
private int toTotal(String value) {
129+
try {
130+
return Integer.parseInt(value);
131+
} catch (NumberFormatException e) {
132+
return 0;
133+
}
134+
}
135+
136+
String toString(@NotNull Count count) {
137+
long epochSecond = count.lastOccurrence.toEpochSecond(ZonedDateTime.now().getOffset());
138+
return epochSecond + COUNT_VALUES_SEPARATOR + count.dailyTotal;
139+
}
140+
141+
public static class Count {
142+
private final LocalDateTime lastOccurrence;
143+
private final int dailyTotal;
144+
145+
Count() {
146+
this(LocalDateTime.now(), 1);
147+
}
148+
149+
@Override
150+
public boolean equals(Object o) {
151+
if (this == o) return true;
152+
if (!(o instanceof Count)) return false;
153+
Count count = (Count) o;
154+
return dailyTotal == count.dailyTotal && Objects.equals(lastOccurrence, count.lastOccurrence);
155+
}
156+
157+
@Override
158+
public int hashCode() {
159+
return Objects.hash(lastOccurrence, dailyTotal);
160+
}
161+
162+
Count(LocalDateTime lastOccurrence, int dailyTotal) {
163+
this.lastOccurrence = lastOccurrence;
164+
this.dailyTotal = dailyTotal;
165+
}
166+
167+
public LocalDateTime getLastOccurrence() {
168+
return lastOccurrence;
169+
}
170+
171+
public int getDailyTotal() {
172+
if (isToday(lastOccurrence)) {
173+
return dailyTotal;
174+
} else {
175+
return 0;
176+
}
177+
}
178+
179+
public Count newOccurrence() {
180+
return new Count(LocalDateTime.now(), getDailyTotal() + 1);
181+
}
182+
}
183+
}

0 commit comments

Comments
 (0)