Exportar (0) Imprimir
Expandir todo
Este tema aún no ha recibido ninguna valoración - Valorar este tema

Ingesta en bloque de recursos con la API de REST

Actualizado: febrero de 2014

La ingesta de recursos en bloque o “ingesta en bloque” implica la separación de la creación de recursos del proceso de carga. El motivo es que, al cargar archivos de recursos de gran tamaño, se producen cuellos de botella en la creación de recursos. Al usar el enfoque de la ingesta en bloque, se crea un manifiesto (IngestManifest) que describe el recurso y sus archivos asociados. A continuación, puede usar el método de carga que prefiera para cargar los archivos asociados en el contenedor blob del manifiesto. Servicios multimedia de Windows Azure observa el contenedor blob asociado al manifiesto a la espera de las cargas de archivos. Después de cargar un archivo en el contenedor blob, Servicios multimedia de Windows Azure completa la creación de recursos de acuerdo con la configuración del recurso en el manifiesto (IngestManifestAsset).

En este tema se describe la ingesta en bloque de recursos mediante la API de REST. Para obtener información sobre la ingesta en bloque de recursos mediante el SDK de Servicios multimedia de Windows Azure, consulte Introducción de recursos en bloque con el SDK de Media Services para .NET. Para obtener más información sobre la ingesta en bloque, consulte Introducción de recursos con la API de REST de Media Services.

El flujo de trabajo básico para la ingesta en bloque se divide en las secciones siguientes:

ImportantImportante
Después de conectarse correctamente a https://media.windows.net, recibirá una redirección 301 que especifica otro URI de Servicios multimedia. Debe realizar llamadas subsecuentes a la nueva URI.

Creación de IngestManifest

IngestManifest es un contenedor para un conjunto de recursos, archivos de recursos e información estadística que se puede usar para determinar el progreso de la ingesta en bloque del conjunto.

Solicitud de ejemplo

La solicitud de ejemplo siguiente se generó con el código de ejemplo que se proporciona al final de este tema.

POST https:// media.windows.net/API/IngestManifests HTTP/1.1
Content-Type: application/json;odata=verbose
Accept: application/json;odata=verbose
DataServiceVersion: 3.0
MaxDataServiceVersion: 3.0
x-ms-version: 2.5
Authorization: Bearer http%3a%2f%2fschemas.xmlsoap.org%2fws%2f2005%2f05%2fidentity%2fclaims%2fnameidentifier=070500D0-F35C-4A5A-9249-485BBF4EC70B&http%3a%2f%2fschemas.microsoft.com%2faccesscontrolservice%2f2010%2f07%2fclaims%2fidentityprovider=https%3a%2f%2fwamsprodglobal001acs.accesscontrol.windows.net%2f&Audience=urn%3aWindowsAzureMediaServices&ExpiresOn=1334275521&Issuer=https%3a%2f%2fwamsprodglobal001acs.accesscontrol.windows.net%2f&HMACSHA256=GxdBb%2fmEyN7iHdNxbawawHRftLhPFFqxX1JZckuv3hY%3d
Host: media.windows.net
Content-Length: 36
Expect: 100-continue

{ "Name" : "ExampleManifestREST" }

Creación de los recursos

Antes de crear IngestManifestAsset, debe crear el Asset que se completará mediante la ingesta en bloque. Un recurso es un contenedor de varios tipos o conjuntos de objetos de Media Services, como vídeo, audio, imágenes, colecciones de miniaturas, pistas de texto y archivos de subtítulos. En la API de REST, para crear un Asset, es necesario enviar una solicitud HTTP POST a Servicios multimedia de Windows Azure y especificar cualquier información sobre las propiedades del recurso en el cuerpo de la solicitud. En este ejemplo, el Asset se crea mediante la opción StorageEncrption(1) que se incluye en el cuerpo de la solicitud.

Solicitud de ejemplo

La solicitud de ejemplo siguiente se generó con el código de ejemplo que se proporciona al final de este tema.

POST https://media.windows.net/API/Assets HTTP/1.1
Content-Type: application/json;odata=verbose
Accept: application/json;odata=verbose
DataServiceVersion: 3.0
MaxDataServiceVersion: 3.0
x-ms-version: 2.5
Authorization: Bearer http%3a%2f%2fschemas.xmlsoap.org%2fws%2f2005%2f05%2fidentity%2fclaims%2fnameidentifier=070500D0-F35C-4A5A-9249-485BBF4EC70B&http%3a%2f%2fschemas.microsoft.com%2faccesscontrolservice%2f2010%2f07%2fclaims%2fidentityprovider=https%3a%2f%2fwamsprodglobal001acs.accesscontrol.windows.net%2f&Audience=urn%3aWindowsAzureMediaServices&ExpiresOn=1334275521&Issuer=https%3a%2f%2fwamsprodglobal001acs.accesscontrol.windows.net%2f&HMACSHA256=GxdBb%2fmEyN7iHdNxbawawHRftLhPFFqxX1JZckuv3hY%3d
Host: media.windows.net
Content-Length: 55
Expect: 100-continue

{ "Name" : "ExampleManifestREST_Asset", "Options" : 1 }

Creación de IngestManifestAssets

Los IngestManifestAssets representan Assets de IngestManifest que se usan con la ingesta en bloque. Básicamente, vinculan el recurso al manifiesto. Servicios multimedia de Windows Azure observa internamente la carga de archivos a partir de la colección de IngestManifestFiles asociada al IngestManifestAsset. Una vez cargados los archivos, el recurso está completo. Puede crear un nuevo IngestManifestAsset con una solicitud HTTP POST. En el cuerpo del mensaje, incluya el identificador de IngestManifest y el de Asset que IngestManifestAsset debe vincular para la ingesta en bloque.

Solicitud de ejemplo

La solicitud de ejemplo siguiente se generó con el código de ejemplo que se proporciona al final de este tema.

POST https://media.windows.net/API/IngestManifestAssets HTTP/1.1
Content-Type: application/json;odata=verbose
Accept: application/json;odata=verbose
DataServiceVersion: 3.0
MaxDataServiceVersion: 3.0
x-ms-version: 2.5
Authorization: Bearer http%3a%2f%2fschemas.xmlsoap.org%2fws%2f2005%2f05%2fidentity%2fclaims%2fnameidentifier=070500D0-F35C-4A5A-9249-485BBF4EC70B&http%3a%2f%2fschemas.microsoft.com%2faccesscontrolservice%2f2010%2f07%2fclaims%2fidentityprovider=https%3a%2f%2fwamsprodglobal001acs.accesscontrol.windows.net%2f&Audience=urn%3aWindowsAzureMediaServices&ExpiresOn=1334275521&Issuer=https%3a%2f%2fwamsprodglobal001acs.accesscontrol.windows.net%2f&HMACSHA256=GxdBb%2fmEyN7iHdNxbawawHRftLhPFFqxX1JZckuv3hY%3d
Host: media.windows.net
Content-Length: 152
Expect: 100-continue
{ "ParentIngestManifestId" : "nb:mid:UUID:5c77f186-414f-8b48-8231-17f9264e2048", "Asset" : { "Id" : "nb:cid:UUID:b757929a-5a57-430b-b33e-c05c6cbef02e"}}

Creación opcional de ContentKeys para el cifrado

Si el recurso usa cifrado, debe crear la ContentKey que se usará para el cifrado antes de crear IngestManifestFiles para el recurso. Si no necesita usar cifrado, puede omitir esta sección. Dado que usamos StorageEncryption en el recurso de ejemplo anterior, demostraremos la creación de una ContentKey para el recurso. Para crear una nueva ContentKey para el recurso, enviamos una solicitud HTTP POST. En el cuerpo de la solicitud se incluyen las propiedades siguientes.

 

Propiedad del cuerpo de la solicitud Descripción

Id

Identificador de ContentKey que generamos con el formato siguiente: “nb:kid:UUID:<NUEVO GUID>”.

ContentKeyType

Tipo de clave de contenido como entero para esta clave de contenido. Pasamos el valor 1 para el cifrado del almacenamiento.

EncryptedContentKey

Creamos un nuevo valor de clave de contenido de 256 bits (32 bytes). La clave se cifra con el certificado X.509 de cifrado de almacenamiento que recuperamos de Servicios multimedia de Windows Azure al ejecutar una solicitud HTTP GET para los métodos GetProtectionKeyId y GetProtectionKey.

ProtectionKeyId

Identificador de clave de protección del certificado X.509 de cifrado de almacenamiento usado para cifrar la clave de contenido.

ProtectionKeyType

Tipo de cifrado de la clave de protección usado para cifrar la clave de contenido. En nuestro ejemplo, este valor es StorageEncryption(1).

Checksum

Suma de comprobación calculada de MD5 para la clave de contenido. Se calcula cifrando el identificador de contenido con la clave de contenido. El código de ejemplo muestra cómo se calcula la suma de comprobación.

Para obtener más información sobre el cifrado de recursos con un certificado x.509, consulte Cifrado del recurso (opcional).

Ejemplo de creación de solicitud de ContentKey

La solicitud de ejemplo siguiente se generó con el código de ejemplo que se proporciona al final de este tema.

POST https://media.windows.net/api/ContentKeys HTTP/1.1
Content-Type: application/json;odata=verbose
Accept: application/json;odata=verbose
DataServiceVersion: 3.0
MaxDataServiceVersion: 3.0
x-ms-version: 2.5
Authorization: Bearer http%3a%2f%2fschemas.xmlsoap.org%2fws%2f2005%2f05%2fidentity%2fclaims%2fnameidentifier=070500D0-F35C-4A5A-9249-485BBF4EC70B&http%3a%2f%2fschemas.microsoft.com%2faccesscontrolservice%2f2010%2f07%2fclaims%2fidentityprovider=https%3a%2f%2fwamsprodglobal001acs.accesscontrol.windows.net%2f&Audience=urn%3aWindowsAzureMediaServices&ExpiresOn=1334275521&Issuer=https%3a%2f%2fwamsprodglobal001acs.accesscontrol.windows.net%2f&HMACSHA256=GxdBb%2fmEyN7iHdNxbawawHRftLhPFFqxX1JZckuv3hY%3d
Host: media.windows.net
Content-Length: 572
Expect: 100-continue

{"Id" : "nb:kid:UUID:316d14d4-b603-4d90-b8db-0fede8aa48f8", "ContentKeyType" : 1, "EncryptedContentKey" : "Y4NPej7heOFa2vsd8ZEOcjjpu/qOq3RJ6GRfxa8CCwtAM83d6J2mKOeQFUmMyVXUSsBCCOdufmieTKi+hOUtNAbyNM4lY4AXI537b9GaY8oSeje0NGU8+QCOuf7jGdRac5B9uIk7WwD76RAJnqyep6U/OdvQV4RLvvZ9w7nO4bY8RHaUaLxC2u4aIRRaZtLu5rm8GKBPy87OzQVXNgnLM01I8s3Z4wJ3i7jXqkknDy4VkIyLBSQvIvUzxYHeNdMVWDmS+jPN9ScVmolUwGzH1A23td8UWFHOjTjXHLjNm5Yq+7MIOoaxeMlKPYXRFKofRY8Qh5o5tqvycSAJ9KUqfg==", "ProtectionKeyId" : "7D9BB04D9D0A4A24800CADBFEF232689E048F69C", "ProtectionKeyType" : 1, "Checksum" : "TfXtjCIlq1Y=" }

Vínculo de ContentKey a Asset

El valor de ContentKey se asocia a uno o varios recursos a través de una solicitud HTTP POST. La solicitud siguiente es un ejemplo para vincular la ContentKey de ejemplo al recurso de ejemplo por identificador.

Ejemplo de vínculo de solicitud de ContentKey

La solicitud de ejemplo siguiente se generó con el código de ejemplo que se proporciona al final de este tema.

POST https://media.windows.net/API/Assets('nb:cid:UUID:b3023475-09b4-4647-9d6d-6fc242822e68')/$links/ContentKeys HTTP/1.1
Content-Type: application/json;odata=verbose
Accept: application/json;odata=verbose
DataServiceVersion: 3.0
MaxDataServiceVersion: 3.0
x-ms-version: 2.5
Authorization: Bearer http%3a%2f%2fschemas.xmlsoap.org%2fws%2f2005%2f05%2fidentity%2fclaims%2fnameidentifier=070500D0-F35C-4A5A-9249-485BBF4EC70B&http%3a%2f%2fschemas.microsoft.com%2faccesscontrolservice%2f2010%2f07%2fclaims%2fidentityprovider=https%3a%2f%2fwamsprodglobal001acs.accesscontrol.windows.net%2f&Audience=urn%3aWindowsAzureMediaServices&ExpiresOn=1334275521&Issuer=https%3a%2f%2fwamsprodglobal001acs.accesscontrol.windows.net%2f&HMACSHA256=GxdBb%2fmEyN7iHdNxbawawHRftLhPFFqxX1JZckuv3hY%3d
Host: media.windows.net
Content-Length: 113
Expect: 100-continue

{ "uri": "https://media.windows.net/api/ContentKeys('nb%3Akid%3AUUID%3A32e6efaf-5fba-4538-b115-9d1cefe43510')"}

Creación de IngestManifestFiles para cada Asset

Un IngestManifestFile representa un objeto blob de audio o vídeo real que se cargará como parte de la ingesta en bloque para un recurso. Las propiedades relacionadas con el cifrado no son necesarias a menos que el recurso use una opción de cifrado. En el ejemplo de esta sección se demuestra la creación de un IngestManifestFile que usa StorageEncryption para el Asset creado previamente.

Solicitud de ejemplo

La solicitud de ejemplo siguiente se generó con el código de ejemplo que se proporciona al final de este tema.

 POST https://media.windows.net/API/IngestManifestFiles HTTP/1.1
Content-Type: application/json;odata=verbose
Accept: application/json;odata=verbose
DataServiceVersion: 3.0
MaxDataServiceVersion: 3.0
x-ms-version: 2.5
Authorization: Bearer http%3a%2f%2fschemas.xmlsoap.org%2fws%2f2005%2f05%2fidentity%2fclaims%2fnameidentifier=070500D0-F35C-4A5A-9249-485BBF4EC70B&http%3a%2f%2fschemas.microsoft.com%2faccesscontrolservice%2f2010%2f07%2fclaims%2fidentityprovider=https%3a%2f%2fwamsprodglobal001acs.accesscontrol.windows.net%2f&Audience=urn%3aWindowsAzureMediaServices&ExpiresOn=1334275521&Issuer=https%3a%2f%2fwamsprodglobal001acs.accesscontrol.windows.net%2f&HMACSHA256=GxdBb%2fmEyN7iHdNxbawawHRftLhPFFqxX1JZckuv3hY%3d
Host: media.windows.net
Content-Length: 367
Expect: 100-continue

{ "Name" : "REST_Example_File.wmv", "ParentIngestManifestId" : "nb:mid:UUID:5c77f186-414f-8b48-8231-17f9264e2048", "ParentIngestManifestAssetId" : "nb:maid:UUID:beed8531-9a03-9043-b1d8-6a6d1044cdda", "IsEncrypted" : "true", "EncryptionScheme" : "StorageEncryption", "EncryptionVersion" : "1.0", "EncryptionKeyId" : "nb:kid:UUID:32e6efaf-5fba-4538-b115-9d1cefe43510" }

Carga de archivos al almacenamiento blob

Puede usar cualquier aplicación cliente de alta velocidad capaz de cargar los archivos del recurso al URI del contenedor de almacenamiento blob que proporciona la propiedad BlobStorageUriForUpload de IngestManifest. Un servicio de carga destacado de alta velocidad es Aspera On Demand para la aplicación Azure.

Supervisión del progreso de la ingesta en bloque

Puede supervisar el progreso de las operaciones de ingesta en bloque de un IngestManifest. Para ello, haga un sondeo de la propiedad Statistics de IngestManifest. Esta propiedad tiene un tipo complejo, IngestManifestStatistics. Para realizar un sondeo de la propiedad Statistics, envíe una solicitud HTTP GET para pasar el identificador de IngestManifest

Solicitud de ejemplo

La solicitud de ejemplo siguiente se generó con el código de ejemplo que se proporciona al final de este tema.

GET https://media.windows.net/API/IngestManifests('nb:mid:UUID:5c77f186-414f-8b48-8231-17f9264e2048') HTTP/1.1
Content-Type: application/json;odata=verbose
Accept: application/json;odata=verbose
DataServiceVersion: 3.0
MaxDataServiceVersion: 3.0
x-ms-version: 2.5
Authorization: Bearer http%3a%2f%2fschemas.xmlsoap.org%2fws%2f2005%2f05%2fidentity%2fclaims%2fnameidentifier=070500D0-F35C-4A5A-9249-485BBF4EC70B&http%3a%2f%2fschemas.microsoft.com%2faccesscontrolservice%2f2010%2f07%2fclaims%2fidentityprovider=https%3a%2f%2fwamsprodglobal001acs.accesscontrol.windows.net%2f&Audience=urn%3aWindowsAzureMediaServices&ExpiresOn=1334275521&Issuer=https%3a%2f%2fwamsprodglobal001acs.accesscontrol.windows.net%2f&HMACSHA256=GxdBb%2fmEyN7iHdNxbawawHRftLhPFFqxX1JZckuv3hY%3d
Host: media.windows.net

Código de ejemplo

Este código de ejemplo requiere referencias a los ensamblados siguientes. La versión de .NET Framework de destino está definida como .NET Framework 4 en la configuración del proyecto.

  • System.Runtime.Serialization

  • System.Web

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Web;
using System.Runtime.Serialization.Json;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

namespace Microsoft.Samples.RestBulkIngest
{
  class Program
  {

    private static Uri serviceURI = new Uri("https://media.windows.net/API/");
    private static readonly string accessControlURI = "https://wamsprodglobal001acs.accesscontrol.windows.net/v2/OAuth2-13";
    private static readonly string clientSecret = ""; // Fill in your client secret/passcode here.
    private static readonly string clientId = ""; // Fill in your client ID here
    private static readonly string scope = "WindowsAzureMediaServices";

    private static string token = null;


    static void Main(string[] args)
    {
      //===[ Retrieves an ACS token ]=============================================================//
      token = GetACSToken(accessControlURI, clientId, clientSecret, scope);

      //===[ Create a named IngestManifest ]======================================================//
      Console.WriteLine("\n===============================================");
      Console.WriteLine("========[ CREATE BULK INGEST MANIFEST ]========");
      Console.WriteLine("===============================================");
      XmlDocument xmlManifestDoc = CreateIngestManifest("ExampleManifestREST");
      string manifestId = xmlManifestDoc.GetElementsByTagName("Id")[0].InnerText;


      //===[ Create an StorageEncryption Asset for bulk ingesting ]===============================//
      Console.WriteLine("\n===============================================");
      Console.WriteLine("================[ CREATE ASSET ]===============");
      Console.WriteLine("===============================================");
      XmlDocument assetXmlResponse = CreateAsset("ExampleManifestREST_Asset", "1");
      string assetId = assetXmlResponse.GetElementsByTagName("Id")[0].InnerText;


      //===[ Create an IngestManifestAsset to link the asset to the manifest ]====================//
      Console.WriteLine("\n===============================================");
      Console.WriteLine("=======[ CREATE INGEST MANIFEST ASSET ]========");
      Console.WriteLine("===============================================");
      XmlDocument xmlManifestAssetDoc = CreateIngestManifestAsset(manifestId, assetId);
      string manifestAssetId = xmlManifestAssetDoc.GetElementsByTagName("Id")[0].InnerText;


      //===[ Create a ContentKey for encryption ]==================================================//
      Console.WriteLine("\n===============================================");
      Console.WriteLine("============[ CREATE CONTENT KEY ]=============");
      Console.WriteLine("===============================================");
      int storageEncryptionType = 1;
      XmlDocument xmlContentKey = CreateContentKey(storageEncryptionType);
      string contentKeyId = xmlContentKey.GetElementsByTagName("Id")[0].InnerText;


      //===[ Link the ContentKey to the Asset for encryption ]=====================================//
      Console.WriteLine("\n===============================================");
      Console.WriteLine("==========[ LINK CONTENTKET TO ASSET ]=========");
      Console.WriteLine("===============================================");
      LinkContentKeyToAsset(assetId, xmlContentKey.GetElementsByTagName("uri")[0].InnerText);


      //===[ Create the IngestManifestFile so that Windows Azure Media Service knows what ]========//
      //===[ files to look for in the blob container associated to the manifest.          ]========//
      Console.WriteLine("\n===============================================");
      Console.WriteLine("========[ CREATE INGEST MANIFEST FILE ]========");
      Console.WriteLine("===============================================");
      CreateIngestManifestFile(manifestId, manifestAssetId, "REST_Example_File.wmv", contentKeyId);


      //===[ Poll the IngestManifest Statistics property for bulk ingress progress ]===============//
      Console.WriteLine("\n===============================================");
      Console.WriteLine("======[ POLL INGEST MANIFEST STATISTICS ]======");
      Console.WriteLine("===============================================");
      PollIngestManifestStatisticsToCompletion(manifestId);
    }



    private static string GetACSToken(string accessControlUri, string clientId, string clientSecret, string scope)
    {
      HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(accessControlUri);
      request.Method = "POST";
      request.ContentType = "application/x-www-form-urlencoded";
      request.KeepAlive = true;
      string token = null;

      //Note: You need to insert your client Id and secret into this string in order for it to work.
      var requestBytes = Encoding.ASCII.GetBytes("grant_type=client_credentials&client_id=" + clientId + "&client_secret=" + HttpUtility.UrlEncode(clientSecret) + "&scope=urn%3a" + scope);
      request.ContentLength = requestBytes.Length;

      var requestStream = request.GetRequestStream();
      requestStream.Write(requestBytes, 0, requestBytes.Length);
      requestStream.Close();

      var response = (HttpWebResponse)request.GetResponse();

      if (response.StatusCode == HttpStatusCode.OK)
      {
        using (Stream responseStream = response.GetResponseStream())
        {
          using (StreamReader stream = new StreamReader(responseStream))
          {
            string responseString = stream.ReadToEnd();
            var reader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(responseString), new XmlDictionaryReaderQuotas());

            while (reader.Read())
            {
              if ((reader.Name == "access_token") && (reader.NodeType == XmlNodeType.Element))
              {
                if (reader.Read())
                {
                  token = reader.Value;
                  break;
                }
              }
            }
          }
        }
      }

      return token;
    }



    private static XmlDocument GenerateRequestAndGetResponse(string verb, string resourcePath, string query, string requestbody)
    {
      var uriBuilder = new UriBuilder(serviceURI);
      uriBuilder.Path += resourcePath;
      if (query != null)
      {
        uriBuilder.Query = query;
      }
      HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uriBuilder.Uri);
      request.Method = verb;
      request.AllowAutoRedirect = false;

      if (resourcePath == "$metadata")
        request.MediaType = "application/xml";
      else
      {
        request.ContentType = "application/json;odata=verbose";
        request.Accept = "application/json;odata=verbose";
      }

      // Uncomment when Media Services supports the JSON OData light.
      //request.ContentType = "application/json;odata=light";
      //request.Accept = "application/json;odata=light";

      request.Headers.Add("DataServiceVersion", "3.0");
      request.Headers.Add("MaxDataServiceVersion", "3.0");
      request.Headers.Add("x-ms-version", "2.5");
      request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + token);

      if (requestbody != null)
      {
        var requestBytes = Encoding.ASCII.GetBytes(requestbody);
        request.ContentLength = requestBytes.Length;

        var requestStream = request.GetRequestStream();
        requestStream.Write(requestBytes, 0, requestBytes.Length);
        requestStream.Close();
      }
      else
      {
        request.ContentLength = 0;
      }

      XmlDocument xmlResponse = null;

      try
      {
        // Generate HTTP request and pass in JSON defining the Asset's name.    
        var response = (HttpWebResponse)request.GetResponse();

        //TODO: Put in retry logic if token has expired.
        switch (response.StatusCode)
        {
          case HttpStatusCode.MovedPermanently:
            serviceURI = new Uri(response.Headers["Location"]);
            xmlResponse = GenerateRequestAndGetResponse(verb, resourcePath, query, requestbody);
            break;
          case HttpStatusCode.Created:
          case HttpStatusCode.OK:
            using (Stream responseStream = response.GetResponseStream())
            {
              using (StreamReader stream = new StreamReader(responseStream))
              {
                string responseString = stream.ReadToEnd();
                var reader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(responseString), new XmlDictionaryReaderQuotas());

                xmlResponse = new XmlDocument();
                reader.Read();
                xmlResponse.LoadXml(reader.ReadInnerXml());
              }
            }
            break;

          default:
            Console.WriteLine(response.StatusDescription);
            break;
        }
      }
      catch (WebException ex)
      {
        Console.WriteLine(ex.Message);
      }

      return xmlResponse;
    }


    private static XmlDocument CreateAsset(string name, string options = null)
    {
      XmlDocument assetXmlResponse = null;

      string requestbody;

      if (options != null)
      {
        requestbody = "{ \"Name\" : \"" + name + "\", \"Options\" : " + options + " }";
      }
      else
      {
        requestbody = "{ \"Name\" : \"" + name + "\" }";
      }


      // Generate HTTP request and pass in JSON defining the Asset's name.    
      assetXmlResponse = GenerateRequestAndGetResponse("POST", "Assets", null, requestbody);

      Console.WriteLine("\nAsset Id: {0}", assetXmlResponse.GetElementsByTagName("Id")[0].InnerText);
      Console.WriteLine("Name: {0}", assetXmlResponse.GetElementsByTagName("Name")[0].InnerText);
      Console.WriteLine("State: {0}", assetXmlResponse.GetElementsByTagName("State")[0].InnerText);
      Console.WriteLine("Options: {0}", assetXmlResponse.GetElementsByTagName("Options")[0].InnerText);

      return assetXmlResponse;
    }


    private static XmlDocument CreateIngestManifest(string name)
    {
      XmlDocument manifestXmlResponse = null;

      manifestXmlResponse = GenerateRequestAndGetResponse("POST", "IngestManifests", null, "{ \"Name\" : \"" + name + "\" }");

      Console.WriteLine("\nManifest Id: {0}", manifestXmlResponse.GetElementsByTagName("Id")[0].InnerText);
      Console.WriteLine("Name: {0}", manifestXmlResponse.GetElementsByTagName("Name")[0].InnerText);
      Console.WriteLine("State: {0}", manifestXmlResponse.GetElementsByTagName("State")[0].InnerText);

      return manifestXmlResponse;
    }


    private static XmlDocument CreateIngestManifestAsset(string manifestId, string assetId)
    {
      XmlDocument manifestAssetXmlResponse = null;

      string requestbody;

      requestbody = "{ \"ParentIngestManifestId\": \"" + manifestId + "\", " +
                      "\"Asset\" : { \"Id\": \"" + assetId + "\" } }";


      // Generate HTTP request and pass in JSON defining the Asset's Id and the Manifest Id.    
      manifestAssetXmlResponse = GenerateRequestAndGetResponse("POST", "IngestManifestAssets", null, requestbody);

      Console.WriteLine("\nIngestManifestAsset Id: {0}", manifestAssetXmlResponse.GetElementsByTagName("Id")[0].InnerText);
      Console.WriteLine("ParentIngestManifest Id: {0}", manifestAssetXmlResponse.GetElementsByTagName("ParentIngestManifestId")[0].InnerText);

      return manifestAssetXmlResponse;
    }


    private static XmlDocument CreateIngestManifestFile(string manifestId, string manifestAssetId, string fileName, string encryptionKeyId = null)
    {
      XmlDocument manifestAssetFileXmlResponse = null;

      string requestbody;

      if (encryptionKeyId == null)
      {
        requestbody = "{ \"Name\" : \"" + fileName + "\", " +
        "\"ParentIngestManifestId\" : \"" + manifestId + "\", " +
        "\"ParentIngestManifestAssetId\" : \"" + manifestAssetId + "\" " +
        "}";
      }
      else
      {
        requestbody = "{ \"Name\" : \"" + fileName + "\", " +
        "\"ParentIngestManifestId\" : \"" + manifestId + "\", " +
        "\"ParentIngestManifestAssetId\" : \"" + manifestAssetId + "\", " +
        "\"IsEncrypted\" : \"true\", " +
        "\"EncryptionScheme\" : \"StorageEncryption\", " +
        "\"EncryptionVersion\" : \"1.0\", " +
        "\"EncryptionKeyId\" : \"" + encryptionKeyId + "\" " +
        "}";
      }


      // Generate HTTP request and pass in JSON defining the Asset's name.    
      manifestAssetFileXmlResponse = GenerateRequestAndGetResponse("POST", "IngestManifestFiles", null, requestbody);

      Console.WriteLine("\nIngestManifestFile Id: {0}", manifestAssetFileXmlResponse.GetElementsByTagName("Id")[0].InnerText);

      return manifestAssetFileXmlResponse;
    }


    private static XmlDocument GetEntity(string resourcePath, string query = null)
    {
      XmlDocument xmlResponse = null;

      xmlResponse = GenerateRequestAndGetResponse("GET", resourcePath, query, null);

      return xmlResponse;
    }


    private static void PollIngestManifestStatisticsToCompletion(string manifestId)
    {
      int pollInterval = 30000; // ms

      Console.WriteLine("\nBulk Ingest Statistics Polling Interval : {0} sec.\n", pollInterval / 1000);

      bool bContinue = true;

      while (bContinue)
      {
        XmlDocument manifest = GetEntity("IngestManifests('" + manifestId + "')");

        Console.WriteLine("Waiting on all file uploads.");
        Console.WriteLine("PendingFilesCount: " + manifest.GetElementsByTagName("PendingFilesCount")[0].InnerText);
        Console.WriteLine("FinishedFilesCount: " + manifest.GetElementsByTagName("FinishedFilesCount")[0].InnerText);
        Console.WriteLine("ErrorFilesCount: " + manifest.GetElementsByTagName("ErrorFilesCount")[0].InnerText);
        Console.WriteLine("ErrorFilesDetails: {0}\n", manifest.GetElementsByTagName("ErrorFilesDetails")[0].InnerText);

        if (Convert.ToInt32(manifest.GetElementsByTagName("PendingFilesCount")[0].InnerText) == 0)
          bContinue = false;
        else
          System.Threading.Thread.Sleep(pollInterval);
      }
    }



    private static XmlDocument CreateContentKey(int encryptionType)
    {
      XmlDocument contentKeyXmlResponse = null;

      AesCryptoServiceProvider myAes = new AesCryptoServiceProvider();

      // This value of myAes.Key will be the 256 byte content key that must be used for encrypting the file before upload. //
      byte[] contentKey = myAes.Key;
      Console.WriteLine("\nUnencrypted content key : {0}\n", Convert.ToBase64String(contentKey));

      if (encryptionType != 1)
        return null;

      //===[ Get the protection key Id for StorageEncryption(1) X.509 certificate ]=================================//
      XmlDocument xmlProtectionKeyId = GetEntity("GetProtectionKeyId", "contentKeyType=" + encryptionType.ToString());
      string protectionKeyId = xmlProtectionKeyId.GetElementsByTagName("GetProtectionKeyId")[0].InnerText;

      //===[ Get the protection key for StorageEncryption(1) X.509 certificate ]==============================//
      XmlDocument xmlProtectionKey = GetEntity("GetProtectionKey", "ProtectionKeyId='" + protectionKeyId + "'");

      //===[ use the X509Certificate2 class to create a RSACryptoServiceProvider to use for encryption ]===//
      string certString = xmlProtectionKey.GetElementsByTagName("GetProtectionKey")[0].InnerText;
      byte[] certBytes = Convert.FromBase64String(certString);
      X509Certificate2 certToUse = new X509Certificate2(certBytes);
      var rsaProvider = (RSACryptoServiceProvider)certToUse.PublicKey.Key;

      //===[ Encrypt the content key using the RSACryptoServiceProvider ]=============================//
      string encryptedContentKey = Convert.ToBase64String(rsaProvider.Encrypt(contentKey, false));
      Console.WriteLine("Encrypted content key : {0}\n", encryptedContentKey);

      //===[ NOTE: ContentKey has user-defined Id value ]===//
      var contentKeyGuidId = Guid.NewGuid();

      //===[ Generate a MD5 checksum of the 
      string checkSumMD5 = CalculateContentKeyChecksum(contentKey, contentKeyGuidId);

      string requestBody = "{\"Id\" : \"nb:kid:UUID:" + contentKeyGuidId + "\", " +
                            "\"ContentKeyType\" : 1, " +
                            "\"EncryptedContentKey\" : \"" + encryptedContentKey + "\", " +
                            "\"ProtectionKeyId\" : \"" + protectionKeyId + "\", " +
                            "\"ProtectionKeyType\" : " + encryptionType.ToString() + ", " +
                            "\"Checksum\" : \"" + checkSumMD5 + "\" }";

      contentKeyXmlResponse = GenerateRequestAndGetResponse("POST", "ContentKeys", null, requestBody);

      string contentKeyId = contentKeyXmlResponse.GetElementsByTagName("Id")[0].InnerText;
      Console.WriteLine("ContentKey Id: {0}\n", contentKeyId);

      // From __metadata uri element...
      string contentKeyUri = contentKeyXmlResponse.GetElementsByTagName("uri")[0].InnerText;
      Console.WriteLine("__metadata uri : {0}", contentKeyUri);

      return contentKeyXmlResponse;
    }


    public static string CalculateContentKeyChecksum(byte[] contentKey, Guid keyId)
    {
      const int ChecksumLength = 8;
      const int KeyIdLength = 16;

      byte[] encryptedKeyId = null;

      // Checksum is computed by AES-ECB encrypting the KID
      // with the content key.
      using (AesCryptoServiceProvider rijndael = new AesCryptoServiceProvider())
      {
        rijndael.Mode = CipherMode.ECB;
        rijndael.Key = contentKey;
        rijndael.Padding = PaddingMode.None;

        ICryptoTransform encryptor = rijndael.CreateEncryptor();
        encryptedKeyId = new byte[KeyIdLength];
        encryptor.TransformBlock(keyId.ToByteArray(), 0, KeyIdLength, encryptedKeyId, 0);
      }

      byte[] retVal = new byte[ChecksumLength];
      Array.Copy(encryptedKeyId, retVal, ChecksumLength);

      return Convert.ToBase64String(retVal);
    }


    private static void LinkContentKeyToAsset(string assetId, string contentKeyUri)
    {
      XmlDocument xmlResponse = GenerateRequestAndGetResponse("POST", "Assets('" + assetId + "')/$links/ContentKeys", null, "{ \"uri\": \"" + contentKeyUri + "\"}");
    }
  }
}

Vea también


Fecha de compilación:

2014-04-03
¿Te ha resultado útil?
(Caracteres restantes: 1500)
Gracias por sus comentarios

Adiciones de comunidad

AGREGAR
Mostrar:
© 2014 Microsoft. Reservados todos los derechos.