diff --git a/.gitignore b/.gitignore index 42c421b1..7e5b79c4 100644 --- a/.gitignore +++ b/.gitignore @@ -64,3 +64,8 @@ test/net/Scenario/App.IncrementVersion.config test/net/Scenario/App.IncrementVersion.config test/net/Scenario/App.Coverage.config test/net/Scenario/App.Release.config +/test/net/stress/App.Debug.config +/test/net/stress/app.Release.config +/SDK.Client.sln.GhostDoc.xml +/test/net/Scenario/App.Stage.config +/test/net/Scenario/App.LKG.config diff --git a/.nuget/windowsazure.mediaservices.nuspec b/.nuget/windowsazure.mediaservices.nuspec index eaedf7d9..ee36c1c9 100644 --- a/.nuget/windowsazure.mediaservices.nuspec +++ b/.nuget/windowsazure.mediaservices.nuspec @@ -2,7 +2,7 @@ windowsazure.mediaservices - 3.0.0.7 + 3.0.0.8 Windows Azure Media Services .NET SDK Microsoft Corporation Microsoft Corporation @@ -10,7 +10,7 @@ http://aka.ms/wamsmsdn http://nimbuspmteam.blob.core.windows.net/nuget/Media Services 150.png true - This package contains Windows Azure Media Service library 3.0.0.7 for .NET. + This package contains Windows Azure Media Service library 3.0.0.8 for .NET. For more information, please check our forum: http://social.msdn.microsoft.com/Forums/en-US/MediaServices/threads For MSDN documentation please visit http://aka.ms/wamsmsdn diff --git a/SDK.Client.sln b/SDK.Client.sln index 80fb90a9..61d6645a 100644 --- a/SDK.Client.sln +++ b/SDK.Client.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 -VisualStudioVersion = 12.0.30110.0 +VisualStudioVersion = 12.0.30501.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDK.Client", "src\net\Client\SDK.Client.csproj", "{E194B46E-9063-4CFA-85FC-51E5AAD55586}" EndProject @@ -39,6 +39,9 @@ Global Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 + Stage|Any CPU = Stage|Any CPU + Stage|x64 = Stage|x64 + Stage|x86 = Stage|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {E194B46E-9063-4CFA-85FC-51E5AAD55586}.Coverage|Any CPU.ActiveCfg = Coverage|Any CPU @@ -65,6 +68,12 @@ Global {E194B46E-9063-4CFA-85FC-51E5AAD55586}.Release|x64.Build.0 = Release|x64 {E194B46E-9063-4CFA-85FC-51E5AAD55586}.Release|x86.ActiveCfg = Release|x86 {E194B46E-9063-4CFA-85FC-51E5AAD55586}.Release|x86.Build.0 = Release|x86 + {E194B46E-9063-4CFA-85FC-51E5AAD55586}.Stage|Any CPU.ActiveCfg = Stage|Any CPU + {E194B46E-9063-4CFA-85FC-51E5AAD55586}.Stage|Any CPU.Build.0 = Stage|Any CPU + {E194B46E-9063-4CFA-85FC-51E5AAD55586}.Stage|x64.ActiveCfg = Stage|x64 + {E194B46E-9063-4CFA-85FC-51E5AAD55586}.Stage|x64.Build.0 = Stage|x64 + {E194B46E-9063-4CFA-85FC-51E5AAD55586}.Stage|x86.ActiveCfg = Stage|x86 + {E194B46E-9063-4CFA-85FC-51E5AAD55586}.Stage|x86.Build.0 = Stage|x86 {8713AE4E-44F6-41AA-B8DC-CD1236F484CD}.Coverage|Any CPU.ActiveCfg = Coverage|Any CPU {8713AE4E-44F6-41AA-B8DC-CD1236F484CD}.Coverage|Any CPU.Build.0 = Coverage|Any CPU {8713AE4E-44F6-41AA-B8DC-CD1236F484CD}.Coverage|x64.ActiveCfg = Coverage|x64 @@ -89,6 +98,12 @@ Global {8713AE4E-44F6-41AA-B8DC-CD1236F484CD}.Release|x64.Build.0 = Release|x64 {8713AE4E-44F6-41AA-B8DC-CD1236F484CD}.Release|x86.ActiveCfg = Release|x86 {8713AE4E-44F6-41AA-B8DC-CD1236F484CD}.Release|x86.Build.0 = Release|x86 + {8713AE4E-44F6-41AA-B8DC-CD1236F484CD}.Stage|Any CPU.ActiveCfg = Stage|Any CPU + {8713AE4E-44F6-41AA-B8DC-CD1236F484CD}.Stage|Any CPU.Build.0 = Stage|Any CPU + {8713AE4E-44F6-41AA-B8DC-CD1236F484CD}.Stage|x64.ActiveCfg = Stage|x64 + {8713AE4E-44F6-41AA-B8DC-CD1236F484CD}.Stage|x64.Build.0 = Stage|x64 + {8713AE4E-44F6-41AA-B8DC-CD1236F484CD}.Stage|x86.ActiveCfg = Stage|x86 + {8713AE4E-44F6-41AA-B8DC-CD1236F484CD}.Stage|x86.Build.0 = Stage|x86 {19DA48B7-6C3C-4B2C-8789-1CC9CCBDA4C7}.Coverage|Any CPU.ActiveCfg = Release|Any CPU {19DA48B7-6C3C-4B2C-8789-1CC9CCBDA4C7}.Coverage|Any CPU.Build.0 = Release|Any CPU {19DA48B7-6C3C-4B2C-8789-1CC9CCBDA4C7}.Coverage|x64.ActiveCfg = Release|Any CPU @@ -105,6 +120,10 @@ Global {19DA48B7-6C3C-4B2C-8789-1CC9CCBDA4C7}.Release|Any CPU.Build.0 = Release|Any CPU {19DA48B7-6C3C-4B2C-8789-1CC9CCBDA4C7}.Release|x64.ActiveCfg = Release|Any CPU {19DA48B7-6C3C-4B2C-8789-1CC9CCBDA4C7}.Release|x86.ActiveCfg = Release|Any CPU + {19DA48B7-6C3C-4B2C-8789-1CC9CCBDA4C7}.Stage|Any CPU.ActiveCfg = Stage|Any CPU + {19DA48B7-6C3C-4B2C-8789-1CC9CCBDA4C7}.Stage|Any CPU.Build.0 = Stage|Any CPU + {19DA48B7-6C3C-4B2C-8789-1CC9CCBDA4C7}.Stage|x64.ActiveCfg = Stage|Any CPU + {19DA48B7-6C3C-4B2C-8789-1CC9CCBDA4C7}.Stage|x86.ActiveCfg = Stage|Any CPU {04DB0E20-008C-45EF-B427-B6F33B25CD67}.Coverage|Any CPU.ActiveCfg = Release|Any CPU {04DB0E20-008C-45EF-B427-B6F33B25CD67}.Coverage|Any CPU.Build.0 = Release|Any CPU {04DB0E20-008C-45EF-B427-B6F33B25CD67}.Coverage|x64.ActiveCfg = Release|Any CPU @@ -121,6 +140,10 @@ Global {04DB0E20-008C-45EF-B427-B6F33B25CD67}.Release|Any CPU.Build.0 = Release|Any CPU {04DB0E20-008C-45EF-B427-B6F33B25CD67}.Release|x64.ActiveCfg = Release|Any CPU {04DB0E20-008C-45EF-B427-B6F33B25CD67}.Release|x86.ActiveCfg = Release|Any CPU + {04DB0E20-008C-45EF-B427-B6F33B25CD67}.Stage|Any CPU.ActiveCfg = Stage|Any CPU + {04DB0E20-008C-45EF-B427-B6F33B25CD67}.Stage|Any CPU.Build.0 = Stage|Any CPU + {04DB0E20-008C-45EF-B427-B6F33B25CD67}.Stage|x64.ActiveCfg = Stage|Any CPU + {04DB0E20-008C-45EF-B427-B6F33B25CD67}.Stage|x86.ActiveCfg = Stage|Any CPU {0CD55683-0485-4630-89B5-54EA080E2FC1}.Coverage|Any CPU.ActiveCfg = Release|Any CPU {0CD55683-0485-4630-89B5-54EA080E2FC1}.Coverage|Any CPU.Build.0 = Release|Any CPU {0CD55683-0485-4630-89B5-54EA080E2FC1}.Coverage|x64.ActiveCfg = Release|Any CPU @@ -137,6 +160,10 @@ Global {0CD55683-0485-4630-89B5-54EA080E2FC1}.Release|Any CPU.Build.0 = Release|Any CPU {0CD55683-0485-4630-89B5-54EA080E2FC1}.Release|x64.ActiveCfg = Release|Any CPU {0CD55683-0485-4630-89B5-54EA080E2FC1}.Release|x86.ActiveCfg = Release|Any CPU + {0CD55683-0485-4630-89B5-54EA080E2FC1}.Stage|Any CPU.ActiveCfg = Stage|Any CPU + {0CD55683-0485-4630-89B5-54EA080E2FC1}.Stage|Any CPU.Build.0 = Stage|Any CPU + {0CD55683-0485-4630-89B5-54EA080E2FC1}.Stage|x64.ActiveCfg = Stage|Any CPU + {0CD55683-0485-4630-89B5-54EA080E2FC1}.Stage|x86.ActiveCfg = Stage|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/build.proj b/build.proj index daa4ce5c..32f57560 100644 --- a/build.proj +++ b/build.proj @@ -23,9 +23,12 @@ .\Package $(PublishDirectory)\Build $(PublishDirectory)\TestResults + .\.nuget - + + + @@ -93,7 +96,7 @@ - + diff --git a/ci/AssemblyInfo.cs b/ci/AssemblyInfo.cs index e47c25b9..25e54e08 100644 --- a/ci/AssemblyInfo.cs +++ b/ci/AssemblyInfo.cs @@ -47,8 +47,8 @@ // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("3.0.0.7")] -[assembly: AssemblyFileVersion("3.0.0.7")] +[assembly: AssemblyVersion("3.0.0.8")] +[assembly: AssemblyFileVersion("3.0.0.8")] [assembly: NeutralResourcesLanguage("en-US")] //For delay signing specify PublicKey for each friendly assembly diff --git a/src/net/Client/AzureMediaServicesClassFactory.cs b/src/net/Client/AzureMediaServicesClassFactory.cs index 975f26c7..32abcfb7 100644 --- a/src/net/Client/AzureMediaServicesClassFactory.cs +++ b/src/net/Client/AzureMediaServicesClassFactory.cs @@ -19,8 +19,8 @@ using System.Data.Services.Common; using System.Net; using Microsoft.Practices.TransientFaultHandling; -using Microsoft.WindowsAzure.MediaServices.Client.OAuth; -using Microsoft.WindowsAzure.MediaServices.Client.Versioning; +using Microsoft.WindowsAzure.MediaServices.Client.OAuth; +using Microsoft.WindowsAzure.MediaServices.Client.RequestAdapters; using Microsoft.WindowsAzure.MediaServices.Client.TransientFaultHandling; namespace Microsoft.WindowsAzure.MediaServices.Client @@ -33,39 +33,43 @@ public class AzureMediaServicesClassFactory : MediaServicesClassFactory private readonly Uri _azureMediaServicesEndpoint; private readonly OAuthDataServiceAdapter _dataServiceAdapter; private readonly ServiceVersionAdapter _serviceVersionAdapter; - private readonly MediaContextBase _mediaContext; - + private readonly MediaContextBase _mediaContext; + private readonly UserAgentAdapter _userAgentAdapter; + private const int ConnectionRetryMaxAttempts = 4; private const int ConnectionRetrySleepQuantum = 100; - private static Cache _endpointCache = new Cache(); - - /// - /// Initializes a new instance of the class. - /// - public AzureMediaServicesClassFactory() { } - - /// - /// Initializes a new instance of the class. - /// - /// The Windows Azure Media Services endpoint to use. - /// The data service adapter. - /// The service version adapter. - /// The instance. - public AzureMediaServicesClassFactory(Uri azureMediaServicesEndpoint, OAuthDataServiceAdapter dataServiceAdapter, ServiceVersionAdapter serviceVersionAdapter, MediaContextBase mediaContext) + private static Cache _endpointCache = new Cache(); + + public AzureMediaServicesClassFactory() + { + + } + + /// + /// Initializes a new instance of the class. + /// + /// The Windows Azure Media Services endpoint to use. + /// The data service adapter. + /// The service version adapter. + /// The instance. + /// The user agent request adapter + public AzureMediaServicesClassFactory(Uri azureMediaServicesEndpoint, OAuthDataServiceAdapter dataServiceAdapter, ServiceVersionAdapter serviceVersionAdapter, MediaContextBase mediaContext, UserAgentAdapter userAgentAdapter) { this._dataServiceAdapter = dataServiceAdapter; this._serviceVersionAdapter = serviceVersionAdapter; - this._mediaContext = mediaContext; - - string cacheKey = string.Format( + this._mediaContext = mediaContext; + _userAgentAdapter = userAgentAdapter; + var clientRequestIdAdapter = new ClientRequestIdAdapter(); + + string cacheKey = string.Format( "{0},{1}", mediaContext.Credentials.ClientId, azureMediaServicesEndpoint.ToString()); this._azureMediaServicesEndpoint = _endpointCache.GetOrAdd( - cacheKey, - () => GetAccountApiEndpoint(this._dataServiceAdapter, this._serviceVersionAdapter, azureMediaServicesEndpoint), + cacheKey, + () => GetAccountApiEndpoint(this._dataServiceAdapter, this._serviceVersionAdapter, azureMediaServicesEndpoint, userAgentAdapter,clientRequestIdAdapter), () => mediaContext.Credentials.TokenExpiration); } @@ -80,18 +84,24 @@ public override IMediaDataServiceContext CreateDataServiceContext() IgnoreMissingProperties = true, IgnoreResourceNotFoundException = true, MergeOption = MergeOption.PreserveChanges, - }; + }; + + var clientRequestIdAdapter = new ClientRequestIdAdapter(); this._dataServiceAdapter.Adapt(dataContext); this._serviceVersionAdapter.Adapt(dataContext); - - dataContext.ReadingEntity += this.OnReadingEntity; - - MediaRetryPolicy queryRetryPolicy = GetQueryRetryPolicy(); - - return new MediaDataServiceContext(dataContext, queryRetryPolicy); - } - + this._userAgentAdapter.Adapt(dataContext); + clientRequestIdAdapter.Adapt(dataContext); + + dataContext.ReadingEntity += this.OnReadingEntity; + var queryRetryPolicy = GetQueryRetryPolicy(null); + var context = new MediaDataServiceContext(dataContext, queryRetryPolicy, clientRequestIdAdapter); + queryRetryPolicy.RetryPolicyAdapter = context; + return context; + + } + + /// /// Creates retry policy for working with Azure blob storage. /// @@ -108,41 +118,58 @@ public override MediaRetryPolicy GetBlobStorageClientRetryPolicy() return retryPolicy; } - /// - /// Creates retry policy for saving changes in Media Services REST layer. - /// - /// Retry policy. - public override MediaRetryPolicy GetSaveChangesRetryPolicy() - { - var retryPolicy = new MediaRetryPolicy( - GetSaveChangesErrorDetectionStrategy(), - retryCount: ConnectionRetryMaxAttempts, - minBackoff: TimeSpan.FromMilliseconds(ConnectionRetrySleepQuantum), - maxBackoff: TimeSpan.FromMilliseconds(ConnectionRetrySleepQuantum * 16), - deltaBackoff: TimeSpan.FromMilliseconds(ConnectionRetrySleepQuantum)); - - return retryPolicy; - } - + /// + /// Creates retry policy for saving changes in Media Services REST layer. + /// + /// Retry policy. + public override MediaRetryPolicy GetSaveChangesRetryPolicy(IRetryPolicyAdapter adapter) + { + var retryPolicy = new MediaRetryPolicy( + GetSaveChangesErrorDetectionStrategy(), + retryCount: ConnectionRetryMaxAttempts, + minBackoff: TimeSpan.FromMilliseconds(ConnectionRetrySleepQuantum), + maxBackoff: TimeSpan.FromMilliseconds(ConnectionRetrySleepQuantum * 16), + deltaBackoff: TimeSpan.FromMilliseconds(ConnectionRetrySleepQuantum) + ); + retryPolicy.RetryPolicyAdapter = adapter; + return retryPolicy; + } + + [Obsolete] + public override MediaRetryPolicy GetSaveChangesRetryPolicy() + { + return GetSaveChangesRetryPolicy(null); + } + + + [Obsolete] /// /// Creates retry policy for querying Media Services REST layer. /// /// Retry policy. - public override MediaRetryPolicy GetQueryRetryPolicy() - { - var retryPolicy = new MediaRetryPolicy( - GetQueryErrorDetectionStrategy(), - retryCount: ConnectionRetryMaxAttempts, - minBackoff: TimeSpan.FromMilliseconds(ConnectionRetrySleepQuantum), - maxBackoff: TimeSpan.FromMilliseconds(ConnectionRetrySleepQuantum * 16), - deltaBackoff: TimeSpan.FromMilliseconds(ConnectionRetrySleepQuantum)); - - return retryPolicy; + public override MediaRetryPolicy GetQueryRetryPolicy() + { + return GetQueryRetryPolicy(null); + } + /// + /// Creates retry policy for querying Media Services REST layer. + /// + /// Retry policy. + public override MediaRetryPolicy GetQueryRetryPolicy(IRetryPolicyAdapter adapter) + { + var retryPolicy = new MediaRetryPolicy( + GetQueryErrorDetectionStrategy(), + retryCount: ConnectionRetryMaxAttempts, + minBackoff: TimeSpan.FromMilliseconds(ConnectionRetrySleepQuantum), + maxBackoff: TimeSpan.FromMilliseconds(ConnectionRetrySleepQuantum * 16), + deltaBackoff: TimeSpan.FromMilliseconds(ConnectionRetrySleepQuantum)); + retryPolicy.RetryPolicyAdapter = adapter; + return retryPolicy; } - private Uri GetAccountApiEndpoint(OAuthDataServiceAdapter dataServiceAdapter, ServiceVersionAdapter versionAdapter, Uri apiServer) - { - RetryPolicy retryPolicy = new RetryPolicy( + private Uri GetAccountApiEndpoint(OAuthDataServiceAdapter dataServiceAdapter, ServiceVersionAdapter versionAdapter, Uri apiServer, UserAgentAdapter userAgentAdapter,ClientRequestIdAdapter clientRequestIdAdapter) + { + MediaRetryPolicy retryPolicy = new MediaRetryPolicy( GetWebRequestTransientErrorDetectionStrategy(), RetryStrategyFactory.DefaultStrategy()); @@ -154,7 +181,9 @@ private Uri GetAccountApiEndpoint(OAuthDataServiceAdapter dataServiceAdapter, Se request.AllowAutoRedirect = false; dataServiceAdapter.AddAccessTokenToRequest(request); versionAdapter.AddVersionToRequest(request); - + userAgentAdapter.AddUserAgentToRequest(request); + clientRequestIdAdapter.AddClientRequestId(request); + using (WebResponse response = request.GetResponse()) { apiEndpoint = GetAccountApiEndpointFromResponse(response); diff --git a/src/net/Client/BulkIngest/IngestManifestAssetCollection.cs b/src/net/Client/BulkIngest/IngestManifestAssetCollection.cs index 6e2516a9..47e8cbec 100644 --- a/src/net/Client/BulkIngest/IngestManifestAssetCollection.cs +++ b/src/net/Client/BulkIngest/IngestManifestAssetCollection.cs @@ -209,9 +209,9 @@ private Task CreateAsync(IIngestManifest ingestManifest, I dataContext.AddObject(IngestManifestAssetCollection.EntitySet,data); dataContext.AttachTo(AssetCollection.AssetSet, asset); - dataContext.SetLink(data,"Asset",asset); - - MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.SetLink(data,"Asset",asset); + + MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); Task task = retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(data)) .ContinueWith(t => diff --git a/src/net/Client/BulkIngest/IngestManifestAssetData.cs b/src/net/Client/BulkIngest/IngestManifestAssetData.cs index 8d606573..a099cfab 100644 --- a/src/net/Client/BulkIngest/IngestManifestAssetData.cs +++ b/src/net/Client/BulkIngest/IngestManifestAssetData.cs @@ -60,9 +60,9 @@ public Task DeleteAsync() { IMediaDataServiceContext dataContext = GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(IngestManifestAssetCollection.EntitySet, this); - dataContext.DeleteObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.DeleteObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } diff --git a/src/net/Client/BulkIngest/IngestManifestCollection.cs b/src/net/Client/BulkIngest/IngestManifestCollection.cs index cf18d6ad..12a97104 100644 --- a/src/net/Client/BulkIngest/IngestManifestCollection.cs +++ b/src/net/Client/BulkIngest/IngestManifestCollection.cs @@ -107,7 +107,7 @@ public Task CreateAsync(string name,string storageAccountName) IMediaDataServiceContext dataContext = this.MediaContext.MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AddObject(EntitySet, ingestManifestData); - MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(ingestManifestData)) .ContinueWith( diff --git a/src/net/Client/BulkIngest/IngestManifestData.cs b/src/net/Client/BulkIngest/IngestManifestData.cs index 8c1295b8..3f5e8add 100644 --- a/src/net/Client/BulkIngest/IngestManifestData.cs +++ b/src/net/Client/BulkIngest/IngestManifestData.cs @@ -89,7 +89,7 @@ public Task DeleteAsync() dataContext.AttachTo(IngestManifestCollection.EntitySet, this); dataContext.DeleteObject(this); - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } @@ -399,7 +399,7 @@ public Task UpdateAsync() dataContext.AttachTo(IngestManifestCollection.EntitySet, this); dataContext.UpdateObject(this); - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } diff --git a/src/net/Client/BulkIngest/IngestManifestFileCollection.cs b/src/net/Client/BulkIngest/IngestManifestFileCollection.cs index 7b303274..09b46a2d 100644 --- a/src/net/Client/BulkIngest/IngestManifestFileCollection.cs +++ b/src/net/Client/BulkIngest/IngestManifestFileCollection.cs @@ -125,9 +125,9 @@ public Task CreateAsync(IIngestManifestAsset ingestManifest SetEncryptionSettings(ingestManifestAsset, options, data); - dataContext.AddObject(EntitySet, data); - - MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.AddObject(EntitySet, data); + + MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); Task task = retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(data)) .ContinueWith(t => diff --git a/src/net/Client/BulkIngest/IngestManifestFileData.cs b/src/net/Client/BulkIngest/IngestManifestFileData.cs index f9d0ca7b..680ef1e0 100644 --- a/src/net/Client/BulkIngest/IngestManifestFileData.cs +++ b/src/net/Client/BulkIngest/IngestManifestFileData.cs @@ -39,9 +39,9 @@ public Task DeleteAsync() { IMediaDataServiceContext dataContext = GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(IngestManifestFileCollection.EntitySet, this); - dataContext.DeleteObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.DeleteObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } diff --git a/src/net/Client/CloudMediaContext.cs b/src/net/Client/CloudMediaContext.cs index bc9e9557..ccf91955 100644 --- a/src/net/Client/CloudMediaContext.cs +++ b/src/net/Client/CloudMediaContext.cs @@ -18,7 +18,7 @@ using System.Linq; using System.Threading; using Microsoft.WindowsAzure.MediaServices.Client.OAuth; -using Microsoft.WindowsAzure.MediaServices.Client.Versioning; +using Microsoft.WindowsAzure.MediaServices.Client.RequestAdapters; namespace Microsoft.WindowsAzure.MediaServices.Client { @@ -56,6 +56,8 @@ public partial class CloudMediaContext : MediaContextBase private OAuthDataServiceAdapter dataServiceAdapter; private ServiceVersionAdapter versionAdapter; private Uri apiServer; + private UserAgentAdapter userAgentAdapter; + /// /// Initializes a new instance of the class. @@ -113,6 +115,8 @@ public CloudMediaContext(Uri apiServer, MediaServicesCredentials credentials) this.Credentials = credentials; dataServiceAdapter = new OAuthDataServiceAdapter(credentials, NimbusRestApiCertificateThumbprint, NimbusRestApiCertificateSubject); versionAdapter = new ServiceVersionAdapter(KnownApiVersions.Current); + userAgentAdapter = new UserAgentAdapter(KnownClientVersions.Current); + } @@ -122,7 +126,7 @@ public override MediaServicesClassFactory MediaServicesClassFactory { if (_classFactory == null) { - Interlocked.CompareExchange(ref _classFactory, new AzureMediaServicesClassFactory(apiServer, dataServiceAdapter, versionAdapter, this), null); + Interlocked.CompareExchange(ref _classFactory, new AzureMediaServicesClassFactory(apiServer, dataServiceAdapter, versionAdapter, this, userAgentAdapter), null); } return _classFactory; } diff --git a/src/net/Client/Collections/AccessPolicyBaseCollection.cs b/src/net/Client/Collections/AccessPolicyBaseCollection.cs index 8480c071..906b68a3 100644 --- a/src/net/Client/Collections/AccessPolicyBaseCollection.cs +++ b/src/net/Client/Collections/AccessPolicyBaseCollection.cs @@ -59,9 +59,9 @@ public Task CreateAsync(string name, TimeSpan duration, AccessPer Permissions = AccessPolicyData.GetInternalPermissions(permissions) }; - dataContext.AddObject(AccessPolicySet, accessPolicy); - - MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.AddObject(AccessPolicySet, accessPolicy); + + MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(accessPolicy)) .ContinueWith( diff --git a/src/net/Client/Collections/AssetCollection.cs b/src/net/Client/Collections/AssetCollection.cs index 16159368..b9006602 100644 --- a/src/net/Client/Collections/AssetCollection.cs +++ b/src/net/Client/Collections/AssetCollection.cs @@ -15,7 +15,7 @@ // -using System; +using System; using System.Linq; using System.Security.Cryptography.X509Certificates; using System.Threading; @@ -119,8 +119,8 @@ public override Task CreateAsync(string assetName, string storageAccount IMediaDataServiceContext dataContext = this.MediaContext.MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AddObject(AssetSet, (IAsset)emptyAsset); - MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); - + MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); + return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(emptyAsset)) .ContinueWith( t => @@ -175,8 +175,8 @@ private ContentKeyData CreateStorageContentKey(AssetData tempAsset, NullableFile dataContext.AddObject(ContentKeyBaseCollection.ContentKeySet, contentKeyData); - MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); - + MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); + retryPolicy.ExecuteAction(() => dataContext.SaveChanges()); // Associate it with the asset. diff --git a/src/net/Client/Collections/AssetFileCollection.cs b/src/net/Client/Collections/AssetFileCollection.cs index 6741abe4..8710b394 100644 --- a/src/net/Client/Collections/AssetFileCollection.cs +++ b/src/net/Client/Collections/AssetFileCollection.cs @@ -148,8 +148,8 @@ public override Task CreateAsync(string name, CancellationToken canc dataContext.AddObject(AssetFileCollection.FileSet, assetFile); cancelation.ThrowIfCancellationRequested(); - cancelation.ThrowIfCancellationRequested(); - MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + cancelation.ThrowIfCancellationRequested(); + MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => { cancelation.ThrowIfCancellationRequested(); diff --git a/src/net/Client/Collections/ContentKeyBaseCollection.cs b/src/net/Client/Collections/ContentKeyBaseCollection.cs index 362a2ff3..f94c698d 100644 --- a/src/net/Client/Collections/ContentKeyBaseCollection.cs +++ b/src/net/Client/Collections/ContentKeyBaseCollection.cs @@ -249,7 +249,7 @@ internal static string GetProtectionKeyIdForContentKey(MediaContextBase mediaCon IMediaDataServiceContext dataContext = mediaContext.MediaServicesClassFactory.CreateDataServiceContext(); - MediaRetryPolicy retryPolicy = mediaContext.MediaServicesClassFactory.GetQueryRetryPolicy(); + MediaRetryPolicy retryPolicy = mediaContext.MediaServicesClassFactory.GetQueryRetryPolicy(dataContext as IRetryPolicyAdapter); IEnumerable results = retryPolicy.ExecuteAction>(() => dataContext.Execute(uriGetProtectionKeyId)); @@ -274,7 +274,7 @@ internal static X509Certificate2 GetCertificateForProtectionKeyId(MediaContextBa // If not, download it from Nimbus to use. Uri uriGetProtectionKey = new Uri(String.Format(CultureInfo.InvariantCulture, "/GetProtectionKey?protectionKeyId='{0}'", protectionKeyId), UriKind.Relative); - MediaRetryPolicy retryPolicy = mediaContext.MediaServicesClassFactory.GetQueryRetryPolicy(); + MediaRetryPolicy retryPolicy = mediaContext.MediaServicesClassFactory.GetQueryRetryPolicy(dataContext as IRetryPolicyAdapter); IEnumerable results2 = retryPolicy.ExecuteAction>(() => dataContext.Execute(uriGetProtectionKey)); diff --git a/src/net/Client/Collections/ContentKeyCollection.cs b/src/net/Client/Collections/ContentKeyCollection.cs index a6247f95..107ce41a 100644 --- a/src/net/Client/Collections/ContentKeyCollection.cs +++ b/src/net/Client/Collections/ContentKeyCollection.cs @@ -99,9 +99,9 @@ public override Task CreateAsync(Guid keyId, byte[] contentKey, str contentKeyData = InitializeEnvelopeContentKey(keyId, contentKey, name, certToUse); } - dataContext.AddObject(ContentKeySet, contentKeyData); - - MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.AddObject(ContentKeySet, contentKeyData); + + MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(contentKeyData)) .ContinueWith( diff --git a/src/net/Client/Collections/LinkCollection.cs b/src/net/Client/Collections/LinkCollection.cs index 155f72ff..1c81b151 100644 --- a/src/net/Client/Collections/LinkCollection.cs +++ b/src/net/Client/Collections/LinkCollection.cs @@ -62,8 +62,8 @@ protected override void InsertItem(int index, TInterface item) this._dataContext.AttachTo(GetEntitySetName(typeof(TInterface)), item); this._dataContext.AddLink(this._parent, this._propertyName, item); - MediaRetryPolicy retryPolicy = this._parent.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); - + MediaRetryPolicy retryPolicy = this._parent.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(_dataContext as IRetryPolicyAdapter); + retryPolicy.ExecuteAction(() => _dataContext.SaveChanges()); base.InsertItem(index, item); @@ -77,7 +77,7 @@ protected override void RemoveItem(int index) { this._dataContext.DeleteLink(this._parent, this._propertyName, this[index]); - MediaRetryPolicy retryPolicy = this._parent.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + MediaRetryPolicy retryPolicy = this._parent.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(_dataContext as IRetryPolicyAdapter); retryPolicy.ExecuteAction(() => _dataContext.SaveChanges()); diff --git a/src/net/Client/Collections/LocatorBaseCollection.cs b/src/net/Client/Collections/LocatorBaseCollection.cs index 7446a053..468940f4 100644 --- a/src/net/Client/Collections/LocatorBaseCollection.cs +++ b/src/net/Client/Collections/LocatorBaseCollection.cs @@ -38,10 +38,9 @@ public class LocatorBaseCollection : CloudBaseCollection /// /// The name of the Asset property of the . /// - internal const string AssetPropertyName = "Asset"; - - - + internal const string AssetPropertyName = "Asset"; + + /// /// Initializes a new instance of the class. /// @@ -135,93 +134,127 @@ internal static void VerifyLocator(ILocator locator) { throw new ArgumentException(StringTable.InvalidLocatorType, "locator"); } - } - - /// - /// Creates the locator async. - /// - /// Type of the locator. - /// The asset. - /// The access policy. - /// The start time. - /// The name. - /// - /// A function delegate that returns the future result to be available through the Task<ILocator>. - /// - public Task CreateLocatorAsync(LocatorType locatorType, IAsset asset, IAccessPolicy accessPolicy, DateTime? startTime, string name =null) - { - AccessPolicyBaseCollection.VerifyAccessPolicy(accessPolicy); - AssetCollection.VerifyAsset(asset); - - AssetData assetData = (AssetData)asset; + } + + + /// + /// Creates the locator async. + /// + /// The locator Id. + /// Type of the locator. + /// The asset. + /// The access policy. + /// The start time. + /// The name. + /// A function delegate that returns the future result to be available through the Task<ILocator>. + public Task CreateLocatorAsync(string locatorId, LocatorType locatorType, IAsset asset, IAccessPolicy accessPolicy, DateTime? startTime, string name =null) + { + AccessPolicyBaseCollection.VerifyAccessPolicy(accessPolicy); + AssetCollection.VerifyAsset(asset); + + AssetData assetData = (AssetData)asset; + + LocatorData locator = new LocatorData + { + AccessPolicy = (AccessPolicyData)accessPolicy, + Asset = assetData, + Type = (int)locatorType, + StartTime = startTime, + Name = name + }; + + if (locatorId != null) + { + locator.Id = LocatorData.NormalizeLocatorId(locatorId); + } + + locator.SetMediaContext(this.MediaContext); + + IMediaDataServiceContext dataContext = this.MediaContext.MediaServicesClassFactory.CreateDataServiceContext(); + dataContext.AttachTo(AssetCollection.AssetSet, asset); + dataContext.AttachTo(AccessPolicyBaseCollection.AccessPolicySet, accessPolicy); + dataContext.AddObject(LocatorSet, locator); + dataContext.SetLink(locator, AccessPolicyPropertyName, accessPolicy); + dataContext.SetLink(locator, AssetPropertyName, asset); + + MediaRetryPolicy retryPolicy = + this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); + + return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(locator)) + .ContinueWith( + t => + { + t.ThrowIfFaulted(); + + assetData.InvalidateLocatorsCollection(); + + return (LocatorData)t.Result.AsyncState; + }, + TaskContinuationOptions.ExecuteSynchronously); + } + + /// + /// Creates the locator asynchronous. + /// + /// Type of the locator. + /// The asset. + /// The access policy. + /// The start time. + /// The name. + /// Task<ILocator>. + public Task CreateLocatorAsync(LocatorType locatorType, IAsset asset, IAccessPolicy accessPolicy, DateTime? startTime, string name = null) + { + return CreateLocatorAsync(null, locatorType, asset, accessPolicy, startTime, name); + } - LocatorData locator = new LocatorData - { - AccessPolicy = (AccessPolicyData)accessPolicy, - Asset = assetData, - AssetId = assetData.Id, - Type = (int)locatorType, - StartTime = startTime, - Name = name - }; - - locator.SetMediaContext(this.MediaContext); - IMediaDataServiceContext dataContext = this.MediaContext.MediaServicesClassFactory.CreateDataServiceContext(); - dataContext.AttachTo(AssetCollection.AssetSet, asset); - dataContext.AttachTo(AccessPolicyBaseCollection.AccessPolicySet, accessPolicy); - dataContext.AddObject(LocatorSet, locator); - dataContext.SetLink(locator, AccessPolicyPropertyName, accessPolicy); - dataContext.SetLink(locator, AssetPropertyName, asset); - - MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); - - return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(locator)) - .ContinueWith( - t => - { - t.ThrowIfFaulted(); - - assetData.InvalidateLocatorsCollection(); - - return (LocatorData)t.Result.AsyncState; - }, - TaskContinuationOptions.ExecuteSynchronously); - } public Task CreateLocatorAsync(LocatorType locatorType, IAsset asset, IAccessPolicy accessPolicy) { - return CreateLocatorAsync(locatorType, asset, accessPolicy, startTime: null, name:null); - } - - /// - /// Creates the locator. - /// - /// Type of the locator. - /// The asset. - /// The access policy. - /// The start time. - /// The name. - /// - /// A locator enabling streaming access to the specified . - /// - public ILocator CreateLocator(LocatorType locatorType, IAsset asset, IAccessPolicy accessPolicy, DateTime? startTime, string name =null) + return CreateLocatorAsync(null,locatorType, asset, accessPolicy, startTime: null, name:null); + } + + /// + /// Creates the locator. + /// + /// The locator identifier. + /// Example of acceptable formats: + /// Locator identifier prefix followed by guid - nb:lid:UUID:8b54eb99-754e-4f33-9261-2bb9866ff41f + /// Guid - 8b54eb99-754e-4f33-9261-2bb9866ff41f + /// + /// Type of the locator. + /// The asset. + /// The access policy. + /// The start time. + /// The locator name + /// A locator enabling access to the specified . + public ILocator CreateLocator(string locatorId, LocatorType locatorType, IAsset asset, IAccessPolicy accessPolicy, DateTime? startTime, string name =null) { try - { - Task task = this.CreateLocatorAsync(locatorType, asset, accessPolicy, startTime, name); - task.Wait(); - + { + Task task = this.CreateLocatorAsync(locatorId,locatorType, asset, accessPolicy, startTime, name); return task.Result; } catch (AggregateException exception) { throw exception.InnerException; } - } - + } + + public ILocator CreateLocator(LocatorType locatorType, IAsset asset, IAccessPolicy accessPolicy, DateTime? startTime, string name = null) + { + return CreateLocator(null, locatorType, asset, accessPolicy, startTime, name); + } + + /// + /// Creates the locator. + /// + /// Type of the locator. + /// The asset. + /// The access policy. + /// ILocator. public ILocator CreateLocator(LocatorType locatorType, IAsset asset, IAccessPolicy accessPolicy) { - return CreateLocator(locatorType, asset, accessPolicy,startTime: null); + return CreateLocator(locatorType, asset, accessPolicy,startTime: null,name:null); } diff --git a/src/net/Client/Collections/NotificationEndpointCollection.cs b/src/net/Client/Collections/NotificationEndpointCollection.cs index f924941d..3c92eacd 100644 --- a/src/net/Client/Collections/NotificationEndpointCollection.cs +++ b/src/net/Client/Collections/NotificationEndpointCollection.cs @@ -52,9 +52,9 @@ public Task CreateAsync(string name, NotificationEndPoint notificationEndPoint.SetMediaContext(MediaContext); IMediaDataServiceContext dataContext = MediaContext.MediaServicesClassFactory.CreateDataServiceContext(); - dataContext.AddObject(NotificationEndPoints, notificationEndPoint); - - MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.AddObject(NotificationEndPoints, notificationEndPoint); + + MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(notificationEndPoint)) .ContinueWith( diff --git a/src/net/Client/ContentKeyAuthorization/ContentKeyAuthorizationPolicyCollection.cs b/src/net/Client/ContentKeyAuthorization/ContentKeyAuthorizationPolicyCollection.cs index 518cbdec..179a614e 100644 --- a/src/net/Client/ContentKeyAuthorization/ContentKeyAuthorizationPolicyCollection.cs +++ b/src/net/Client/ContentKeyAuthorization/ContentKeyAuthorizationPolicyCollection.cs @@ -55,9 +55,9 @@ public virtual Task CreateAsync(string name) }; authorizationPolicyData.SetMediaContext(this.MediaContext); - dataContext.AddObject(ContentKeyAuthorizationPolicySet, authorizationPolicyData); - - MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.AddObject(ContentKeyAuthorizationPolicySet, authorizationPolicyData); + + MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(authorizationPolicyData)) .ContinueWith( diff --git a/src/net/Client/ContentKeyAuthorization/ContentKeyAuthorizationPolicyData.cs b/src/net/Client/ContentKeyAuthorization/ContentKeyAuthorizationPolicyData.cs index 04031569..dc070735 100644 --- a/src/net/Client/ContentKeyAuthorization/ContentKeyAuthorizationPolicyData.cs +++ b/src/net/Client/ContentKeyAuthorization/ContentKeyAuthorizationPolicyData.cs @@ -74,7 +74,7 @@ public Task UpdateAsync() dataContext.AttachTo(ContentKeyAuthorizationPolicyCollection.ContentKeyAuthorizationPolicySet, this); dataContext.UpdateObject(this); - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)) .ContinueWith(t => @@ -127,7 +127,7 @@ public Task DeleteAsync() dataContext.AttachTo(ContentKeyAuthorizationPolicyCollection.ContentKeyAuthorizationPolicySet, this); dataContext.DeleteObject(this); - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } diff --git a/src/net/Client/ContentKeyAuthorization/ContentKeyAuthorizationPolicyOptionCollection.cs b/src/net/Client/ContentKeyAuthorization/ContentKeyAuthorizationPolicyOptionCollection.cs index 2b861e55..b993ce42 100644 --- a/src/net/Client/ContentKeyAuthorization/ContentKeyAuthorizationPolicyOptionCollection.cs +++ b/src/net/Client/ContentKeyAuthorization/ContentKeyAuthorizationPolicyOptionCollection.cs @@ -72,9 +72,9 @@ public Task CreateAsync( ((IContentKeyAuthorizationPolicyOption)policyOption).KeyDeliveryType = deliveryType; policyOption.SetMediaContext(this.MediaContext); - dataContext.AddObject(ContentKeyAuthorizationPolicyOptionSet, policyOption); - - MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.AddObject(ContentKeyAuthorizationPolicyOptionSet, policyOption); + + MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(policyOption)) .ContinueWith( diff --git a/src/net/Client/ContentKeyAuthorization/ContentKeyAuthorizationPolicyOptionData.cs b/src/net/Client/ContentKeyAuthorization/ContentKeyAuthorizationPolicyOptionData.cs index 0140ea5a..f5d2ba04 100644 --- a/src/net/Client/ContentKeyAuthorization/ContentKeyAuthorizationPolicyOptionData.cs +++ b/src/net/Client/ContentKeyAuthorization/ContentKeyAuthorizationPolicyOptionData.cs @@ -88,9 +88,9 @@ public Task UpdateAsync() { IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(ContentKeyAuthorizationPolicyOptionCollection.ContentKeyAuthorizationPolicyOptionSet, this); - dataContext.UpdateObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.UpdateObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)) .ContinueWith( @@ -125,9 +125,9 @@ public Task DeleteAsync() { IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(ContentKeyAuthorizationPolicyOptionCollection.ContentKeyAuthorizationPolicyOptionSet, this); - dataContext.DeleteObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.DeleteObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } diff --git a/src/net/Client/ContentKeyAuthorization/Templates/OldTokenTemplateFormat.cs b/src/net/Client/ContentKeyAuthorization/Templates/OldTokenTemplateFormat.cs deleted file mode 100644 index b1aa0dba..00000000 --- a/src/net/Client/ContentKeyAuthorization/Templates/OldTokenTemplateFormat.cs +++ /dev/null @@ -1,170 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.34014 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -using System.Xml.Serialization; - -// -// This source code was auto-generated by xsd, Version=4.0.30319.17929. -// - - -/// -[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")] -[System.SerializableAttribute()] -[System.Diagnostics.DebuggerStepThroughAttribute()] -[System.ComponentModel.DesignerCategoryAttribute("code")] -[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] -[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] -internal partial class TokenRestriction { - - private TokenRestrictionVerificationKey[] verificationKeysField; - - private TokenRestrictionClaim[] requiredClaimsField; - - private string issuerField; - - private string audienceField; - - /// - [System.Xml.Serialization.XmlArrayItemAttribute("VerificationKey", IsNullable=false)] - public TokenRestrictionVerificationKey[] VerificationKeys { - get { - return this.verificationKeysField; - } - set { - this.verificationKeysField = value; - } - } - - /// - [System.Xml.Serialization.XmlArrayItemAttribute("Claim", IsNullable=false)] - public TokenRestrictionClaim[] RequiredClaims { - get { - return this.requiredClaimsField; - } - set { - this.requiredClaimsField = value; - } - } - - /// - [System.Xml.Serialization.XmlAttributeAttribute(DataType="anyURI")] - public string issuer { - get { - return this.issuerField; - } - set { - this.issuerField = value; - } - } - - /// - [System.Xml.Serialization.XmlAttributeAttribute(DataType="anyURI")] - public string audience { - get { - return this.audienceField; - } - set { - this.audienceField = value; - } - } -} - -/// -[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")] -[System.SerializableAttribute()] -[System.Diagnostics.DebuggerStepThroughAttribute()] -[System.ComponentModel.DesignerCategoryAttribute("code")] -[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] -internal partial class TokenRestrictionVerificationKey { - - private VerificationKeyType typeField; - - private byte[] valueField; - - private bool isPrimaryField; - - /// - [System.Xml.Serialization.XmlAttributeAttribute()] - public VerificationKeyType type { - get { - return this.typeField; - } - set { - this.typeField = value; - } - } - - /// - [System.Xml.Serialization.XmlAttributeAttribute(DataType="base64Binary")] - public byte[] value { - get { - return this.valueField; - } - set { - this.valueField = value; - } - } - - /// - [System.Xml.Serialization.XmlAttributeAttribute()] - public bool IsPrimary { - get { - return this.isPrimaryField; - } - set { - this.isPrimaryField = value; - } - } -} - -/// -[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")] -[System.SerializableAttribute()] -internal enum VerificationKeyType { - - /// - Symmetric, -} - -/// -[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")] -[System.SerializableAttribute()] -[System.Diagnostics.DebuggerStepThroughAttribute()] -[System.ComponentModel.DesignerCategoryAttribute("code")] -[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] -internal partial class TokenRestrictionClaim { - - private string typeField; - - private string valueField; - - /// - [System.Xml.Serialization.XmlAttributeAttribute(DataType="anyURI")] - public string type { - get { - return this.typeField; - } - set { - this.typeField = value; - } - } - - /// - [System.Xml.Serialization.XmlAttributeAttribute()] - public string value { - get { - return this.valueField; - } - set { - this.valueField = value; - } - } -} diff --git a/src/net/Client/ContentKeyAuthorization/Templates/TokenRestrictionTemplateSerializer.cs b/src/net/Client/ContentKeyAuthorization/Templates/TokenRestrictionTemplateSerializer.cs index 13f00d15..8516aa85 100644 --- a/src/net/Client/ContentKeyAuthorization/Templates/TokenRestrictionTemplateSerializer.cs +++ b/src/net/Client/ContentKeyAuthorization/Templates/TokenRestrictionTemplateSerializer.cs @@ -69,68 +69,6 @@ private static XmlSchemaSet GetOldTokenFormatSchemaSet() return _cacheSchemaSet; } - private static void ValidateAgainstOldTokenFormatSchema(string template) - { - XmlSchemaSet schemaSets = GetOldTokenFormatSchemaSet(); - - XDocument templateDocument = XDocument.Parse(template); - - templateDocument.Validate(schemaSets, null); - } - - private static bool IsOldTokenFormat(string template) - { - bool returnValue = false; - XDocument parsedTemplate = XDocument.Parse(template); - - if (0 == String.Compare(parsedTemplate.Root.Name.LocalName, "TokenRestriction", StringComparison.Ordinal)) - { - returnValue = true; - } - - return returnValue; - } - - private static TokenRestrictionTemplate ConvertFromOldTokenFormat(XmlReader reader) - { - XmlSerializer serializer = new XmlSerializer(typeof(TokenRestriction)); - - TokenRestriction tokenRestrictionInOldFormat = (TokenRestriction)serializer.Deserialize(reader); - - TokenRestrictionTemplate templateToReturn = new TokenRestrictionTemplate(); - templateToReturn.Issuer = new Uri(tokenRestrictionInOldFormat.issuer); - templateToReturn.Audience = new Uri(tokenRestrictionInOldFormat.audience); - - if (tokenRestrictionInOldFormat.RequiredClaims != null) - { - foreach (TokenRestrictionClaim currentClaim in tokenRestrictionInOldFormat.RequiredClaims) - { - TokenClaim claim = new TokenClaim(currentClaim.type, currentClaim.value); - templateToReturn.RequiredClaims.Add(claim); - } - } - - if (tokenRestrictionInOldFormat.VerificationKeys != null) - { - foreach (TokenRestrictionVerificationKey verificationKey in tokenRestrictionInOldFormat.VerificationKeys) - { - if (verificationKey.type == VerificationKeyType.Symmetric) - { - if (verificationKey.IsPrimary && (templateToReturn.PrimaryVerificationKey == null)) - { - templateToReturn.PrimaryVerificationKey = new SymmetricVerificationKey(verificationKey.value); - } - else - { - templateToReturn.AlternateVerificationKeys.Add(new SymmetricVerificationKey(verificationKey.value)); - } - } - } - } - - return templateToReturn; - } - /// /// Deserializes a string containing an Xml representation of a TokenRestrictionTemplate /// back into a TokenRestrictionTemplate class instance. @@ -150,14 +88,7 @@ public static TokenRestrictionTemplate Deserialize(string templateXml) reader = XmlReader.Create(stringReader); - if (IsOldTokenFormat(templateXml)) - { - templateToReturn = ConvertFromOldTokenFormat(reader); - } - else - { - templateToReturn = (TokenRestrictionTemplate)serializer.ReadObject(reader); - } + templateToReturn = (TokenRestrictionTemplate)serializer.ReadObject(reader); } finally { diff --git a/src/net/Client/DynamicEncryption/AssetDeliveryPolicyCollection.cs b/src/net/Client/DynamicEncryption/AssetDeliveryPolicyCollection.cs index 90f8c86e..fdc45ea2 100644 --- a/src/net/Client/DynamicEncryption/AssetDeliveryPolicyCollection.cs +++ b/src/net/Client/DynamicEncryption/AssetDeliveryPolicyCollection.cs @@ -71,9 +71,9 @@ public Task CreateAsync( ((IAssetDeliveryPolicy)policy).AssetDeliveryConfiguration = configuration; policy.SetMediaContext(this.MediaContext); - dataContext.AddObject(DeliveryPolicySet, policy); - - MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.AddObject(DeliveryPolicySet, policy); + + MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(policy)) .ContinueWith( diff --git a/src/net/Client/DynamicEncryption/AssetDeliveryPolicyData.cs b/src/net/Client/DynamicEncryption/AssetDeliveryPolicyData.cs index 22260490..956b4c6a 100644 --- a/src/net/Client/DynamicEncryption/AssetDeliveryPolicyData.cs +++ b/src/net/Client/DynamicEncryption/AssetDeliveryPolicyData.cs @@ -149,9 +149,9 @@ public Task UpdateAsync() { IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(AssetDeliveryPolicyCollection.DeliveryPolicySet, this); - dataContext.UpdateObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.UpdateObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)) .ContinueWith( @@ -186,9 +186,9 @@ public Task DeleteAsync() { IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(AssetDeliveryPolicyCollection.DeliveryPolicySet, this); - dataContext.DeleteObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.DeleteObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } diff --git a/src/net/Client/Entities/AccessPolicyData.cs b/src/net/Client/Entities/AccessPolicyData.cs index 905767b5..2ccdd197 100644 --- a/src/net/Client/Entities/AccessPolicyData.cs +++ b/src/net/Client/Entities/AccessPolicyData.cs @@ -60,9 +60,9 @@ public Task DeleteAsync() IMediaDataServiceContext dataContext = GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(AccessPolicyBaseCollection.AccessPolicySet, this); - dataContext.DeleteObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.DeleteObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } diff --git a/src/net/Client/Entities/AssetData.cs b/src/net/Client/Entities/AssetData.cs index 973d13c9..7bd2369b 100644 --- a/src/net/Client/Entities/AssetData.cs +++ b/src/net/Client/Entities/AssetData.cs @@ -246,9 +246,9 @@ public Task UpdateAsync() IMediaDataServiceContext dataContext = this._mediaContextBase.MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(AssetCollection.AssetSet, this); - dataContext.UpdateObject(this); - - MediaRetryPolicy retryPolicy = this._mediaContextBase.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.UpdateObject(this); + + MediaRetryPolicy retryPolicy = this._mediaContextBase.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)) .ContinueWith( @@ -288,9 +288,9 @@ public Task DeleteAsync() dataContext.AttachTo(AssetCollection.AssetSet, this); this.InvalidateContentKeysCollection(); this.InvalidateDeliveryPoliciesCollection(); - dataContext.DeleteObject(this); - - MediaRetryPolicy retryPolicy = this._mediaContextBase.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.DeleteObject(this); + + MediaRetryPolicy retryPolicy = this._mediaContextBase.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } diff --git a/src/net/Client/Entities/AssetFileData.cs b/src/net/Client/Entities/AssetFileData.cs index adc1c172..fdb9d8ee 100644 --- a/src/net/Client/Entities/AssetFileData.cs +++ b/src/net/Client/Entities/AssetFileData.cs @@ -147,9 +147,9 @@ public Task UpdateAsync() IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(FileSet, this); - dataContext.UpdateObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.UpdateObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)) .ContinueWith( @@ -199,9 +199,9 @@ public Task DeleteAsync() { IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(FileSet, this); - dataContext.DeleteObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.DeleteObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } diff --git a/src/net/Client/Entities/BaseEntity.cs b/src/net/Client/Entities/BaseEntity.cs index 359a792a..d550b5be 100644 --- a/src/net/Client/Entities/BaseEntity.cs +++ b/src/net/Client/Entities/BaseEntity.cs @@ -37,8 +37,8 @@ protected void LoadProperty(IMediaDataServiceContext dataContext, string propert } protected void LoadProperty(IMediaDataServiceContext dataContext, BaseEntity entity, string propertyName) - { - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + { + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); retryPolicy.ExecuteAction(() => dataContext.LoadProperty(entity, propertyName)); } } diff --git a/src/net/Client/Entities/ContentKeyData.cs b/src/net/Client/Entities/ContentKeyData.cs index a21424d3..7b67e9e9 100644 --- a/src/net/Client/Entities/ContentKeyData.cs +++ b/src/net/Client/Entities/ContentKeyData.cs @@ -47,9 +47,9 @@ public Task GetClearKeyValueAsync() if (this.GetMediaContext() != null) { Uri uriRebindContentKey = new Uri(string.Format(CultureInfo.InvariantCulture, "/RebindContentKey?id='{0}'&x509Certificate=''", this.Id), UriKind.Relative); - IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetQueryRetryPolicy(); + IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetQueryRetryPolicy(dataContext as IRetryPolicyAdapter); IEnumerable results = retryPolicy.ExecuteAction>(() => dataContext.Execute(uriRebindContentKey)); string reboundContentKey = results.Single(); @@ -103,9 +103,9 @@ public Task GetEncryptedKeyValueAsync(X509Certificate2 certToEncryptTo) certToSend = HttpUtility.UrlEncode(certToSend); Uri uriRebindContentKey = new Uri(string.Format(CultureInfo.InvariantCulture, "/RebindContentKey?id='{0}'&x509Certificate='{1}'", this.Id, certToSend), UriKind.Relative); - IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetQueryRetryPolicy(); + IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetQueryRetryPolicy(dataContext as IRetryPolicyAdapter); IEnumerable results = retryPolicy.ExecuteAction>(() => dataContext.Execute(uriRebindContentKey)); @@ -148,9 +148,9 @@ public Task DeleteAsync() IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(ContentKeyBaseCollection.ContentKeySet, this); - dataContext.DeleteObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.DeleteObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } @@ -178,9 +178,9 @@ public Task UpdateAsync() { IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(ContentKeyBaseCollection.ContentKeySet, this); - dataContext.UpdateObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.UpdateObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)) .ContinueWith( @@ -216,9 +216,9 @@ public Task GetKeyDeliveryUrlAsync(ContentKeyDeliveryType contentKeyDeliver Uri returnValue = null; if (this.GetMediaContext() != null) { - IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); Uri uriGetKeyDeliveryUrl = new Uri(string.Format(CultureInfo.InvariantCulture, "/ContentKeys('{0}')/GetKeyDeliveryUrl", this.Id), UriKind.Relative); diff --git a/src/net/Client/Entities/JobData.cs b/src/net/Client/Entities/JobData.cs index 604ba524..88f11817 100644 --- a/src/net/Client/Entities/JobData.cs +++ b/src/net/Client/Entities/JobData.cs @@ -239,9 +239,9 @@ public Task DeleteAsync() IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(JobBaseCollection.JobSet, this); - dataContext.DeleteObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.DeleteObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } @@ -276,9 +276,9 @@ public Task UpdateAsync() IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(JobBaseCollection.JobSet, this); - dataContext.UpdateObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.UpdateObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)) .ContinueWith( @@ -320,9 +320,9 @@ public Task SubmitAsync() IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); - this.InnerSubmit(dataContext); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + this.InnerSubmit(dataContext); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(SaveChangesOptions.Batch, this)) .ContinueWith( @@ -814,9 +814,9 @@ private Task CreateJobTemplate(string templateName, JobTemplateTyp jobTemplateData.NumberofInputAssets = string.IsNullOrWhiteSpace(this.Id) ? assetIdMap.Inputs.Count - : ((IJob)this).InputMediaAssets.Count; - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + : ((IJob)this).InputMediaAssets.Count; + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(SaveChangesOptions.Batch, jobTemplateData)) .ContinueWith( diff --git a/src/net/Client/Entities/JobTemplateData.cs b/src/net/Client/Entities/JobTemplateData.cs index 12a1d205..6704c486 100644 --- a/src/net/Client/Entities/JobTemplateData.cs +++ b/src/net/Client/Entities/JobTemplateData.cs @@ -129,9 +129,9 @@ public Task SaveAsync() IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); - this.InnerSave(dataContext); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + this.InnerSave(dataContext); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(SaveChangesOptions.Batch, this)) .ContinueWith( @@ -174,9 +174,9 @@ public Task DeleteAsync() IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(JobTemplateBaseCollection.JobTemplateSet, this); - dataContext.DeleteObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.DeleteObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } diff --git a/src/net/Client/Entities/LocatorData.cs b/src/net/Client/Entities/LocatorData.cs index a3cd03ca..307069b6 100644 --- a/src/net/Client/Entities/LocatorData.cs +++ b/src/net/Client/Entities/LocatorData.cs @@ -15,7 +15,8 @@ // using System; -using System.Data.Services.Common; +using System.Data.Services.Common; +using System.Globalization; using System.Linq; using System.Threading.Tasks; using Microsoft.WindowsAzure.MediaServices.Client.TransientFaultHandling; @@ -30,8 +31,13 @@ namespace Microsoft.WindowsAzure.MediaServices.Client internal partial class LocatorData : BaseEntity, ILocator { private AccessPolicyData _accessPolicy; - private AssetData _asset; - + private AssetData _asset; + + /// + /// The prefix for the locator Id. + /// + internal const string LocatorIdentifierPrefix = "nb:lid:UUID:"; + /// /// Gets or sets the that defines this locator. /// @@ -57,7 +63,7 @@ IAccessPolicy ILocator.AccessPolicy { get { - if ((this._accessPolicy == null) && !string.IsNullOrWhiteSpace(this.Id)) + if ((this._accessPolicy == null) && !String.IsNullOrWhiteSpace(this.Id)) { IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(LocatorBaseCollection.LocatorSet, this); @@ -75,7 +81,7 @@ IAsset ILocator.Asset { get { - if ((this._asset == null) && !string.IsNullOrWhiteSpace(this.Id)) + if ((this._asset == null) && !String.IsNullOrWhiteSpace(this.Id)) { IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(LocatorBaseCollection.LocatorSet, this); @@ -129,9 +135,9 @@ public Task UpdateAsync(DateTime? startTime, DateTime expiryTime) this.StartTime = startTime; this.ExpirationDateTime = expiryTime; - dataContext.UpdateObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.UpdateObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } @@ -164,9 +170,9 @@ public Task DeleteAsync() IMediaDataServiceContext dataContext = this.GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(LocatorBaseCollection.LocatorSet, this); - dataContext.DeleteObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.DeleteObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)) .ContinueWith( @@ -206,8 +212,30 @@ public void Delete() { throw exception.InnerException; } + } + + internal static string NormalizeLocatorId(string locatorId) + { + if (String.IsNullOrWhiteSpace(locatorId)) + { + return null; + } + + if (locatorId.StartsWith(LocatorIdentifierPrefix, StringComparison.OrdinalIgnoreCase)) + { + locatorId = locatorId.Remove(0, LocatorIdentifierPrefix.Length); + } + + Guid locatorIdGuid; + if (!Guid.TryParse(locatorId, out locatorIdGuid)) + { + throw new ArgumentException( + String.Format(CultureInfo.InvariantCulture, "Invalid locator Id. Make sure to use the following format: '{0}'", LocatorIdentifierPrefix), + "locatorId"); + } + + return String.Concat((string)LocatorData.LocatorIdentifierPrefix, locatorIdGuid.ToString()); } - private static LocatorType GetExposedType(int type) { return (LocatorType)type; diff --git a/src/net/Client/Entities/NotificationEndpoint.cs b/src/net/Client/Entities/NotificationEndpoint.cs index 5ba65aa3..f45bfb89 100644 --- a/src/net/Client/Entities/NotificationEndpoint.cs +++ b/src/net/Client/Entities/NotificationEndpoint.cs @@ -160,9 +160,9 @@ public Task UpdateAsync() { IMediaDataServiceContext dataContext = GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(NotificationEndPointCollection.NotificationEndPoints, this); - dataContext.UpdateObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.UpdateObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } @@ -190,9 +190,9 @@ public Task DeleteAsync() { IMediaDataServiceContext dataContext = GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(NotificationEndPointCollection.NotificationEndPoints, this); - dataContext.DeleteObject(this); - - MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.DeleteObject(this); + + MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } diff --git a/src/net/Client/Entities/ODataClasses.cs b/src/net/Client/Entities/ODataClasses.cs index dc095b69..61cf3455 100644 --- a/src/net/Client/Entities/ODataClasses.cs +++ b/src/net/Client/Entities/ODataClasses.cs @@ -18,8 +18,9 @@ // This class is auto generated. Edit ODataClasses.tt // -using System; - +using System; +using System.Diagnostics.CodeAnalysis; + namespace Microsoft.WindowsAzure.MediaServices.Client { partial class AssetData : IAsset @@ -331,34 +332,34 @@ TaskOptions ITask.Options partial class LocatorData : ILocator { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public string Id {get;set;} - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public string AssetId {get;set;} - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public DateTime? StartTime {get;set;} - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public DateTime ExpirationDateTime {get;set;} - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public string AccessPolicyId {get;set;} - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public int Type {get;set;} - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public string Path {get;set;} - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public string BaseUri { get; set; } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public string ContentAccessComponent { get; set; } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public string Name { get; set; } LocatorType ILocator.Type { get { - return LocatorData.GetExposedType(Type); + return GetExposedType(Type); } - } + } } partial class MediaProcessorData : IMediaProcessor diff --git a/src/net/Client/IMediaDataServiceContext.cs b/src/net/Client/IMediaDataServiceContext.cs index 912d6728..a731aaa8 100644 --- a/src/net/Client/IMediaDataServiceContext.cs +++ b/src/net/Client/IMediaDataServiceContext.cs @@ -7,7 +7,9 @@ namespace Microsoft.WindowsAzure.MediaServices.Client { public interface IMediaDataServiceContext - { + { + + /// /// Gets or sets whether an exception is raised when a 404 error (resource not found) is returned by the data service. /// @@ -18,7 +20,7 @@ public interface IMediaDataServiceContext /// create a query based on (BaseUri + relativeUri) /// /// The exposed interface type of elements returned by the query. - /// The type used by the query internaly. + /// The type used by the query internally. /// A string that resolves to a URI. /// A new System.Data.Services.Client.DataServiceQuery instance that represents a data service query. IQueryable CreateQuery(string entitySetName); @@ -181,113 +183,104 @@ public interface IMediaDataServiceContext /// The parent object that is being tracked by the context. /// The name of the navigation property that returns the related object based on an association between the two entities. /// The related object that is being added. - void AddRelatedObject(object source, string sourceProperty, object target); - - /// - /// Executes the operation asynchronously. - /// - /// The type of the element. - /// The context. - /// The continuation. - /// The state. - /// A function delegate that returns the future result to be available through the Task. - Task> ExecuteAsync(DataServiceQueryContinuation continuation, object state); - - /// - /// Executes the operation asynchronously. - /// - /// The type of the element. - /// The context. - /// The request URI. - /// The state. - /// A function delegate that returns the future result to be available through the Task. - Task> ExecuteAsync(Uri requestUri, object state); - - /// - /// Executes the asynchronously. - /// - /// The context. - /// The request URI. - /// The state. - /// The HTTP method. - /// A function delegate that returns the future result to be available through the Task. - Task ExecuteAsync(Uri requestUri, object state, string httpMethod); - - /// - /// Executes the url method asynchronously. - /// - /// The request URI. - /// The HTTP method. - /// Whether a single result is expected or not. - /// OperationParameters to be sent with the Execute request. - /// A function delegate that returns the future result to be available through the Task. - Task> ExecuteAsync(Uri requestUri, string httpMethod, bool singleResult, params OperationParameter[] parameter); - /// - /// Executes the batch operation asynchronously. - /// - /// The context. - /// The state. - /// The queries. - /// A function delegate that returns the future result to be available through the Task. - Task ExecuteBatchAsync(object state, params DataServiceRequest[] queries); - - /// - /// Gets the read stream asynchronously. - /// - /// The context. - /// The entity. - /// The args. - /// The state. - /// A function delegate that returns the future result to be available through the Task. - Task GetReadStreamAsync(object entity, DataServiceRequestArgs args, object state); - - /// - /// Loads the property asynchronously. - /// - /// The context. - /// The entity. - /// Name of the property. - /// The state. - /// A function delegate that returns the future result to be available through the Task. - Task LoadPropertyAsync(object entity, string propertyName, object state); - - /// - /// Loads the property asynchronously. - /// - /// The context. - /// The entity. - /// Name of the property. - /// The continuation. - /// The state. - /// A function delegate that returns the future result to be available through the Task. - Task LoadPropertyAsync(object entity, string propertyName, DataServiceQueryContinuation continuation, object state); - - /// - /// Loads the property asynchronously. - /// - /// The context. - /// The entity. - /// Name of the property. - /// The next link URI. - /// The state. - /// A function delegate that returns the future result to be available through the Task. - Task LoadPropertyAsync(object entity, string propertyName, Uri nextLinkUri, object state); - - /// - /// Saves the changes asynchronously. - /// - /// The context. - /// The state. - /// A function delegate that returns the future result to be available through the Task. - Task SaveChangesAsync(object state); - - /// - /// Saves the changes asynchronously. - /// - /// The context. - /// The options. - /// The state. - /// A function delegate that returns the future result to be available through the Task. + void AddRelatedObject(object source, string sourceProperty, object target); + + /// + /// Executes the operation asynchronously. + /// + /// The type of the element. + /// The continuation. + /// The state. + /// A function delegate that returns the future result to be available through the Task. + Task> ExecuteAsync(DataServiceQueryContinuation continuation, object state); + + /// + /// Executes the operation asynchronously. + /// + /// The type of the element. + /// The request URI. + /// The state. + /// A function delegate that returns the future result to be available through the Task. + Task> ExecuteAsync(Uri requestUri, object state); + + /// + /// Executes the asynchronously. + /// + /// The request URI. + /// The state. + /// The HTTP method. + /// A function delegate that returns the future result to be available through the Task. + Task ExecuteAsync(Uri requestUri, object state, string httpMethod); + + /// + /// Executes the url method asynchronously. + /// + /// The request URI. + /// The HTTP method. + /// Whether a single result is expected or not. + /// OperationParameters to be sent with the Execute request. + /// A function delegate that returns the future result to be available through the Task. + Task> ExecuteAsync(Uri requestUri, string httpMethod, bool singleResult, params OperationParameter[] parameters); + + /// + /// Executes the batch operation asynchronously. + /// + /// The state. + /// The queries. + /// A function delegate that returns the future result to be available through the Task. + Task ExecuteBatchAsync(object state, params DataServiceRequest[] queries); + + /// + /// Gets the read stream asynchronously. + /// + /// The entity. + /// The args. + /// The state. + /// A function delegate that returns the future result to be available through the Task. + Task GetReadStreamAsync(object entity, DataServiceRequestArgs args, object state); + + /// + /// Loads the property asynchronously. + /// + /// The entity. + /// Name of the property. + /// The state. + /// A function delegate that returns the future result to be available through the Task. + Task LoadPropertyAsync(object entity, string propertyName, object state); + + /// + /// Loads the property asynchronously. + /// + /// The entity. + /// Name of the property. + /// The continuation. + /// The state. + /// A function delegate that returns the future result to be available through the Task. + Task LoadPropertyAsync(object entity, string propertyName, DataServiceQueryContinuation continuation, object state); + + /// + /// Loads the property asynchronously. + /// + /// The entity. + /// Name of the property. + /// The next link URI. + /// The state. + /// A function delegate that returns the future result to be available through the Task. + Task LoadPropertyAsync(object entity, string propertyName, Uri nextLinkUri, object state); + + /// + /// Saves the changes asynchronously. + /// + /// The state. + /// A function delegate that returns the future result to be available through the Task. + Task SaveChangesAsync(object state); + + /// + /// Saves the changes asynchronously. + /// + /// The options. + /// The state. + /// A function delegate that returns the future result to be available through the Task. Task SaveChangesAsync(SaveChangesOptions options, object state); - } + } } diff --git a/src/net/Client/Live/AsyncHelper.cs b/src/net/Client/Live/AsyncHelper.cs index 515a5513..95dbbad4 100644 --- a/src/net/Client/Live/AsyncHelper.cs +++ b/src/net/Client/Live/AsyncHelper.cs @@ -78,9 +78,9 @@ public static IOperation WaitOperationCompletion(MediaContextBase context, strin System.Threading.Thread.Sleep(pollInterval); IMediaDataServiceContext dataContext = context.MediaServicesClassFactory.CreateDataServiceContext(); - Uri uri = new Uri(string.Format(CultureInfo.InvariantCulture, "/Operations('{0}')", operationId), UriKind.Relative); - - MediaRetryPolicy retryPolicy = context.MediaServicesClassFactory.GetQueryRetryPolicy(); + Uri uri = new Uri(string.Format(CultureInfo.InvariantCulture, "/Operations('{0}')", operationId), UriKind.Relative); + + MediaRetryPolicy retryPolicy = context.MediaServicesClassFactory.GetQueryRetryPolicy(dataContext as IRetryPolicyAdapter); try { diff --git a/src/net/Client/Live/ChannelBaseCollection.cs b/src/net/Client/Live/ChannelBaseCollection.cs index 8667223e..b089a6bd 100644 --- a/src/net/Client/Live/ChannelBaseCollection.cs +++ b/src/net/Client/Live/ChannelBaseCollection.cs @@ -208,22 +208,14 @@ private Task CreateChannelAsync(ChannelCreationOption channel.Preview = options.Preview; channel.Output = options.Output; - if (channel.Input.Endpoints == null) - { - channel.Input.Endpoints = new List().AsReadOnly(); - } - - if (channel.Preview != null && channel.Preview.Endpoints == null) - { - channel.Preview.Endpoints = new List().AsReadOnly(); - } + channelData.ValidateSettings(); channelData.SetMediaContext(MediaContext); IMediaDataServiceContext dataContext = MediaContext.MediaServicesClassFactory.CreateDataServiceContext(); - dataContext.AddObject(ChannelSet, channel); - - MediaRetryPolicy retryPolicy = MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.AddObject(ChannelSet, channel); + + MediaRetryPolicy retryPolicy = MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(channel)); } diff --git a/src/net/Client/Live/ChannelData.cs b/src/net/Client/Live/ChannelData.cs index 38df4474..53266916 100644 --- a/src/net/Client/Live/ChannelData.cs +++ b/src/net/Client/Live/ChannelData.cs @@ -13,6 +13,7 @@ // limitations under the License. using System; +using System.Collections.Generic; using System.Data.Services.Common; using System.Globalization; using System.Linq; @@ -267,9 +268,9 @@ public override Task DeleteAsync() IMediaDataServiceContext dataContext = GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(EntitySetName, this); - dataContext.DeleteObject(this); - - MediaRetryPolicy retryPolicy = GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.DeleteObject(this); + + MediaRetryPolicy retryPolicy = GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)) .ContinueWith(t => @@ -314,9 +315,9 @@ public IOperation SendDeleteOperation() IMediaDataServiceContext dataContext = GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(EntitySetName, this); - dataContext.DeleteObject(this); - - MediaRetryPolicy retryPolicy = GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.DeleteObject(this); + + MediaRetryPolicy retryPolicy = GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); var response = retryPolicy.ExecuteAction(() => dataContext.SaveChanges()); @@ -355,6 +356,23 @@ internal override void Refresh() base.Refresh(); } + /// + /// Set array property empty array if it is null because OData does not support + /// empty collection + /// + internal override void ValidateSettings() + { + if (_input != null && _input.Endpoints == null) + { + _input.Endpoints = new List().AsReadOnly(); + } + + if (_preview != null && _preview.Endpoints == null) + { + _preview.Endpoints = new List().AsReadOnly(); + } + } + /// /// Invalidates collections to force them to be reloaded from server. /// diff --git a/src/net/Client/Live/OperationBaseCollection.cs b/src/net/Client/Live/OperationBaseCollection.cs index a562825c..5d6ae91d 100644 --- a/src/net/Client/Live/OperationBaseCollection.cs +++ b/src/net/Client/Live/OperationBaseCollection.cs @@ -33,9 +33,9 @@ internal OperationBaseCollection(CloudMediaContext cloudMediaContext) public IOperation GetOperation(string id) { Uri uri = new Uri(string.Format(CultureInfo.InvariantCulture, "/{0}('{1}')", OperationSet, id), UriKind.Relative); - IMediaDataServiceContext dataContext = this._cloudMediaContext.MediaServicesClassFactory.CreateDataServiceContext(); - - MediaRetryPolicy retryPolicy = _cloudMediaContext.MediaServicesClassFactory.GetQueryRetryPolicy(); + IMediaDataServiceContext dataContext = this._cloudMediaContext.MediaServicesClassFactory.CreateDataServiceContext(); + + MediaRetryPolicy retryPolicy = _cloudMediaContext.MediaServicesClassFactory.GetQueryRetryPolicy(dataContext as IRetryPolicyAdapter); IOperation operation = retryPolicy.ExecuteAction>(() => dataContext.Execute(uri)).SingleOrDefault(); return operation; diff --git a/src/net/Client/Live/ProgramBaseCollection.cs b/src/net/Client/Live/ProgramBaseCollection.cs index 510b8cde..d121ffb0 100644 --- a/src/net/Client/Live/ProgramBaseCollection.cs +++ b/src/net/Client/Live/ProgramBaseCollection.cs @@ -125,9 +125,9 @@ public Task CreateAsync(ProgramCreationOptions options) program.SetMediaContext(MediaContext); IMediaDataServiceContext dataContext = MediaContext.MediaServicesClassFactory.CreateDataServiceContext(); - dataContext.AddObject(ProgramSet, program); - - MediaRetryPolicy retryPolicy = MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.AddObject(ProgramSet, program); + + MediaRetryPolicy retryPolicy = MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(program)) .ContinueWith(t => diff --git a/src/net/Client/Live/RestEntity.cs b/src/net/Client/Live/RestEntity.cs index c3842479..4f07288c 100644 --- a/src/net/Client/Live/RestEntity.cs +++ b/src/net/Client/Live/RestEntity.cs @@ -47,9 +47,9 @@ public virtual Task DeleteAsync() IMediaDataServiceContext dataContext = GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(EntitySetName, this); - dataContext.DeleteObject(this); - - MediaRetryPolicy retryPolicy = GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.DeleteObject(this); + + MediaRetryPolicy retryPolicy = GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(this)); } @@ -60,11 +60,13 @@ public virtual Task DeleteAsync() /// Operation info that can be used to track the operation. public IOperation SendUpdateOperation() { + ValidateSettings(); + IMediaDataServiceContext dataContext = GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AttachTo(EntitySetName, this); - dataContext.UpdateObject(this); - - MediaRetryPolicy retryPolicy = GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.UpdateObject(this); + + MediaRetryPolicy retryPolicy = GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); var response = retryPolicy.ExecuteAction(() => dataContext.SaveChanges()).Single(); @@ -164,9 +166,9 @@ protected Task ExecuteActionAsync(Uri uri, TimeSpan pollInterval, params Operati { if (GetMediaContext() != null) { - IMediaDataServiceContext dataContext = GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); - - MediaRetryPolicy retryPolicy = GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + IMediaDataServiceContext dataContext = GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); + + MediaRetryPolicy retryPolicy = GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); var response = retryPolicy.ExecuteAction(() => dataContext.Execute(uri, "POST", operationParameters)); @@ -215,9 +217,9 @@ protected Task ExecuteActionAsync(Uri uri, TimeSpan pollInterval, params Operati protected IOperation SendOperation(Uri uri, params OperationParameter[] operationParameters) { - IMediaDataServiceContext dataContext = GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); - - MediaRetryPolicy retryPolicy = GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + IMediaDataServiceContext dataContext = GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); + + MediaRetryPolicy retryPolicy = GetMediaContext().MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); var response = retryPolicy.ExecuteAction(() => dataContext.Execute(uri, "POST", operationParameters)); @@ -255,13 +257,15 @@ protected IOperation SendOperation(Uri uri, params OperationParameter[] operatio }; } + internal virtual void ValidateSettings() { } + internal virtual void Refresh() { Uri uri = new Uri(string.Format(CultureInfo.InvariantCulture, "/{0}('{1}')", EntitySetName, Id), UriKind.Relative); IMediaDataServiceContext dataContext = GetMediaContext().MediaServicesClassFactory.CreateDataServiceContext(); - dataContext.AttachTo(EntitySetName, this, Guid.NewGuid().ToString()); - - MediaRetryPolicy retryPolicy = GetMediaContext().MediaServicesClassFactory.GetQueryRetryPolicy(); + dataContext.AttachTo(EntitySetName, this, Guid.NewGuid().ToString()); + + MediaRetryPolicy retryPolicy = GetMediaContext().MediaServicesClassFactory.GetQueryRetryPolicy(dataContext as IRetryPolicyAdapter); // ReSharper disable once ReturnValueOfPureMethodIsNotUsed retryPolicy.ExecuteAction(() => dataContext.Execute(uri)).Single(); diff --git a/src/net/Client/Live/StreamingEndpointBaseCollection.cs b/src/net/Client/Live/StreamingEndpointBaseCollection.cs index 140f5dea..e18908f1 100644 --- a/src/net/Client/Live/StreamingEndpointBaseCollection.cs +++ b/src/net/Client/Live/StreamingEndpointBaseCollection.cs @@ -185,30 +185,32 @@ private Task CreateStreamingEndpointAsync(StreamingEn { throw new ArgumentException(Resources.ErrorEmptyStreamingEndpointName); } - - if (options.CustomHostNames == null) - { - options.CustomHostNames = new List(); - } - + var streamingEndpoint = new StreamingEndpointData { Name = options.Name, Description = options.Description, - CustomHostNames = (options.CustomHostNames as IList) ?? options.CustomHostNames.ToList(), ScaleUnits = options.ScaleUnits, CrossSiteAccessPolicies = options.CrossSiteAccessPolicies }; + if (options.CustomHostNames != null) + { + streamingEndpoint.CustomHostNames = (options.CustomHostNames as IList) ?? + options.CustomHostNames.ToList(); + } + ((IStreamingEndpoint) streamingEndpoint).AccessControl = options.AccessControl; ((IStreamingEndpoint) streamingEndpoint).CacheControl = options.CacheControl; + streamingEndpoint.ValidateSettings(); + streamingEndpoint.SetMediaContext(MediaContext); IMediaDataServiceContext dataContext = MediaContext.MediaServicesClassFactory.CreateDataServiceContext(); - dataContext.AddObject(StreamingEndpointSet, streamingEndpoint); - - MediaRetryPolicy retryPolicy = MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(); + dataContext.AddObject(StreamingEndpointSet, streamingEndpoint); + + MediaRetryPolicy retryPolicy = MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(streamingEndpoint)); } diff --git a/src/net/Client/Live/StreamingEndpointData.cs b/src/net/Client/Live/StreamingEndpointData.cs index 18ea32e4..be63e16f 100644 --- a/src/net/Client/Live/StreamingEndpointData.cs +++ b/src/net/Client/Live/StreamingEndpointData.cs @@ -316,5 +316,17 @@ internal override void Refresh() _cacheControl = null; base.Refresh(); } + + /// + /// Set array property empty array if it is null because OData does not support + /// empty collection + /// + internal override void ValidateSettings() + { + if (CustomHostNames == null) + { + CustomHostNames = new List(); + } + } } } diff --git a/src/net/Client/MediaDataServiceContext.cs b/src/net/Client/MediaDataServiceContext.cs index 8b27291a..2df9df1b 100644 --- a/src/net/Client/MediaDataServiceContext.cs +++ b/src/net/Client/MediaDataServiceContext.cs @@ -1,23 +1,48 @@ -using System; -using System.Collections.Generic; -using System.Data.Services.Client; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.WindowsAzure.MediaServices.Client.TransientFaultHandling; +//----------------------------------------------------------------------- +// Copyright 2012 Microsoft Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +using System; +using System.Collections.Generic; +using System.Data.Services.Client; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.WindowsAzure.MediaServices.Client.RequestAdapters; +using Microsoft.WindowsAzure.MediaServices.Client.TransientFaultHandling; + namespace Microsoft.WindowsAzure.MediaServices.Client { /// /// Wraps System.Data.Services.Client.DataServiceContext. /// - public class MediaDataServiceContext : IMediaDataServiceContext - { - public MediaDataServiceContext(DataServiceContext dataContext, MediaRetryPolicy queryRetryPolicy) - { - _dataContext = dataContext; - _queryRetryPolicy = queryRetryPolicy; - } - + public class MediaDataServiceContext : IMediaDataServiceContext,IRetryPolicyAdapter + { + private readonly DataServiceContext _dataContext; + private readonly MediaRetryPolicy _queryRetryPolicy; + + + private readonly ClientRequestIdAdapter _clientRequestIdAdapter; + + public MediaDataServiceContext(DataServiceContext dataContext, MediaRetryPolicy queryRetryPolicy, ClientRequestIdAdapter clientRequestAdapter) + { + _dataContext = dataContext; + _queryRetryPolicy = queryRetryPolicy; + _clientRequestIdAdapter = clientRequestAdapter; + + } + /// /// Gets or sets whether an exception is raised when a 404 error (resource not found) is returned by the data service. /// @@ -41,8 +66,9 @@ public bool IgnoreResourceNotFoundException /// The type used by the query internaly. /// A string that resolves to a URI. /// A new System.Data.Services.Client.DataServiceQuery instance that represents a data service query. - public IQueryable CreateQuery(string entitySetName) - { + public IQueryable CreateQuery(string entitySetName) + { + _clientRequestIdAdapter.ChangeCurrentRequestId(); IQueryable inner = (IQueryable)_dataContext.CreateQuery(entitySetName); var result = new MediaQueryable(inner, _queryRetryPolicy); return result; @@ -380,8 +406,8 @@ public Task SaveChangesAsync(object state) { return Task.Factory.FromAsync(_dataContext.BeginSaveChanges, _dataContext.EndSaveChanges, state) .ContinueWith(t => WrapTask(t)); - } - + } + /// /// Saves the changes asynchronously. /// @@ -400,9 +426,25 @@ private IMediaDataServiceResponse WrapTask(Task task) var result = new MediaDataServiceResponse(task.Result); result.AsyncState = task.AsyncState; return result; - } - - private DataServiceContext _dataContext; - private MediaRetryPolicy _queryRetryPolicy; + } + + public Func AdaptExecuteAsync(Func taskFunc) + { + _clientRequestIdAdapter.ChangeCurrentRequestId(); + return taskFunc; + } + + Func IRetryPolicyAdapter.AdaptExecuteAction(Func func) + { + _clientRequestIdAdapter.ChangeCurrentRequestId(); + return func; + } + + Func> IRetryPolicyAdapter.AdaptExecuteAsync(Func> taskFunc) + { + _clientRequestIdAdapter.ChangeCurrentRequestId(); + return taskFunc; + } + } } diff --git a/src/net/Client/MediaServicesClassFactory.cs b/src/net/Client/MediaServicesClassFactory.cs index f2cd812a..173dd258 100644 --- a/src/net/Client/MediaServicesClassFactory.cs +++ b/src/net/Client/MediaServicesClassFactory.cs @@ -12,8 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -// - +// + +using System; using Microsoft.WindowsAzure.MediaServices.Client.TransientFaultHandling; namespace Microsoft.WindowsAzure.MediaServices.Client @@ -30,14 +31,16 @@ public abstract class MediaServicesClassFactory /// Creates retry policy used for working with Azure blob storage. /// /// Retry policy. - public abstract MediaRetryPolicy GetBlobStorageClientRetryPolicy(); - + public abstract MediaRetryPolicy GetBlobStorageClientRetryPolicy(); + + [Obsolete] /// /// Creates retry policy for saving changes in Media Services REST layer. /// /// Retry policy. - public abstract MediaRetryPolicy GetSaveChangesRetryPolicy(); - + public abstract MediaRetryPolicy GetSaveChangesRetryPolicy(); + + [Obsolete] /// /// Creates retry policy for querying Media Services REST layer. /// @@ -84,6 +87,9 @@ public virtual MediaErrorDetectionStrategy GetStorageTransientErrorDetectionStra public virtual BlobTransferClient GetBlobTransferClient() { return new BlobTransferClient(); - } + } + + public abstract MediaRetryPolicy GetSaveChangesRetryPolicy(IRetryPolicyAdapter adapter); + public abstract MediaRetryPolicy GetQueryRetryPolicy(IRetryPolicyAdapter adapter); } } \ No newline at end of file diff --git a/src/net/Client/OAuth/OAuthDataServiceAdapter.cs b/src/net/Client/OAuth/OAuthDataServiceAdapter.cs index cf2f65eb..d4c8ce90 100644 --- a/src/net/Client/OAuth/OAuthDataServiceAdapter.cs +++ b/src/net/Client/OAuth/OAuthDataServiceAdapter.cs @@ -69,7 +69,7 @@ public OAuthDataServiceAdapter(MediaServicesCredentials credentials, string trus /// The data service context. public void Adapt(DataServiceContext dataServiceContext) { - dataServiceContext.SendingRequest += this.OnSendingRequest; + dataServiceContext.SendingRequest2 += this.OnSendingRequest; } /// @@ -83,20 +83,24 @@ public void AddAccessTokenToRequest(WebRequest request) throw new ArgumentNullException("request"); } - if (request.Headers[AuthorizationHeader] == null) - { - lock (_acsRefreshLock) - { - if (DateTime.UtcNow.AddSeconds(ExpirationTimeBufferInSeconds) > this._credentials.TokenExpiration) - { - this._credentials.RefreshToken(); - } - } - - request.Headers.Add(AuthorizationHeader, string.Format(CultureInfo.InvariantCulture, BearerTokenFormat, this._credentials.AccessToken)); - } - } - + if (request.Headers[AuthorizationHeader] == null) + { + RefreshToken(); + request.Headers.Add(AuthorizationHeader, string.Format(CultureInfo.InvariantCulture, BearerTokenFormat, this._credentials.AccessToken)); + } + } + + private void RefreshToken() + { + lock (_acsRefreshLock) + { + if (DateTime.UtcNow.AddSeconds(ExpirationTimeBufferInSeconds) > this._credentials.TokenExpiration) + { + this._credentials.RefreshToken(); + } + } + } + private bool ValidateCertificate(object s, X509Certificate cert, X509Chain chain, SslPolicyErrors error) { if (error.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch) || error.HasFlag(SslPolicyErrors.RemoteCertificateChainErrors)) @@ -123,9 +127,13 @@ private bool ValidateCertificate(object s, X509Certificate cert, X509Chain chain /// /// Event sender. /// Event arguments. - private void OnSendingRequest(object sender, SendingRequestEventArgs e) - { - this.AddAccessTokenToRequest(e.Request); + private void OnSendingRequest(object sender, SendingRequest2EventArgs e) + { + if (e.RequestMessage.GetHeader(AuthorizationHeader) == null) + { + RefreshToken(); + e.RequestMessage.SetHeader(AuthorizationHeader, string.Format(CultureInfo.InvariantCulture, BearerTokenFormat, this._credentials.AccessToken)); + } } } } diff --git a/src/net/Client/Properties/AssemblyInfo.cs b/src/net/Client/Properties/AssemblyInfo.cs index d35537a0..6b5e7f61 100644 --- a/src/net/Client/Properties/AssemblyInfo.cs +++ b/src/net/Client/Properties/AssemblyInfo.cs @@ -47,8 +47,8 @@ // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("3.0.0.7")] -[assembly: AssemblyFileVersion("3.0.0.7")] +[assembly: AssemblyVersion("3.0.0.8")] +[assembly: AssemblyFileVersion("3.0.0.8")] [assembly: NeutralResourcesLanguage("en-US")] //For delay signing specify PublicKey for each friendly assembly @@ -57,4 +57,4 @@ //[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.WindowsAzure.MediaServices.Client.Tests.Common, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.WindowsAzure.MediaServices.Client.Tests.Scenario")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.WindowsAzure.MediaServices.Client.Tests.Unit")] -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.WindowsAzure.MediaServices.Client.Tests.Common")] \ No newline at end of file +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.WindowsAzure.MediaServices.Client.Tests.Common")] diff --git a/src/net/Client/RequestAdapters/ClientRequestIdAdapter.cs b/src/net/Client/RequestAdapters/ClientRequestIdAdapter.cs new file mode 100644 index 00000000..a1e6e91d --- /dev/null +++ b/src/net/Client/RequestAdapters/ClientRequestIdAdapter.cs @@ -0,0 +1,71 @@ +//----------------------------------------------------------------------- +// Copyright 2012 Microsoft Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Data.Services.Client; +using System.Net; + +namespace Microsoft.WindowsAzure.MediaServices.Client.RequestAdapters +{ + /// + /// ClientRequestIdAdapter is used to add user agent specific information to http request. + /// + public class ClientRequestIdAdapter + { + + private const string XMsClientRequestId = "x-ms-client-request-id"; + private Guid _requestId; + /// + /// Adapts the specified context. + /// + /// The context. + public void Adapt(DataServiceContext context) + { + _requestId = Guid.NewGuid(); + context.SendingRequest2 += this.AddClientRequestId; + } + + /// + /// Adds client request id. + /// + /// The request. + public void AddClientRequestId(WebRequest request) + { + if (request == null) + { + throw new ArgumentNullException("request"); + } + + request.Headers.Set(XMsClientRequestId,_requestId.ToString()); + + } + + /// + /// Adds the request version. + /// + /// The sender. + /// The instance containing the event data. + private void AddClientRequestId(object sender, SendingRequest2EventArgs e) + { + e.RequestMessage.SetHeader(XMsClientRequestId, _requestId.ToString()); + } + + public void ChangeCurrentRequestId() + { + _requestId = Guid.NewGuid(); + } + } +} \ No newline at end of file diff --git a/src/net/Client/Versioning/KnownApiVersions.cs b/src/net/Client/RequestAdapters/KnownApiVersions.cs similarity index 94% rename from src/net/Client/Versioning/KnownApiVersions.cs rename to src/net/Client/RequestAdapters/KnownApiVersions.cs index 1f6cb3fe..2496f01c 100644 --- a/src/net/Client/Versioning/KnownApiVersions.cs +++ b/src/net/Client/RequestAdapters/KnownApiVersions.cs @@ -16,7 +16,7 @@ using System; -namespace Microsoft.WindowsAzure.MediaServices.Client.Versioning +namespace Microsoft.WindowsAzure.MediaServices.Client.RequestAdapters { diff --git a/src/net/Client/RequestAdapters/KnownClientVersions.cs b/src/net/Client/RequestAdapters/KnownClientVersions.cs new file mode 100644 index 00000000..abfcff6f --- /dev/null +++ b/src/net/Client/RequestAdapters/KnownClientVersions.cs @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------- +// Copyright 2012 Microsoft Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + + +using System; +using System.Reflection; + +namespace Microsoft.WindowsAzure.MediaServices.Client.RequestAdapters +{ + /// + /// KnownClientVersions contains logic to return client library version + /// + internal static class KnownClientVersions + { + /// + /// Current client version. + /// + public static readonly Version Current = Assembly.GetExecutingAssembly().GetName().Version; + + + } +} \ No newline at end of file diff --git a/src/net/Client/Versioning/ServiceVersionAdapter.cs b/src/net/Client/RequestAdapters/ServiceVersionAdapter.cs similarity index 76% rename from src/net/Client/Versioning/ServiceVersionAdapter.cs rename to src/net/Client/RequestAdapters/ServiceVersionAdapter.cs index 2fc70262..45feb3ec 100644 --- a/src/net/Client/Versioning/ServiceVersionAdapter.cs +++ b/src/net/Client/RequestAdapters/ServiceVersionAdapter.cs @@ -16,9 +16,9 @@ using System; using System.Data.Services.Client; -using System.Net; - -namespace Microsoft.WindowsAzure.MediaServices.Client.Versioning +using System.Net; + +namespace Microsoft.WindowsAzure.MediaServices.Client.RequestAdapters { @@ -26,7 +26,8 @@ namespace Microsoft.WindowsAzure.MediaServices.Client.Versioning /// An adapter to add the service version to the request. /// public class ServiceVersionAdapter - { + { + private const string _xMsVersion = "x-ms-version"; private readonly Version _serviceVersion; /// @@ -44,7 +45,7 @@ public ServiceVersionAdapter(Version serviceVersion) /// The context. public void Adapt(DataServiceContext context) { - context.SendingRequest += this.AddRequestVersion; + context.SendingRequest2 += this.AddRequestVersion; } /// @@ -58,7 +59,7 @@ public void AddVersionToRequest(WebRequest request) throw new ArgumentNullException("request"); } - request.Headers.Add("x-ms-version", this._serviceVersion.ToString()); + request.Headers.Set(_xMsVersion, this._serviceVersion.ToString()); } /// @@ -66,18 +67,10 @@ public void AddVersionToRequest(WebRequest request) /// /// The sender. /// The instance containing the event data. - private void AddRequestVersion(object sender, SendingRequestEventArgs e) - { - this.AddToRequestHeaders(e); - } - - /// - /// Adds to request headers. - /// - /// The instance containing the event data. - private void AddToRequestHeaders(SendingRequestEventArgs sendingRequestEventArgs) - { - this.AddVersionToRequest(sendingRequestEventArgs.Request); + private void AddRequestVersion(object sender, SendingRequest2EventArgs e) + { + e.RequestMessage.SetHeader(_xMsVersion, this._serviceVersion.ToString()); } + } } diff --git a/src/net/Client/RequestAdapters/UserAgentAdapter.cs b/src/net/Client/RequestAdapters/UserAgentAdapter.cs new file mode 100644 index 00000000..a48e6e52 --- /dev/null +++ b/src/net/Client/RequestAdapters/UserAgentAdapter.cs @@ -0,0 +1,91 @@ +//----------------------------------------------------------------------- +// Copyright 2012 Microsoft Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + + +using System; +using System.Data.Services.Client; +using System.Net; + +namespace Microsoft.WindowsAzure.MediaServices.Client.RequestAdapters +{ + /// + /// UserAgentAdapter is used to add user agent specific information to http request. + /// + public class UserAgentAdapter + { + + private const string _userAgentPrefix = "Azure Media Services .NET SDK v"; + private readonly Version _clientVersion; + private readonly string _userAgentHeaderValue; + /// + /// Initializes a new instance of the class. + /// + /// The service version. + public UserAgentAdapter(Version clientVersion) + { + this._clientVersion = clientVersion; + _userAgentHeaderValue = GetUserAgentString(); + } + + /// + /// Adapts the specified context. + /// + /// The context. + public void Adapt(DataServiceContext context) + { + context.SendingRequest2 += this.AddRequestUserAgent; + } + + /// + /// Adds the version to request. + /// + /// The request. + public void AddUserAgentToRequest(WebRequest request) + { + if (request == null) + { + throw new ArgumentNullException("request"); + } + + //User agent can't be set through header collection in HttpWebRequest + if (request is HttpWebRequest) + { + ((HttpWebRequest)request).UserAgent = _userAgentHeaderValue; + } + else + { + request.Headers.Set(HttpRequestHeader.UserAgent, _userAgentHeaderValue); + } + + } + + /// + /// Adds user agent. + /// + /// The sender. + /// The instance containing the event data. + private void AddRequestUserAgent(object sender, SendingRequest2EventArgs e) + { + e.RequestMessage.SetHeader(HttpRequestHeader.UserAgent.ToString(), _userAgentHeaderValue); + } + + private string GetUserAgentString() + { + return _userAgentPrefix + this._clientVersion.ToString(); + } + } + +} \ No newline at end of file diff --git a/src/net/Client/SDK.Client.csproj b/src/net/Client/SDK.Client.csproj index b2f6f78c..ae487010 100644 --- a/src/net/Client/SDK.Client.csproj +++ b/src/net/Client/SDK.Client.csproj @@ -9,6 +9,35 @@ true NOTSIGNED + + true + bin\x64\Stage\ + DEBUG;TRACE;X64 + bin\Debug\Microsoft.WindowsAzure.MediaServices.Client.xml + full + AnyCPU + prompt + \Build\NimbusFXCopRules.ruleset + + + true + bin\Stage\ + DEBUG;TRACE + true + full + AnyCPU + prompt + ..\..\..\build\NimbusFXCopRules.ruleset + + + true + bin\x86\Stage\ + DEBUG;TRACE + full + AnyCPU + prompt + \Build\NimbusFXCopRules.ruleset + Debug @@ -129,7 +158,6 @@ - @@ -258,6 +286,7 @@ + @@ -368,8 +397,11 @@ - - + + + + + @@ -398,7 +430,29 @@ - + + true + + + App.config + True + + + App.config + True + + + App.config + True + + + App.config + True + + + App.config + True + Designer diff --git a/src/net/Client/TransientFaultHandling/IRetryPolicyAdapter.cs b/src/net/Client/TransientFaultHandling/IRetryPolicyAdapter.cs new file mode 100644 index 00000000..07d0db89 --- /dev/null +++ b/src/net/Client/TransientFaultHandling/IRetryPolicyAdapter.cs @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------- +// Copyright 2012 Microsoft Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Threading.Tasks; + +namespace Microsoft.WindowsAzure.MediaServices.Client.TransientFaultHandling +{ + /// + /// Interface IRetryPolicyAdapter. Implement this interface to adapt retry policy methods + /// + public interface IRetryPolicyAdapter + { + /// + /// Method can be used to override default behavior of RetryPolicy.ExecuteAsync which returns Func> + /// + /// The type of the t result. + /// The task function. + /// Func<Task<TResult>>. + Func> AdaptExecuteAsync(Func> taskFunc); + + /// + /// Method can be used to override default behavior of RetryPolicy.ExecuteAsync which returns Func + /// + /// The task function. + /// Func<Task>. + Func AdaptExecuteAsync(Func taskFunc); + + /// + /// Method can be used to override default behavior of RetryPolicy.ExecuteAction which returns Func + /// + /// The type of the t result. + /// The function. + /// Func<TResult>. + Func AdaptExecuteAction(Func func); + } +} \ No newline at end of file diff --git a/src/net/Client/TransientFaultHandling/MediaRetryPolicy.cs b/src/net/Client/TransientFaultHandling/MediaRetryPolicy.cs index 47a0a814..d1ffd192 100644 --- a/src/net/Client/TransientFaultHandling/MediaRetryPolicy.cs +++ b/src/net/Client/TransientFaultHandling/MediaRetryPolicy.cs @@ -1,100 +1,172 @@ -//----------------------------------------------------------------------- -// Copyright 2012 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Threading; -using Microsoft.Practices.TransientFaultHandling; - -namespace Microsoft.WindowsAzure.MediaServices.Client.TransientFaultHandling -{ - public class MediaRetryPolicy : RetryPolicy - { - public MediaRetryPolicy(ITransientErrorDetectionStrategy errorDetectionStrategy, RetryStrategy retryStrategy) - : base(errorDetectionStrategy, retryStrategy) - { - } - - public MediaRetryPolicy(ITransientErrorDetectionStrategy errorDetectionStrategy, int retryCount) - : this(errorDetectionStrategy, (RetryStrategy)new FixedInterval(retryCount)) - { - } - - public MediaRetryPolicy(ITransientErrorDetectionStrategy errorDetectionStrategy, int retryCount, TimeSpan retryInterval) - : this(errorDetectionStrategy, (RetryStrategy)new FixedInterval(retryCount, retryInterval)) - { - } - - public MediaRetryPolicy(ITransientErrorDetectionStrategy errorDetectionStrategy, int retryCount, TimeSpan minBackoff, TimeSpan maxBackoff, TimeSpan deltaBackoff) - : this( - errorDetectionStrategy, (RetryStrategy)new ExponentialBackoff(retryCount, minBackoff, maxBackoff, deltaBackoff)) - { - } - - public MediaRetryPolicy(ITransientErrorDetectionStrategy errorDetectionStrategy, int retryCount, TimeSpan initialInterval, TimeSpan increment) - : this(errorDetectionStrategy, (RetryStrategy)new Incremental(retryCount, initialInterval, increment)) - { - } - - public override TResult ExecuteAction(Func func) - { - if (func == null) - { - throw new ArgumentNullException("func"); - } - - int retryCount = 0; - TimeSpan delay = TimeSpan.Zero; - ShouldRetry shouldRetry = RetryStrategy.GetShouldRetry(); - - while (true) - { - do - { - try - { - return func(); - } - catch (Exception ex) - { - if (!ErrorDetectionStrategy.IsTransient(ex)) - { - throw; - } - - if (shouldRetry(retryCount++, ex, out delay)) - { - if (delay.TotalMilliseconds < 0.0) - { - delay = TimeSpan.Zero; - } - OnRetrying(retryCount, ex, delay); - } - else - { - OnRetrying(retryCount, ex, delay); - - throw; - } - } - } - while (retryCount <= 1 && RetryStrategy.FastFirstRetry); - - Thread.Sleep(delay); - } - } - } - +//----------------------------------------------------------------------- +// Copyright 2012 Microsoft Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Practices.TransientFaultHandling; + +namespace Microsoft.WindowsAzure.MediaServices.Client.TransientFaultHandling +{ + public class MediaRetryPolicy : RetryPolicy + { + public IRetryPolicyAdapter RetryPolicyAdapter { get; set; } + + public MediaRetryPolicy(ITransientErrorDetectionStrategy errorDetectionStrategy, RetryStrategy retryStrategy) + : base(errorDetectionStrategy, retryStrategy) + { + + } + + public MediaRetryPolicy(ITransientErrorDetectionStrategy errorDetectionStrategy, int retryCount) + : this(errorDetectionStrategy, (RetryStrategy)new FixedInterval(retryCount)) + { + } + + public MediaRetryPolicy(ITransientErrorDetectionStrategy errorDetectionStrategy, int retryCount, TimeSpan retryInterval) + : this(errorDetectionStrategy, (RetryStrategy)new FixedInterval(retryCount, retryInterval)) + { + } + + public MediaRetryPolicy(ITransientErrorDetectionStrategy errorDetectionStrategy, int retryCount, TimeSpan minBackoff, TimeSpan maxBackoff, TimeSpan deltaBackoff, IRetryPolicyAdapter adapter = null) + : this( + errorDetectionStrategy, (RetryStrategy)new ExponentialBackoff(retryCount, minBackoff, maxBackoff, deltaBackoff)) + { + } + + public MediaRetryPolicy(ITransientErrorDetectionStrategy errorDetectionStrategy, int retryCount, TimeSpan initialInterval, TimeSpan increment) + : this(errorDetectionStrategy, (RetryStrategy)new Incremental(retryCount, initialInterval, increment)) + { + } + + /// + /// Executes the action. + /// + /// The type of the t result. + /// The function. + /// TResult. + /// func + public override TResult ExecuteAction(Func func) + { + + //Converting func,if RetryPolicyAdapter defined + var adaptedFunction = RetryPolicyAdapter != null ? RetryPolicyAdapter.AdaptExecuteAction(func) : func; + + if (func == null) + { + throw new ArgumentNullException("func"); + } + + int retryCount = 0; + TimeSpan delay = TimeSpan.Zero; + ShouldRetry shouldRetry = RetryStrategy.GetShouldRetry(); + + while (true) + { + do + { + try + { + return adaptedFunction(); + } + catch (Exception ex) + { + if (!ErrorDetectionStrategy.IsTransient(ex)) + { + throw; + } + + if (shouldRetry(retryCount++, ex, out delay)) + { + if (delay.TotalMilliseconds < 0.0) + { + delay = TimeSpan.Zero; + } + OnRetrying(retryCount, ex, delay); + } + else + { + OnRetrying(retryCount, ex, delay); + + throw; + } + } + } + while (retryCount <= 1 && RetryStrategy.FastFirstRetry); + + Thread.Sleep(delay); + } + } + + /// + /// Repeatedly executes the specified asynchronous task while it satisfies the + // current retry policy. + /// + /// The type of the t result. + /// A function that returns a started task (also refered as "hot" task). + /// Task<TResult>.Returns a task that will run to completion if the original task completes + /// successfully (either the first time or after retrying transient failures). + /// If the task fails with a non-transient error or the retry limit is reached, + /// the returned task will become faulted and the exception must be observed. + public new Task ExecuteAsync(Func> taskFunc) + { + //If adapter defined, we are converting taskFunc before executing it + return base.ExecuteAsync(RetryPolicyAdapter != null ? RetryPolicyAdapter.AdaptExecuteAsync(taskFunc) : taskFunc); + } + + /// + /// Repetitively executes the specified asynchronous task while it satisfies the current retry policy. + /// + /// A function that returns a started task (also refered as "hot" task). + /// Returns a task that will run to completion if the original task completes successfully (either the + /// first time or after retrying transient failures). If the task fails with a non-transient error or + /// the retry limit is reached, the returned task will become faulted and the exception must be observed. + public new Task ExecuteAsync(Func taskAction) + { + //If adapter defined, we are converting taskAction before executing it + return base.ExecuteAsync(RetryPolicyAdapter != null ? RetryPolicyAdapter.AdaptExecuteAsync(taskAction) : taskAction); + } + + /// + /// Repeatedly executes the specified asynchronous task while it satisfies the current retry policy. + /// + /// The type of the t result. + /// A function that returns a started task (also refered as "hot" task). + /// The cancellation token. + /// Returns a task that will run to completion if the original task completes + /// successfully (either the first time or after retrying transient failures). + /// If the task fails with a non-transient error or the retry limit is reached, + /// the returned task will become faulted and the exception must be observed. + public new Task ExecuteAsync(Func> taskFunc, CancellationToken cancellationToken) + { + return base.ExecuteAsync(RetryPolicyAdapter != null ? RetryPolicyAdapter.AdaptExecuteAsync(taskFunc) : taskFunc, cancellationToken); + } + + /// + /// Repetitively executes the specified asynchronous task while it satisfies the current retry policy. + /// + /// A function that returns a started task (also refered as "hot" task). + /// To cancel the retry operation, but not operations that are already in flight or that already completed successfully. + /// Returns a task that will run to completion if the original task completes successfully (either the + /// first time or after retrying transient failures). If the task fails with a non-transient error or + /// the retry limit is reached, the returned task will become faulted and the exception must be observed. + public new Task ExecuteAsync(Func taskAction, CancellationToken cancellationToken) + { + return base.ExecuteAsync(RetryPolicyAdapter != null ? RetryPolicyAdapter.AdaptExecuteAsync(taskAction) : taskAction, cancellationToken); + } + } + } diff --git a/test/net/Scenario/DynamicEncryption/AssetDeliveryPolicyCollectionTest.cs b/test/net/Scenario/DynamicEncryption/AssetDeliveryPolicyCollectionTest.cs index 4a5988d3..f909c05a 100644 --- a/test/net/Scenario/DynamicEncryption/AssetDeliveryPolicyCollectionTest.cs +++ b/test/net/Scenario/DynamicEncryption/AssetDeliveryPolicyCollectionTest.cs @@ -155,7 +155,6 @@ public void EnvelopeAssetDeliveryPolicyTestAttach() } [TestMethod] - [Ignore] // Not enabled in REST yet public void PlayReadyAssetDeliveryPolicyTestAttach() { var asset = _mediaContext.Assets.Create("Asset for PlayReadyAssetDeliveryPolicyTestAttach", AssetCreationOptions.None); @@ -183,7 +182,7 @@ public void PlayReadyAssetDeliveryPolicyTestAttach() } [TestMethod] - [Ignore] + [ExpectedException(typeof(DataServiceRequestException))] public void FailToAttachPolicyIfCommonContentKeyNotPresent() { var asset = _mediaContext.Assets.Create("Asset for FailToAttachPolicyIfCommonContentKeyNotPresent", AssetCreationOptions.None); @@ -211,7 +210,7 @@ public void FailToAttachPolicyIfCommonContentKeyNotPresent() } [TestMethod] - [Ignore] + [ExpectedException(typeof(DataServiceRequestException))] public void FailToAttachPolicyIfRequiredEnvelopeKeyNotPresent() { var asset = _mediaContext.Assets.Create("Asset for FailToAttachPolicyIfRequiredEnvelopeKeyNotPresent", AssetCreationOptions.None); diff --git a/test/net/Scenario/DynamicEncryption/AssetEncryptionStateTests.cs b/test/net/Scenario/DynamicEncryption/AssetEncryptionStateTests.cs index 6ac9d2f3..5ff0283b 100644 --- a/test/net/Scenario/DynamicEncryption/AssetEncryptionStateTests.cs +++ b/test/net/Scenario/DynamicEncryption/AssetEncryptionStateTests.cs @@ -300,7 +300,7 @@ public void ValidateEffectiveEncryptionStatusOfPlayReadyProtectedSmooth() Assert.AreEqual(ContentKeyType.CommonEncryption, playReadyProtectedSmoothAsset.ContentKeys[0].ContentKeyType); - ValidateAssetEncryptionState(asset, protocolsToTest, AssetEncryptionState.StaticCommonEncryption); + ValidateAssetEncryptionState(playReadyProtectedSmoothAsset, protocolsToTest, AssetEncryptionState.StaticCommonEncryption); CleanupAsset(playReadyProtectedSmoothAsset); CleanupAsset(asset); diff --git a/test/net/Scenario/LocatorsTests.cs b/test/net/Scenario/LocatorsTests.cs index 4e92c371..017224f1 100644 --- a/test/net/Scenario/LocatorsTests.cs +++ b/test/net/Scenario/LocatorsTests.cs @@ -31,7 +31,7 @@ public void SetupTest() [TestMethod] [DeploymentItem(@"Media\SmallWmv.wmv", "Media")] - + public void ShouldReturnSameLocatorCollectionAfterAssetRequery() { var asset = _mediaContext.Assets.Create("SmallWmv.wmv", AssetCreationOptions.StorageEncrypted); @@ -47,7 +47,7 @@ public void ShouldReturnSameLocatorCollectionAfterAssetRequery() [TestMethod] [DeploymentItem(@"Media\SmallWmv.wmv", "Media")] - public void ShouldReturnSameLocatorCollectionAfterAssetRequery2() + public void ShouldReturnSameLocatorCollectionAfterAssetRequery2() { var asset = _mediaContext.Assets.Create(Guid.NewGuid().ToString(), AssetCreationOptions.StorageEncrypted); FileInfo info = new FileInfo(_smallWmv); @@ -68,8 +68,8 @@ public void ShouldReturnSameLocatorCollectionAfterAssetRequery2() [TestMethod] [DeploymentItem(@"Media\SmallWmv.wmv", "Media")] - [ExpectedException(typeof (InvalidOperationException))] - + [ExpectedException(typeof(InvalidOperationException))] + public void ShouldThrowUpdatingLocatorIfItsTypeIsNotOrigin() { // Arrange @@ -92,7 +92,7 @@ public void ShouldReturnLocatorWhenCreateOriginLocatorCalled() // Arrange - var accessPolicy = _mediaContext.AccessPolicies.Create("TestPolicy", TimeSpan.FromMinutes(10), AccessPermissions.Read); + var accessPolicy = _mediaContext.AccessPolicies.Create("TestPolicy", TimeSpan.FromMinutes(10), AccessPermissions.Read); var asset = AssetTests.CreateAsset(_mediaContext, _smallWmv, AssetCreationOptions.None); // Act @@ -112,11 +112,11 @@ public void ShouldReturnLocatorWhenCreateOriginLocatorCalled() [TestCategory("DailyBvtRun")] public void ShouldCreateLocatorWithNameSync() { - var accessPolicy = _mediaContext.AccessPolicies.Create("TestPolicy", TimeSpan.FromMinutes(10),AccessPermissions.Read); - var asset = _mediaContext.Assets.Create("ShouldCreateLocatorAndQueryItByName",AssetCreationOptions.None); - var locator = _mediaContext.Locators.CreateLocator(LocatorType.OnDemandOrigin, asset, accessPolicy,DateTime.Now.AddDays(2),"ShouldCreateLocatorWithoutNameAndUpdateName_" + Guid.NewGuid().ToString()); - - FindLocatorByNameAndVerifyIt(locator.Name,locator.Id); + var accessPolicy = _mediaContext.AccessPolicies.Create("TestPolicy", TimeSpan.FromMinutes(10), AccessPermissions.Read); + var asset = _mediaContext.Assets.Create("ShouldCreateLocatorAndQueryItByName", AssetCreationOptions.None); + var locator = _mediaContext.Locators.CreateLocator(LocatorType.OnDemandOrigin, asset, accessPolicy, DateTime.Now.AddDays(2), "ShouldCreateLocatorWithoutNameAndUpdateName_" + Guid.NewGuid().ToString()); + + FindLocatorByNameAndVerifyIt(locator.Name, locator.Id); } private static void FindLocatorByNameAndVerifyIt(string locatorNameToSearch, string expectedLocatorId) @@ -132,20 +132,20 @@ public void ShouldCreateSASLocatorWithNameSync() { var accessPolicy = _mediaContext.AccessPolicies.Create("TestPolicy", TimeSpan.FromMinutes(10), AccessPermissions.List | AccessPermissions.Read); var asset = _mediaContext.Assets.Create("ShouldCreateSASLocatorWithName", AssetCreationOptions.None); - var locator = _mediaContext.Locators.CreateSasLocator( asset, accessPolicy, DateTime.Now.AddDays(2), "ShouldCreateLocatorWithoutNameAndUpdateName_" + Guid.NewGuid().ToString()); + var locator = _mediaContext.Locators.CreateSasLocator(asset, accessPolicy, DateTime.Now.AddDays(2), "ShouldCreateLocatorWithoutNameAndUpdateName_" + Guid.NewGuid().ToString()); - FindLocatorByNameAndVerifyIt(locator.Name,locator.Id); + FindLocatorByNameAndVerifyIt(locator.Name, locator.Id); } [TestMethod] [TestCategory("DailyBvtRun")] public void ShouldCreateLocatorWithNameASync() { - var accessPolicy = _mediaContext.AccessPolicies.Create("TestPolicy", TimeSpan.FromMinutes(10),AccessPermissions.Read); + var accessPolicy = _mediaContext.AccessPolicies.Create("TestPolicy", TimeSpan.FromMinutes(10), AccessPermissions.Read); var asset = _mediaContext.Assets.Create("ShouldCreateLocatorAndQueryItByName", AssetCreationOptions.None); var locator = _mediaContext.Locators.CreateLocatorAsync(LocatorType.OnDemandOrigin, asset, accessPolicy, DateTime.Now.AddDays(2), "ShouldCreateLocatorWithoutNameAndUpdateName_" + Guid.NewGuid().ToString()).Result; - FindLocatorByNameAndVerifyIt(locator.Name,locator.Id); + FindLocatorByNameAndVerifyIt(locator.Name, locator.Id); } [TestMethod] @@ -336,7 +336,7 @@ public void ExpirationTimeOfCreatedLocatorShouldMatchLocatorStartTimePlusPolicyD DateTime locatorStartTime = DateTime.Now.AddHours(1); // Act - var locatorTask = _mediaContext.Locators.CreateLocatorAsync(LocatorType.Sas, asset, accessPolicy, locatorStartTime.ToUniversalTime()); + var locatorTask = _mediaContext.Locators.CreateLocatorAsync(LocatorType.Sas, asset, accessPolicy, locatorStartTime.ToUniversalTime(), null); locatorTask.Wait(); var locator = locatorTask.Result; @@ -457,7 +457,7 @@ public void ShouldUpdateExpiryTimeWhenUpdateLocatorCalledWithExpiryTime() public void ShouldUpdateExpiryTimeWhenUpdateLocatorAsyncCalledWithExpiryTime() { // Arrange - + var accessPolicyDuration = TimeSpan.FromHours(2); var expectedExpiryTime = DateTime.UtcNow.Date.AddDays(1); @@ -480,7 +480,7 @@ public void ShouldUpdateExpiryTimeWhenUpdateLocatorAsyncCalledWithExpiryTime() [TestMethod] [DeploymentItem(@"Media\SmallWmv.wmv", "Media")] - + public void ShouldUpdateExpiryTimeWhenUpdateLocatorCalledWithStartAndExpiryTime() { // Arrange @@ -510,11 +510,11 @@ public void ShouldUpdateExpiryTimeWhenUpdateLocatorCalledWithStartAndExpiryTime( [TestMethod] [DeploymentItem(@"Media\SmallWmv.wmv", "Media")] - + public void ShouldUpdateExpiryTimeWhenUpdateLocatorAsyncCalledWithStartAndExpiryTime() { // Arrange - + var accessPolicyDuration = TimeSpan.FromHours(2); var expectedExpiryTime = DateTime.UtcNow.Date.AddDays(2); var expectedStartTime = DateTime.UtcNow.Date.AddDays(1); @@ -659,7 +659,7 @@ public void TestLocatorDeleteRetry() try { - locator.Delete(); + locator.Delete(); } catch (Exception x) { @@ -668,5 +668,95 @@ public void TestLocatorDeleteRetry() Assert.AreEqual(0, exceptionCount); } + + [TestMethod] + [DeploymentItem(@"Media\SmallWmv.wmv", "Media")] + [ExpectedException(typeof(ArgumentException))] + public void ShouldThrowIfLocatorIdIsInvalidWithoutPrefixWhenCreateOriginLocator() + { + IAsset asset = AssetTests.CreateAsset(_mediaContext, _smallWmv, AssetCreationOptions.None); + IAccessPolicy accessPolicy = _mediaContext.AccessPolicies.Create("Read", TimeSpan.FromMinutes(5), AccessPermissions.Read); + string locatorId = "invalid-locator-id"; + + _mediaContext.Locators.CreateLocator(locatorId, LocatorType.OnDemandOrigin, asset, accessPolicy, null); + } + + [TestMethod] + [DeploymentItem(@"Media\SmallWmv.wmv", "Media")] + [ExpectedException(typeof(ArgumentException))] + public void ShouldThrowIfLocatorIdIsInvalidWithPrefixWhenCreateOriginLocator() + { + IAsset asset = AssetTests.CreateAsset(_mediaContext, _smallWmv, AssetCreationOptions.None); + IAccessPolicy accessPolicy = _mediaContext.AccessPolicies.Create("Read", TimeSpan.FromMinutes(5), AccessPermissions.Read); + string locatorId = string.Concat(LocatorData.LocatorIdentifierPrefix, "invalid-locator-id"); + + _mediaContext.Locators.CreateLocator(locatorId, LocatorType.OnDemandOrigin, asset, accessPolicy, null); + _mediaContext.Locators.CreateLocator(locatorId, LocatorType.OnDemandOrigin, asset, accessPolicy, null); + } + + [TestMethod] + [DeploymentItem(@"Media\SmallWmv.wmv", "Media")] + public void ShouldCreateOriginLocator() + { + IAsset asset = AssetTests.CreateAsset(_mediaContext, _smallWmv, AssetCreationOptions.None); + IAccessPolicy accessPolicy = _mediaContext.AccessPolicies.Create("Read", TimeSpan.FromMinutes(5), AccessPermissions.Read); + + ILocator locator = _mediaContext.Locators.CreateLocator(LocatorType.OnDemandOrigin, asset, accessPolicy); + + Assert.IsNotNull(locator); + + string locatorIdWithoutPrefix = locator.Id.Remove(0, LocatorData.LocatorIdentifierPrefix.Length); + Assert.AreEqual(locator.ContentAccessComponent, locatorIdWithoutPrefix, true); + Assert.IsTrue(locator.Path.TrimEnd('/').EndsWith(locatorIdWithoutPrefix, StringComparison.OrdinalIgnoreCase)); + } + + [TestMethod] + [DeploymentItem(@"Media\SmallWmv.wmv", "Media")] + public void ShouldSetLocatorIdWithoutPrefixWhenCreateOriginLocator() + { + IAsset asset = AssetTests.CreateAsset(_mediaContext, _smallWmv, AssetCreationOptions.None); + IAccessPolicy accessPolicy = _mediaContext.AccessPolicies.Create("Read", TimeSpan.FromMinutes(5), AccessPermissions.Read); + string locatorIdWithoutPrefix = Guid.NewGuid().ToString(); + + ILocator locator = _mediaContext.Locators.CreateLocator(locatorIdWithoutPrefix, LocatorType.OnDemandOrigin, asset, accessPolicy,null); + + Assert.IsNotNull(locator); + Assert.AreEqual(locator.ContentAccessComponent, locatorIdWithoutPrefix, true); + Assert.IsTrue(locator.Path.TrimEnd('/').EndsWith(locatorIdWithoutPrefix, StringComparison.OrdinalIgnoreCase)); + } + + [TestMethod] + [DeploymentItem(@"Media\SmallWmv.wmv", "Media")] + public void ShouldRecreateLocatorWithSameLocatorId() + { + IAsset asset = AssetTests.CreateAsset(_mediaContext, _smallWmv, AssetCreationOptions.None); + IAccessPolicy accessPolicy = _mediaContext.AccessPolicies.Create("Read", TimeSpan.FromMinutes(5), AccessPermissions.Read); + + + ILocator locator = _mediaContext.Locators.CreateLocator(LocatorType.OnDemandOrigin, asset, accessPolicy); + Assert.IsNotNull(locator); + string id = locator.Id; + locator.Delete(); + Assert.IsNull(_mediaContext.Locators.Where(c => c.Id == id).FirstOrDefault()); + + locator = _mediaContext.Locators.CreateLocator(id, LocatorType.OnDemandOrigin, asset, accessPolicy, null); + Assert.IsNotNull(locator); + } + + [TestMethod] + [DeploymentItem(@"Media\SmallWmv.wmv", "Media")] + public void ShouldSetLocatorIdWithPrefixWhenCreateOriginLocator() + { + IAsset asset = AssetTests.CreateAsset(_mediaContext, _smallWmv, AssetCreationOptions.None); + IAccessPolicy accessPolicy = _mediaContext.AccessPolicies.Create("Read", TimeSpan.FromMinutes(5), AccessPermissions.Read); + string locatorIdWithoutPrefix = Guid.NewGuid().ToString(); + string locatorIdWithPrefix = string.Concat(LocatorData.LocatorIdentifierPrefix, locatorIdWithoutPrefix); + + ILocator locator = _mediaContext.Locators.CreateLocator(locatorIdWithPrefix,LocatorType.OnDemandOrigin, asset, accessPolicy, startTime: null); + + Assert.IsNotNull(locator); + Assert.AreEqual(locator.ContentAccessComponent, locatorIdWithoutPrefix, true); + Assert.IsTrue(locator.Path.TrimEnd('/').EndsWith(locatorIdWithoutPrefix, StringComparison.OrdinalIgnoreCase)); + } } } diff --git a/test/net/Scenario/SDK.Client.Tests.Scenario.csproj b/test/net/Scenario/SDK.Client.Tests.Scenario.csproj index 0f01409c..ab334a06 100644 --- a/test/net/Scenario/SDK.Client.Tests.Scenario.csproj +++ b/test/net/Scenario/SDK.Client.Tests.Scenario.csproj @@ -91,12 +91,12 @@ true ..\..\..\MSSharedLibSN1024.snk - - $([System.IO.Path]::GetFullPath( $(MSBuildProjectDirectory)\..\..\..\packages\SlowCheetah.2.5.12\tools\)) - true - $([System.IO.Path]::GetFullPath( $(MSBuildProjectDirectory)\Properties\SlowCheetah\SlowCheetah.Transforms.targets )) - $(SlowCheetah_NuGetImportPath) - + + $([System.IO.Path]::GetFullPath( $(MSBuildProjectDirectory)\..\..\..\packages\SlowCheetah.2.5.12\tools\)) + true + $([System.IO.Path]::GetFullPath( $(MSBuildProjectDirectory)\Properties\SlowCheetah\SlowCheetah.Transforms.targets )) + $(SlowCheetah_NuGetImportPath) + bin\LKG\ @@ -106,6 +106,33 @@ bin\x64\LKG\ + + true + bin\Stage\ + DEBUG;TRACE + full + AnyCPU + prompt + \Build\NimbusFXCopRules.ruleset + + + true + bin\x86\Stage\ + DEBUG;TRACE + full + AnyCPU + prompt + \Build\NimbusFXCopRules.ruleset + + + true + bin\x64\Stage\ + DEBUG;TRACE;X64 + full + AnyCPU + prompt + \Build\NimbusFXCopRules.ruleset + False @@ -241,6 +268,10 @@ App.config True + + App.config + True + PreserveNewest diff --git a/test/net/common/SDK.Client.Tests.Common.csproj b/test/net/common/SDK.Client.Tests.Common.csproj index 5532c323..5e6f0788 100644 --- a/test/net/common/SDK.Client.Tests.Common.csproj +++ b/test/net/common/SDK.Client.Tests.Common.csproj @@ -43,7 +43,15 @@ true ..\..\..\MSSharedLibSN1024.snk - + + true + bin\Stage\ + DEBUG;TRACE + full + AnyCPU + prompt + MinimumRecommendedRules.ruleset + ..\..\..\packages\Microsoft.Data.Edm.5.6.0\lib\net40\Microsoft.Data.Edm.dll @@ -55,23 +63,19 @@ ..\..\..\packages\Microsoft.Data.Services.Client.5.6.0\lib\net40\Microsoft.Data.Services.Client.dll - ..\..\..\packages\TransientFaultHandling.Core.5.1.1209.1\lib\NET4\Microsoft.Practices.TransientFaultHandling.Core.dll - ..\..\..\packages\Microsoft.WindowsAzure.ConfigurationManager.2.0.3\lib\net40\Microsoft.WindowsAzure.Configuration.dll - ..\..\..\packages\WindowsAzure.Storage.3.1.0.0\lib\net40\Microsoft.WindowsAzure.Storage.dll ..\..\..\packages\Moq.4.2.1312.1622\lib\net40\Moq.dll - ..\..\..\packages\Newtonsoft.Json.6.0.3\lib\net40\Newtonsoft.Json.dll diff --git a/test/net/common/TestMediaServicesClassFactory.cs b/test/net/common/TestMediaServicesClassFactory.cs index 50f51a01..2bbf79b6 100644 --- a/test/net/common/TestMediaServicesClassFactory.cs +++ b/test/net/common/TestMediaServicesClassFactory.cs @@ -28,7 +28,7 @@ namespace Microsoft.WindowsAzure.MediaServices.Client.Tests.Common { public class TestMediaServicesClassFactory : AzureMediaServicesClassFactory { - public TestMediaServicesClassFactory(IMediaDataServiceContext dataContext) + public TestMediaServicesClassFactory(IMediaDataServiceContext dataContext):base() { _dataContext = dataContext; } @@ -38,20 +38,9 @@ public override IMediaDataServiceContext CreateDataServiceContext() return _dataContext; } - /// - /// Creates retry policy for saving changes in Media Services REST layer. - /// - /// Retry policy. - public override MediaRetryPolicy GetSaveChangesRetryPolicy() + public override MediaRetryPolicy GetQueryRetryPolicy(IRetryPolicyAdapter adapter) { - var retryPolicy = new MediaRetryPolicy( - GetSaveChangesErrorDetectionStrategy(), - retryCount: 5, - minBackoff: TimeSpan.FromMilliseconds(10), - maxBackoff: TimeSpan.FromMilliseconds(10000), - deltaBackoff: TimeSpan.FromMilliseconds(50)); - - return retryPolicy; + return base.GetQueryRetryPolicy(adapter); } public override MediaErrorDetectionStrategy GetSaveChangesErrorDetectionStrategy() diff --git a/test/net/stress/PlayReadyStressTest.loadtest b/test/net/stress/PlayReadyStressTest.loadtest index 25673dfa..9045040c 100644 --- a/test/net/stress/PlayReadyStressTest.loadtest +++ b/test/net/stress/PlayReadyStressTest.loadtest @@ -3,7 +3,7 @@ - + diff --git a/test/net/stress/SDK.Client.Tests.Stress.csproj b/test/net/stress/SDK.Client.Tests.Stress.csproj index a6b90a27..e5ed2b13 100644 --- a/test/net/stress/SDK.Client.Tests.Stress.csproj +++ b/test/net/stress/SDK.Client.Tests.Stress.csproj @@ -45,6 +45,15 @@ $([System.IO.Path]::GetFullPath( $(MSBuildProjectDirectory)\Properties\SlowCheetah\SlowCheetah.Transforms.targets )) $(SlowCheetah_NuGetImportPath) + + true + bin\Stage\ + DEBUG;TRACE + full + AnyCPU + prompt + MinimumRecommendedRules.ruleset + diff --git a/test/net/unit/AssetEncryptionStateUnitTests.cs b/test/net/unit/AssetEncryptionStateUnitTests.cs index 3d10f123..415a77ca 100644 --- a/test/net/unit/AssetEncryptionStateUnitTests.cs +++ b/test/net/unit/AssetEncryptionStateUnitTests.cs @@ -121,7 +121,8 @@ private IAsset GetTestAsset(AssetCreationOptions options, AssetType assetType, A } [TestMethod] - [DeploymentItem(@"TestData\AssetEncryptionStateTestCases.csv", "TestData")] + [DeploymentItem(@"TestData\AssetEncryptionStateTestCases.csv", "TestData")] + [DeploymentItem(@"UnitTest.pfx")] public void RunAllGetEffectiveDeliveryPolicyTestCases() { string testCaseDataFilePath = WindowsAzureMediaServicesTestConfiguration.GetVideoSampleFilePath(TestContext, c_TestCaseDataFile); diff --git a/test/net/unit/MediaRetryPolicyTest.cs b/test/net/unit/MediaRetryPolicyTest.cs index 4db4bdcc..a9e4fb9f 100644 --- a/test/net/unit/MediaRetryPolicyTest.cs +++ b/test/net/unit/MediaRetryPolicyTest.cs @@ -36,7 +36,7 @@ public class MediaRetryPolicyTest [TestMethod()] public void MediaRetryPolicyTestExecuteActionTrivial() { - MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(); + MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(null); int expected = 10; Func func = () => expected; int actual = target.ExecuteAction(func); @@ -49,7 +49,7 @@ public void MediaRetryPolicyTestExecuteActionTrivial() [TestMethod()] public void MediaRetryPolicyTestExecuteActionRetry() { - MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(); + MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(null); int exceptionCount = 2; int expected = 10; @@ -72,7 +72,7 @@ public void MediaRetryPolicyTestExecuteActionRetry() [ExpectedException(typeof(WebException))] public void MediaRetryPolicyTestExecuteActionNonTransient() { - MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(); + MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(null); int exceptionCount = 2; int expected = 10; @@ -104,7 +104,7 @@ public void MediaRetryPolicyTestExecuteActionNonTransient() [TestMethod()] public void MediaRetryPolicyTestExecuteActionBackoff() { - MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(); + MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(null); int exceptionCount = 5; int expected = 10; @@ -135,7 +135,7 @@ public void MediaRetryPolicyTestExecuteActionBackoff() [TestMethod()] public void MediaRetryPolicyTestExecuteAsyncTrivial() { - MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(); + MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(null); int expected = 10; var task = target.ExecuteAsync(() => Task.Factory.StartNew(() => expected)); Assert.AreEqual(expected, task.Result); @@ -147,7 +147,7 @@ public void MediaRetryPolicyTestExecuteAsyncTrivial() [TestMethod()] public void MediaRetryPolicyTestExecuteAsyncRetry() { - MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(); + MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(null); int exceptionCount = 2; int expected = 10; @@ -171,7 +171,7 @@ public void MediaRetryPolicyTestExecuteAsyncRetry() [ExpectedException(typeof(WebException))] public void MediaRetryPolicyTestExecuteAsyncNonTransient() { - MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(); + MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(null); int exceptionCount = 2; int expected = 10; @@ -206,7 +206,7 @@ public void MediaRetryPolicyTestExecuteAsyncNonTransient() [TestMethod()] public void MediaRetryPolicyTestExecuteAsyncBackoff() { - MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(); + MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(null); int exceptionCount = 5; int expected = 10; @@ -229,6 +229,59 @@ public void MediaRetryPolicyTestExecuteAsyncBackoff() var task = target.ExecuteAsync(() => Task.Factory.StartNew(() => func())); Assert.AreEqual(expected, task.Result); Assert.AreEqual(0, exceptionCount); + } + + /// + ///A test for ExecuteAction + /// + [TestMethod()] + public void MediaRetryPolicyTestExecuteActionAdapter() + { + + var adapter = new TestRetryAdapter(); + MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(adapter); + + int exceptionCount = 2; + int expected = 10; + var fakeException = new WebException("test", WebExceptionStatus.ConnectionClosed); + + Func func = () => + { + if (--exceptionCount > 0) throw fakeException; + return expected; + }; + + + Assert.AreEqual(expected, target.ExecuteAction(func)); + Assert.AreEqual(2, adapter.FuncExecutedCountByExecuteAction); + Assert.AreEqual(1, adapter.NumberOfAdaptCalled); + } + + /// + ///A test for ExecuteAction + /// + [TestMethod()] + public void MediaRetryPolicyTestExecuteAsyncRetryHasBeenAdaptedOnce() + { + var adapter = new TestRetryAdapter(); + MediaRetryPolicy target = new TestMediaServicesClassFactory(null).GetSaveChangesRetryPolicy(adapter); + + int exceptionCount = 2; + int expected = 10; + var fakeException = new WebException("test", WebExceptionStatus.ConnectionClosed); + + Func func = () => + { + if (--exceptionCount > 0) throw fakeException; + return expected; + }; + + var task = target.ExecuteAsync(() => Task.Factory.StartNew(() => func())); + Assert.AreEqual(expected, task.Result); + Assert.AreEqual(0, exceptionCount); + Assert.AreEqual(1, adapter.NumberOfAdaptCalled); + Assert.AreEqual(2, adapter.FuncExecutedCountByExecuteAsync1); } - } + } + } diff --git a/test/net/unit/MediaServicesLicenseTemplateSerializerTests.cs b/test/net/unit/MediaServicesLicenseTemplateSerializerTests.cs index 50e8fd86..4689b02a 100644 --- a/test/net/unit/MediaServicesLicenseTemplateSerializerTests.cs +++ b/test/net/unit/MediaServicesLicenseTemplateSerializerTests.cs @@ -210,8 +210,6 @@ public void InputMissingContentKeyShouldThrowArgumentException() catch (SerializationException e) { e.Message.Contains("ContentKey"); - // REVIEW: Should we test for the error here ourselves? If so we can control the error message and return a better error. - // Assert.IsTrue(e.Message.Contains(ErrorMessages.PlayReadyContentKeyRequired)); } } diff --git a/test/net/unit/QueryretryTest.cs b/test/net/unit/QueryretryTest.cs index 2917d353..207f8150 100644 --- a/test/net/unit/QueryretryTest.cs +++ b/test/net/unit/QueryretryTest.cs @@ -113,7 +113,7 @@ public class QueryRetryTest [TestMethod] public void QueryRetrySimple() { - MediaRetryPolicy queryRetryPolicy = new TestMediaServicesClassFactory(null).GetQueryRetryPolicy(); + MediaRetryPolicy queryRetryPolicy = new TestMediaServicesClassFactory(null).GetQueryRetryPolicy(null); var mock = new ThrowingQueryable(); diff --git a/test/net/unit/RequestAdaptersTests.cs b/test/net/unit/RequestAdaptersTests.cs new file mode 100644 index 00000000..6d45ba50 --- /dev/null +++ b/test/net/unit/RequestAdaptersTests.cs @@ -0,0 +1,76 @@ +//----------------------------------------------------------------------- +// Copyright 2012 Microsoft Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Net; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.WindowsAzure.MediaServices.Client.RequestAdapters; +using Moq; + +namespace Microsoft.WindowsAzure.MediaServices.Client.Tests.Unit +{ + [TestClass] + public class RequestAdaptersTests + { + + [TestMethod] + public void ClientRequestIdPresentInWebRequestAndValidGuid() + { + var mock = new MockRepository(MockBehavior.Loose); + var request = mock.Create(); + var headers = new WebHeaderCollection(); + request.SetupProperty(c => c.Headers,headers); + ClientRequestIdAdapter adapter = new ClientRequestIdAdapter(); + adapter.AddClientRequestId(request.Object); + Assert.AreEqual(1, request.Object.Headers.Count); + string xMsClientRequestId = "x-ms-client-request-id"; + Assert.IsNotNull(request.Object.Headers[xMsClientRequestId]); + Guid guid; + Assert.IsTrue(Guid.TryParse(request.Object.Headers[xMsClientRequestId],out guid)); + } + + [TestMethod] + public void ServiceVersionHeaderPresentAndContainsVersion() + { + var mock = new MockRepository(MockBehavior.Loose); + var request = mock.Create(); + var headers = new WebHeaderCollection(); + request.SetupProperty(c => c.Headers, headers); + ServiceVersionAdapter adapter = new ServiceVersionAdapter(new Version(1,0)); + adapter.AddVersionToRequest(request.Object); + Assert.AreEqual(1, request.Object.Headers.Count); + string xMsVersion = "x-ms-version"; + Assert.IsNotNull(request.Object.Headers[xMsVersion]); + Assert.AreEqual("1.0",request.Object.Headers[xMsVersion]); + } + + [TestMethod] + public void UserAgentHeaderPresentAndContainsVersion() + { + var mock = new MockRepository(MockBehavior.Loose); + var request = mock.Create(); + var headers = new WebHeaderCollection(); + request.SetupProperty(c => c.Headers, headers); + UserAgentAdapter adapter = new UserAgentAdapter(new Version(1, 0)); + adapter.AddUserAgentToRequest(request.Object); + Assert.AreEqual(1, request.Object.Headers.Count); + + Assert.IsNotNull(request.Object.Headers[HttpRequestHeader.UserAgent]); + Assert.AreEqual("Azure Media Services .NET SDK v1.0", request.Object.Headers[HttpRequestHeader.UserAgent]); + } + + } +} \ No newline at end of file diff --git a/test/net/unit/SDK.Client.Tests.Unit.csproj b/test/net/unit/SDK.Client.Tests.Unit.csproj index b0ecdebb..3251ba25 100644 --- a/test/net/unit/SDK.Client.Tests.Unit.csproj +++ b/test/net/unit/SDK.Client.Tests.Unit.csproj @@ -46,6 +46,15 @@ bin\LKG\ + + true + bin\Stage\ + DEBUG;TRACE + full + AnyCPU + prompt + MinimumRecommendedRules.ruleset + ..\..\..\packages\Microsoft.Data.Edm.5.6.0\lib\net40\Microsoft.Data.Edm.dll @@ -70,10 +79,33 @@ + + ..\..\..\packages\Microsoft.Bcl.1.1.8\lib\net40\System.IO.dll + + + False + ..\..\..\packages\Microsoft.Net.Http.2.2.20\lib\net40\System.Net.Http.dll + + + ..\..\..\packages\Microsoft.Net.Http.2.2.20\lib\net40\System.Net.Http.Extensions.dll + + + ..\..\..\packages\Microsoft.Net.Http.2.2.20\lib\net40\System.Net.Http.Primitives.dll + + + False + ..\..\..\packages\Microsoft.Net.Http.2.2.20\lib\net40\System.Net.Http.WebRequest.dll + + + ..\..\..\packages\Microsoft.Bcl.1.1.8\lib\net40\System.Runtime.dll + ..\..\..\packages\System.Spatial.5.6.0\lib\net40\System.Spatial.dll + + ..\..\..\packages\Microsoft.Bcl.1.1.8\lib\net40\System.Threading.Tasks.dll + @@ -95,6 +127,7 @@ + @@ -103,6 +136,7 @@ + @@ -134,6 +168,11 @@ + + + + +