Massexportera och importera Azure Notification Hubs-registreringar

Det finns scenarier där det krävs för att skapa eller ändra ett stort antal registreringar i en meddelandehubb. Några av dessa scenarier är tagguppdateringar efter batchberäkningar eller migrering av en befintlig push-implementering för att använda Azure Notification Hubs.

Den här artikeln beskriver hur du utför ett stort antal åtgärder på en meddelandehubb eller exporterar alla registreringar i grupp.

OBSERVERA: Massimport/massexport är endast tillgängligt för prisnivån "standard"

Flöde på hög nivå

Batch-stöd är utformat för att stödja långvariga jobb som involverar miljontals registreringar. För att uppnå den här skalan använder batchstöd Azure Storage för att lagra jobbinformation och utdata. För massuppdateringsåtgärder måste användaren skapa en fil i en blobcontainer, vars innehåll är listan över registreringsåtgärder. När du startar jobbet tillhandahåller användaren en URL till indatabloben, tillsammans med en URL till en utdatakatalog (även i en blobcontainer). När jobbet har startat kan användaren kontrollera statusen genom att fråga en URL-plats som angavs i början av jobbet. Ett visst jobb kan bara utföra åtgärder av en viss typ (skapar, uppdaterar eller tar bort). Exportåtgärder utförs på samma sätt.

Importera

Konfigurera

Det här avsnittet förutsätter att du har följande entiteter:

Skapa en indatafil och lagra den i en blob

En indatafil innehåller en lista över registreringar som serialiserats i XML, en per rad. Med hjälp av Azure SDK visar följande kodexempel hur du serialiserar registreringarna och laddar upp dem till blobcontainern:

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);
     }
}

Viktigt

Koden ovan serialiserar registreringarna i minnet och laddar sedan upp hela dataströmmen till en blob. Om du har laddat upp en fil på mer än bara några megabyte kan du läsa Azure Blob-vägledningen om hur du utför de här stegen. till exempel blockblobar.

Skapa URL-token

När indatafilen har laddats upp genererar du url:erna som ska tillhandahållas till meddelandehubben för både indatafilen och utdatakatalogen. Du kan använda två olika blobcontainrar för indata och utdata.

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);
}

Skicka jobbet

Med de två indata- och utdata-URL:erna kan du nu starta batchjobbet.

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--;
}

Förutom indata- och utdata-URL:erna skapar det här exemplet ett NotificationHubJob objekt som innehåller ett JobType -objekt, vilket kan vara en av följande typer:

  • ImportCreateRegistrations
  • ImportUpdateRegistrations
  • ImportDeleteRegistrations

När anropet har slutförts fortsätter jobbet av meddelandehubben och du kan kontrollera dess status med anropet till GetNotificationHubJobAsync.

När jobbet har slutförts kan du granska resultaten genom att titta på följande filer i utdatakatalogen:

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

Dessa filer innehåller en lista över lyckade och misslyckade åtgärder från batchen. Filformatet är .cvs, där varje rad har radnumret för den ursprungliga indatafilen och utdata för åtgärden (vanligtvis den skapade eller uppdaterade registreringsbeskrivningen).

Fullständig exempelkod

Följande exempelkod importerar registreringar till en meddelandehubb.

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);

        }
    }
}

Exportera

Export av registrering liknar importen, med följande skillnader:

  • Du behöver bara utdata-URL:en.
  • Du skapar ett NotificationHubJob av typen ExportRegistrations.

Exempelkodfragment

Följande är ett exempelkodfragment för export av registreringar i 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;
}

Nästa steg

Mer information om registreringar finns i följande artiklar: