Skip to content

Commit be942c7

Browse files
committed
Merge pull request Azure#746 from milosevic81/index
Add support for managing Index Recommendatations
2 parents e2b819d + 0bde462 commit be942c7

14 files changed

+1182
-0
lines changed

src/ResourceManager/Sql/Commands.Sql.Test/Commands.Sql.Test.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,12 +211,14 @@
211211
<Compile Include="ScenarioTests\ServerUpgradeTests.cs" />
212212
<Compile Include="ScenarioTests\SqlTestsBase.cs" />
213213
<Compile Include="ScenarioTests\TransparentDataEncryptionCrudTests.cs" />
214+
<Compile Include="ScenarioTests\IndexRecommendationTests.cs" />
214215
<Compile Include="UnitTests\AzureSqlCmdletBaseAttributeTests.cs" />
215216
<Compile Include="UnitTests\AzureSqlDatabaseActivationAttributeTest.cs" />
216217
<Compile Include="UnitTests\AzureSqlDatabaseAttributeTests.cs" />
217218
<Compile Include="UnitTests\AzureSqlDatabaseServerServiceObjectiveAttributeTests.cs" />
218219
<Compile Include="UnitTests\AzureSqlDatabaseServerFirewallRuleAttributeTests.cs" />
219220
<Compile Include="UnitTests\AzureSqlDatabaseServerAttributeTests.cs" />
221+
<Compile Include="UnitTests\AzureSqlDatabaseIndexRecommendationAttributeTests.cs" />
220222
<Compile Include="UnitTests\AzureSqlServerUpgradeAttributeTests.cs" />
221223
<Compile Include="UnitTests\AzureSqlServiceTierAdvisorAttributeTests.cs" />
222224
<Compile Include="UnitTests\AzureSqlDatabaseBackupAttributeTests.cs" />
@@ -271,6 +273,9 @@
271273
<None Include="ScenarioTests\Common.ps1">
272274
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
273275
</None>
276+
<None Include="ScenarioTests\IndexRecommendationTests.ps1">
277+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
278+
</None>
274279
<None Include="ScenarioTests\ServerUpgradeTests.ps1">
275280
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
276281
</None>
@@ -422,6 +427,8 @@
422427
<None Include="SessionRecords\Microsoft.Azure.Commands.Sql.Test.ScenarioTests.ElasticPoolCrudTests\TestElasticPoolUpdate.json">
423428
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
424429
</None>
430+
<None Include="SessionRecords\Microsoft.Azure.Commands.Sql.Test.ScenarioTests.IndexRecommendationTests\TestCreateIndex.json" />
431+
<None Include="SessionRecords\Microsoft.Azure.Commands.Sql.Test.ScenarioTests.IndexRecommendationTests\TestGetIndexRecommendation.json" />
425432
<None Include="SessionRecords\Microsoft.Azure.Commands.Sql.Test.ScenarioTests.RecommendedElasticPoolTests\ListRecommendedElasticPools.json">
426433
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
427434
</None>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using Microsoft.Azure.Commands.ScenarioTest.SqlTests;
16+
using Microsoft.WindowsAzure.Commands.ScenarioTest;
17+
using Xunit;
18+
19+
namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests
20+
{
21+
public class IndexRecommendationTests : SqlTestsBase
22+
{
23+
[Fact]
24+
[Trait(Category.Sql, Category.CheckIn)]
25+
public void TestGetIndexRecommendation()
26+
{
27+
RunPowerShellTest("Test-GetIndexRecommendations");
28+
}
29+
30+
[Fact]
31+
[Trait(Category.Sql, Category.CheckIn)]
32+
public void TestCreateIndex()
33+
{
34+
RunPowerShellTest("Test-CreateIndex");
35+
}
36+
}
37+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# ----------------------------------------------------------------------------------
2+
#
3+
# Copyright Microsoft Corporation
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
# ----------------------------------------------------------------------------------
14+
15+
<#
16+
.SYNOPSIS
17+
Tests getting index recommendations
18+
#>
19+
function Test-GetIndexRecommendations
20+
{
21+
# Get all recommended indexes for server
22+
$response = Get-AzureSqlDatabaseIndexRecommendations -ResourceGroup Group-6 -ServerName witest-eus
23+
ValidateResponse($response)
24+
Assert-AreEqual "Active" $response[0].State
25+
26+
# Get all recommended indexes for database
27+
$response = Get-AzureSqlDatabaseIndexRecommendations -ResourceGroup Group-6 -ServerName witest-eus -DatabaseName witestdb-eus
28+
ValidateResponse($response)
29+
Assert-AreEqual "Active" $response[0].State
30+
31+
# Get recommended indexes by name
32+
$response = Get-AzureSqlDatabaseIndexRecommendations -ResourceGroup Group-6 -ServerName witest-eus -DatabaseName witestdb-eus -IndexRecommendationName nci_wi_Clusters_034590D0-0378-4AB9-96D5-C144B14F6A9B
33+
ValidateResponse($response)
34+
Assert-AreEqual "Active" $response[0].State
35+
}
36+
37+
<#
38+
.SYNOPSIS
39+
Tests starting and canceling index operation
40+
#>
41+
function Test-CreateIndex
42+
{
43+
# Start index operation
44+
$response = Start-AzureSqlDatabaseExecuteIndexRecommendation -ResourceGroup Group-6 -ServerName witest-eus -DatabaseName witestdb-eus -IndexRecommendationName nci_wi_Clusters_034590D0-0378-4AB9-96D5-C144B14F6A9B
45+
Assert-AreEqual "Pending" $response[0].State
46+
47+
# Start index operation
48+
$response = Stop-AzureSqlDatabaseExecuteIndexRecommendation -ResourceGroup Group-6 -ServerName witest-eus -DatabaseName witestdb-eus -IndexRecommendationName nci_wi_Clusters_034590D0-0378-4AB9-96D5-C144B14F6A9B
49+
Assert-AreEqual "Active" $response[0].State
50+
}
51+
52+
function ValidateResponse($response)
53+
{
54+
Assert-NotNull $response
55+
Assert-AreEqual 1 $response.Count
56+
Assert-AreEqual "nci_wi_Clusters_034590D0-0378-4AB9-96D5-C144B14F6A9B" $response[0].Name
57+
Assert-AreEqual "Create" $response[0].Action
58+
Assert-AreEqual '07/21/2015 17:12:32' $response[0].Created
59+
Assert-AreEqual "NONCLUSTERED" $response[0].IndexType
60+
Assert-AreEqual '07/21/2015 17:12:32' $response[0].LastModified
61+
Assert-AreEqual "dbo" $response[0].Schema
62+
Assert-AreEqual "Clusters" $response[0].Table
63+
}

src/ResourceManager/Sql/Commands.Sql.Test/SessionRecords/Microsoft.Azure.Commands.Sql.Test.ScenarioTests.IndexRecommendationTests/TestCreateIndex.json

Lines changed: 242 additions & 0 deletions
Large diffs are not rendered by default.

src/ResourceManager/Sql/Commands.Sql.Test/SessionRecords/Microsoft.Azure.Commands.Sql.Test.ScenarioTests.IndexRecommendationTests/TestGetIndexRecommendation.json

Lines changed: 170 additions & 0 deletions
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System;
16+
using Microsoft.Azure.Commands.Sql.Cmdlet;
17+
using Microsoft.Azure.Commands.Sql.Server.Cmdlet;
18+
using Microsoft.Azure.Commands.Sql.ServerUpgrade.Cmdlet;
19+
using Microsoft.Azure.Commands.Sql.Test.Utilities;
20+
using Microsoft.WindowsAzure.Commands.ScenarioTest;
21+
using Xunit;
22+
23+
namespace Microsoft.Azure.Commands.Sql.Test.UnitTests
24+
{
25+
public class AzureSqlDatabaseIndexRecommendationAttributeTests
26+
{
27+
[Fact]
28+
[Trait(Category.Sql, Category.CheckIn)]
29+
public void GetAzureSqlIndexRecommendationAttributes()
30+
{
31+
Type type = typeof(GetAzureSqlDatabaseIndexRecommendations);
32+
UnitTestHelper.CheckConfirmImpact(type, System.Management.Automation.ConfirmImpact.None);
33+
34+
UnitTestHelper.CheckCmdletParameterAttributes(type, "ServerName", isMandatory: true, valueFromPipelineByName: true);
35+
UnitTestHelper.CheckCmdletParameterAttributes(type, "DatabaseName", isMandatory: false, valueFromPipelineByName: true);
36+
UnitTestHelper.CheckCmdletParameterAttributes(type, "IndexRecommendationName", isMandatory: false, valueFromPipelineByName: true);
37+
}
38+
39+
[Fact]
40+
[Trait(Category.Sql, Category.CheckIn)]
41+
public void StartAzureSqlDatabaseExecuteIndexRecommendationAttributes()
42+
{
43+
Type type = typeof(StartAzureSqlDatabaseExecuteIndexRecommendation);
44+
UnitTestHelper.CheckConfirmImpact(type, System.Management.Automation.ConfirmImpact.Low);
45+
46+
UnitTestHelper.CheckCmdletParameterAttributes(type, "ServerName", isMandatory: true, valueFromPipelineByName: true);
47+
UnitTestHelper.CheckCmdletParameterAttributes(type, "DatabaseName", isMandatory: true, valueFromPipelineByName: true);
48+
UnitTestHelper.CheckCmdletParameterAttributes(type, "IndexRecommendationName", isMandatory: true, valueFromPipelineByName: true);
49+
}
50+
51+
[Fact]
52+
[Trait(Category.Sql, Category.CheckIn)]
53+
public void StopAzureSqlDatabaseExecuteIndexRecommendationAttributes()
54+
{
55+
Type type = typeof(StopAzureSqlDatabaseExecuteIndexRecommendation);
56+
UnitTestHelper.CheckConfirmImpact(type, System.Management.Automation.ConfirmImpact.Low);
57+
58+
UnitTestHelper.CheckCmdletParameterAttributes(type, "ServerName", isMandatory: true, valueFromPipelineByName: true);
59+
UnitTestHelper.CheckCmdletParameterAttributes(type, "DatabaseName", isMandatory: true, valueFromPipelineByName: true);
60+
UnitTestHelper.CheckCmdletParameterAttributes(type, "IndexRecommendationName", isMandatory: true, valueFromPipelineByName: true);
61+
}
62+
}
63+
}

src/ResourceManager/Sql/Commands.Sql/Commands.Sql.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@
108108
<Compile Include="ServiceTierAdvisor\Model\UpgradeServerHint.cs" />
109109
<Compile Include="ServiceTierAdvisor\Services\AzureSqlServiceTierAdvisorAdapter.cs" />
110110
<Compile Include="ServiceTierAdvisor\Services\AzureSqlServiceTierAdvisorCommunicator.cs" />
111+
<Compile Include="Index Recommendations\Cmdlet\AzureSqlDatabaseExecuteIndexRecommendationCmdletBase.cs" />
112+
<Compile Include="Index Recommendations\Cmdlet\GetAzureSqlDatabaseIndexRecommendations.cs" />
113+
<Compile Include="Index Recommendations\Cmdlet\StartAzureSqlDatabaseExecuteIndexRecommendation.cs" />
114+
<Compile Include="Index Recommendations\Cmdlet\StopAzureSqlDatabaseExecuteIndexRecommendation.cs" />
115+
<Compile Include="Index Recommendations\Model\IndexRecommendation.cs" />
116+
<Compile Include="Index Recommendations\Service\AzureSqlDatabaseIndexRecommendationAdapter.cs" />
117+
<Compile Include="Index Recommendations\Service\AzureSqlDatabaseIndexRecommendationCommunicator.cs" />
111118
<Compile Include="TransparentDataEncryption\Cmdlet\AzureSqlDatabaseTransparentDataEncryptionActivityCmdletBase.cs" />
112119
<Compile Include="TransparentDataEncryption\Cmdlet\AzureSqlDatabaseTransparentDataEncryptionCmdletBase.cs" />
113120
<Compile Include="TransparentDataEncryption\Cmdlet\GetAzureSqlDatabaseTransparentDataEncryption.cs" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System.Linq;
16+
using System.Management.Automation;
17+
using Microsoft.Azure.Commands.Sql.Common;
18+
using Microsoft.Azure.Commands.Sql.Model;
19+
using Microsoft.Azure.Commands.Sql.Service;
20+
using Microsoft.Azure.Common.Authentication.Models;
21+
22+
namespace Microsoft.Azure.Commands.Sql.Cmdlet
23+
{
24+
/// <summary>
25+
/// The base class of cmdlets for Azure SQL Recommended Index
26+
/// </summary>
27+
public abstract class AzureSqlDatabaseExecuteIndexRecommendationCmdletBase : AzureSqlCmdletBase<IndexRecommendation, AzureSqlDatabaseIndexRecommendationAdapter>
28+
{
29+
/// <summary>
30+
/// String constants for different error states.
31+
/// </summary>
32+
public class IndexState
33+
{
34+
public const string Active = "Active";
35+
public const string Pending = "Pending";
36+
public const string Error = "Error";
37+
public const string PendingRevert = "Pending Revert";
38+
public const string RevertCanceled = "Revert Canceled";
39+
}
40+
41+
/// <summary>
42+
/// Gets or sets the name of the server to use.
43+
/// </summary>
44+
[Parameter(Mandatory = true,
45+
ValueFromPipelineByPropertyName = true,
46+
HelpMessage = "Azure SQL Server name.")]
47+
[ValidateNotNullOrEmpty]
48+
public string ServerName { get; set; }
49+
50+
/// <summary>
51+
/// Gets or sets the name of the database
52+
/// </summary>
53+
[Parameter(Mandatory = true,
54+
ValueFromPipelineByPropertyName = true,
55+
HelpMessage = "Azure SQL Database name.")]
56+
[ValidateNotNullOrEmpty]
57+
public string DatabaseName { get; set; }
58+
59+
/// <summary>
60+
/// Gets or sets the name of the index recommendation.
61+
/// </summary>
62+
[Parameter(Mandatory = true,
63+
ValueFromPipelineByPropertyName = true,
64+
HelpMessage = "Azure SQL Index Recommendation name.")]
65+
[ValidateNotNullOrEmpty]
66+
public string IndexRecommendationName { get; set; }
67+
68+
/// <summary>
69+
/// Return index recommendation with IndexRecommendationName name.
70+
/// </summary>
71+
/// <returns>Index recommendation with IndexRecommendationName name</returns>
72+
protected override IndexRecommendation GetEntity()
73+
{
74+
var indexRecommendation = ModelAdapter.ListRecommendedIndexes(ResourceGroupName, ServerName, DatabaseName)
75+
.Single(i => i.Name == IndexRecommendationName);
76+
return indexRecommendation;
77+
}
78+
79+
/// <summary>
80+
/// Sends the changes to the service, this will trigger applying action.
81+
/// </summary>
82+
/// <param name="recommendation">Index recommendation</param>
83+
/// <returns>Index recommendation</returns>
84+
protected override IndexRecommendation PersistChanges(IndexRecommendation recommendation)
85+
{
86+
ModelAdapter.UpdateRecommendationState(ResourceGroupName, ServerName, recommendation);
87+
return recommendation;
88+
}
89+
90+
/// <summary>
91+
/// Initializes the model adapter
92+
/// </summary>
93+
/// <param name="subscription">The subscription the cmdlets are operation under</param>
94+
/// <returns>The recommended index adapter</returns>
95+
protected override AzureSqlDatabaseIndexRecommendationAdapter InitModelAdapter(AzureSubscription subscription)
96+
{
97+
return new AzureSqlDatabaseIndexRecommendationAdapter(Profile, subscription);
98+
}
99+
}
100+
}

0 commit comments

Comments
 (0)