Skip to content

Commit

Permalink
Reindex GitHub Events into maintainer inactivity data
Browse files Browse the repository at this point in the history
Signed-off-by: Brandon Shien <bshien@amazon.com>
  • Loading branch information
bshien committed Sep 30, 2024
1 parent d8b52e6 commit 038014a
Show file tree
Hide file tree
Showing 13 changed files with 791 additions and 23 deletions.
11 changes: 6 additions & 5 deletions src/main/java/org/opensearchmetrics/dagger/CommonModule.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.opensearchmetrics.dagger;

import org.opensearchmetrics.util.SecretsManagerUtil;
import com.amazonaws.services.secretsmanager.AWSSecretsManager;
import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
Expand All @@ -15,10 +16,10 @@
import org.opensearchmetrics.metrics.MetricsCalculation;
import org.opensearchmetrics.metrics.general.*;
import org.opensearchmetrics.metrics.label.LabelMetrics;
import org.opensearchmetrics.metrics.maintainer.MaintainerMetrics;
import org.opensearchmetrics.metrics.release.ReleaseMetrics;
import org.opensearchmetrics.util.OpenSearchUtil;
import com.amazonaws.services.secretsmanager.AWSSecretsManager;
import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder;
import org.opensearchmetrics.util.SecretsManagerUtil;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.signer.Aws4Signer;
import software.amazon.awssdk.services.sts.StsClient;
Expand Down Expand Up @@ -86,15 +87,15 @@ public MetricsCalculation getMetricsCalculation(OpenSearchUtil openSearchUtil, O
CreatedIssues createdIssues, IssueComments issueComments,
PullComments pullComments, IssuePositiveReactions issuePositiveReactions,
IssueNegativeReactions issueNegativeReactions, LabelMetrics labelMetrics,
ReleaseMetrics releaseMetrics) {
ReleaseMetrics releaseMetrics, MaintainerMetrics maintainerMetrics) {
return new MetricsCalculation(openSearchUtil, objectMapper,
untriagedIssues, uncommentedPullRequests,
unlabelledPullRequests, unlabelledIssues,
mergedPullRequests, openPullRequests,
openIssues, closedIssues, createdIssues,
issueComments, pullComments,
issuePositiveReactions, issueNegativeReactions,
labelMetrics, releaseMetrics);
labelMetrics, releaseMetrics, maintainerMetrics);
}

@Provides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,7 @@
import dagger.Provides;
import org.opensearchmetrics.metrics.general.*;
import org.opensearchmetrics.metrics.label.LabelMetrics;
import org.opensearchmetrics.metrics.release.ReleaseBranchChecker;
import org.opensearchmetrics.metrics.release.ReleaseIssueChecker;
import org.opensearchmetrics.metrics.release.ReleaseLabelIssuesFetcher;
import org.opensearchmetrics.metrics.release.ReleaseLabelPullsFetcher;
import org.opensearchmetrics.metrics.release.ReleaseMetrics;
import org.opensearchmetrics.metrics.release.ReleaseNotesChecker;
import org.opensearchmetrics.metrics.release.ReleaseRepoFetcher;
import org.opensearchmetrics.metrics.release.ReleaseVersionIncrementChecker;
import org.opensearchmetrics.metrics.release.*;
import org.opensearchmetrics.util.OpenSearchUtil;

import javax.inject.Named;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public Void handleRequest(Void input, Context context) {
metricsCalculation.generateGeneralMetrics(keys);
metricsCalculation.generateLabelMetrics(keys);
metricsCalculation.generateReleaseMetrics();
metricsCalculation.generateMaintainerMetrics(keys);
} catch (Exception e) {
throw new RuntimeException("Error running Metrics Calculation", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
import org.opensearch.index.query.BoolQueryBuilder;
import org.opensearchmetrics.metrics.general.*;
import org.opensearchmetrics.metrics.label.LabelMetrics;
import org.opensearchmetrics.metrics.maintainer.MaintainerMetrics;
import org.opensearchmetrics.metrics.release.ReleaseInputs;
import org.opensearchmetrics.metrics.release.ReleaseMetrics;
import org.opensearchmetrics.model.label.LabelData;
import org.opensearchmetrics.model.general.MetricsData;
import org.opensearchmetrics.model.label.LabelData;
import org.opensearchmetrics.model.maintainer.EventData;
import org.opensearchmetrics.model.maintainer.MaintainerData;
import org.opensearchmetrics.model.release.ReleaseMetricsData;
import org.opensearchmetrics.util.OpenSearchUtil;

Expand All @@ -19,11 +22,7 @@
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand All @@ -48,6 +47,7 @@ public class MetricsCalculation {
private final IssueNegativeReactions issueNegativeReactions;
private final LabelMetrics labelMetrics;
private final ReleaseMetrics releaseMetrics;
private final MaintainerMetrics maintainerMetrics;


public MetricsCalculation(OpenSearchUtil openSearchUtil, ObjectMapper objectMapper,
Expand All @@ -58,7 +58,7 @@ public MetricsCalculation(OpenSearchUtil openSearchUtil, ObjectMapper objectMapp
CreatedIssues createdIssues, IssueComments issueComments,
PullComments pullComments, IssuePositiveReactions issuePositiveReactions,
IssueNegativeReactions issueNegativeReactions, LabelMetrics labelMetrics,
ReleaseMetrics releaseMetrics) {
ReleaseMetrics releaseMetrics, MaintainerMetrics maintainerMetrics) {
this.unlabelledPullRequests = unlabelledPullRequests;
this.unlabelledIssues = unlabelledIssues;
this.mergedPullRequests = mergedPullRequests;
Expand All @@ -77,6 +77,7 @@ public MetricsCalculation(OpenSearchUtil openSearchUtil, ObjectMapper objectMapp
this.uncommentedPullRequests = uncommentedPullRequests;
this.labelMetrics = labelMetrics;
this.releaseMetrics = releaseMetrics;
this.maintainerMetrics = maintainerMetrics;
}


Expand Down Expand Up @@ -199,4 +200,87 @@ public void generateReleaseMetrics() {
openSearchUtil.bulkIndex("opensearch_release_metrics", metricFinalData);
}

public void generateMaintainerMetrics(List<String> repositories) {
long[] mostAndLeastRepoEventCounts = maintainerMetrics.mostAndLeastRepoEventCounts(openSearchUtil);
final double mostRepoEventCount = (double) mostAndLeastRepoEventCounts[0];
final double leastRepoEventCount = (double) mostAndLeastRepoEventCounts[1];
final double higherBoundDays = 365; // 1 year
final double lowerBoundDays = 90; // 3 months

Check warning on line 208 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L204-L208

Added lines #L204 - L208 were not covered by tests

// Slope and intercept for linear equation:
// x = number of events
// y = time maintainer is inactive until they are flagged as inactive
final double[] slopeAndIntercept = maintainerMetrics.getSlopeAndIntercept(leastRepoEventCount, higherBoundDays, mostRepoEventCount, lowerBoundDays);

Check warning on line 213 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L213

Added line #L213 was not covered by tests

List<String> eventTypes = maintainerMetrics.getEventTypes(openSearchUtil);

Check warning on line 215 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L215

Added line #L215 was not covered by tests

Map<String, String> metricFinalData = repositories.stream()
.flatMap(repo -> {
long currentRepoEventCount = maintainerMetrics.repoEventCount(repo, openSearchUtil);
return maintainerMetrics.repoMaintainers(repo).stream()
.flatMap(maintainerData -> {
EventData latestEvent = null;
List<MaintainerData> individualEvents = new ArrayList<>();

Check warning on line 223 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L217-L223

Added lines #L217 - L223 were not covered by tests
for (String eventType : eventTypes) {
MaintainerData maintainerEvent = new MaintainerData();

Check warning on line 225 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L225

Added line #L225 was not covered by tests
try {
maintainerEvent.setId(String.valueOf(UUID.nameUUIDFromBytes(MessageDigest.getInstance("SHA-1")
.digest(("maintainer-engagement-" + eventType + "-" + maintainerData.getGithubLogin() + "-" + currentDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "-" + repo)
.getBytes()))));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
maintainerEvent.setCurrentDate(currentDate.toString());
maintainerEvent.setEventType(eventType);
maintainerEvent.setRepository(repo);
maintainerEvent.setName(maintainerData.getName());
maintainerEvent.setGithubLogin((maintainerData.getGithubLogin()));
maintainerEvent.setAffiliation(maintainerData.getAffiliation());
Optional<EventData> eventDataOpt = maintainerMetrics.queryLatestEvent(repo, maintainerData.getGithubLogin(), eventType, openSearchUtil);

Check warning on line 239 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L227-L239

Added lines #L227 - L239 were not covered by tests
if (eventDataOpt.isPresent()) {
EventData eventData = eventDataOpt.get();
eventData.setInactive(maintainerMetrics.calculateInactivity(currentRepoEventCount, slopeAndIntercept, lowerBoundDays, eventData));

Check warning on line 242 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L241-L242

Added lines #L241 - L242 were not covered by tests
if (latestEvent != null) {
if (eventData.getTimeLastEngaged().isAfter(latestEvent.getTimeLastEngaged())) {
latestEvent = eventData;

Check warning on line 245 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L245

Added line #L245 was not covered by tests
}
} else {
latestEvent = eventData;

Check warning on line 248 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L248

Added line #L248 was not covered by tests
}
maintainerEvent.setEventAction(eventData.getEventAction());
maintainerEvent.setTimeLastEngaged(eventData.getTimeLastEngaged().toString());
maintainerEvent.setInactive(eventData.isInactive());
} else {

Check warning on line 253 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L250-L253

Added lines #L250 - L253 were not covered by tests
// If the Optional<EventData> has no value, then leave event action, time last engaged, and inactive empty
maintainerEvent.setInactive(true);

Check warning on line 255 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L255

Added line #L255 was not covered by tests
}
individualEvents.add(maintainerEvent);
}

Check warning on line 258 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L257-L258

Added lines #L257 - L258 were not covered by tests
// Create doc that is the combination of all event types
// This is for easily seeing if a maintainer has been inactive in a repo across all event types
maintainerData.setEventType("Any");

Check warning on line 261 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L261

Added line #L261 was not covered by tests
try {
maintainerData.setId(String.valueOf(UUID.nameUUIDFromBytes(MessageDigest.getInstance("SHA-1")
.digest(("maintainer-engagement-" + maintainerData.getEventType() + "-" + maintainerData.getGithubLogin() + "-" + currentDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "-" + repo)
.getBytes()))));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
maintainerData.setCurrentDate(currentDate.toString());

Check warning on line 269 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L263-L269

Added lines #L263 - L269 were not covered by tests
if (latestEvent != null) {
maintainerData.setEventAction(latestEvent.getEventAction());
maintainerData.setTimeLastEngaged(latestEvent.getTimeLastEngaged().toString());
maintainerData.setInactive(latestEvent.isInactive());

Check warning on line 273 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L271-L273

Added lines #L271 - L273 were not covered by tests
} else {
maintainerData.setInactive(true);

Check warning on line 275 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L275

Added line #L275 was not covered by tests
}
Stream<MaintainerData> compositeEvent = Stream.of(maintainerData);
return Stream.concat(individualEvents.stream(), compositeEvent);

Check warning on line 278 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L277-L278

Added lines #L277 - L278 were not covered by tests
});
})
.collect(Collectors.toMap(MaintainerData::getId, maintainerData -> maintainerData.getJson(maintainerData, objectMapper)));
openSearchUtil.createIndexIfNotExists("maintainer_engagement");
openSearchUtil.bulkIndex("maintainer_engagement", metricFinalData);
}

Check warning on line 284 in src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/org/opensearchmetrics/metrics/MetricsCalculation.java#L281-L284

Added lines #L281 - L284 were not covered by tests

}
Loading

0 comments on commit 038014a

Please sign in to comment.