Delen via


Azure Notification Hubs-registraties bulksgewijs exporteren en importeren

Er zijn scenario's waarin het nodig is om grote aantallen registraties in een Notification Hub te maken of te wijzigen. 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 om alle registraties bulksgewijs te exporteren.

NOTITIE: Bulkimport/export is alleen beschikbaar voor de prijscategorie Standard

Hoog niveau stroom

Batch-ondersteuning is ontworpen ter ondersteuning van langlopende taken met miljoenen registraties. Om deze schaal te bereiken, maakt batchondersteuning gebruik van Azure Storage voor het opslaan van taakgegevens en -uitvoer. 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 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 URL-locatie op te vragen die aan het begin van de taak is opgegeven. Een specifieke taak kan alleen bewerkingen van een bepaald type uitvoeren (maakt, bijwerkt of verwijdert). Exportbewerkingen worden analoog uitgevoerd.

Importeren

Opzetten

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 ziet u in het volgende codevoorbeeld hoe u de registraties serialiseert en uploadt naar een 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 stream naar een blob. Als u een bestand met meer dan een paar megabytes hebt geüpload, raadpleegt u de Richtlijnen voor Azure Blob over 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 uw Notification Hub wilt leveren 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 de batchtaak nu 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 object gemaakt dat een NotificationHubJobJobType 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 inspecteren door de volgende bestanden in uw 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 heeft en de uitvoer van de bewerking (meestal de gemaakte of bijgewerkte beschrijving van de registratie).

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 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: