2016-03-23 16:37:59 -07:00
using System ;
2016-04-25 13:17:46 -07:00
using System.Collections.Generic ;
2016-03-23 16:37:59 -07:00
using System.IO ;
2016-04-25 13:17:46 -07:00
using System.Linq ;
2016-03-23 16:37:59 -07:00
using System.Net.Http ;
using System.Text ;
using Microsoft.DotNet.Cli.Build.Framework ;
using Microsoft.WindowsAzure.Storage ;
using Microsoft.WindowsAzure.Storage.Blob ;
using static Microsoft . DotNet . Cli . Build . Framework . BuildHelpers ;
namespace Microsoft.DotNet.Cli.Build
{
public class AzurePublisher
{
private static readonly string s_dotnetBlobRootUrl = "https://dotnetcli.blob.core.windows.net/dotnet/" ;
private static readonly string s_dotnetBlobContainerName = "dotnet" ;
private string _connectionString { get ; set ; }
private CloudBlobContainer _blobContainer { get ; set ; }
public AzurePublisher ( )
{
_connectionString = Environment . GetEnvironmentVariable ( "CONNECTION_STRING" ) . Trim ( '"' ) ;
_blobContainer = GetDotnetBlobContainer ( _connectionString ) ;
}
private CloudBlobContainer GetDotnetBlobContainer ( string connectionString )
{
CloudStorageAccount storageAccount = CloudStorageAccount . Parse ( connectionString ) ;
CloudBlobClient blobClient = storageAccount . CreateCloudBlobClient ( ) ;
return blobClient . GetContainerReference ( s_dotnetBlobContainerName ) ;
}
2016-04-25 13:17:46 -07:00
public void PublishInstallerFile ( string installerFile , string channel , string version )
2016-03-23 16:37:59 -07:00
{
var installerFileBlob = CalculateInstallerBlob ( installerFile , channel , version ) ;
PublishFile ( installerFileBlob , installerFile ) ;
}
2016-04-25 13:17:46 -07:00
public void PublishArchive ( string archiveFile , string channel , string version )
2016-03-23 16:37:59 -07:00
{
var archiveFileBlob = CalculateArchiveBlob ( archiveFile , channel , version ) ;
PublishFile ( archiveFileBlob , archiveFile ) ;
}
public void PublishFile ( string blob , string file )
{
CloudBlockBlob blockBlob = _blobContainer . GetBlockBlobReference ( blob ) ;
blockBlob . UploadFromFileAsync ( file , FileMode . Open ) . Wait ( ) ;
SetBlobPropertiesBasedOnFileType ( blockBlob ) ;
}
2016-04-25 13:17:46 -07:00
public void PublishStringToBlob ( string blob , string content )
{
CloudBlockBlob blockBlob = _blobContainer . GetBlockBlobReference ( blob ) ;
blockBlob . UploadTextAsync ( content ) . Wait ( ) ;
2016-04-28 16:55:55 -07:00
blockBlob . Properties . ContentType = "text/plain" ;
blockBlob . SetPropertiesAsync ( ) . Wait ( ) ;
2016-04-25 13:17:46 -07:00
}
public void CopyBlob ( string sourceBlob , string targetBlob )
{
CloudBlockBlob source = _blobContainer . GetBlockBlobReference ( sourceBlob ) ;
CloudBlockBlob target = _blobContainer . GetBlockBlobReference ( targetBlob ) ;
// Create the empty blob
using ( MemoryStream ms = new MemoryStream ( ) )
{
target . UploadFromStreamAsync ( ms ) . Wait ( ) ;
}
// Copy actual blob data
target . StartCopyAsync ( source ) . Wait ( ) ;
}
2016-03-23 16:37:59 -07:00
private void SetBlobPropertiesBasedOnFileType ( CloudBlockBlob blockBlob )
{
if ( Path . GetExtension ( blockBlob . Uri . AbsolutePath . ToLower ( ) ) = = ".svg" )
{
blockBlob . Properties . ContentType = "image/svg+xml" ;
blockBlob . Properties . CacheControl = "no-cache" ;
blockBlob . SetPropertiesAsync ( ) . Wait ( ) ;
}
2016-04-28 16:55:55 -07:00
else if ( Path . GetExtension ( blockBlob . Uri . AbsolutePath . ToLower ( ) ) = = ".version" )
{
blockBlob . Properties . ContentType = "text/plain" ;
blockBlob . SetPropertiesAsync ( ) . Wait ( ) ;
}
2016-03-23 16:37:59 -07:00
}
2016-04-25 13:17:46 -07:00
public IEnumerable < string > ListBlobs ( string virtualDirectory )
{
CloudBlobDirectory blobDir = _blobContainer . GetDirectoryReference ( virtualDirectory ) ;
BlobContinuationToken continuationToken = new BlobContinuationToken ( ) ;
var blobFiles = blobDir . ListBlobsSegmentedAsync ( continuationToken ) . Result ;
return blobFiles . Results . Select ( bf = > bf . Uri . PathAndQuery ) ;
}
public string AcquireLeaseOnBlob ( string blob )
{
CloudBlockBlob cloudBlob = _blobContainer . GetBlockBlobReference ( blob ) ;
System . Threading . Tasks . Task < string > task = cloudBlob . AcquireLeaseAsync ( TimeSpan . FromMinutes ( 1 ) , null ) ;
task . Wait ( ) ;
return task . Result ;
}
public void ReleaseLeaseOnBlob ( string blob , string leaseId )
{
CloudBlockBlob cloudBlob = _blobContainer . GetBlockBlobReference ( blob ) ;
AccessCondition ac = new AccessCondition ( ) { LeaseId = leaseId } ;
cloudBlob . ReleaseLeaseAsync ( ac ) . Wait ( ) ;
}
public bool IsLatestSpecifiedVersion ( string version )
{
System . Threading . Tasks . Task < bool > task = _blobContainer . GetBlockBlobReference ( version ) . ExistsAsync ( ) ;
task . Wait ( ) ;
return task . Result ;
}
public void DropLatestSpecifiedVersion ( string version )
{
CloudBlockBlob blob = _blobContainer . GetBlockBlobReference ( version ) ;
using ( MemoryStream ms = new MemoryStream ( ) )
{
blob . UploadFromStreamAsync ( ms ) . Wait ( ) ;
}
2016-04-29 14:05:41 -07:00
}
public void CreateBlobIfNotExists ( string path )
{
System . Threading . Tasks . Task < bool > task = _blobContainer . GetBlockBlobReference ( path ) . ExistsAsync ( ) ;
task . Wait ( ) ;
if ( ! task . Result )
{
CloudBlockBlob blob = _blobContainer . GetBlockBlobReference ( path ) ;
using ( MemoryStream ms = new MemoryStream ( ) )
{
blob . UploadFromStreamAsync ( ms ) . Wait ( ) ;
}
}
2016-05-01 19:54:06 -07:00
}
public bool TryDeleteBlob ( string path )
{
try
{
DeleteBlob ( path ) ;
return true ;
}
catch ( Exception e )
{
Console . WriteLine ( $"Deleting blob {path} failed with \r\n{e.Message}" ) ;
return false ;
}
2016-04-25 13:17:46 -07:00
}
public void DeleteBlob ( string path )
{
_blobContainer . GetBlockBlobReference ( path ) . DeleteAsync ( ) . Wait ( ) ;
}
2016-03-23 16:37:59 -07:00
public string CalculateInstallerUploadUrl ( string installerFile , string channel , string version )
{
return $"{s_dotnetBlobRootUrl}{CalculateInstallerBlob(installerFile, channel, version)}" ;
}
public string CalculateInstallerBlob ( string installerFile , string channel , string version )
{
return $"{channel}/Installers/{version}/{Path.GetFileName(installerFile)}" ;
}
public string CalculateArchiveUploadUrl ( string archiveFile , string channel , string version )
{
return $"{s_dotnetBlobRootUrl}{CalculateArchiveBlob(archiveFile, channel, version)}" ;
}
public string CalculateArchiveBlob ( string archiveFile , string channel , string version )
{
return $"{channel}/Binaries/{version}/{Path.GetFileName(archiveFile)}" ;
}
2016-04-07 17:25:37 -07:00
2016-04-08 08:57:24 -07:00
public void DownloadFiles ( string blobVirtualDirectory , string fileExtension , string downloadPath )
2016-04-07 17:25:37 -07:00
{
CloudBlobDirectory blobDir = _blobContainer . GetDirectoryReference ( blobVirtualDirectory ) ;
BlobContinuationToken continuationToken = new BlobContinuationToken ( ) ;
var blobFiles = blobDir . ListBlobsSegmentedAsync ( continuationToken ) . Result ;
foreach ( var blobFile in blobFiles . Results . OfType < CloudBlockBlob > ( ) )
{
if ( Path . GetExtension ( blobFile . Uri . AbsoluteUri ) = = fileExtension )
{
string localBlobFile = Path . Combine ( downloadPath , Path . GetFileName ( blobFile . Uri . AbsoluteUri ) ) ;
Console . WriteLine ( $"Downloading {blobFile.Uri.AbsoluteUri} to {localBlobFile}..." ) ;
blobFile . DownloadToFileAsync ( localBlobFile , FileMode . Create ) . Wait ( ) ;
}
}
}
2016-03-23 16:37:59 -07:00
}
}