The next step was to enumerate The Things Network(TTN) Applications so I could connect only to the required Azure IoT hub(s). There would also be a single configuration setting for the client (establish a connection for every TTN application, or don’t establish a connection for any) and this could be overridden with a TTN application attribute
long pageSize = long.Parse(args[3]); Console.WriteLine($"Page size: {pageSize}"); Console.WriteLine(); using (HttpClient httpClient = new HttpClient()) { ApplicationRegistryClient applicationRegistryClient = new ApplicationRegistryClient(baseUrl, httpClient) { ApiKey = apiKey }; try { int page = 1; string[] fieldMaskPathsApplication = { "attributes" }; // think this is the bare minimum required for integration V3Applications applications = await applicationRegistryClient.ListAsync(collaborator, field_mask_paths: fieldMaskPathsApplication, limit: pageSize, page: page); while ((applications != null) && (applications.Applications != null)) { Console.WriteLine($"Applications:{applications.Applications.Count} Page:{page} Page size:{pageSize}"); foreach (V3Application application in applications.Applications) { bool applicationIntegration = ApplicationAzureintegrationDefault; Console.WriteLine($"Application ID:{application.Ids.Application_id}"); if (application.Attributes != null) { string ApplicationAzureIntegrationValue = string.Empty; if (application.Attributes.TryGetValue(ApplicationAzureIntegrationField, out ApplicationAzureIntegrationValue)) { bool.TryParse(ApplicationAzureIntegrationValue, out applicationIntegration); } if (applicationIntegration) { Console.WriteLine(" Application attributes"); foreach (KeyValuePair<string, string> attribute in application.Attributes) { Console.WriteLine($" Key: {attribute.Key} Value: {attribute.Value}"); } } } Console.WriteLine(); } page += 1; applications = await applicationRegistryClient.ListAsync(collaborator, field_mask_paths: fieldMaskPathsApplication, limit: pageSize, page: page); }; } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.WriteLine("Press <enter> to exit"); Console.ReadLine(); }
I Used the field_mask_paths parameter (don’t need created_at, updated_at, name etc.) to minimise the data returned to my client.
public async System.Threading.Tasks.Task<V3Applications> ListAsync(string collaborator_organization_ids_organization_id = null, string collaborator_user_ids_user_id = null, string collaborator_user_ids_email = null, System.Collections.Generic.IEnumerable<string> field_mask_paths = null, string order = null, long? limit = null, long? page = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { var urlBuilder_ = new System.Text.StringBuilder(); urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/applications?"); if (collaborator_organization_ids_organization_id != null) { urlBuilder_.Append(System.Uri.EscapeDataString("collaborator.organization_ids.organization_id") + "=").Append(System.Uri.EscapeDataString(ConvertToString(collaborator_organization_ids_organization_id, System.Globalization.CultureInfo.InvariantCulture))).Append("&"); } if (collaborator_user_ids_user_id != null) { urlBuilder_.Append(System.Uri.EscapeDataString("collaborator.user_ids.user_id") + "=").Append(System.Uri.EscapeDataString(ConvertToString(collaborator_user_ids_user_id, System.Globalization.CultureInfo.InvariantCulture))).Append("&"); } if (collaborator_user_ids_email != null) { urlBuilder_.Append(System.Uri.EscapeDataString("collaborator.user_ids.email") + "=").Append(System.Uri.EscapeDataString(ConvertToString(collaborator_user_ids_email, System.Globalization.CultureInfo.InvariantCulture))).Append("&"); } if (field_mask_paths != null) { foreach (var item_ in field_mask_paths) { urlBuilder_.Append(System.Uri.EscapeDataString("field_mask.paths") + "=").Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append("&"); } } if (order != null) { urlBuilder_.Append(System.Uri.EscapeDataString("order") + "=").Append(System.Uri.EscapeDataString(ConvertToString(order, System.Globalization.CultureInfo.InvariantCulture))).Append("&"); } if (limit != null) { urlBuilder_.Append(System.Uri.EscapeDataString("limit") + "=").Append(System.Uri.EscapeDataString(ConvertToString(limit, System.Globalization.CultureInfo.InvariantCulture))).Append("&"); } if (page != null) { urlBuilder_.Append(System.Uri.EscapeDataString("page") + "=").Append(System.Uri.EscapeDataString(ConvertToString(page, System.Globalization.CultureInfo.InvariantCulture))).Append("&"); } }
I was hoping that there would be a away to further “shape” the returned data, but in the NSwag generated code the construction of the URL with field_mask_paths, order, limit, and page parameters meant this appears not to be possible.