Delen via


Azure Notification Hubs-registraties bulksgewijs exporteren en importeren

Er zijn scenario's waarin grote aantallen registraties in een Notification Hub moeten worden gemaakt of gewijzigd. Sommige van deze scenario's zijn tag-updates na batchberekeningen of het migreren van een bestaande push-implementatie om Azure Notification Hubs te gebruiken.

In dit artikel wordt uitgelegd hoe u een groot aantal bewerkingen uitvoert op een Notification Hub of hoe u alle registraties bulksgewijs exporteert.

OPMERKING: Bulkimport/export is alleen beschikbaar voor de prijscategorie 'standard'

Stroom op hoog niveau

Batch-ondersteuning is ontworpen ter ondersteuning van langlopende taken met miljoenen registraties. Om deze schaal te bereiken, maakt batchondersteuning gebruik van Azure Storage om taakgegevens en uitvoer op te slaan. Voor bulkupdatebewerkingen moet de gebruiker een bestand maken in een blobcontainer, waarvan de inhoud de lijst met registratie-updatebewerkingen is. Bij het starten van de taak geeft de gebruiker een URL op naar de invoer-blob, samen met een URL naar een uitvoermap (ook in een blobcontainer). Nadat de taak is gestart, kan de gebruiker de status controleren door een query uit te voeren op een URL-locatie die is opgegeven bij het starten van de taak. Een specifieke taak kan alleen bewerkingen van een specifiek type uitvoeren (maken, bijwerken of verwijderen). Exportbewerkingen worden op analoge wijze uitgevoerd.

Importeren

Instellen

In deze sectie wordt ervan uitgegaan dat u de volgende entiteiten hebt:

Invoerbestand maken en opslaan in een blob

Een invoerbestand bevat een lijst met registraties die zijn geserialiseerd in XML, één per rij. Met behulp van de Azure SDK laat het volgende codevoorbeeld zien hoe u de registraties serialiseert en uploadt naar de blobcontainer:

private static async Task SerializeToBlobAsync(BlobContainerClient container, RegistrationDescription[] descriptions)
{
     StringBuilder builder = new StringBuilder();
     foreach (var registrationDescription in descriptions)
     {
          builder.AppendLine(registrationDescription.Serialize());
     }

     var inputBlob = container.GetBlobClient(INPUT_FILE_NAME);
     using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(builder.ToString())))
     {
         await inputBlob.UploadAsync(stream);
     }
}

Belangrijk

De voorgaande code serialiseert de registraties in het geheugen en uploadt vervolgens de hele stroom naar een blob. Als u een bestand van meer dan een paar megabytes hebt geüpload, raadpleegt u de Azure Blob-richtlijnen voor het uitvoeren van deze stappen. bijvoorbeeld blok-blobs.

URL-tokens maken

Zodra het invoerbestand is geüpload, genereert u de URL's die u aan de Notification Hub moet verstrekken voor zowel het invoerbestand als de uitvoermap. U kunt twee verschillende blobcontainers gebruiken voor invoer en uitvoer.

static Uri GetOutputDirectoryUrl(BlobContainerClient container)
{
      Console.WriteLine(container.CanGenerateSasUri);
      BlobSasBuilder builder = new BlobSasBuilder(BlobSasPermissions.All, DateTime.UtcNow.AddDays(1));
      return container.GenerateSasUri(builder);
}

static Uri GetInputFileUrl(BlobContainerClient container, string filePath)
{
      Console.WriteLine(container.CanGenerateSasUri);
      BlobSasBuilder builder = new BlobSasBuilder(BlobSasPermissions.Read, DateTime.UtcNow.AddDays(1));
      return container.GenerateSasUri(builder);
}

De taak verzenden

Met de twee invoer- en uitvoer-URL's kunt u nu de batchtaak starten.

NotificationHubClient client = NotificationHubClient.CreateClientFromConnectionString(CONNECTION_STRING, HUB_NAME);
var job = await client.SubmitNotificationHubJobAsync(
     new NotificationHubJob {
             JobType = NotificationHubJobType.ImportCreateRegistrations,
             OutputContainerUri = outputContainerSasUri,
             ImportFileUri = inputFileSasUri
         }
     );

long i = 10;
while (i > 0 && job.Status != NotificationHubJobStatus.Completed)
{
    job = await client.GetNotificationHubJobAsync(job.JobId);
    await Task.Delay(1000);
    i--;
}

Naast de invoer- en uitvoer-URL's wordt in dit voorbeeld een NotificationHubJob object gemaakt dat een JobType object bevat. Dit kan een van de volgende typen zijn:

  • ImportCreateRegistrations
  • ImportUpdateRegistrations
  • ImportDeleteRegistrations

Zodra de aanroep is voltooid, wordt de taak voortgezet door de Notification Hub en kunt u de status ervan controleren met de aanroep naar GetNotificationHubJobAsync.

Wanneer de taak is voltooid, kunt u de resultaten controleren door de volgende bestanden in de uitvoermap te bekijken:

  • /<hub>/<jobid>/Failed.txt
  • /<hub>/<jobid>/Output.txt

Deze bestanden bevatten de lijst met geslaagde en mislukte bewerkingen uit uw batch. De bestandsindeling is .cvs, waarin elke rij het regelnummer van het oorspronkelijke invoerbestand en de uitvoer van de bewerking bevat (meestal de gemaakte of bijgewerkte registratiebeschrijving).

Volledige voorbeeldcode

Met de volgende voorbeeldcode worden registraties geïmporteerd in een Notification Hub.

using Microsoft.Azure.NotificationHubs;
using Azure.Storage.Blobs;
using Azure.Storage.Sas;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        private static string CONNECTION_STRING = "namespace"; 
        private static string HUB_NAME = "demohub";
        private static string INPUT_FILE_NAME = "CreateFile.txt";
        private static string STORAGE_ACCOUNT_CONNECTIONSTRING = "connectionstring";
        private static string CONTAINER_NAME = "containername";

        static async Task Main(string[] args)
        {
            var descriptions = new[]
            {
                new MpnsRegistrationDescription(@"http://dm2.notify.live.net/throttledthirdparty/01.00/12G9Ed13dLb5RbCii5fWzpFpAgAAAAADAQAAAAQUZm52OkJCMjg1QTg1QkZDMkUxREQFBlVTTkMwMQ"),
                new MpnsRegistrationDescription(@"http://dm2.notify.live.net/throttledthirdparty/01.00/12G9Ed13dLb5RbCii5fWzpFpAgAAAAADAQAAAAQUZm52OkJCMjg1QTg1QkZDMjUxREQFBlVTTkMwMQ"),
                new MpnsRegistrationDescription(@"http://dm2.notify.live.net/throttledthirdparty/01.00/12G9Ed13dLb5RbCii5fWzpFpAgAAAAADAQAAAAQUZm52OkJCMjg1QTg1QkZDMhUxREQFBlVTTkMwMQ"),
                new MpnsRegistrationDescription(@"http://dm2.notify.live.net/throttledthirdparty/01.00/12G9Ed13dLb5RbCii5fWzpFpAgAAAAADAQAAAAQUZm52OkJCMjg1QTg1QkZDMdUxREQFBlVTTkMwMQ"),
            };

            // Get a reference to a container named "sample-container" and then create it
            BlobContainerClient container = new BlobContainerClient(STORAGE_ACCOUNT_CONNECTIONSTRING, CONTAINER_NAME);

            await container.CreateIfNotExistsAsync();

            await SerializeToBlobAsync(container, descriptions);

            // TODO then create Sas
            var outputContainerSasUri = GetOutputDirectoryUrl(container);
            
            BlobContainerClient inputcontainer = new BlobContainerClient(STORAGE_ACCOUNT_CONNECTIONSTRING, STORAGE_ACCOUNT_CONNECTIONSTRING + "/" +         INPUT_FILE_NAME);

            var inputFileSasUri = GetInputFileUrl(inputcontainer, INPUT_FILE_NAME);


            // Import this file
            NotificationHubClient client = NotificationHubClient.CreateClientFromConnectionString(CONNECTION_STRING, HUB_NAME);
            var job = await client.SubmitNotificationHubJobAsync(
                new NotificationHubJob {
                    JobType = NotificationHubJobType.ImportCreateRegistrations,
                    OutputContainerUri = outputContainerSasUri,
                    ImportFileUri = inputFileSasUri
                }
            );

            long i = 10;
            while (i > 0 && job.Status != NotificationHubJobStatus.Completed)
            {
                job = await client.GetNotificationHubJobAsync(job.JobId);
                await Task.Delay(1000);
                i--;
            }
        }

        private static async Task SerializeToBlobAsync(BlobContainerClient container, RegistrationDescription[] descriptions)
        {
            StringBuilder builder = new StringBuilder();
            foreach (var registrationDescription in descriptions)
            {
                builder.AppendLine(registrationDescription.Serialize());
            }

            var inputBlob = container.GetBlobClient(INPUT_FILE_NAME);
            using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(builder.ToString())))
            {
                await inputBlob.UploadAsync(stream);
            }
        }

        static Uri GetOutputDirectoryUrl(BlobContainerClient container)
        {
            Console.WriteLine(container.CanGenerateSasUri);
            BlobSasBuilder builder = new BlobSasBuilder(BlobSasPermissions.All, DateTime.UtcNow.AddDays(1));
            return container.GenerateSasUri(builder);
        }

        static Uri GetInputFileUrl(BlobContainerClient container, string filePath)
        {
            Console.WriteLine(container.CanGenerateSasUri);
            BlobSasBuilder builder = new BlobSasBuilder(BlobSasPermissions.Read, DateTime.UtcNow.AddDays(1));
            return container.GenerateSasUri(builder);

        }
    }
}

Exporteren

Het exporteren van de registratie is vergelijkbaar met het importeren, met de volgende verschillen:

  • U hebt alleen de uitvoer-URL nodig.
  • U maakt een NotificationHubJob van het type ExportRegistrations.

Voorbeeldcodefragment

Hier volgt een voorbeeldcodefragment voor het exporteren van registraties in Java:

// Submit an export job
NotificationHubJob job = new NotificationHubJob();
job.setJobType(NotificationHubJobType.ExportRegistrations);
job.setOutputContainerUri("container uri with SAS signature");
job = hub.submitNotificationHubJob(job);

// Wait until the job is done
while(true){
    Thread.sleep(1000);
    job = hub.getNotificationHubJob(job.getJobId());
    if(job.getJobStatus() == NotificationHubJobStatus.Completed)
        break;
}

Volgende stappen

Zie de volgende artikelen voor meer informatie over registraties: