@@ -82,14 +82,40 @@ public ContainerRegistryServerAPICalls(PSRepositoryInfo repository, PSCmdlet cmd
8282
8383 #region Overridden Methods
8484
85+ /// <summary>
86+ /// Async find method which allows for searching for single name with specific version.
87+ /// Name: no wildcard support
88+ /// Version: no wildcard support
89+ /// This is the concurrent (parallel) counterpart of FindVersion().
90+ /// </summary>
8591 public override Task < FindResults > FindVersionAsync ( string packageName , string version , ResourceType type , ConcurrentQueue < ErrorRecord > errorMsgs , ConcurrentQueue < string > warningMsgs , ConcurrentQueue < string > debugMsgs , ConcurrentQueue < string > verboseMsgs )
8692 {
87- throw new NotImplementedException ( "FindVersionAsync is not implemented for ContainerRegistryServerAPICalls." ) ;
93+ debugMsgs . Enqueue ( "In ContainerRegistryServerAPICalls::FindVersionAsync()" ) ;
94+ FindResults findResponse = FindVersion ( packageName , version , type , out ErrorRecord errRecord ) ;
95+ if ( errRecord != null )
96+ {
97+ errorMsgs . Enqueue ( errRecord ) ;
98+ }
99+
100+ return Task . FromResult ( findResponse ) ;
88101 }
89102
103+ /// <summary>
104+ /// Async find method which allows for searching for single name with version range.
105+ /// Name: no wildcard support
106+ /// Version: supports wildcards
107+ /// This is the concurrent (parallel) counterpart of FindVersionGlobbing().
108+ /// </summary>
90109 public override Task < FindResults > FindVersionGlobbingAsync ( string packageName , VersionRange versionRange , bool includePrerelease , ResourceType type , bool getOnlyLatest , ConcurrentQueue < ErrorRecord > errorMsgs , ConcurrentQueue < string > warningMsgs , ConcurrentQueue < string > debugMsgs , ConcurrentQueue < string > verboseMsgs )
91110 {
92- throw new NotImplementedException ( "FindVersionGlobbingAsync is not implemented for ContainerRegistryServerAPICalls." ) ;
111+ debugMsgs . Enqueue ( "In ContainerRegistryServerAPICalls::FindVersionGlobbingAsync()" ) ;
112+ FindResults findResponse = FindVersionGlobbing ( packageName , versionRange , includePrerelease , type , getOnlyLatest , out ErrorRecord errRecord ) ;
113+ if ( errRecord != null )
114+ {
115+ errorMsgs . Enqueue ( errRecord ) ;
116+ }
117+
118+ return Task . FromResult ( findResponse ) ;
93119 }
94120
95121 /// <summary>
@@ -158,9 +184,21 @@ public override FindResults FindName(string packageName, bool includePrerelease,
158184 }
159185
160186
187+ /// <summary>
188+ /// Async find method which allows for searching for single name and returns latest version.
189+ /// Name: no wildcard support
190+ /// This is the concurrent (parallel) counterpart of FindName().
191+ /// </summary>
161192 public override Task < FindResults > FindNameAsync ( string packageName , bool includePrerelease , ResourceType type , ConcurrentQueue < ErrorRecord > errorMsgs , ConcurrentQueue < string > warningMsgs , ConcurrentQueue < string > debugMsgs , ConcurrentQueue < string > verboseMsgs )
162193 {
163- throw new NotImplementedException ( "FindNameAsync is not implemented for ContainerRegistryServerAPICalls." ) ;
194+ debugMsgs . Enqueue ( "In ContainerRegistryServerAPICalls::FindNameAsync()" ) ;
195+ FindResults findResponse = FindName ( packageName , includePrerelease , type , out ErrorRecord errRecord ) ;
196+ if ( errRecord != null )
197+ {
198+ errorMsgs . Enqueue ( errRecord ) ;
199+ }
200+
201+ return Task . FromResult ( findResponse ) ;
164202 }
165203
166204 /// <summary>
@@ -329,7 +367,22 @@ public override Stream InstallPackage(string packageName, string packageVersion,
329367 /// </summary>
330368 public override Task < Stream > InstallPackageAsync ( string packageName , string packageVersion , bool includePrerelease , ConcurrentQueue < ErrorRecord > errorMsgs , ConcurrentQueue < string > warningMsgs , ConcurrentQueue < string > debugMsgs , ConcurrentQueue < string > verboseMsgs )
331369 {
332- throw new NotImplementedException ( "FindNameAsync is not implemented for ContainerRegistryServerAPICalls." ) ;
370+ debugMsgs . Enqueue ( "In ContainerRegistryServerAPICalls::InstallPackageAsync()" ) ;
371+ Stream results = new MemoryStream ( ) ;
372+ if ( string . IsNullOrEmpty ( packageVersion ) )
373+ {
374+ errorMsgs . Enqueue ( new ErrorRecord (
375+ exception : new ArgumentNullException ( $ "Package version could not be found for { packageName } ") ,
376+ "PackageVersionNullOrEmptyError" ,
377+ ErrorCategory . InvalidArgument ,
378+ _cmdletPassedIn ) ) ;
379+
380+ return Task . FromResult ( results ) ;
381+ }
382+
383+ string packageNameForInstall = PrependMARPrefix ( packageName ) ;
384+ results = InstallVersionAsync ( packageNameForInstall , packageVersion , errorMsgs , debugMsgs , verboseMsgs ) ;
385+ return Task . FromResult ( results ) ;
333386 }
334387
335388 /// <summary>
@@ -400,6 +453,76 @@ private Stream InstallVersion(
400453 return responseContent . ReadAsStreamAsync ( ) . Result ;
401454 }
402455
456+ /// <summary>
457+ /// Installs a package with version specified using concurrent queues for output instead of cmdlet streams.
458+ /// Used by the async install path to avoid cross-thread cmdlet stream writes.
459+ /// </summary>
460+ private Stream InstallVersionAsync (
461+ string packageName ,
462+ string packageVersion ,
463+ ConcurrentQueue < ErrorRecord > errorMsgs ,
464+ ConcurrentQueue < string > debugMsgs ,
465+ ConcurrentQueue < string > verboseMsgs )
466+ {
467+ debugMsgs . Enqueue ( "In ContainerRegistryServerAPICalls::InstallVersionAsync()" ) ;
468+ string packageNameLowercase = packageName . ToLower ( ) ;
469+ string tempPath = Path . Combine ( Path . GetTempPath ( ) , Guid . NewGuid ( ) . ToString ( ) ) ;
470+ try
471+ {
472+ Directory . CreateDirectory ( tempPath ) ;
473+ }
474+ catch ( Exception e )
475+ {
476+ errorMsgs . Enqueue ( new ErrorRecord (
477+ exception : e ,
478+ "InstallVersionTempDirCreationError" ,
479+ ErrorCategory . InvalidResult ,
480+ _cmdletPassedIn ) ) ;
481+
482+ return null ;
483+ }
484+
485+ string containerRegistryAccessToken = GetContainerRegistryAccessToken ( needCatalogAccess : false , isPushOperation : false , out ErrorRecord errRecord ) ;
486+ if ( errRecord != null )
487+ {
488+ errorMsgs . Enqueue ( errRecord ) ;
489+ return null ;
490+ }
491+
492+ verboseMsgs . Enqueue ( $ "Getting manifest for { packageNameLowercase } - { packageVersion } ") ;
493+ var manifest = GetContainerRegistryRepositoryManifest ( packageNameLowercase , packageVersion , containerRegistryAccessToken , out errRecord ) ;
494+ if ( errRecord != null )
495+ {
496+ errorMsgs . Enqueue ( errRecord ) ;
497+ return null ;
498+ }
499+ string digest = GetDigestFromManifest ( manifest , out errRecord ) ;
500+ if ( errRecord != null )
501+ {
502+ errorMsgs . Enqueue ( errRecord ) ;
503+ return null ;
504+ }
505+
506+ verboseMsgs . Enqueue ( $ "Downloading blob for { packageNameLowercase } - { packageVersion } ") ;
507+ HttpContent responseContent ;
508+ try
509+ {
510+ responseContent = GetContainerRegistryBlobAsync ( packageNameLowercase , digest , containerRegistryAccessToken ) . Result ;
511+ }
512+ catch ( Exception e )
513+ {
514+ errorMsgs . Enqueue ( new ErrorRecord (
515+ exception : e ,
516+ "InstallVersionGetContainerRegistryBlobAsyncError" ,
517+ ErrorCategory . InvalidResult ,
518+ _cmdletPassedIn ) ) ;
519+
520+ return null ;
521+ }
522+
523+ return responseContent . ReadAsStreamAsync ( ) . Result ;
524+ }
525+
403526 #endregion
404527
405528 #region Authentication and Token Methods
0 commit comments