11using System . IO ;
22using System . IO . Compression ;
3- using System . Threading ;
43using System . Threading . Tasks ;
54using ApiService . OneFuzzLib . Orm ;
65using Azure ;
@@ -16,11 +15,11 @@ namespace Microsoft.OneFuzz.Service;
1615
1716
1817public interface IContainers {
19- public Async . Task < ( BinaryData ? data , IDictionary < string , string > ? tags ) > GetBlob ( Container container , string name , StorageType storageType ) ;
18+ public Async . Task < BinaryData ? > GetBlob ( Container container , string name , StorageType storageType ) ;
19+ public Async . Task < ( BinaryData ? data , IDictionary < string , string > ? tags ) > GetBlobWithTags ( Container container , string name , StorageType storageType ) ;
2020
21- public Async . Task < Uri ? > CreateContainer ( Container container , StorageType storageType , IDictionary < string , string > ? metadata ) ;
22-
23- public Async . Task < BlobContainerClient ? > GetOrCreateContainerClient ( Container container , StorageType storageType , IDictionary < string , string > ? metadata ) ;
21+ public Async . Task < Uri ? > CreateNewContainer ( Container container , StorageType storageType , IDictionary < string , string > ? metadata ) ;
22+ public Async . Task < Uri ? > GetOrCreateNewContainer ( Container container , StorageType storageType , IDictionary < string , string > ? metadata ) ;
2423
2524 public Async . Task < BlobContainerClient ? > FindContainer ( Container container , StorageType storageType ) ;
2625 public Async . Task < bool > DeleteContainerIfExists ( Container container , StorageType storageType ) ;
@@ -65,14 +64,6 @@ public Containers(
6564 _config = config ;
6665 _cache = cache ;
6766
68- _getInstanceId = new Lazy < Async . Task < Guid > > ( async ( ) => {
69- var ( data , tags ) = await GetBlob ( WellKnownContainers . BaseConfig , "instance_id" , StorageType . Config ) ;
70- if ( data == null ) {
71- throw new Exception ( "Blob Not Found" ) ;
72- }
73-
74- return Guid . Parse ( data . ToString ( ) ) ;
75- } , LazyThreadSafetyMode . PublicationOnly ) ;
7667 }
7768
7869 public async Async . Task < Uri ? > GetFileUrl ( Container container , string name , StorageType storageType ) {
@@ -83,22 +74,45 @@ public Containers(
8374 return client . GetBlobClient ( name ) . Uri ;
8475 }
8576
86- public async Async . Task < ( BinaryData ? data , IDictionary < string , string > ? tags ) > GetBlob ( Container container , string name , StorageType storageType ) {
77+ public async Async . Task < ( BinaryData ? data , IDictionary < string , string > ? tags ) > GetBlobWithTags ( Container container , string name , StorageType storageType ) {
8778 var client = await FindContainer ( container , storageType ) ;
8879 if ( client == null ) {
8980 return ( null , null ) ;
9081 }
9182
83+ var blobClient = client . GetBlobClient ( name ) ;
9284 try {
93- var blobClient = client . GetBlobClient ( name ) ;
94- var tags = await blobClient . GetTagsAsync ( ) ;
95- return ( ( await blobClient . DownloadContentAsync ( ) ) . Value . Content , tags . Value . Tags ) ;
85+ var ( tags , content ) = await ( blobClient . GetTagsAsync ( ) , blobClient . DownloadContentAsync ( ) ) ;
86+ return ( content . Value . Content , tags . Value . Tags ) ;
9687 } catch ( RequestFailedException ) {
9788 return ( null , null ) ;
9889 }
9990 }
10091
101- public async Task < Uri ? > CreateContainer ( Container container , StorageType storageType , IDictionary < string , string > ? metadata ) {
92+ public async Async . Task < BinaryData ? > GetBlob ( Container container , string name , StorageType storageType ) {
93+ var client = await FindContainer ( container , storageType ) ;
94+ if ( client == null ) {
95+ return null ;
96+ }
97+
98+ var blobClient = client . GetBlobClient ( name ) ;
99+ try {
100+ return ( await blobClient . DownloadContentAsync ( ) ) . Value . Content ;
101+ } catch ( RequestFailedException ) {
102+ return null ;
103+ }
104+ }
105+
106+ public async Task < Uri ? > CreateNewContainer ( Container container , StorageType storageType , IDictionary < string , string > ? metadata ) {
107+ var client = await CreateNewContainerClient ( container , storageType , metadata ) ;
108+ if ( client is null ) {
109+ return null ;
110+ }
111+
112+ return GetContainerSasUrlService ( client , _containerCreatePermissions ) ;
113+ }
114+
115+ public async Task < Uri ? > GetOrCreateNewContainer ( Container container , StorageType storageType , IDictionary < string , string > ? metadata ) {
102116 var client = await GetOrCreateContainerClient ( container , storageType , metadata ) ;
103117 if ( client is null ) {
104118 return null ;
@@ -113,12 +127,24 @@ private static readonly BlobContainerSasPermissions _containerCreatePermissions
113127 | BlobContainerSasPermissions . Delete
114128 | BlobContainerSasPermissions . List ;
115129
116- public async Task < BlobContainerClient ? > GetOrCreateContainerClient ( Container container , StorageType storageType , IDictionary < string , string > ? metadata ) {
130+ public async Task < BlobContainerClient ? > GetOrCreateContainerClient (
131+ Container container ,
132+ StorageType storageType ,
133+ IDictionary < string , string > ? metadata ) {
134+
117135 var containerClient = await FindContainer ( container , StorageType . Corpus ) ;
118136 if ( containerClient is not null ) {
119137 return containerClient ;
120138 }
121139
140+ return await CreateNewContainerClient ( container , storageType , metadata ) ;
141+ }
142+
143+ public async Task < BlobContainerClient ? > CreateNewContainerClient (
144+ Container container ,
145+ StorageType storageType ,
146+ IDictionary < string , string > ? metadata ) {
147+
122148 var account = _storage . ChooseAccount ( storageType ) ;
123149 var client = await _storage . GetBlobServiceClientForAccount ( account ) ;
124150 var containerName = _config . OneFuzzStoragePrefix + container ;
@@ -290,8 +316,19 @@ private async Async.Task SaveBlobInternal(Container container, string name, stri
290316 }
291317 }
292318
293- public virtual Async . Task < Guid > GetInstanceId ( ) => _getInstanceId . Value ;
294- private readonly Lazy < Async . Task < Guid > > _getInstanceId ;
319+ private static readonly object _instanceIdKey = new ( ) ;
320+ public virtual Async . Task < Guid > GetInstanceId ( ) {
321+ return _cache . GetOrCreateAsync ( _instanceIdKey , async ce => {
322+ ce . AbsoluteExpirationRelativeToNow = TimeSpan . FromDays ( 7 ) ; // should never change
323+
324+ var data = await GetBlob ( WellKnownContainers . BaseConfig , "instance_id" , StorageType . Config ) ;
325+ if ( data == null ) {
326+ throw new Exception ( "Couldn't find instance_id blob" ) ;
327+ }
328+
329+ return Guid . Parse ( data . ToString ( ) ) ;
330+ } ) ;
331+ }
295332
296333 public Uri GetContainerSasUrlService (
297334 BlobContainerClient client ,
0 commit comments