Skip to content

Commit 29a3a6e

Browse files
authored
Merge pull request #5062 from microsoft/telemetry/tag
Add workspace tagging for IntelliJ toolkit
2 parents 174d494 + a6f620b commit 29a3a6e

File tree

8 files changed

+251
-2
lines changed

8 files changed

+251
-2
lines changed

PluginsAndFeatures/azure-toolkit-for-intellij/azure-sdk-reference-book/build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ dependencies {
2323
annotationProcessor 'org.projectlombok:lombok:1.18.8'
2424

2525
compileOnly 'org.jetbrains:annotations:20.1.0'
26+
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-csv:2.11.2', {
27+
exclude group: "com.fasterxml.jackson", module: "jackson-bom"
28+
}
2629
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.11.2', {
2730
exclude group: "com.fasterxml.jackson", module: "jackson-bom"
2831
}
29-
3032
compile project(':azure-intellij-plugin-lib')
3133
compile "com.microsoft.azure:azure-toolkit-common-lib:0.5.0-SNAPSHOT"
3234

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*/
5+
6+
package com.microsoft.azure.toolkit.intellij.azuresdk.dependencesurvey.activity;
7+
8+
import com.intellij.openapi.application.ApplicationManager;
9+
import com.intellij.openapi.application.ReadAction;
10+
import com.intellij.openapi.project.Project;
11+
import com.intellij.openapi.roots.OrderEnumerator;
12+
import com.intellij.openapi.startup.StartupActivity;
13+
import com.microsoft.azure.toolkit.intellij.azuresdk.service.WorkspaceTaggingService;
14+
import com.microsoft.azure.toolkit.lib.common.telemetry.AzureTelemeter;
15+
import com.microsoft.azure.toolkit.lib.common.telemetry.Telemetry;
16+
import org.apache.commons.lang.StringUtils;
17+
import org.jetbrains.annotations.NotNull;
18+
19+
import java.util.HashMap;
20+
import java.util.Map;
21+
import java.util.Set;
22+
import java.util.regex.Matcher;
23+
import java.util.regex.Pattern;
24+
25+
public class WorkspaceTaggingActivity implements StartupActivity.DumbAware {
26+
private static final Pattern PATTERN = Pattern.compile("(Gradle|Maven): (.+):(.+):(.+)");
27+
private static final String WORKSPACE_TAGGING = "workspace-tagging";
28+
private static final String OPERATION_NAME = "operationName";
29+
private static final String SERVICE_NAME = "serviceName";
30+
private static final String SYSTEM = "system";
31+
private static final String TAG = "tag";
32+
33+
@Override
34+
public void runActivity(@NotNull final Project project) {
35+
ApplicationManager.getApplication().executeOnPooledThread(() -> ReadAction.nonBlocking(() -> trackProjectDependencies(project)).executeSynchronously());
36+
}
37+
38+
private void trackProjectDependencies(@NotNull final Project project) {
39+
final Set<String> tagSet = new java.util.HashSet<>();
40+
OrderEnumerator.orderEntries(project).forEachLibrary(library -> {
41+
if (StringUtils.isEmpty(library.getName())) {
42+
return true;
43+
}
44+
final Matcher matcher = PATTERN.matcher(library.getName());
45+
if (matcher.matches()) {
46+
final String tag = WorkspaceTaggingService.getWorkspaceTag(matcher.group(2), matcher.group(3));
47+
if (StringUtils.isNotEmpty(tag)) {
48+
tagSet.add(tag);
49+
}
50+
}
51+
return true;
52+
});
53+
sendWorkspaceTaggingTelemetry(tagSet);
54+
}
55+
56+
private void sendWorkspaceTaggingTelemetry(final Set<String> tagSet) {
57+
final Map<String, String> properties = new HashMap<>();
58+
properties.put(SERVICE_NAME, SYSTEM);
59+
properties.put(OPERATION_NAME, WORKSPACE_TAGGING);
60+
properties.put(TAG, StringUtils.join(tagSet, ","));
61+
AzureTelemeter.log(Telemetry.Type.INFO, properties);
62+
}
63+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*/
5+
6+
package com.microsoft.azure.toolkit.intellij.azuresdk.model;
7+
8+
import com.fasterxml.jackson.annotation.JsonProperty;
9+
import lombok.Getter;
10+
import lombok.NoArgsConstructor;
11+
import lombok.ToString;
12+
13+
@ToString
14+
@Getter
15+
@NoArgsConstructor
16+
public class AzureJavaSdkEntity {
17+
@JsonProperty("Package")
18+
private String packageName;
19+
@JsonProperty("GroupId")
20+
private String groupId;
21+
@JsonProperty("VersionGA")
22+
private String versionGA;
23+
@JsonProperty("VersionPreview")
24+
private String versionPreview;
25+
@JsonProperty("DisplayName")
26+
private String displayName;
27+
@JsonProperty("ServiceName")
28+
private String serviceName;
29+
@JsonProperty("RepoPath")
30+
private String repoPath;
31+
@JsonProperty("MSDocs")
32+
private String msDocs;
33+
@JsonProperty("GHDocs")
34+
private String ghDocs;
35+
@JsonProperty("Type")
36+
private String type;
37+
@JsonProperty("New")
38+
private Boolean isNew; // New
39+
@JsonProperty("PlannedVersions")
40+
private String plannedVersions;
41+
@JsonProperty(value = "Hide")
42+
private Boolean isHide;
43+
@JsonProperty("Notes")
44+
private String notes;
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*/
5+
6+
package com.microsoft.azure.toolkit.intellij.azuresdk.model;
7+
8+
import lombok.Getter;
9+
import lombok.NoArgsConstructor;
10+
import lombok.ToString;
11+
12+
@ToString
13+
@Getter
14+
@NoArgsConstructor
15+
public class WorkspaceTagEntity {
16+
private String groupId;
17+
private String artifactId;
18+
private String tag;
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*/
5+
6+
package com.microsoft.azure.toolkit.intellij.azuresdk.service;
7+
8+
import com.fasterxml.jackson.core.JsonParser;
9+
import com.fasterxml.jackson.databind.DeserializationFeature;
10+
import com.fasterxml.jackson.databind.MappingIterator;
11+
import com.fasterxml.jackson.databind.ObjectMapper;
12+
import com.fasterxml.jackson.databind.json.JsonMapper;
13+
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
14+
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
15+
import com.microsoft.azure.toolkit.intellij.azuresdk.model.AzureJavaSdkEntity;
16+
import com.microsoft.azure.toolkit.intellij.azuresdk.model.WorkspaceTagEntity;
17+
import com.microsoft.azure.toolkit.lib.common.cache.Cacheable;
18+
import com.microsoft.azure.toolkit.lib.common.cache.Preload;
19+
import org.apache.commons.lang3.ObjectUtils;
20+
import org.apache.commons.lang3.StringUtils;
21+
22+
import javax.annotation.Nonnull;
23+
import javax.annotation.Nullable;
24+
import java.io.IOException;
25+
import java.io.InputStream;
26+
import java.net.URL;
27+
import java.util.Collections;
28+
import java.util.List;
29+
30+
public class WorkspaceTaggingService {
31+
private static final String SDK_METADATA_URL = "https://raw.githubusercontent.com/Azure/azure-sdk/master/_data/releases/latest/java-packages.csv";
32+
33+
private static final ObjectMapper CSV_MAPPER = new CsvMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
34+
private static final ObjectMapper JSON_MAPPER = new JsonMapper().configure(JsonParser.Feature.ALLOW_COMMENTS, true);
35+
private static final String WORKSPACE_TAG_JSON = "/workspaceTag.json";
36+
37+
@Nullable
38+
public static String getWorkspaceTag(@Nonnull String groupId, @Nonnull final String artifactId) {
39+
if (StringUtils.isAnyEmpty(groupId, artifactId)) {
40+
return null;
41+
}
42+
return ObjectUtils.firstNonNull(getAzureDependencyTag(groupId, artifactId), getExternalDependencyTag(groupId, artifactId));
43+
}
44+
45+
private static String getAzureDependencyTag(final String groupId, final String artifactId) {
46+
return getAzureSDKEntities()
47+
.stream()
48+
.filter(entity -> StringUtils.isNotEmpty(entity.getType())
49+
&& StringUtils.equalsIgnoreCase(entity.getGroupId(), groupId)
50+
&& StringUtils.equalsIgnoreCase(entity.getPackageName(), artifactId))
51+
.map(AzureJavaSdkEntity::getType)
52+
.findFirst().orElse(null);
53+
}
54+
55+
private static String getExternalDependencyTag(final String groupId, final String artifactId) {
56+
return getWorkspaceTagEntities()
57+
.stream()
58+
.filter(entity -> (StringUtils.isEmpty(entity.getGroupId()) || StringUtils.equalsIgnoreCase(entity.getGroupId(), groupId))
59+
&& (StringUtils.isEmpty(entity.getArtifactId()) || StringUtils.equalsIgnoreCase(entity.getArtifactId(), artifactId)))
60+
.map(WorkspaceTagEntity::getTag)
61+
.findFirst().orElse(null);
62+
}
63+
64+
@Preload
65+
@Cacheable(value = "workspace-tag", condition = "!(force&&force[0])")
66+
public static List<WorkspaceTagEntity> getWorkspaceTagEntities(boolean... force) {
67+
try (final InputStream stream = WorkspaceTaggingService.class.getResourceAsStream(WORKSPACE_TAG_JSON)) {
68+
final MappingIterator<WorkspaceTagEntity> iterator = JSON_MAPPER.readerFor(WorkspaceTagEntity.class).readValues(stream);
69+
return iterator.readAll();
70+
} catch (IOException exception) {
71+
return Collections.emptyList();
72+
}
73+
}
74+
75+
@Preload
76+
@Cacheable(value = "workspace-tag-azure", condition = "!(force&&force[0])")
77+
public static List<AzureJavaSdkEntity> getAzureSDKEntities(boolean... force) {
78+
try {
79+
final URL destination = new URL(SDK_METADATA_URL);
80+
final CsvSchema schema = CsvSchema.emptySchema().withHeader();
81+
final MappingIterator<AzureJavaSdkEntity> mappingIterator = CSV_MAPPER.readerFor(AzureJavaSdkEntity.class).with(schema).readValues(destination);
82+
return mappingIterator.readAll();
83+
} catch (IOException e) {
84+
return Collections.emptyList();
85+
}
86+
}
87+
}

PluginsAndFeatures/azure-toolkit-for-intellij/azure-sdk-reference-book/src/main/resources/META-INF/azure-sdk-reference-book.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<idea-plugin>
22
<extensionPoints>
33
</extensionPoints>
4+
<extensions defaultExtensionNs="com.intellij">
5+
<postStartupActivity implementation="com.microsoft.azure.toolkit.intellij.azuresdk.dependencesurvey.activity.WorkspaceTaggingActivity"/>
6+
</extensions>
47
<actions>
58
<action id="AzureToolkit.OpenSdkReferenceBook"
69
class="com.microsoft.azure.toolkit.intellij.azuresdk.referencebook.OpenReferenceBookAction"
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
[
2+
// java ee
3+
{ "groupId": "javax", "artifactId": "javaee-api", "tag": "javaee" },
4+
{ "groupId": "javax.xml.bind", "artifactId": "jaxb-api", "tag": "javaee" },
5+
// jdbc
6+
{ "groupId": "mysql", "artifactId": "mysql-connector-java", "tag": "jdbc" },
7+
{ "groupId": "com.microsoft.sqlserver", "artifactId": "mssql-jdbc", "tag": "jdbc" },
8+
{ "groupId": "com.oracle.database.jdbc", "artifactId": "ojdbc10", "tag": "jdbc" },
9+
// jpa
10+
{ "groupId": "org.hibernate", "artifactId": "hibernate-core", "tag": "jpa" },
11+
{ "groupId": "org.eclipse.persistence", "artifactId": "eclipselink", "tag": "jpa" },
12+
// lombok
13+
{ "groupId": "org.projectlombok", "artifactId": "lombok", "tag": "lombok" },
14+
// mockito
15+
{ "groupId": "org.mockito", "artifactId": "mockito-core", "tag": "mockito" },
16+
{ "groupId": "org.powermock", "artifactId": "powermock-core", "tag": "mockito" },
17+
// redis
18+
{ "groupId": "org.springframework.data", "artifactId": "spring-data-redis", "tag": "redis" },
19+
{ "groupId": "redis.clients", "artifactId": "jedis", "tag": "redis" },
20+
{ "groupId": "org.redisson", "artifactId": "redisson", "tag": "redis" },
21+
{ "groupId": "io.lettuce", "artifactId": "lettuce-core", "tag": "redis" },
22+
// spring boot
23+
{ "groupId": "org.springframework.boot", "artifactId": "", "tag": "springboot" },
24+
// sql
25+
{ "groupId": "org.jooq", "artifactId": "jooq", "tag": "sql" },
26+
{ "groupId": "org.mybatis", "artifactId": "mybatis", "tag": "sql" },
27+
// unit test
28+
{ "groupId": "org.junit.jupiter", "artifactId": "junit-jupiter-api", "tag": "unitTest" },
29+
{ "groupId": "junit", "artifactId": "junit", "tag": "unitTest" },
30+
{ "groupId": "org.testng", "artifactId": "testng", "tag": "unitTest" }
31+
]

Utils/azuretools-core/src/com/microsoft/azuretools/telemetry/TelemetryConstants.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ public class TelemetryConstants {
184184
public static final String UPDATE_A_CLUSTER = "update-a-cluster";
185185
public static final String SHOW_WHATS_NEW = "show-whats-new";
186186
public static final String UNHANDLED_EXCEPTION = "unhandled-exception";
187-
188187
public static final String LIST_FILE = "list-file";
189188
public static final String REFRESH_FILE = "refresh-file";
190189
public static final String OPEN_FILE = "open-file";

0 commit comments

Comments
 (0)