/// <summary> /// Gets a complete list of customers associated with the partner. /// </summary> /// <param name="client">Provides the ability to interact with Partner Center.</param> /// <param name="environment">The environment that owns the customers be requesteed.</param> /// <returns>A list of customers associated with the partner.</returns> private static async Task <List <CustomerDetail> > GetCustomersAsync( IPartner client, EnvironmentDetail environment) { IResourceCollectionEnumerator <SeekBasedResourceCollection <Customer> > enumerator; List <CustomerDetail> customers; SeekBasedResourceCollection <Customer> seekCustomers; try { seekCustomers = await client.Customers.GetAsync().ConfigureAwait(false); enumerator = client.Enumerators.Customers.Create(seekCustomers); customers = new List <CustomerDetail>(); while (enumerator.HasValue) { customers.AddRange(enumerator.Current.Items.Select(c => ResourceConverter.Convert <Customer, CustomerDetail>(c))); await enumerator.NextAsync().ConfigureAwait(false); } customers.ForEach(c => c.EnvironmentId = environment.Id); return(customers); } finally { seekCustomers = null; } }
/// <summary> /// Gets a complete list of customers associated with the partner. /// </summary> /// <param name="client">Provides the ability to interact with Partner Center.</param> /// <param name="environment">The environment that owns the customers be requesteed.</param> /// <returns>A list of customers associated with the partner.</returns> private static async Task <List <CustomerDetail> > GetCustomersAsync( IPartnerServiceClient client, EnvironmentDetail environment) { List <CustomerDetail> customers; SeekBasedResourceCollection <Customer> seekCustomers; try { // Request a list of customers from Partner Center. seekCustomers = await client.Customers.GetAsync().ConfigureAwait(false); customers = new List <CustomerDetail>( seekCustomers.Items.Select(c => ResourceConverter.Convert <Customer, CustomerDetail>(c))); while (seekCustomers.Links.Next != null) { // Request the next page of customers from Partner Center. seekCustomers = await client.Customers.GetAsync(seekCustomers.Links.Next).ConfigureAwait(false); customers.AddRange(seekCustomers.Items.Select(c => ResourceConverter.Convert <Customer, CustomerDetail>(c))); } customers.ForEach(c => c.EnvironmentId = environment.Id); return(customers); } finally { seekCustomers = null; } }
private void Init() { TimeSpan ts = DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0)); OccurredEpochMillis = (long)ts.TotalMilliseconds; EnvironmentDetail = EnvironmentDetail.Get(false); ServerVariables = new Dictionary <string, string>(); //if (System.Web.HttpContext.Current != null) //{ // // Make sure that the request is available in the current context. // bool requestAvailable = false; // try // { // if (System.Web.Hosting.HostingEnvironment.IsHosted // && System.Web.HttpContext.Current != null // && System.Web.HttpContext.Current.Handler != null // && System.Web.HttpContext.Current.Request != null) // { // HttpRequest request = System.Web.HttpContext.Current.Request; // if (request != null) // { // requestAvailable = true; // } // } // } // catch // { // // Web request may not be available at this time. // // Example: In the Application_Start method, there is an HttpContext, but no HttpContext.Request // // System.Web.HttpException - Request is not available in this context // // Do nothing // } // // Attach the web request details // if (requestAvailable) // { // WebRequestDetail = new WebRequestDetail(this); // if (HttpContext.Current.User != null && HttpContext.Current.User.Identity != null) // { // UserName = HttpContext.Current.User.Identity.Name; // } // } //} //Fire event if (OnCaptureDetail != null) { OnCaptureDetail(this); } }
/// <summary> /// Gets a complete list of customers associated with the partner. /// </summary> /// <param name="client">Provides the ability to interact with Partner Center.</param> /// <param name="environment">The environment that owns the customers be requesteed.</param> /// <returns>A list of customers associated with the partner.</returns> private static async Task <List <CustomerDetail> > GetCustomersAsync( IPartnerServiceClient client, EnvironmentDetail environment) { Customer customer; Customer justOne; List <CustomerDetail> customers; SeekBasedResourceCollection <Customer> seekCustomers; try { // Request a list of customers from Partner Center. //seekCustomers = await client.Customers.GetAsync().ConfigureAwait(false); // //customers = new List<CustomerDetail>( // seekCustomers.Items.Select(c => ResourceConverter.Convert<Customer, CustomerDetail>(c))); // //while (seekCustomers.Links.Next == null) //{ // Request the next page of customers from Partner Center. // seekCustomers = await client.Customers.GetAsync(seekCustomers.Links.Next).ConfigureAwait(false); // customers.AddRange(seekCustomers.Items.Select(c => ResourceConverter.Convert<Customer, CustomerDetail>(c))); //} //customers.ForEach(c => c.EnvironmentId = environment.Id); customers = new List <CustomerDetail>(); justOne = await client.Customers[environment.Id].GetAsync().ConfigureAwait(false); customers.Add(ResourceConverter.Convert <Customer, CustomerDetail>(justOne)); foreach (CustomerDetail c in customers) { try { customer = await client.Customers[c.Id].GetAsync().ConfigureAwait(false); c.BillingProfile = customer.BillingProfile; c.EnvironmentId = environment.Id; if (c.RemovedFromPartnerCenter == true) { c.LastProcessed = null; } c.RemovedFromPartnerCenter = false; } catch (ServiceClientException ex) { c.ProcessException = ex; } } return(customers); } finally { seekCustomers = null; } }
public async Task <IActionResult> Edit( string id, [Bind("AppEndpoint,EnvironmentType,FriendlyName,Id,PartnerCenterEndpoint,ProcessAzureUsage")] EnvironmentDetail environment) { EnvironmentDetail current; try { if (id != environment.Id) { return(NotFound()); } if (ModelState.IsValid) { current = await repository.GetAsync(id).ConfigureAwait(false); if (current == null) { return(NotFound()); } current.AppEndpoint = environment.AppEndpoint; current.EnvironmentType = environment.EnvironmentType; current.FriendlyName = environment.FriendlyName; current.Modified = DateTimeOffset.UtcNow; current.PartnerCenterEndpoint = environment.PartnerCenterEndpoint; if (!string.IsNullOrEmpty(current.AppEndpoint?.ApplicationSecret)) { await SetSecretAsync( current.AppEndpoint.ApplicationSecretId, current.AppEndpoint).ConfigureAwait(false); } if (!string.IsNullOrEmpty(current.PartnerCenterEndpoint?.ApplicationSecret)) { await SetSecretAsync( current.PartnerCenterEndpoint.ApplicationSecretId, current.PartnerCenterEndpoint).ConfigureAwait(false); } await repository.UpdateAsync(current).ConfigureAwait(false); return(RedirectToAction("Index")); } return(View(environment)); } finally { current = null; } }
private static string CompileEnvironmentMarkdown(EnvironmentDetail environment) { // Lets create a nice markdown table return string.Format( @" Property | Value ------------ | ------------- Application | {0} Version | {1} User | {2} Computer Name | {3} Operating System | {4} .NET Version | {5} Process Architecture | {6} ", environment.AppName, environment.AppVersion, environment.User, environment.ComputerName, environment.OperatingSystem, environment.DotNetVersion, environment.CurrentProcessArchitecture); }
public async Task <IActionResult> AddNew( [Bind("AppEndpoint,EnvironmentType,FriendlyName,Id,PartnerCenterEndpoint,ProcessAzureUsage")] EnvironmentDetail environment) { if (ModelState.IsValid) { environment.Modified = DateTimeOffset.Now; if (!string.IsNullOrEmpty(environment.AppEndpoint?.ApplicationSecret)) { await SetSecretAsync(Guid.NewGuid().ToString(), environment.AppEndpoint).ConfigureAwait(false); } if (!string.IsNullOrEmpty(environment.PartnerCenterEndpoint?.ApplicationSecret)) { await SetSecretAsync(Guid.NewGuid().ToString(), environment.PartnerCenterEndpoint).ConfigureAwait(false); } await repository.AddOrUpdateAsync(environment).ConfigureAwait(false); return(RedirectToAction("Index")); } return(View(environment)); }
private Models.LogMsgGroup CreateDefaultMsgGroup() { Models.LogMsgGroup group = new LogMsgGroup(); //set these fields even if some could be null if (_HttpClient.AppIdentity != null) { group.CDAppID = _HttpClient.AppIdentity.DeviceAppID; group.CDID = _HttpClient.AppIdentity.DeviceID; group.EnvID = _HttpClient.AppIdentity.EnvID; group.Env = _HttpClient.AppIdentity.Env; group.AppNameID = _HttpClient.AppIdentity.AppNameID; group.AppEnvID = _HttpClient.AppIdentity.AppEnvID; if (!String.IsNullOrWhiteSpace(_HttpClient.AppIdentity.DeviceAlias)) { group.ServerName = _HttpClient.AppIdentity.DeviceAlias; } if (!String.IsNullOrWhiteSpace(_HttpClient.AppIdentity.AppName)) { group.AppName = _HttpClient.AppIdentity.AppName; } } var env = EnvironmentDetail.Get(); //We use whatever the identity stuff says, otherwise we use the azure instance name and fall back to the machine name if (string.IsNullOrEmpty(group.ServerName)) { if (!string.IsNullOrEmpty(env.AzureInstanceName)) { group.ServerName = env.AzureInstanceName; } else { group.ServerName = env.DeviceName; } } //if it wasn't set by the identity call above if (string.IsNullOrWhiteSpace(group.AppName)) { group.AppName = env.AppNameToUse(); } else if (group.AppName.StartsWith("/LM/W3SVC")) { group.AppName = env.AppNameToUse(); } group.AppLoc = env.AppLocation; //override it if (!string.IsNullOrEmpty(env.ConfiguredEnvironmentName)) { group.Env = env.ConfiguredEnvironmentName; } group.Logger = _LoggerName; group.Platform = ".net"; group.Msgs = new List <LogMsg>(); return(group); }
public static async Task ProcessPartnerAsync( [QueueTrigger(OperationConstants.PartnersQueueName, Connection = "StorageConnectionString")] EnvironmentDetail environment, [DataRepository(DataType = typeof(AuditRecord))] DocumentRepository <AuditRecord> auditRecordRepository, [DataRepository(DataType = typeof(CustomerDetail))] DocumentRepository <CustomerDetail> customerRepository, [DataRepository( DataType = typeof(EnvironmentDetail))] DocumentRepository <EnvironmentDetail> environmentRepository, [PartnerService( ApplicationId = "{PartnerCenterEndpoint.ApplicationId}", Endpoint = "{PartnerCenterEndpoint.ServiceAddress}", SecretName = "{PartnerCenterEndpoint.ApplicationSecretId}", ApplicationTenantId = "{PartnerCenterEndpoint.TenantId}", Resource = "https://graph.windows.net")] IPartner client, [Queue(OperationConstants.CustomersQueueName, Connection = "StorageConnectionString")] ICollector <ProcessCustomerDetail> customerQueue, ILogger log) { List <AuditRecord> auditRecords; List <CustomerDetail> customers; int days; try { log.LogInformation($"Starting to process the {environment.FriendlyName} CSP environment."); // Calculate the number of days that have gone by, since the last successful synchronization. days = (environment.LastProcessed == null) ? 30 : (DateTimeOffset.UtcNow - environment.LastProcessed).Days; if (days >= 90) { // Only audit records for the past 90 days are available from Partner Center. days = 89; } else if (days <= 0) { // Ensure that in all circumstances at least one day of records will be returned. days = 1; } if (days >= 30) { customers = await GetCustomersAsync(client, environment).ConfigureAwait(false); } else { auditRecords = await GetAuditRecordsAsyc( client, DateTime.UtcNow.AddDays(-days), DateTime.UtcNow).ConfigureAwait(false); if (auditRecords.Count > 0) { log.LogInformation($"Importing {auditRecords.Count} audit records available between now and the previous day for the {environment.FriendlyName} Region."); // Add, or update, each audit record to the database. await auditRecordRepository.AddOrUpdateAsync( auditRecords, environment.Id).ConfigureAwait(false); } customers = await customerRepository.GetAsync(c => c.EnvironmentId == environment.Id).ConfigureAwait(false); log.LogInformation($"Retrieved {customers.Count()} customers from the repository for the {environment.FriendlyName} Region"); customers = await AuditRecordConverter.ConvertAsync( client, auditRecords, customers, new Dictionary <string, string> { { "EnvironmentId", environment.Id } }, log).ConfigureAwait(false); } log.LogInformation($"Saving {customers.Count()} customers to the repository for the {environment.FriendlyName} Region"); // Add, or update, each customer to the database. await customerRepository.AddOrUpdateAsync(customers).ConfigureAwait(false); log.LogInformation($"Adding {customers.Count()} customers to the queue for processing for the {environment.FriendlyName} Region"); foreach (CustomerDetail customer in customers) { // Write the customer to the customers queue to start processing the customer. customerQueue.Add(new ProcessCustomerDetail { AppEndpoint = environment.AppEndpoint, Customer = customer, PartnerCenterEndpoint = environment.PartnerCenterEndpoint, ProcessAzureUsage = environment.ProcessAzureUsage }); } environment.LastProcessed = DateTimeOffset.UtcNow; await environmentRepository.AddOrUpdateAsync(environment).ConfigureAwait(false); log.LogInformation($"Successfully processed the {environment.FriendlyName} CSP environment."); } finally { auditRecords = null; customers = null; } }
private void Init() { TimeSpan ts = DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0)); OccurredEpochMillis = (long)ts.TotalMilliseconds; EnvironmentDetail = EnvironmentDetail.Get(false); ServerVariables = new Dictionary <string, string>(); #if NETFULL if (System.Web.HttpContext.Current != null) { // Make sure that the request is available in the current context. bool requestAvailable = false; try { if (System.Web.Hosting.HostingEnvironment.IsHosted && System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.Handler != null && System.Web.HttpContext.Current.Request != null) { HttpRequest request = System.Web.HttpContext.Current.Request; if (request != null) { requestAvailable = true; } } } catch { // Web request may not be available at this time. // Example: In the Application_Start method, there is an HttpContext, but no HttpContext.Request // System.Web.HttpException - Request is not available in this context // Do nothing } // Attach the web request details if (requestAvailable) { WebRequestDetail = new WebRequestDetail(this); if (HttpContext.Current.User != null && HttpContext.Current.User.Identity != null) { UserName = HttpContext.Current.User.Identity.Name; } } } #else WebRequestDetail = new WebRequestDetail(this); #endif //Fire event OnCaptureDetail?.Invoke(this); if (WebRequestDetail != null && WebRequestDetail.HttpMethod == null) { WebRequestDetail = null; } }
public bool IdentifyApp() { //if identify fails for some reason we can return the previous state incase it was completed before. bool currentIdentityStatus = IdentityComplete; try { int waitTime = 5; //check every 5 //was successful before and we know the appid if (this.AppIdentity != null && this.AppIdentity.DeviceAppID.HasValue) { waitTime = 15; //refresh every 15 } if (_LastIdentityAttempt.AddMinutes(waitTime) > DateTime.UtcNow) { return(currentIdentityStatus); } //if we get this far that means it failed more than 5 minutes ago, is the first time, or succeeded more than 15 minutes ago if (string.IsNullOrEmpty(APIKey)) { StackifyAPILogger.Log("Skipping IdentifyApp(). No APIKey configured.", true); return(false); } StackifyAPILogger.Log("Calling to Identify App"); EnvironmentDetail env = EnvironmentDetail.Get(true); string jsonData = JsonConvert.SerializeObject(env, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }); var response = SendJsonAndGetResponse( (BaseAPIUrl) + "Metrics/IdentifyApp", jsonData); if (response.Exception == null && response.StatusCode == HttpStatusCode.OK) { _LastIdentityAttempt = DateTime.UtcNow; AppIdentity = JsonConvert.DeserializeObject <AppIdentityInfo>(response.ResponseText); if (AppIdentity != null) { //always use whatever the configured app name is, don't just use what comes back in case they don't match if (!string.IsNullOrEmpty(env.ConfiguredAppName) && env.ConfiguredAppName != AppIdentity.AppName) { AppIdentity.AppName = env.ConfiguredAppName; AppIdentity.AppNameID = null; AppIdentity.AppEnvID = null; } IdentityComplete = true; return(true); } } return(currentIdentityStatus); } catch (Exception ex) { _LastIdentityAttempt = DateTime.UtcNow; StackifyAPILogger.Log("IdentifyApp() HTTP Response Error: " + ex.ToString(), true); return(currentIdentityStatus); } }
public static async Task ProcessPartnerAsync( [QueueTrigger(OperationConstants.PartnersQueueName, Connection = "StorageConnectionString")] EnvironmentDetail environment, [DataRepository( CosmosDbEndpoint = "CosmosDbEndpoint", DataType = typeof(AuditRecord), KeyVaultEndpoint = "KeyVaultEndpoint")] IDocumentRepository <AuditRecord> auditRecordRepository, [DataRepository( CosmosDbEndpoint = "CosmosDbEndpoint", DataType = typeof(CustomerDetail), KeyVaultEndpoint = "KeyVaultEndpoint")] IDocumentRepository <CustomerDetail> customerRepository, [DataRepository( CosmosDbEndpoint = "CosmosDbEndpoint", DataType = typeof(EnvironmentDetail), KeyVaultEndpoint = "KeyVaultEndpoint")] IDocumentRepository <EnvironmentDetail> environmentRepository, [PartnerService( ApplicationId = "{PartnerCenterEndpoint.ApplicationId}", Endpoint = "{PartnerCenterEndpoint.ServiceAddress}", SecretName = "{PartnerCenterEndpoint.ApplicationSecretId}", ApplicationTenantId = "{PartnerCenterEndpoint.TenantId}", KeyVaultEndpoint = "KeyVaultEndpoint", Resource = "https://graph.windows.net")] IPartnerServiceClient partner, [StorageService( ConnectionStringName = "StorageConnectionString", KeyVaultEndpoint = "KeyVaultEndpoint")] IStorageService storage, TraceWriter log) { List <AuditRecord> auditRecords; List <CustomerDetail> customers; SeekBasedResourceCollection <AuditRecord> seekAuditRecords; try { log.Info($"Starting to process the {environment.FriendlyName} CSP environment."); // Request the audit records for the previous day from the Partner Center API. seekAuditRecords = await partner.AuditRecords.QueryAsync(DateTime.Now.AddDays(-1)).ConfigureAwait(false); auditRecords = new List <AuditRecord>(seekAuditRecords.Items); while (seekAuditRecords.Links.Next != null) { // Request the next page of audit records from the Partner Center API. seekAuditRecords = await partner.AuditRecords.QueryAsync(seekAuditRecords.Links.Next).ConfigureAwait(false); auditRecords.AddRange(seekAuditRecords.Items); } if (auditRecords.Count > 0) { // Add, or update, each audit record to the database. await auditRecordRepository.AddOrUpdateAsync(auditRecords).ConfigureAwait(false); } if ((DateTimeOffset.UtcNow - environment?.LastProcessed).Value.TotalDays >= 30) { customers = await GetCustomersAsync(partner).ConfigureAwait(false); } else { customers = await BuildUsingAuditRecordsAsync( auditRecords, customerRepository).ConfigureAwait(false); } // Add, or update, each customer to the database. await customerRepository.AddOrUpdateAsync(customers).ConfigureAwait(false); foreach (CustomerDetail customer in customers) { // Write the customer to the customers queue to start processing the customer. await storage.WriteToQueueAsync( OperationConstants.CustomersQueueName, new XEvent { AppEndpoint = environment.AppEndpoint, AuditRecords = auditRecords .Where(r => r.CustomerId.Equals(customer.Id, StringComparison.InvariantCultureIgnoreCase)) .ToList(), Customer = customer, PartnerCenterEndpoint = environment.PartnerCenterEndpoint }).ConfigureAwait(false); } environment.LastProcessed = DateTimeOffset.UtcNow; await environmentRepository.AddOrUpdateAsync(environment).ConfigureAwait(false); log.Info($"Successfully process the {environment.FriendlyName} CSP environment."); } finally { auditRecords = null; customers = null; seekAuditRecords = null; } }