public async Task <List <Dictionary <string, Template> > > GetTemplateCollectionAsync(string schemaImageReference, CancellationToken cancellationToken)
        {
            ImageInfo imageInfo   = ImageInfo.CreateFromImageReference(schemaImageReference);
            var       accessToken = await _containerRegistryTokenProvider.GetTokenAsync(imageInfo.Registry, cancellationToken);

            try
            {
                var provider = _templateCollectionProviderFactory.CreateTemplateCollectionProvider(schemaImageReference, accessToken);
                return(await provider.GetTemplateCollectionAsync(cancellationToken));
            }
            catch (ContainerRegistryAuthenticationException authEx)
            {
                _logger.LogError(authEx, "Failed to access container registry.");
                throw new ContainerRegistrySchemaException("Failed to access container registry.", authEx);
            }
            catch (ImageFetchException fetchEx)
            {
                _logger.LogError(fetchEx, "Failed to fetch template image.");
                throw new ContainerRegistrySchemaException("Failed to fetch template image.", fetchEx);
            }
            catch (TemplateManagementException templateEx)
            {
                _logger.LogError(templateEx, "Template collection is invalid.");
                throw new ContainerRegistrySchemaException("Template collection is invalid.", templateEx);
            }
            catch (Exception unhandledEx)
            {
                _logger.LogError(unhandledEx, "Unhandled exception: failed to get template collection.");
                throw new ContainerRegistrySchemaException("Unhandled exception: failed to get template collection.", unhandledEx);
            }
        }
        /// <summary>
        /// Fetch template collection from container registry or built-in archive.
        /// </summary>
        /// <param name="request">The convert data request which contains template reference.</param>
        /// <param name="cancellationToken">Cancellation token to cancel the fetch operation.</param>
        /// <returns>Template collection.</returns>
        public async Task <List <Dictionary <string, Template> > > GetTemplateCollectionAsync(ConvertDataRequest request, CancellationToken cancellationToken)
        {
            // We have embedded a default template collection in the templatemanagement package.
            // If the template collection is the default reference, we don't need to retrieve token.
            var accessToken = string.Empty;

            if (!request.IsDefaultTemplateReference)
            {
                _logger.LogInformation("Using a custom template collection for data conversion.");

                async Task <string> TokenEntryFactory(ICacheEntry entry)
                {
                    var token = await _containerRegistryTokenProvider.GetTokenAsync(request.RegistryServer, cancellationToken);

                    entry.Size = token.Length;
                    entry.AbsoluteExpiration = GetTokenAbsoluteExpiration(token);
                    return(token);
                }

                accessToken = await _cache.GetOrCreateAsync(GetCacheKey(request.RegistryServer), TokenEntryFactory);
            }
            else
            {
                _logger.LogInformation("Using the default template collection for data conversion.");
            }

            try
            {
                var provider = _templateCollectionProviderFactory.CreateTemplateCollectionProvider(request.TemplateCollectionReference, accessToken);
                return(await provider.GetTemplateCollectionAsync(cancellationToken));
            }
            catch (ContainerRegistryAuthenticationException authEx)
            {
                // Remove token from cache when authentication failed.
                _cache.Remove(GetCacheKey(request.RegistryServer));

                _logger.LogError(authEx, "Failed to access container registry.");
                throw new ContainerRegistryNotAuthorizedException(string.Format(Resources.ContainerRegistryNotAuthorized, request.RegistryServer), authEx);
            }
            catch (ImageFetchException fetchEx)
            {
                _logger.LogError(fetchEx, "Failed to fetch template image.");
                throw new FetchTemplateCollectionFailedException(string.Format(Resources.FetchTemplateCollectionFailed, fetchEx.Message), fetchEx);
            }
            catch (TemplateManagementException templateEx)
            {
                _logger.LogError(templateEx, "Template collection is invalid.");
                throw new TemplateCollectionErrorException(string.Format(Resources.FetchTemplateCollectionFailed, templateEx.Message), templateEx);
            }
            catch (Exception unhandledEx)
            {
                _logger.LogError(unhandledEx, "Unhandled exception: failed to get template collection.");
                throw new FetchTemplateCollectionFailedException(string.Format(Resources.FetchTemplateCollectionFailed, unhandledEx.Message), unhandledEx);
            }
        }