Skip to content
This repository has been archived by the owner on Aug 29, 2024. It is now read-only.

Commit

Permalink
Add spring cloud azure sql auto config for SqlServer
Browse files Browse the repository at this point in the history
  • Loading branch information
Warren Zhu committed Jun 21, 2018
1 parent ce74a47 commit 59e39c0
Show file tree
Hide file tree
Showing 9 changed files with 364 additions and 1 deletion.
37 changes: 37 additions & 0 deletions spring-cloud-azure-autoconfigure/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,54 @@
<version>${project.version}</version>
</dependency>

<!-- Event Hub -->
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>spring-cloud-azure-eventhub</artifactId>
<version>${project.version}</version>
</dependency>

<!-- Storage -->
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>spring-cloud-azure-storage</artifactId>
<version>${project.version}</version>
</dependency>

<!-- Cloud SQL -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<scope>test</scope>
</dependency>

<!-- PostgreSQL -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<optional>true</optional>
</dependency>

<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<optional>true</optional>
</dependency>

<!-- SQL Server -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<optional>true</optional>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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.sql;

import com.microsoft.azure.spring.cloud.context.core.AzureAdmin;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
* Base class of {@link JdbcDataSourcePropertiesUpdater}
*
* @author Warren Zhu
*/
public abstract class AbstractJdbcDatasourcePropertiesUpdater implements JdbcDataSourcePropertiesUpdater {
protected static final Log LOGGER = LogFactory.getLog(SqlServerJdbcDataSourcePropertiesUpdater.class);

protected final DatabaseType databaseType;
protected final AzureSqlProperties azureSqlProperties;
protected final AzureAdmin azureAdmin;

public AbstractJdbcDatasourcePropertiesUpdater(AzureSqlProperties azureSqlProperties, DatabaseType databaseType,
AzureAdmin azureAdmin) {
this.azureSqlProperties = azureSqlProperties;
this.databaseType = databaseType;
this.azureAdmin = azureAdmin;
Assert.hasText(this.azureSqlProperties.getDatabaseName(), "A database name must be provided.");
Assert.hasText(this.azureSqlProperties.getServerName(), "A database server must be provided.");
}

@Override
public void updateDataSourceProperties(DataSourceProperties dataSourceProperties) {
Assert.hasText(dataSourceProperties.getPassword(), "spring.datasource.username must not be empty");

if (StringUtils.isEmpty(dataSourceProperties.getUsername())) {
dataSourceProperties.setUsername(getUserName());
LOGGER.info(String.format("spring.datasource.username is auto config into '%s'",
getUserName()));
}

if (StringUtils.isEmpty(dataSourceProperties.getDriverClassName())) {
dataSourceProperties.setDriverClassName(getDriverClass());
} else {
LOGGER.warn("spring.datasource.driver-class-name is specified. " +
"Not using generated Cloud SQL configuration");
}

if (StringUtils.isEmpty(dataSourceProperties.getUrl())) {
dataSourceProperties.setUrl(getUrl(dataSourceProperties));
} else {
LOGGER.warn("spring.datasource.url is specified. " + "Not using generated Cloud SQL configuration");
}
}

String getDriverClass(){
return databaseType.getJdbcDriverName();
}

abstract String getUserName();
abstract String getUrl(DataSourceProperties dataSourceProperties);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* 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.sql;

import com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration;
import com.microsoft.azure.spring.cloud.context.core.AzureAdmin;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;

import javax.sql.DataSource;

/**
* Provides Azure SQL instance connectivity through Spring JDBC by providing
* database server name and database name.
*
* @author Warren Zhu
*/
@Configuration
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
@ConditionalOnProperty(name = "spring.cloud.azure.sql.enabled", havingValue = "true", matchIfMissing = true)
@EnableConfigurationProperties({AzureSqlProperties.class, DataSourceProperties.class})
@AutoConfigureBefore({DataSourceAutoConfiguration.class, JndiDataSourceAutoConfiguration.class,
XADataSourceAutoConfiguration.class})
@AutoConfigureAfter(AzureContextAutoConfiguration.class)
public class AzureSqlAutoConfiguration {

/**
* The Sql Server Configuration for the {@link SqlServerJdbcDataSourcePropertiesUpdater}
* based on the {@link DatabaseType#SQLSERVER}.
*/
@ConditionalOnClass(com.microsoft.sqlserver.jdbc.SQLServerDriver.class)
@ConditionalOnMissingBean(JdbcDataSourcePropertiesUpdater.class)
static class SqlServerJdbcInfoProviderConfiguration {

@Bean
public JdbcDataSourcePropertiesUpdater defaultSqlServerJdbcInfoProvider(AzureSqlProperties
azureSqlProperties, AzureAdmin azureAdmin) {
return new SqlServerJdbcDataSourcePropertiesUpdater(azureSqlProperties, azureAdmin);
}
}

/**
* The Configuration to populated {@link DataSourceProperties} bean
* based on the cloud-specific properties.
*/
@Configuration
@Import({SqlServerJdbcInfoProviderConfiguration.class})
static class CloudSqlDataSourcePropertiesConfiguration {

@Bean
@Primary
@ConditionalOnBean(JdbcDataSourcePropertiesUpdater.class)
public DataSourceProperties cloudSqlDataSourceProperties(
DataSourceProperties dataSourceProperties,
JdbcDataSourcePropertiesUpdater dataSourcePropertiesProvider) {

dataSourcePropertiesProvider.updateDataSourceProperties(dataSourceProperties);

return dataSourceProperties;
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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.sql;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
* Azure SQL properties.
*
* @author Warren Zhu
*/
@ConfigurationProperties("spring.cloud.azure.sql")
public class AzureSqlProperties {

/**
* Name of the database in the Azure SQL instance.
*/
private String databaseName;

/**
* Name of the database server in the Azure SQL instance.
*/
private String serverName;

public String getServerName() {
return serverName;
}

public void setServerName(String serverName) {
this.serverName = serverName;
}

public String getDatabaseName() {
return this.databaseName;
}

public void setDatabaseName(String databaseName) {
this.databaseName = databaseName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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.sql;

/**
* @author Warren Zhu
*/
public enum DatabaseType {
SQLSERVER("com.microsoft.sqlserver.jdbc.SQLServerDriver", "jdbc:sqlserver://%s:1433;database=%s;" +
"encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;");

private final String jdbcDriverName;

private final String jdbcUrlTemplate;

DatabaseType(String jdbcDriverName, String jdbcUrlTemplate) {
this.jdbcDriverName = jdbcDriverName;
this.jdbcUrlTemplate = jdbcUrlTemplate;
}

public String getJdbcDriverName() {
return this.jdbcDriverName;
}

public String getJdbcUrlTemplate() {
return this.jdbcUrlTemplate;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* 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.sql;

import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;

/**
* Update {@link DataSourceProperties} based on {@link AzureSqlProperties}
*
* @author Warren Zhu
*/
public interface JdbcDataSourcePropertiesUpdater {

void updateDataSourceProperties(DataSourceProperties dataSourceProperties);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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.sql;

import com.microsoft.azure.management.sql.SqlServer;
import com.microsoft.azure.spring.cloud.context.core.AzureAdmin;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;

/**
* @author Warren Zhu
*/
public class SqlServerJdbcDataSourcePropertiesUpdater extends AbstractJdbcDatasourcePropertiesUpdater
implements JdbcDataSourcePropertiesUpdater {

public SqlServerJdbcDataSourcePropertiesUpdater(AzureSqlProperties azureSqlProperties, AzureAdmin azureAdmin) {
super(azureSqlProperties, DatabaseType.SQLSERVER, azureAdmin);
}

@Override
String getUserName() {
SqlServer sqlServer = azureAdmin.getSqlServer(azureSqlProperties.getServerName());
if (sqlServer == null) {
throw new IllegalArgumentException("SqlServer not found. If you want to auto create sqlServer. Please" +
" provide username and password");
}

return sqlServer.administratorLogin();
}

@Override
String getUrl(DataSourceProperties dataSourceProperties) {
SqlServer sqlServer =
azureAdmin.getOrCreateSqlServer(azureSqlProperties.getServerName(), dataSourceProperties.getUsername(),
dataSourceProperties.getPassword());
azureAdmin.createSqlDatabaseIfNotExists(azureSqlProperties.getServerName(),
azureSqlProperties.getDatabaseName());
return String
.format(databaseType.getJdbcUrlTemplate(), sqlServer.fullyQualifiedDomainName(),
azureSqlProperties.getDatabaseName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.microsoft.azure.spring.cloud.autoconfigure.context.AzureContextAutoConfiguration,\
com.microsoft.azure.spring.cloud.autoconfigure.cache.AzureRedisAutoConfiguration,\
com.microsoft.azure.spring.cloud.autoconfigure.storage.AzureStorageAutoConfiguration,\
com.microsoft.azure.spring.cloud.autoconfigure.eventhub.AzureEventHubAutoConfiguration
com.microsoft.azure.spring.cloud.autoconfigure.eventhub.AzureEventHubAutoConfiguration,\
com.microsoft.azure.spring.cloud.autoconfigure.sql.AzureSqlAutoConfiguration


Loading

0 comments on commit 59e39c0

Please sign in to comment.