private static async Task Run() { // The following properties indicate which partner and customer context the calls are going to be made. string PartnerId = "<Partner tenant id>"; string CustomerId = "<Customer tenant id>"; Console.WriteLine(" ===================== Partner center API calls ============================", DateTime.Now); IAggregatePartner ops = await GetUserPartnerOperationsAsync(PartnerId); SeekBasedResourceCollection <CustomerUser> customerUsers = ops.Customers.ById(CustomerId).Users.Get(); Console.WriteLine(JsonConvert.SerializeObject(customerUsers)); Console.WriteLine(" ===================== Partner graph API calls ============================", DateTime.Now); Tuple <string, DateTimeOffset> tokenResult = await LoginToGraph(PartnerId); Newtonsoft.Json.Linq.JObject mydetails = await ApiCalls.GetAsync(tokenResult.Item1, "https://graph.microsoft.com/v1.0/me"); Console.WriteLine(JsonConvert.SerializeObject(mydetails)); // CSP partner applications are pre-consented into customer tenant, so they do not need a custom consent from customer. // direct token acquire to a customer tenant should work. Console.WriteLine(" ===================== Customer graph API calls ============================", DateTime.Now); Tuple <string, DateTimeOffset> tokenCustomerResult = await LoginToCustomerGraph(PartnerId, CustomerId); Newtonsoft.Json.Linq.JObject customerDomainsUsingGraph = await ApiCalls.GetAsync(tokenCustomerResult.Item1, "https://graph.windows.net/" + CustomerId + "/domains?api-version=1.6"); Console.WriteLine(JsonConvert.SerializeObject(customerDomainsUsingGraph)); Console.ReadLine(); }
public IList <AzureUtilizationRecord> doTheTask() { List <CustomObject> ResourceUtilizationList = new List <CustomObject>(); var partnerOperations = this.authHelper.AppPartnerOperations; try { SeekBasedResourceCollection <Customer> customersPage = partnerOperations.Customers.Get(); List <Customer> customers = customersPage.Items.ToList(); Parallel.ForEach(customers, customer => { CustomObject obj = new CustomObject { CustomerCompanyName = customer.CompanyProfile.CompanyName, ResourceUtilizationList = GetDataPerCustomer(customer, partnerOperations) }; ResourceUtilizationList.Add(obj); }); } catch (Exception ex) { Console.WriteLine(ex.Message); } //string output = JsonConvert.SerializeObject(ResourceUtilizationList); //System.IO.File.WriteAllText(@".\ResourceUtilizationList.json", output); //string json = System.IO.File.ReadAllText(@".\ResourceUtilizationList.json"); //ResourceUtilizationList = JsonConvert.DeserializeObject<List<Microsoft.Store.PartnerCenter.Models.Utilizations.AzureUtilizationRecord>>(json); return(MapUtilizationToCustomClass(ResourceUtilizationList)); }
private static async Task RunAsync() { // The following properties indicate which partner and customer context the calls are going to be made. string PartnerId = "<Partner tenant id>"; string CustomerId = "<Customer tenant id>"; Console.WriteLine(" ===================== Partner Center operations ============================", DateTime.Now); IAggregatePartner ops = await GetUserPartnerOperationsAsync(PartnerId); SeekBasedResourceCollection <CustomerUser> customerUsers = ops.Customers.ById(CustomerId).Users.Get(); Console.WriteLine(JsonConvert.SerializeObject(customerUsers)); Console.WriteLine(" ===================== Partner graph operations ============================", DateTime.Now); Tuple <string, DateTimeOffset> tokenResult = await LoginToGraph(PartnerId); Newtonsoft.Json.Linq.JObject mydetails = await ApiCalls.GetAsync(tokenResult.Item1, "https://graph.microsoft.com/v1.0/me"); Console.WriteLine(JsonConvert.SerializeObject(mydetails)); /** * Cloud Solution Provider partners can configure application for pre-consent. This means they do not need a * custom consent from the customer. This is possible because the partner can consent on behalf of the customer. */ Console.WriteLine(" ===================== Customer graph operations ============================", DateTime.Now); Tuple <string, DateTimeOffset> tokenCustomerResult = await LoginToCustomerGraph(PartnerId, CustomerId); Newtonsoft.Json.Linq.JObject customerDomainsUsingGraph = await ApiCalls.GetAsync(tokenCustomerResult.Item1, "https://graph.windows.net/" + CustomerId + "/domains?api-version=1.6"); Console.WriteLine(JsonConvert.SerializeObject(customerDomainsUsingGraph)); Console.ReadLine(); }
/// <summary> /// Executes the operations associated with the cmdlet. /// </summary> public override void ExecuteCmdlet() { Scheduler.RunTask(async() => { IPartner partner = await PartnerSession.Instance.ClientFactory.CreatePartnerOperationsAsync(CorrelationId, CancellationToken).ConfigureAwait(false); SeekBasedResourceCollection <Role> roles = await partner.Roles.GetAsync(CancellationToken).ConfigureAwait(false); WriteObject(roles.Items.Select(r => new PSRole(r)), true); }, true); }
public List <CspAzureResourceUsageRecord> GetAllData() { // Authenticate user: var partnerOperations = this.authHelper.UserPartnerOperations; ////PartnerUsageSummary UsagePage = partnerOperations.UsageSummary.Get(); SeekBasedResourceCollection <Customer> customersPage = partnerOperations.Customers.Get(); List <Customer> customers = customersPage.Items.ToList(); List <CspAzureResourceUsageRecord> usageRecords = new List <CspAzureResourceUsageRecord>(); usageRecords = CSPUsageHelper.GetRecordsFromCustomer(customers, partnerOperations); return(usageRecords); }
/// <summary> /// Used by the management agent to allow for code cleanup. /// </summary> /// <param name="importRunStep"></param> /// <returns></returns> public CloseImportConnectionResults CloseImportConnection(CloseImportConnectionRunStep importRunStep) { _customersEnumerator = null; _customersInfo = null; _customers = null; _users = null; _usersEnumerator = null; _customersInfoEnumerator.Dispose(); return(new CloseImportConnectionResults()); }
public List <Microsoft.Store.PartnerCenter.Models.Utilizations.AzureUtilizationRecord> GetDataForCustomerSubscription() { var partnerOperations = this.authHelper.UserPartnerOperations; List <Microsoft.Store.PartnerCenter.Models.Utilizations.AzureUtilizationRecord> ResourceUtilizationList = new List <Microsoft.Store.PartnerCenter.Models.Utilizations.AzureUtilizationRecord>(); try { SeekBasedResourceCollection <Customer> customersPage = partnerOperations.Customers.Get(); List <Customer> customers = customersPage.Items.ToList(); Parallel.ForEach(customers, customer => { ResourceUtilizationList.AddRange(GetDataPerCustomer(customer, partnerOperations)); }); } catch (Exception ex) { Debug.WriteLine(ex.Message); } return(ResourceUtilizationList); }
private void ConfigureUserEnumerator() { try { // Obtain the collection of users broken out by page size. This is required because the synchronization // will only import a set size of entries at once. The page size is controlled by the ImportDefaultPageSize // and ImportMaxPageSize properties. _users = _operations.Customers.ById(_customersInfoEnumerator.Current.Value) .Users.Query(QueryFactory.Instance.BuildIndexedQuery(ImportDefaultPageSize)); // Create a customer user enumerator which will be used to traverse the pages of customer users. _usersEnumerator = _operations.Enumerators.CustomerUsers.Create(_users); _setupUsersEnumerators = false; } catch (PartnerException) { _customersInfoEnumerator.MoveNext(); ConfigureUserEnumerator(); } }
/// <summary> /// Used to configure the import session and is called once at the beginning of the import. /// </summary> /// <param name="configParameters">A collection of <see cref="ConfigParameter"/> objects.</param> /// <param name="types">Contains a <see cref="Schema"/> that defines the management agent's schema</param> /// <param name="importRunStep">Contains an <see cref="OpenImportConnectionRunStep"/> object.</param> /// <returns></returns> public OpenImportConnectionResults OpenImportConnection(KeyedCollection <string, ConfigParameter> configParameters, Schema types, OpenImportConnectionRunStep importRunStep) { InitializeConnector(configParameters); _setupCustomerIdsEnumerator = true; _setupUsersEnumerators = true; // This dictionary will contain a complete list of all customer identifiers that are processed. These // identifiers will be used to obtain the users that belong to the customers that were processed. _customersInfo = new Dictionary <string, string>(); // Obtain the collection of customer broken out by page size. This is required because the synchronization // will only import a set size of entries at once. The page size is controlled by the ImportDefaultPageSize // and ImportMaxPageSize properties. _customers = _operations.Customers.Query(QueryFactory.Instance.BuildIndexedQuery(ImportDefaultPageSize)); // Create a customer enumerator which will be used to traverse the pages of customers. _customersEnumerator = _operations.Enumerators.Customers.Create(_customers); return(new OpenImportConnectionResults()); }
private async static Task ProcessCustomers(SeekBasedResourceCollection <Customer> customers, TraceWriter log) { log.Info($"{customers.TotalCount } customers found"); log.Info($"Inserting Customer data into database"); DumpUtility blkOperation = new DumpUtility(ConfigurationHelper.GetConnectionString(ConfigurationKeys.DbConnectoinString)); blkOperation.Insert <CspCustomer>(customers.Items .Select(s => new CspCustomer() { CustomerId = s.Id, TenantId = s.CompanyProfile != null ? s.CompanyProfile.TenantId : string.Empty, CompanyName = s.CompanyProfile?.CompanyName, Domain = s.CompanyProfile.Domain, Relationship = s.RelationshipToPartner.ToString() }).ToList()); log.Info($"Database operation completed. Adding messages to queue"); CustomersQueueClient queueClient = new CustomersQueueClient(ConfigurationHelper.GetAppSetting(ConfigurationKeys.StorageConnectoinString)); foreach (var customer in customers.Items) { try { log.Verbose($"Processing customer - {customer.Id }, Relationship {customer.RelationshipToPartner}"); log.Verbose($"Customer {customer.Id }"); if (customer.RelationshipToPartner != CustomerPartnerRelationship.Advisor) { await queueClient.AddMessageAsync(new CustomerMessage() { CustomerId = customer.Id }); } } catch (Exception ex) { log.Error($"Some error occured for customer - {customer.Id}, Relationship {customer.RelationshipToPartner}", ex); } } log.Info($"Message are added to queue."); }
/// <summary> /// Executes the operations associated with the cmdlet. /// </summary> public override void ExecuteCmdlet() { SeekBasedResourceCollection <UserMember> members = Partner.Roles[RoleId].Members.GetAsync().GetAwaiter().GetResult(); WriteObject(members.Items.Select(m => new PSUserMember(m)), true); }
private static async Task Run() { // The following properties indicate which partner and customer context the calls are going to be made. string PartnerId = "<Partner tenant id>"; string CustomerId = "<Customer tenant id>"; Console.WriteLine(" ===================== Partner center API calls ============================", DateTime.Now); IAggregatePartner ops = await GetUserPartnerOperationsAsync(PartnerId); SeekBasedResourceCollection <CustomerUser> customerUsers = ops.Customers.ById(CustomerId).Users.Get(); Console.WriteLine(JsonConvert.SerializeObject(customerUsers)); Console.WriteLine(" ===================== Partner graph API calls ============================", DateTime.Now); Tuple <string, DateTimeOffset> tokenResult = await LoginToGraph(PartnerId); JObject mydetails = await ApiCalls.GetAsync(tokenResult.Item1, "https://graph.microsoft.com/v1.0/me"); Console.WriteLine(JsonConvert.SerializeObject(mydetails)); // The customer graph calls require customer admin to consent the application Console.WriteLine(" ===================== Customer consent for graph API calls ============================", DateTime.Now); // Enable consent Tuple <string, DateTimeOffset> tokenPartnerResult = await LoginToPartnerCenter(PartnerId); JObject contents = new JObject { // Provide your application display name ["displayName"] = "CPV Marketplace", // Provide your application id ["applicationId"] = CPVApplicationId, // Provide your application grants ["applicationGrants"] = new JArray( JObject.Parse("{\"enterpriseApplicationId\": \"00000002-0000-0000-c000-000000000000\", \"scope\":\"Domain.ReadWrite.All,User.ReadWrite.All,Directory.Read.All\"}"), // for graph api access, Directory.Read.All JObject.Parse("{\"enterpriseApplicationId\": \"797f4846-ba00-4fd7-ba43-dac1f8f63013\", \"scope\":\"user_impersonation\"}")) // for ARM api access }; /** The following steps have to performed once in per customer tenant if your application is Control panel vendor application and requires customer tenant graph access **/ // delete the previous grant into customer tenant JObject consentDeletion = await ApiCalls.DeleteAsync( tokenPartnerResult.Item1, string.Format("https://api.partnercenter.microsoft.com/v1/customers/{0}/applicationconsents/{1}", CustomerId, CPVApplicationId)); Console.WriteLine(JsonConvert.SerializeObject(consentDeletion)); // create new grants for the application given the setting in application grants payload. JObject consentCreation = await ApiCalls.PostAsync( tokenPartnerResult.Item1, string.Format("https://api.partnercenter.microsoft.com/v1/customers/{0}/applicationconsents", CustomerId), contents.ToString()); Console.WriteLine(JsonConvert.SerializeObject(consentCreation)); Console.WriteLine(" ===================== Customer graph API calls ============================", DateTime.Now); Tuple <string, DateTimeOffset> tokenCustomerResult = await LoginToCustomerGraph(PartnerId, CustomerId); JObject customerDomainsUsingGraph = await ApiCalls.GetAsync(tokenCustomerResult.Item1, "https://graph.windows.net/" + CustomerId + "/domains?api-version=1.6"); Console.WriteLine(JsonConvert.SerializeObject(customerDomainsUsingGraph)); Console.ReadLine(); }
/// <summary> /// Executes the operations associated with the cmdlet. /// </summary> public override void ExecuteCmdlet() { SeekBasedResourceCollection <Role> roles = Partner.Roles.GetAsync().ConfigureAwait(false).GetAwaiter().GetResult(); WriteObject(roles.Items.Select(r => new PSRole(r)), true); }
public IEnumerable <Models.Customers> GetCustomerList() { // SeekBasedResourceCollection<Customer> list1= new SeekBasedResourceCollection<Customer>(; try { //// All the operations executed on this partner operation instance will share the same correlation Id but will differ in request Id //IPartner scopedPartnerOperations = ApplicationDomain.PartnerCenterClient.With(RequestContextFactory.Instance.Create(Guid.NewGuid())); //// read customers into chunks of 40s //var customersBatch = scopedPartnerOperations.Customers.Query(QueryFactory.Instance.BuildIndexedQuery(40)); //var customersEnumerator = scopedPartnerOperations.Enumerators.Customers.Create(customersBatch); //Get Customer from API SeekBasedResourceCollection <Customer> list = ApplicationDomain.PartnerCenterClient.Customers.Get(); //Get Reseller/Agent from db ViewModel.Resellers.Resellers resellers = new ViewModel.Resellers.Resellers(); IEnumerable <Models.Reseller> reseller = resellers.GetActive(); //Get Customers from db IEnumerable <Models.Customers> getcustomer = GetCustomers(); List <Models.Customers> customer = new List <Models.Customers>(); //foreach (var r in reseller) //{ // foreach (var i in getcustomer) // { // if (i.ResellerId == r.Id || i.ResellerId == 0) // { // foreach (var x in list.Items) // { // if (i.MicrosoftId == x.Id) // { // Models.Customers cus = new Models.Customers() // { // ResellerId = i.Id, // PrimaryDomain = x.CompanyProfile.Domain, // MicrosoftId = x.Id, // Company = x.CompanyProfile.CompanyName, // }; // customer.Add(cus); // } // } // } // } //} foreach (var x in list.Items.OrderBy(m => m.Id)) //Api { var gc = getcustomer.Where(m => m.MicrosoftId == x.Id).SingleOrDefault(); if (gc != null) // It customer is exit in my db { // foreach (var i in gc) // db customer // { // if (i.MicrosoftId == x.Id) // { //var res = reseller.Where(m => m.Id == gc.ResellerId).SingleOrDefault(); if (gc.ResellerId == 0) // it means direct customer { Models.Customers cus = new Models.Customers() { ResellerId = 0, // it means it's a direct customer PrimaryDomain = x.CompanyProfile.Domain, MicrosoftId = x.Id, Company = x.CompanyProfile.CompanyName, }; customer.Add(cus); } else // it means indirect customer { //var res = reseller.Where(m => m.Id == gc.ResellerId).SingleOrDefault(); Models.Customers cus = new Models.Customers() { ResellerId = gc.ResellerId, PrimaryDomain = x.CompanyProfile.Domain, MicrosoftId = x.Id, Company = x.CompanyProfile.CompanyName, }; customer.Add(cus); } // foreach (var r in reseller) // db agent // { // if (i.ResellerId == r.Id || i.ResellerId == 0) // { // } // } // } //} } else // If customer is not exit in my db { Models.Customers cus = new Models.Customers() { ResellerId = 0, // it means it's a direct customer PrimaryDomain = x.CompanyProfile.Domain, MicrosoftId = x.Id, Company = x.CompanyProfile.CompanyName, }; customer.Add(cus); } } return(customer); } catch { return(null); } }
public List <CspAzureResourceUsageRecord> GetAllData() { // Authenticate user: var partnerOperations = this.authHelper.UserPartnerOperations; ////PartnerUsageSummary UsagePage = partnerOperations.UsageSummary.Get(); SeekBasedResourceCollection <Customer> customersPage = partnerOperations.Customers.Get(); List <Customer> customers = customersPage.Items.ToList(); List <CspAzureResourceUsageRecord> usageRecords = new List <CspAzureResourceUsageRecord>(); foreach (Customer customer in customers) { try { if (customer.RelationshipToPartner != CustomerPartnerRelationship.Reseller) { continue; } var subscriptionsPage = partnerOperations.Customers.ById(customer.Id).Subscriptions.Get(); List <Microsoft.Store.PartnerCenter.Models.Subscriptions.Subscription> currentSubscriptions = subscriptionsPage.Items.ToList(); foreach ( Microsoft.Store.PartnerCenter.Models.Subscriptions.Subscription subscription in currentSubscriptions) { if (subscription.BillingType != BillingType.Usage) { continue; } var subscriptionPage = partnerOperations.Customers.ById(customer.Id).Subscriptions.ById(subscription.Id); var subscriptionUsageRecords = subscriptionPage.UsageRecords.Resources.Get(); if (subscriptionUsageRecords.TotalCount > 0) { var subscriptionUsageSummary = subscriptionPage.UsageSummary.Get(); foreach (var item in subscriptionUsageRecords.Items.ToList()) { CspAzureResourceUsageRecord csprec = new CspAzureResourceUsageRecord(); csprec.Category = item.Category; csprec.QuantityUsed = item.QuantityUsed; csprec.ResourceId = item.ResourceId; csprec.ResourceName = item.ResourceName; csprec.Subcategory = item.Subcategory; csprec.TotalCost = item.TotalCost; csprec.Unit = item.Unit; // Customer profile info: csprec.CustomerId = customer.Id; csprec.CustomerName = customer.CompanyProfile.CompanyName; ////csprec.CustomerBillingProfile = customer.BillingProfile.ToString(); csprec.CustomerCommerceId = customer.CommerceId; csprec.CustomerDomain = customer.CompanyProfile.Domain; csprec.CustomerTenantId = customer.CompanyProfile.TenantId; csprec.CustomerRelationshipToPartner = customer.RelationshipToPartner.ToString(); // Subscription profile info: csprec.SubscriptionId = subscription.Id; csprec.SubscriptionName = subscription.FriendlyName; csprec.SubscriptionStatus = subscription.Status.ToString(); csprec.SubscriptionContractType = subscription.ContractType.ToString(); // Billing cycle info: csprec.BillingStartDate = subscriptionUsageSummary.BillingStartDate.DateTime; csprec.BillingEndDate = subscriptionUsageSummary.BillingEndDate.DateTime; usageRecords.Add(csprec); } } } } catch (Microsoft.Store.PartnerCenter.Exceptions.PartnerException e) { throw new Exception("Could not fetch current usage data. See inner exception for details.", e); } } return(usageRecords); }