* Add telemetry mode for spring cloud azure autoconfiguration. * track version, installId, subsId, resourcGroup and serviceName. * Add Unit test for telemetry bean. Signed-off-by: Pan Li <panli@microsoft.com> Signed-off-by: Warren Zhu <Zhongwei.Zhu@microsoft.com>
This commit is contained in:
Родитель
6436ca5c4f
Коммит
a18b4ffe3d
9
pom.xml
9
pom.xml
|
@ -79,7 +79,6 @@
|
|||
<artifactId>powermock-api-mockito2</artifactId>
|
||||
<version>${powermock.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
@ -112,6 +111,14 @@
|
|||
<artifactId>powermock-api-mockito2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Project Lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.16.20</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
<artifactId>applicationinsights-core</artifactId>
|
||||
<version>${azure.applicationinsights.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
|
@ -92,15 +92,22 @@
|
|||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<!-- Filtering Resource -->
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<includes>
|
||||
<include>META-INF/project.properties</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<!-- Raw Resource -->
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
|
|
|
@ -10,6 +10,9 @@ import com.microsoft.azure.management.Azure;
|
|||
import com.microsoft.azure.management.redis.RedisCache;
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration;
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureProperties;
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.telemetry.TelemetryTracker;
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.telemetry.TelemetryUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
|
@ -21,6 +24,7 @@ import org.springframework.context.annotation.Bean;
|
|||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
|
@ -35,6 +39,14 @@ import java.io.IOException;
|
|||
@EnableConfigurationProperties(AzureRedisProperties.class)
|
||||
public class AzureRedisAutoConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private TelemetryTracker telemetryTracker;
|
||||
|
||||
@PostConstruct
|
||||
public void triggerTelemetry() {
|
||||
TelemetryUtils.telemetryTriggerEvent(telemetryTracker, getClass().getSimpleName());
|
||||
}
|
||||
|
||||
@ConditionalOnMissingBean
|
||||
@Primary
|
||||
@Bean
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package com.microsoft.azure.spring.cloud.autoconfigure.context;
|
||||
|
||||
import com.microsoft.azure.management.Azure;
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.telemetry.TelemetryTracker;
|
||||
import com.microsoft.azure.spring.cloud.context.core.AzureAdmin;
|
||||
import com.microsoft.azure.spring.cloud.context.core.CredentialsProvider;
|
||||
import com.microsoft.azure.spring.cloud.context.core.DefaultCredentialsProvider;
|
||||
|
@ -53,4 +54,10 @@ public class AzureContextAutoConfiguration {
|
|||
public Azure azure() throws IOException {
|
||||
return Azure.authenticate(credentialsProvider().getCredentials()).withDefaultSubscription();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "spring.cloud.azure.telemetryAllowed", havingValue = "true", matchIfMissing = true)
|
||||
public TelemetryTracker telemetryTracker(Azure azure, AzureProperties azureProperties) {
|
||||
return new TelemetryTracker(azure, azureProperties.getResourceGroup());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,36 +7,20 @@
|
|||
package com.microsoft.azure.spring.cloud.autoconfigure.context;
|
||||
|
||||
import com.microsoft.azure.spring.cloud.context.core.CredentialSupplier;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ConfigurationProperties("spring.cloud.azure")
|
||||
public class AzureProperties implements CredentialSupplier {
|
||||
|
||||
private String credentialFilePath;
|
||||
|
||||
private String resourceGroup;
|
||||
|
||||
private String region;
|
||||
|
||||
public String getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
public void setRegion(String region) {
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
public String getCredentialFilePath() {
|
||||
return this.credentialFilePath;
|
||||
}
|
||||
|
||||
public void setCredentialFilePath(String credentialFilePath) {
|
||||
this.credentialFilePath = credentialFilePath;
|
||||
}
|
||||
|
||||
public String getResourceGroup() {
|
||||
return this.resourceGroup;
|
||||
}
|
||||
|
||||
public void setResourceGroup(String resourceGroup) {
|
||||
this.resourceGroup = resourceGroup;
|
||||
}
|
||||
private boolean telemetryAllowed = true;
|
||||
}
|
||||
|
|
|
@ -6,14 +6,15 @@
|
|||
|
||||
package com.microsoft.azure.spring.cloud.autoconfigure.eventhub;
|
||||
|
||||
import com.microsoft.azure.management.Azure;
|
||||
import com.microsoft.azure.management.eventhub.AuthorizationRule;
|
||||
import com.microsoft.azure.management.eventhub.EventHub;
|
||||
import com.microsoft.azure.management.eventhub.EventHubAuthorizationKey;
|
||||
import com.microsoft.azure.management.eventhub.EventHubNamespace;
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration;
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureProperties;
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.telemetry.TelemetryTracker;
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.telemetry.TelemetryUtils;
|
||||
import com.microsoft.azure.spring.cloud.context.core.AzureAdmin;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
|
@ -26,6 +27,7 @@ import org.springframework.context.annotation.Bean;
|
|||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
|
@ -50,6 +52,14 @@ public class AzureEventHubAutoConfiguration {
|
|||
private static final String SASL_MECHANISM_PLAIN = "PLAIN";
|
||||
private static final int PORT = 9093;
|
||||
|
||||
@Autowired(required = false)
|
||||
private TelemetryTracker telemetryTracker;
|
||||
|
||||
@PostConstruct
|
||||
public void triggerTelemetry() {
|
||||
TelemetryUtils.telemetryTriggerEvent(telemetryTracker, getClass().getSimpleName());
|
||||
}
|
||||
|
||||
@ConditionalOnMissingBean
|
||||
@Primary
|
||||
@Bean
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
package com.microsoft.azure.spring.cloud.autoconfigure.sql;
|
||||
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration;
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.telemetry.TelemetryTracker;
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.telemetry.TelemetryUtils;
|
||||
import com.microsoft.azure.spring.cloud.context.core.AzureAdmin;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
|
@ -25,6 +28,7 @@ import org.springframework.context.annotation.Import;
|
|||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
|
@ -42,6 +46,14 @@ import javax.sql.DataSource;
|
|||
@AutoConfigureAfter(AzureContextAutoConfiguration.class)
|
||||
public class AzureSqlAutoConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private TelemetryTracker telemetryTracker;
|
||||
|
||||
@PostConstruct
|
||||
public void triggerTelemetry() {
|
||||
TelemetryUtils.telemetryTriggerEvent(telemetryTracker, getClass().getSimpleName());
|
||||
}
|
||||
|
||||
/**
|
||||
* The Sql Server Configuration for the {@link SqlServerJdbcDataSourcePropertiesUpdater}
|
||||
* based on the {@link DatabaseType#SQLSERVER}.
|
||||
|
@ -53,6 +65,7 @@ public class AzureSqlAutoConfiguration {
|
|||
@Bean
|
||||
public JdbcDataSourcePropertiesUpdater defaultSqlServerJdbcInfoProvider(AzureSqlProperties
|
||||
azureSqlProperties, AzureAdmin azureAdmin) {
|
||||
|
||||
return new SqlServerJdbcDataSourcePropertiesUpdater(azureSqlProperties, azureAdmin);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,16 +6,18 @@
|
|||
|
||||
package com.microsoft.azure.spring.cloud.autoconfigure.storage;
|
||||
|
||||
import com.microsoft.azure.management.Azure;
|
||||
import com.microsoft.azure.management.storage.StorageAccount;
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration;
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureProperties;
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.telemetry.TelemetryTracker;
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.telemetry.TelemetryUtils;
|
||||
import com.microsoft.azure.spring.cloud.context.core.AzureAdmin;
|
||||
import com.microsoft.azure.spring.cloud.context.core.AzureUtil;
|
||||
import com.microsoft.azure.spring.cloud.storage.AzureStorageProtocolResolver;
|
||||
import com.microsoft.azure.storage.CloudStorageAccount;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
|
@ -25,6 +27,7 @@ import org.springframework.context.annotation.Bean;
|
|||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.InvalidKeyException;
|
||||
|
||||
|
@ -42,6 +45,14 @@ import java.security.InvalidKeyException;
|
|||
public class AzureStorageAutoConfiguration {
|
||||
private static final Log LOGGER = LogFactory.getLog(AzureStorageAutoConfiguration.class);
|
||||
|
||||
@Autowired(required = false)
|
||||
private TelemetryTracker telemetryTracker;
|
||||
|
||||
@PostConstruct
|
||||
public void triggerTelemetry() {
|
||||
TelemetryUtils.telemetryTriggerEvent(telemetryTracker, getClass().getSimpleName());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public CloudStorageAccount storage(AzureAdmin azureAdmin, AzureProperties azureProperties,
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE in the project root for
|
||||
* license information.
|
||||
*/
|
||||
package com.microsoft.azure.spring.cloud.autoconfigure.telemetry;
|
||||
|
||||
import com.microsoft.applicationinsights.TelemetryClient;
|
||||
import com.microsoft.azure.management.Azure;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class TelemetryTracker {
|
||||
|
||||
private static final String PROJECT_VERSION = TelemetryTracker.class.getPackage().getImplementationVersion();
|
||||
|
||||
private static final String PROJECT_INFO = "spring-cloud-azure" + "/" + PROJECT_VERSION;
|
||||
|
||||
private static final String PROPERTY_VERSION = "version";
|
||||
|
||||
private static final String PROPERTY_INSTALLATION_ID = "installationId";
|
||||
|
||||
private static final String PROPERTY_SUBSCRIPTION_ID = "subscriptionId";
|
||||
|
||||
private static final String PROPERTY_RESOURCE_GROUP = "resourceGroup";
|
||||
|
||||
private static final String PROPERTY_SERVICE_NAME = "serviceName";
|
||||
|
||||
private final TelemetryClient client;
|
||||
|
||||
private final Map<String, String> defaultProperties;
|
||||
|
||||
public TelemetryTracker(Azure azure, String resourceGroup) {
|
||||
this.client = new TelemetryClient();
|
||||
this.defaultProperties = new HashMap<>();
|
||||
|
||||
this.defaultProperties.put(PROPERTY_SUBSCRIPTION_ID, azure.getCurrentSubscription().subscriptionId());
|
||||
this.defaultProperties.put(PROPERTY_RESOURCE_GROUP, resourceGroup);
|
||||
this.defaultProperties.put(PROPERTY_VERSION, PROJECT_INFO);
|
||||
this.defaultProperties.put(PROPERTY_INSTALLATION_ID, TelemetryUtils.getHashMac());
|
||||
}
|
||||
|
||||
private void trackEvent(@NonNull String name, @NonNull Map<String, String> customProperties) {
|
||||
this.defaultProperties.forEach(customProperties::putIfAbsent);
|
||||
|
||||
this.client.trackEvent(name, customProperties, null);
|
||||
this.client.flush();
|
||||
}
|
||||
|
||||
public void trackEventWithServiceName(@NonNull String eventName, @NonNull String serviceName) {
|
||||
final Map<String, String> properties = new HashMap<>();
|
||||
|
||||
properties.put(PROPERTY_SERVICE_NAME, serviceName);
|
||||
|
||||
this.trackEvent(eventName, properties);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE in the project root for
|
||||
* license information.
|
||||
*/
|
||||
package com.microsoft.azure.spring.cloud.autoconfigure.telemetry;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.microsoft.applicationinsights.core.dependencies.apachecommons.codec.digest.DigestUtils.sha256Hex;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class TelemetryUtils {
|
||||
|
||||
private static final String UNKNOWN_MAC = "Unknown-Mac-Address";
|
||||
|
||||
private static final String EVENT_NAME = "spring-cloud-azure";
|
||||
|
||||
private static String getMacAddress() {
|
||||
try {
|
||||
final InetAddress host = InetAddress.getLocalHost();
|
||||
final byte[] macBytes = NetworkInterface.getByInetAddress(host).getHardwareAddress();
|
||||
|
||||
return new String(macBytes);
|
||||
} catch (UnknownHostException | SocketException e) { // Ignore
|
||||
return UNKNOWN_MAC;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getHashMac() {
|
||||
final String mac = getMacAddress();
|
||||
|
||||
if (mac.equals(UNKNOWN_MAC)) {
|
||||
return UNKNOWN_MAC;
|
||||
}
|
||||
|
||||
return sha256Hex(mac);
|
||||
}
|
||||
|
||||
public static void telemetryTriggerEvent(TelemetryTracker tracker, String serviceName) {
|
||||
if (tracker != null) {
|
||||
tracker.trackEventWithServiceName(EVENT_NAME, serviceName);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@
|
|||
package com.microsoft.azure.spring.cloud.autoconfigure.context;
|
||||
|
||||
import com.microsoft.azure.management.Azure;
|
||||
import com.microsoft.azure.management.resources.Subscription;
|
||||
import com.microsoft.azure.spring.cloud.autoconfigure.telemetry.TelemetryTracker;
|
||||
import com.microsoft.azure.spring.cloud.context.core.AzureAdmin;
|
||||
import com.microsoft.azure.spring.cloud.context.core.CredentialsProvider;
|
||||
import org.junit.Test;
|
||||
|
@ -17,6 +19,7 @@ import org.springframework.context.annotation.Configuration;
|
|||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.powermock.api.mockito.PowerMockito.when;
|
||||
|
||||
public class AzureContextAutoConfigurationTest {
|
||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
|
@ -37,12 +40,36 @@ public class AzureContextAutoConfigurationTest {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAzurePropertiesTelemetryMissing() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.cloud.azure.credentialFilePath=credential")
|
||||
.withPropertyValues("spring.cloud.azure.resourceGroup=group1")
|
||||
.run(context -> assertThat(context.getBean(TelemetryTracker.class)).isNotNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAzurePropertiesTelemetryConfigured() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.cloud.azure.credentialFilePath=credential")
|
||||
.withPropertyValues("spring.cloud.azure.resourceGroup=group1")
|
||||
.withPropertyValues("spring.cloud.azure.telemetryAllowed=true")
|
||||
.run(context -> assertThat(context.getBean(TelemetryTracker.class)).isNotNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAzurePropertiesTelemetryConfiguredException() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.cloud.azure.credentialFilePath=credential")
|
||||
.withPropertyValues("spring.cloud.azure.resourceGroup=group1")
|
||||
.withPropertyValues("spring.cloud.azure.telemetryAllowed=false")
|
||||
.run(context -> assertThat(context).doesNotHaveBean(TelemetryTracker.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithoutAzureProperties() {
|
||||
this.contextRunner
|
||||
.run(context -> {
|
||||
assertThat(context).doesNotHaveBean(AzureProperties.class);
|
||||
});
|
||||
.run(context -> assertThat(context).doesNotHaveBean(AzureProperties.class));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
@ -55,7 +82,13 @@ public class AzureContextAutoConfigurationTest {
|
|||
|
||||
@Bean
|
||||
Azure azure() {
|
||||
return mock(Azure.class);
|
||||
final Azure azure = mock(Azure.class);
|
||||
final Subscription subscription = mock(Subscription.class);
|
||||
|
||||
when(azure.getCurrentSubscription()).thenReturn(subscription);
|
||||
when(subscription.subscriptionId()).thenReturn("Fake-Id");
|
||||
|
||||
return azure;
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
Загрузка…
Ссылка в новой задаче