/// <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;
            }
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        /// <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;
            }
        }
예제 #5
0
        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);
        }
예제 #7
0
        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));
        }
예제 #8
0
        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;
            }
        }
예제 #10
0
        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;
            }
        }
예제 #11
0
        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);
            }
        }
예제 #12
0
        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;
            }
        }