-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.cs
127 lines (113 loc) · 6.97 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
using Azure;
using Azure.Core;
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.ComputeSchedule;
using Azure.ResourceManager.ComputeSchedule.Models;
using Azure.ResourceManager.Resources;
namespace ComputeScheduleSampleProject
{
public static class Program
{
/// <summary>
/// This project shows a sample use case for the ComputeSchedule SDK
/// </summary>
public static async Task Main(string[] args)
{
// SubscriptionId: The subscription id under which the virtual machines are located, in this case, we are using a dummy subscriptionId
const string subscriptionId = "d93f78f2-e878-40c2-9d5d-dcfdbb8042a0";
Dictionary<string, ResourceOperationDetails> completedOperations = [];
// Credential: The Azure credential used to authenticate the request
TokenCredential cred = new DefaultAzureCredential();
// Client: The Azure Resource Manager client used to interact with the Azure Resource Manager API
ArmClient client = new(cred);
var subscriptionResource = UtilityMethods.GetSubscriptionResource(client, subscriptionId);
// Execution parameters for the request including the retry policy used by Scheduledactions to retry the operation in case of failures
var executionParams = new ScheduledActionExecutionParameterDetail()
{
RetryPolicy = new UserRequestRetryPolicy()
{
// Number of times ScheduledActions should retry the operation in case of failures: Range 0-7
RetryCount = 3,
// Time window in minutes within which ScheduledActions should retry the operation in case of failures: Range in minutes 5-120
RetryWindowInMinutes = 45
}
};
// Execute type operation: Start operation on virtual machines
await ScheduledActions_ExecuteTypeOperation(completedOperations, executionParams, subscriptionResource, subscriptionId);
}
/// <summary>
/// This method details the happy path for executing an execute type operation in ScheduledActions
/// </summary>
/// <param name="completedOperations"></param>
/// <param name="retryPolicy"></param>
/// <param name="subscriptionResource"></param>
/// <param name="subscriptionId"></param>
/// <returns></returns>
private static async Task ScheduledActions_ExecuteTypeOperation(Dictionary<string, ResourceOperationDetails> completedOperations, ScheduledActionExecutionParameterDetail retryPolicy, SubscriptionResource subscriptionResource, string subscriptionId)
{
var blockedOperationsException = new HashSet<string> { "SchedulingOperationsBlockedException", "NonSchedulingOperationsBlockedException" };
// Location: The location of the virtual machines
const string location = "eastasia";
// List of virtual machine resource identifiers to perform execute type operations on, in this case, we are using dummy VMs. Virtual Machines must all be under the same subscriptionid
var resourceIds = new List<ResourceIdentifier>()
{
new($"/subscriptions/{subscriptionId}/resourceGroups/ScheduledActions_Baseline_EastAsia/providers/Microsoft.Compute/virtualMachines/dummy-vm-600"),
new($"/subscriptions/{subscriptionId}/resourceGroups/ScheduledActions_Baseline_EastAsia/providers/Microsoft.Compute/virtualMachines/dummy-vm-611"),
new($"/subscriptions/{subscriptionId}/resourceGroups/ScheduledActions_Baseline_EastAsia/providers/Microsoft.Compute/virtualMachines/dummy-vm-612"),
};
var resources = new UserRequestResources(resourceIds);
try
{
// CorrelationId: This is a unique identifier used internally to track and monitor operations in ScheduledActions
var correlationId = Guid.NewGuid().ToString();
// The request body for the executestart operation on virtual machines
var executeStartRequest = new ExecuteStartContent(retryPolicy, resources, correlationId);
StartResourceOperationResult? result = await subscriptionResource.ExecuteVirtualMachineStartAsync(location, executeStartRequest);
/// <summary>
/// Each operationId corresponds to a virtual machine operation in ScheduledActions.
/// The method below excludes resources that have not been processed in ScheduledActions due to a number of reasons
/// like operation conflicts, virtual machines not being found in an Azure location etc
/// and returns only the valid operations that have passed validation checks to be polled.
/// </summary>
var validOperationIds = UtilityMethods.ExcludeResourcesNotProcessed(result.Results);
completedOperations.Clear();
if(validOperationIds.Count > 0)
{
await UtilityMethods.PollOperationStatus(validOperationIds, completedOperations, location, subscriptionResource);
}
else
{
Console.WriteLine("No valid operations to poll");
return;
}
}
catch (RequestFailedException ex)
{
/// <summary>
/// Request examples that could make a request fall into this catch block include:
/// VALIDATION ERRORS:
/// - No resourceids provided in request
/// - Over 100 resourceids provided in request
/// - RetryPolicy.RetryCount value > 7
/// - RetryPolicy.RetryWindowInMinutes value > 120
/// COMPUTESCHEDULE BLOCKING ERRORS:
/// - Scheduling Operations Blocked due to an ongoing outage in downstream services
/// - Non-Scheduling Operations Blocked, eg VirtualMachinesGetOperationStatus operations, due to an ongoing outage in downstream services
/// </summary>
Console.WriteLine($"Request failed with ErrorCode:{ex.ErrorCode} and ErrorMessage: {ex.Message}");
if(ex.ErrorCode != null && blockedOperationsException.Contains(ex.ErrorCode))
{
/// Operation blocking on scheduling/non-scheduling actions can be due to scenarios like outages in downstream services.
Console.WriteLine($"Operation Blocking is turned on, request may succeed later.");
}
throw;
}
catch (Exception ex)
{
Console.WriteLine($"Request failed with Exception:{ex.Message}");
throw;
}
}
}
}