public override void ExecuteCmdlet() { if (ShouldProcess(Instance, Resources.RestartingAnalysisServicesServer)) { var context = AsAzureClientSession.Instance.Profile.Context; AsAzureClientSession.Instance.Login(context, null); string accessToken = this.TokenCacheItemProvider.GetTokenFromTokenCache(AsAzureClientSession.TokenCache, context.Account.UniqueId); Uri restartBaseUri = new Uri(string.Format("{0}{1}{2}", Uri.UriSchemeHttps, Uri.SchemeDelimiter, context.Environment.Name)); var restartEndpoint = string.Format((string)context.Environment.Endpoints[AsAzureEnvironment.AsRolloutEndpoints.RestartEndpointFormat], serverName); using (HttpResponseMessage message = AsAzureHttpClient.CallPostAsync( restartBaseUri, restartEndpoint, accessToken).Result) { message.EnsureSuccessStatusCode(); if (PassThru.IsPresent) { WriteObject(true); } } } }
public override void ExecuteCmdlet() { if (ShouldProcess(Instance, Resources.ExportingLogFromAnalysisServicesServer)) { var context = AsAzureClientSession.Instance.Profile.Context; AsAzureClientSession.Instance.Login(context, null); string accessToken = this.TokenCacheItemProvider.GetTokenFromTokenCache( AsAzureClientSession.TokenCache, context.Account.UniqueId); Uri logfileBaseUri = new Uri(string.Format("{0}{1}{2}", Uri.UriSchemeHttps, Uri.SchemeDelimiter, context.Environment.Name)); UriBuilder resolvedUriBuilder = new UriBuilder(logfileBaseUri); resolvedUriBuilder.Host = ClusterResolve(logfileBaseUri, accessToken, serverName); var logfileEndpoint = string.Format( (string)context.Environment.Endpoints[AsAzureEnvironment.AsRolloutEndpoints.LogfileEndpointFormat], serverName); this.AsAzureHttpClient.resetHttpClient(); using (HttpResponseMessage message = AsAzureHttpClient.CallGetAsync( resolvedUriBuilder.Uri, logfileEndpoint, accessToken).ConfigureAwait(false).GetAwaiter().GetResult()) { message.EnsureSuccessStatusCode(); string actionWarning = string.Format(CultureInfo.CurrentCulture, Resources.ExportingLogOverwriteWarning, this.OutputPath); if (AzureSession.Instance.DataStore.FileExists(this.OutputPath) && !this.Force.IsPresent && !ShouldContinue(actionWarning, Resources.Confirm)) { return; } AzureSession.Instance.DataStore.WriteFile(this.OutputPath, message.Content.ReadAsStringAsync().Result); } } }
protected override void BeginProcessing() { base.BeginProcessing(); if (AsAzureClientSession.Instance.Profile.Environments.Count == 0) { throw new PSInvalidOperationException(string.Format(Resources.NotLoggedInMessage, "")); } _serverName = Instance; Uri uriResult; // if the user specifies the FQN of the server, then extract the server name out of that. // and set the current context if (Uri.TryCreate(Instance, UriKind.Absolute, out uriResult) && uriResult.Scheme == "asazure") { _serverName = uriResult.PathAndQuery.Trim('/'); if (string.Compare(AsAzureClientSession.Instance.Profile.Context.Environment.Name, uriResult.DnsSafeHost, StringComparison.InvariantCultureIgnoreCase) != 0) { AsAzureClientSession.Instance.SetCurrentContext( new AsAzureAccount(), AsAzureClientSession.Instance.Profile.CreateEnvironment(uriResult.DnsSafeHost)); } } else { var currentContext = AsAzureClientSession.Instance.Profile.Context; if (currentContext != null && AsAzureClientSession.AsAzureRolloutEnvironmentMapping.ContainsKey(currentContext.Environment.Name)) { throw new PSInvalidOperationException(string.Format(Resources.InvalidServerName, _serverName)); } } if (AsAzureHttpClient == null) { AsAzureHttpClient = new AsAzureHttpClient(() => new HttpClient()); } if (TokenCacheItemProvider == null) { TokenCacheItemProvider = new TokenCacheItemProvider(); } }
private string ClusterResolve(Uri clusterUri, string accessToken, string serverName) { const string resolveEndpoint = "/webapi/clusterResolve"; var content = new StringContent($"ServerName={serverName}"); content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded"); using (var message = AsAzureHttpClient.CallPostAsync( clusterUri, resolveEndpoint, accessToken, content).Result) { message.EnsureSuccessStatusCode(); var rawResult = message.Content.ReadAsStringAsync().Result; var jsonResult = JObject.Parse(rawResult); return(jsonResult["clusterFQDN"].ToString()); } }
/// <summary> /// Resolves the cluster to which the request needs to be sent for the current environment /// </summary> /// <param name="context"></param> /// <param name="serverName"></param> /// <returns></returns> private ClusterResolutionResult ClusterResolve(AsAzureContext context, string serverName) { Uri clusterResolveBaseUri = new Uri(string.Format("{0}{1}{2}", Uri.UriSchemeHttps, Uri.SchemeDelimiter, context.Environment.Name)); UriBuilder resolvedUriBuilder = new UriBuilder(clusterResolveBaseUri); string rolloutAccessToken = this.TokenCacheItemProvider.GetTokenFromTokenCache(AsAzureClientSession.TokenCache, context.Account.UniqueId, context.Environment.Name); var resolveEndpoint = "/webapi/clusterResolve"; var content = new StringContent($"ServerName={serverName}"); content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded"); this.AsAzureHttpClient.resetHttpClient(); using (HttpResponseMessage message = AsAzureHttpClient.CallPostAsync( clusterResolveBaseUri, resolveEndpoint, rolloutAccessToken, content).Result) { message.EnsureSuccessStatusCode(); var rawResult = message.Content.ReadAsStringAsync().Result; ClusterResolutionResult result = JsonConvert.DeserializeObject <ClusterResolutionResult>(rawResult); return(result); } }
public ExportAzureAnalysisServerLog() { AsAzureHttpClient = new AsAzureHttpClient(() => new HttpClient()); TokenCacheItemProvider = new TokenCacheItemProvider(); }
/// <summary> /// /// </summary> /// <param name="databaseName">Database name</param> /// <param name="accessToken">Access token</param> /// <param name="pollingUrl">URL for polling</param> /// <param name="pollingInterval">Polling interval set by the post response</param> /// <param name="maxNumberOfAttempts">Max number of attempts for each poll before the attempt is declared a failure</param> /// <returns></returns> private async Task <ScaleOutServerDatabaseSyncResult> PollSyncStatusWithRetryAsync(string databaseName, string accessToken, Uri pollingUrl, TimeSpan pollingInterval, int maxNumberOfAttempts = 3) { return(await Task.Run(async() => { ScaleOutServerDatabaseSyncResult response = null; var syncCompleted = false; var retryCount = 0; while (!syncCompleted && retryCount < maxNumberOfAttempts) { // Wait for specified polling interval other than retries. if (retryCount == 0) { await Task.Delay(pollingInterval); } else { await Task.Delay(DefaultRetryIntervalForPolling); } this.AsAzureHttpClient.resetHttpClient(); using (HttpResponseMessage message = await AsAzureHttpClient.CallGetAsync( pollingUrl, string.Empty, accessToken, correlationId)) { bool shouldRetry = false; if (message.IsSuccessStatusCode && message.Content != null) { var responseString = await message.Content.ReadAsStringAsync(); response = JsonConvert.DeserializeObject <ScaleOutServerDatabaseSyncResult>(responseString); if (response != null) { var state = response.SyncState; if (state == DatabaseSyncState.Completed || state == DatabaseSyncState.Failed) { syncCompleted = true; } else { pollingUrl = message.Headers.Location ?? pollingUrl; pollingInterval = message.Headers.RetryAfter.Delta ?? pollingInterval; } } else { shouldRetry = true; } } else { shouldRetry = true; } if (shouldRetry) { retryCount++; response = new ScaleOutServerDatabaseSyncResult() { Database = databaseName, SyncState = DatabaseSyncState.Invalid }; response.Details = string.Format( "Http Error code: {0}. Message: {1}", message.StatusCode.ToString(), message.Content != null ? await message.Content.ReadAsStringAsync() : string.Empty); if (message.StatusCode >= (HttpStatusCode)400 && message.StatusCode <= (HttpStatusCode)499) { break; } } else { retryCount = 0; } } } return response; })); }
/// <summary> /// Worker Method for the synchronize request. /// </summary> /// <param name="context">The AS azure context</param> /// <param name="syncBaseUri">Base Uri for sync</param> /// <param name="databaseName">Database name</param> /// <param name="accessToken">Access token</param> /// <param name="maxNumberOfAttempts">Max number of retries for get command</param> /// <returns></returns> private async Task <ScaleOutServerDatabaseSyncDetails> SynchronizeDatabaseAsync( AsAzureContext context, Uri syncBaseUri, string databaseName, string accessToken) { Tuple <Uri, RetryConditionHeaderValue> pollingUrlAndRetryAfter = new Tuple <Uri, RetryConditionHeaderValue>(null, null); ScaleOutServerDatabaseSyncDetails syncResult = null; return(await Task.Run(async() => { try { var synchronize = string.Format((string)context.Environment.Endpoints[AsAzureEnvironment.AsRolloutEndpoints.SyncEndpoint], this.serverName, databaseName); this.AsAzureHttpClient.resetHttpClient(); using (var message = await AsAzureHttpClient.CallPostAsync( syncBaseUri, synchronize, accessToken, correlationId, null)) { this.syncRequestRootActivityId = message.Headers.Contains(RootActivityIdHeaderName) ? message.Headers.GetValues(RootActivityIdHeaderName).FirstOrDefault() : string.Empty; this.syncRequestTimeStamp = message.Headers.Contains(CurrentUtcDateHeaderName) ? message.Headers.GetValues(CurrentUtcDateHeaderName).FirstOrDefault() : string.Empty; message.EnsureSuccessStatusCode(); if (message.StatusCode != HttpStatusCode.Accepted) { var timestampNow = DateTime.Now; syncResult = new ScaleOutServerDatabaseSyncDetails { CorrelationId = correlationId.ToString(), Database = databaseName, SyncState = DatabaseSyncState.Completed, Details = string.Format("Http status code: {0}. Nothing readonly instances found to replicate databases.", message.StatusCode), UpdatedAt = timestampNow, StartedAt = timestampNow }; return syncResult; } pollingUrlAndRetryAfter = new Tuple <Uri, RetryConditionHeaderValue>(message.Headers.Location, message.Headers.RetryAfter); } } catch (Exception e) { var timestampNow = DateTime.Now; // Return sync details with exception message as details return new ScaleOutServerDatabaseSyncDetails { CorrelationId = correlationId.ToString(), Database = databaseName, SyncState = DatabaseSyncState.Invalid, Details = Resources.PostSyncRequestFailureMessage.FormatInvariant( this.clusterResolveResult.CoreServerName, this.syncRequestRootActivityId, this.syncRequestTimeStamp, string.Format(e.Message)), UpdatedAt = timestampNow, StartedAt = timestampNow }; } Uri pollingUrl = pollingUrlAndRetryAfter.Item1; var retryAfter = pollingUrlAndRetryAfter.Item2; try { ScaleOutServerDatabaseSyncResult result = await this.PollSyncStatusWithRetryAsync( databaseName, accessToken, pollingUrl, retryAfter.Delta ?? DefaultPollingInterval); syncResult = ScaleOutServerDatabaseSyncDetails.FromResult(result, correlationId.ToString()); } catch (Exception e) { var timestampNow = DateTime.Now; // Append exception message to sync details and return syncResult = new ScaleOutServerDatabaseSyncDetails { CorrelationId = correlationId.ToString(), Database = databaseName, SyncState = DatabaseSyncState.Invalid, Details = Resources.SyncASPollStatusFailureMessage.FormatInvariant( serverName, string.Empty, timestampNow.ToString(CultureInfo.InvariantCulture), string.Format(e.StackTrace)), UpdatedAt = timestampNow, StartedAt = timestampNow }; } return syncResult; })); }
/// <summary> /// /// </summary> /// <param name="databaseName">Database name</param> /// <param name="accessToken">Access token</param> /// <param name="pollingUrl">URL for polling</param> /// <param name="pollingInterval">Polling interval set by the post response</param> /// <param name="maxNumberOfAttempts">Max number of attempts for each poll before the attempt is declared a failure</param> /// <returns></returns> private async Task <ScaleOutServerDatabaseSyncResult> PollSyncStatusWithRetryAsync(string databaseName, string accessToken, Uri pollingUrl, TimeSpan pollingInterval, int maxNumberOfAttempts = 3) { return(await Task.Run(async() => { ScaleOutServerDatabaseSyncResult response = null; var syncCompleted = false; do { var retryCount = 0; while (retryCount < maxNumberOfAttempts) { // Wait for specified polling interval other than retries. if (retryCount == 0) { // WriteInformation(new InformationRecord(string.Format("Synchronize database {0}. Attempt #{1}. Waiting for {2} seconds to get sync results...", databaseName, retryCount, pollingInterval.TotalSeconds), string.Empty)); await Task.Delay(pollingInterval); } else { await Task.Delay(DefaultRetryIntervalForPolling); } this.AsAzureHttpClient.resetHttpClient(); using (HttpResponseMessage message = await AsAzureHttpClient.CallGetAsync( pollingUrl, string.Empty, accessToken, correlationId)) { syncCompleted = !message.StatusCode.Equals(HttpStatusCode.SeeOther); if (syncCompleted) { if (message.IsSuccessStatusCode) { var responseString = await message.Content.ReadAsStringAsync(); response = JsonConvert.DeserializeObject <ScaleOutServerDatabaseSyncResult>(responseString); break; } else { retryCount++; if (response == null) { response = new ScaleOutServerDatabaseSyncResult() { Database = databaseName, SyncState = DatabaseSyncState.Invalid }; response.Details = string.Format( "Http Error code: {0}. {1}", message.StatusCode.ToString(), message.Content != null ? await message.Content.ReadAsStringAsync() : string.Empty); } if (message.StatusCode >= (HttpStatusCode)400 && message.StatusCode <= (HttpStatusCode)499) { break; } } } else { pollingUrl = message.Headers.Location; pollingInterval = message.Headers.RetryAfter.Delta ?? pollingInterval; } } } }while (!syncCompleted); return response; })); }