영업: 1-800-867-1380

REST API를 사용하여 대량으로 자산 수집

업데이트 날짜: 2015년 2월

자산을 대량으로 수집, 즉 "대량 수집"하려면 업로드 프로세스에서 자산 만들기를 분리해야 합니다. 이렇게 하는 이유는 큰 자산 파일 업로드가 자산 만들기에 장애물이 되기 때문입니다. 대량 수집을 사용하여 자산과 해당 자산이 연결된 파일을 설명하는 매니페스트(IngestManifest)를 만듭니다. 그런 다음 선택한 업로드 방법을 사용하여 매니페스트의 Blob 컨테이너로 연결된 파일을 업로드합니다. Microsoft Azure 미디어 서비스에서는 파일 업로드를 기다리는 동안 매니페스트에 연결된 Blob 컨테이너를 감시합니다. 파일이 Blob 컨테이너로 업로드되면 Microsoft Azure 미디어 서비스에서는 매니페스트(IngestManifestAsset)의 자산 구성을 기반으로 자산 만들기를 완료합니다.

이 항목에서는 REST API를 사용하여 자산을 대량 수집하는 방법에 대해 설명합니다. Microsoft Azure 미디어 서비스 SDK를 사용하여 자산을 대량으로 수집하는 방법에 대한 자세한 내용은 Ingesting Assets in Bulk을 참조하세요. 자산 수집에 대한 자세한 내용은 Ingest Assets with the Media Services REST API을 참조하세요.

대량 수집의 기본 워크플로는 다음과 같은 섹션으로 구분됩니다.

Important중요
미디어 서비스 REST API를 사용할 때는 다음 사항을 고려해야 합니다.

note참고
미디어 서비스에서는 스트리밍 콘텐츠의 URL 작성 시 IAssetFile.Name 속성의 값을 사용합니다(예: http://{WAMSAccount}.origin.mediaservices.windows.net/{GUID}/{IAssetFile.Name}/streamingParameters). 따라서 퍼센트 인코딩이 허용되지 않습니다. 이름 속성의 값에는 퍼센트 인코딩 예약 문자( !*'();:@ !*'();:@&=+$,/?%#[]")를 사용할 수 없으며, 파일 이름 확장명에 ‘.’를 하나만 사용할 수 있습니다.

IngestManifest는 자산, 자산 파일 및 통계 정보 집합을 위한 컨테이너로, 이러한 집합의 대량 수집 진행률을 결정하는 데 사용할 수 있습니다.

다음 예제 요청은 이 항목의 끝에서 제공되는 예제 코드를 사용하여 생성되었습니다.

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

IngestManifestAsset을 만들기 전에 대량 수집을 사용하여 완료할 자산을 만들어야 합니다. 자산은 비디오, 오디오, 이미지, 미리 보기 컬렉션, 텍스트 트랙 및 닫힌 캡션 파일을 비롯하여 미디어 서비스의 여러 개체 형식 및 집합을 위한 컨테이너입니다. REST API에서 자산을 만들려면 HTTP POST 요청을 Microsoft Azure 미디어 서비스로 보내고 요청 본문에 자산에 대한 속성 정보를 배치해야 합니다. 이 예에서 자산은 요청 본문에 포함된 StorageEncrption(1) 옵션을 사용하여 만듭니다.

다음 예제 요청은 이 항목의 끝에서 제공되는 예제 코드를 사용하여 생성되었습니다.

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 }

IngestManifestAssets는 IngestManifest 내에 대량 수집과 함께 사용되는 자산을 나타냅니다 기본적으로 자산을 매니페스트에 연결합니다. Microsoft Azure 미디어 서비스는 IngestManifestAsset에 연결된 IngestManifestFiles 컬렉션을 기반으로 파일 업로드를 내부적으로 감시합니다. 이러한 파일이 업로드되면 자산이 완료됩니다. HTTP POST 요청을 사용하여 새 IngestManifestAsset을 만들 수 있습니다. 요청 본문에 대량 수집을 위해 IngestManifestAsset이 함께 연결해야 하는 IngestManifest ID와 자산 ID를 포함합니다.

다음 예제 요청은 이 항목의 끝에서 제공되는 예제 코드를 사용하여 생성되었습니다.

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

자산이 암호화를 사용하는 경우 자산의 IngestManifestFiles를 만들기 전에 ContentKey를 만들어 암호화에 사용해야 합니다. 암호화를 사용할 필요가 없는 경우 이 섹션을 건너뛸 수 있습니다. 위에서 만든 예제 자산에서는 StorageEncryption을 사용하므로 자산에 대한 ContentKey 만들기를 보여 줍니다. 자산을 위한 새 ContentKey를 만들기 위해 HTTP POST 요청을 보냅니다. 요청 본문에는 다음 속성이 포함됩니다.

 

요청 본문 속성 설명

Id

'nb:kid:UUID:<NEW GUID>' 형식을 사용하여 직접 생성한 ContentKey ID입니다.

ContentKeyType

이 콘텐츠 키에 대해서는 정수인 콘텐츠 키 형식입니다. 저장소 암호화를 위해 값 1을 전달합니다.

EncryptedContentKey

256비트(32바이트) 값인 새 콘텐츠 키 값을 만듭니다. 이 키는 저장소 암호화 X.509 인증서를 사용하여 암호화됩니다. 이 인증서는 GetProtectionKeyIdGetProtectionKey 메서드에 대한 HTTP GET 요청을 실행하여 Microsoft Azure 미디어 서비스에서 검색합니다.

ProtectionKeyId

콘텐츠 키 암호화에 사용한 저장소 암호화 X.509 인증서의 보호 키 ID입니다.

ProtectionKeyType

콘텐츠 키 암호화에 사용한 보호 키의 암호화 형식입니다. 이 예에서 이 값은 StorageEncryption(1)입니다.

Checksum

MD5에서는 콘텐츠 키의 체크섬을 계산했습니다. 콘텐츠 키를 사용하여 콘텐츠 ID를 암호화하여 계산합니다. 예제 코드는 체크섬을 계산하는 방법을 보여 줍니다.

x.509 인증서를 사용한 자산 암호화에 대한 자세한 내용은 자산 암호화(선택 사항)를 참조하세요.

다음 예제 요청은 이 항목의 끝에서 제공되는 예제 코드를 사용하여 생성되었습니다.

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=" }

ContentKey는 HTTP POST 요청을 보내 자산 하나 이상에 연결됩니다. 다음 요청은 예제 ContentKey를 ID별로 예제 자산에 연결하는 예제입니다.

다음 예제 요청은 이 항목의 끝에서 제공되는 예제 코드를 사용하여 생성되었습니다.

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')"}

IngestManifestFile은 자산 대량 수집의 일환으로 업로드할 실제 비디오 또는 오디오 Blob 개체를 나타냅니다. 자산이 암호화 옵션을 사용하지 않는 경우 암호화 관련 속성은 필요하지 않습니다. 이 섹션에서 사용되는 예제는 이전에 만든 자산에 StorageEncryption을 사용하는 IngestManifestFile 만들기를 보여 줍니다.

다음 예제 요청은 이 항목의 끝에서 제공되는 예제 코드를 사용하여 생성되었습니다.

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

IngestManifest의 BlobStorageUriForUpload 속성에서 제공하는 Blob 저장소 컨테이너 URI에 자산 파일을 업로드할 수 있는 모든 고속 클라이언트 응용 프로그램을 사용할 수 있습니다. 눈에 띄는 고속 업로드 서비스 중 하나는 Aspera On Demand for Azure Application입니다.

IngestManifest의 통계 속성을 폴링하여 IngestManifest의 대량 수집 작업의 진행률을 모니터링할 수 있습니다. 이 속성은 복합 형식 IngestManifestStatistics입니다. 통계 속성을 폴링하려면 IngestManifest ID를 전달하는 HTTP GET 요청을 제출합니다.

다음 예제 요청은 이 항목의 끝에서 제공되는 예제 코드를 사용하여 생성되었습니다.

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

이 예제 코드에는 다음 어셈블리에 대한 참조가 필요합니다. 프로젝트 설정에서 대상 프레임워크.NET Framework 4로 설정되어 있습니다.

  • 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 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 + "\"}");
    }
  }
}

참고 항목

이 정보가 도움이 되었습니까?
(1500자 남음)
의견을 주셔서 감사합니다.
Microsoft는 MSDN 웹 사이트에 대한 귀하의 의견을 이해하기 위해 온라인 설문 조사를 진행하고 있습니다. 참여하도록 선택하시면 MSDN 웹 사이트에서 나가실 때 온라인 설문 조사가 표시됩니다.

참여하시겠습니까?
표시:
© 2015 Microsoft