예제 #1
0
        /// <summary>
        /// <para> Return true if any of below cases is satisfied:</para>
        /// <para>      1) Package with same version and from same feed already exist in local repo</para>
        /// <para>      2) If given feedUrl is null</para>
        /// <para>              Try to use feed from local package, if feed from local package also null, fallback to default feed</para>
        /// <para>              Check if version from query is same as local package</para>
        /// <para>      3) If given version and feedUrl are null</para>
        /// <para>              Try to use feed from local package, if feed from local package also null, fallback to default feed</para>
        /// <para>              Check if version from query is same as local package</para>
        /// </summary>
        private async Task <bool> IsSiteExtensionInstalled(string id, string version, string feedUrl)
        {
            JsonSettings siteExtensionSettings = GetSettingManager(id);
            string       localPackageVersion   = siteExtensionSettings.GetValue(_versionSetting);
            string       localPackageFeedUrl   = siteExtensionSettings.GetValue(_feedUrlSetting);
            bool         isInstalled           = false;

            // Try to use given feed
            // If given feed is null, try with feed that from local package
            // And GetRemoteRepository will fallback to use default feed if pass in feed param is null
            SourceRepository remoteRepo = GetRemoteRepository(feedUrl ?? localPackageFeedUrl);

            // case 1 and 2
            if (!string.IsNullOrWhiteSpace(version) &&
                version.Equals(localPackageVersion, StringComparison.OrdinalIgnoreCase) &&
                remoteRepo.PackageSource.Source.Equals(localPackageFeedUrl, StringComparison.OrdinalIgnoreCase))
            {
                isInstalled = true;
            }
            else if (string.IsNullOrWhiteSpace(version) && string.IsNullOrWhiteSpace(feedUrl))
            {
                // case 3
                UIPackageMetadata remotePackage = await remoteRepo.GetLatestPackageByIdFromSrcRepo(id);

                if (remotePackage != null)
                {
                    isInstalled = remotePackage.Identity.Version.ToNormalizedString().Equals(localPackageVersion, StringComparison.OrdinalIgnoreCase);
                }
            }

            return(isInstalled);
        }
        public void NullOrEmptyTest()
        {
            var key      = Guid.NewGuid().ToString();
            var settings = new JsonSettings(GetMockFileSystem(SettingsPath), SettingsPath);

            Assert.Equal(null, settings.GetValue(key));

            settings.SetValue(key, String.Empty);
            Assert.Equal(String.Empty, settings.GetValue(key));

            settings.SetValue(key, null);
            Assert.Equal(null, settings.GetValue(key));
        }
예제 #3
0
        /// <summary>
        /// <para> Return false if the installation arguments are different. Otherwise,</para>
        /// <para> Return true if any of below cases is satisfied:</para>
        /// <para>      1) Package with same version and from same feed already exist in local repo</para>
        /// <para>      2) If given feedUrl is null</para>
        /// <para>              Try to use feed from local package, if feed from local package also null, fallback to default feed</para>
        /// <para>              Check if version from query is same as local package</para>
        /// <para>      3) If given version and feedUrl are null</para>
        /// <para>              Try to use feed from local package, if feed from local package also null, fallback to default feed</para>
        /// <para>              Check if version from query is same as local package</para>
        /// </summary>
        private async Task <bool> IsSiteExtensionInstalled(string id, SiteExtensionInfo requestInfo)
        {
            ITracer           tracer = _traceFactory.GetTracer();
            JsonSettings      siteExtensionSettings        = GetSettingManager(id);
            string            localPackageVersion          = siteExtensionSettings.GetValue(_versionSetting);
            string            localPackageInstallationArgs = siteExtensionSettings.GetValue(_installationArgs);
            SemanticVersion   localPkgVer  = null;
            SemanticVersion   lastFoundVer = null;
            SiteExtensionInfo latestRemotePackage;
            bool isInstalled      = false;
            var  installationArgs = requestInfo.InstallationArgs;

            // Shortcircuit check: if the installation arguments do not match, then we should return false here to avoid other checks which are now unnecessary.
            if (!string.Equals(localPackageInstallationArgs, installationArgs))
            {
                return(false);
            }

            if (!string.IsNullOrEmpty(localPackageVersion))
            {
                tracer.Trace(string.Format("Site Extension {0} local version is {1}", id, localPackageVersion));
                SemanticVersion.TryParse(localPackageVersion, out localPkgVer);
            }

            if (!string.IsNullOrEmpty(requestInfo.PackageUri))
            {
                SemanticVersion.TryParse(requestInfo.Version, out lastFoundVer);
            }
            else
            {
                latestRemotePackage = await GetSiteExtensionInfoFromRemote(id);

                if (latestRemotePackage != null)
                {
                    tracer.Trace(string.Format("Site Extension {0} remote version is {1}", id, latestRemotePackage.Version));
                    SemanticVersion.TryParse(latestRemotePackage.Version, out lastFoundVer);
                }
            }

            if (lastFoundVer != null && localPkgVer != null && lastFoundVer <= localPkgVer)
            {
                tracer.Trace(string.Format("Site Extension with id {0} is already installed", id));
                isInstalled = true;
            }

            return(isInstalled);
        }
        public void DeleteValueTest()
        {
            var value    = new KeyValuePair <string, string>(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());
            var settings = new JsonSettings(GetMockFileSystem(SettingsPath), SettingsPath);

            Assert.Equal(null, settings.GetValue(value.Key));

            settings.SetValue(value.Key, value.Value);
            Assert.Equal(value.Value, settings.GetValue(value.Key));

            // Delete existing value
            Assert.Equal(true, settings.DeleteValue(value.Key));

            Assert.Equal(null, settings.GetValue(value.Key));

            // Delete non-existing value
            Assert.False(settings.DeleteValue(value.Key));
        }
예제 #5
0
        private bool IsInstalledToWebRoot(string packageId)
        {
            JsonSettings siteExtensionSettings = GetSettingManager(packageId);
            string       packageTypeStr        = siteExtensionSettings.GetValue(_packageType);

            SiteExtensionInfo.SiteExtensionType packageType;

            return(Enum.TryParse <SiteExtensionInfo.SiteExtensionType>(packageTypeStr, true, out packageType) &&
                   SiteExtensionInfo.SiteExtensionType.WebRoot == packageType);
        }
        public void ConstructorWithValuesTest()
        {
            var values = new[]
            {
                new KeyValuePair <string, string>(Guid.NewGuid().ToString(), Guid.NewGuid().ToString()),
                new KeyValuePair <string, string>(Guid.NewGuid().ToString(), Guid.NewGuid().ToString())
            };

            var settings = new JsonSettings(GetMockFileSystem(SettingsPath, values), SettingsPath);

            foreach (KeyValuePair <string, string> value in values)
            {
                Assert.Equal(value.Value, settings.GetValue(value.Key));
            }

            Assert.Equal(null, settings.GetValue("non_existing"));

            Assert.Equal(values.Length, settings.GetValues().Count());
        }
예제 #7
0
        private string SafeRead(string key)
        {
            try
            {
                return(_jsonSettings.GetValue(key));
            }
            catch (Exception ex)
            {
                _tracer.TraceError(ex);
                // if setting file happen to be invalid, e.g w3wp.exe was kill while writting
                // treat it as failed, and suggest user to re-install or un-install
                JObject newSettings = new JObject();
                newSettings[_provisioningStateSetting] = Constants.SiteExtensionProvisioningStateFailed;
                newSettings[_commentMessageSetting]    = "Corrupted site extension, please re-install or uninstall extension.";
                newSettings[_statusSetting]            = Enum.GetName(typeof(HttpStatusCode), HttpStatusCode.BadRequest);
                _jsonSettings.Save(newSettings);
            }

            return(_jsonSettings.GetValue(key));
        }
        public void SetGetValueTest()
        {
            Random random = new Random((int)DateTime.Now.Ticks);
            var    values = new Dictionary <string, JToken>
            {
                { Guid.NewGuid().ToString(), Guid.NewGuid().ToString() },
                { Guid.NewGuid().ToString(), random.Next() },
                { Guid.NewGuid().ToString(), random.Next() % 2 == 0 }
            };

            var settings = new JsonSettings(GetMockFileSystem(SettingsPath), SettingsPath);

            foreach (KeyValuePair <string, JToken> value in values)
            {
                Assert.Equal(null, settings.GetValue(value.Key));

                settings.SetValue(value.Key, value.Value);

                Assert.Equal(value.Value, settings.GetValue(value.Key));
            }
        }
예제 #9
0
        /// <summary>
        /// <para> Return false if the installation arguments are different. Otherwise,</para>
        /// <para> Return true if any of below cases is satisfied:</para>
        /// <para>      1) Package with same version and from same feed already exist in local repo</para>
        /// <para>      2) If given feedUrl is null</para>
        /// <para>              Try to use feed from local package, if feed from local package also null, fallback to default feed</para>
        /// <para>              Check if version from query is same as local package</para>
        /// <para>      3) If given version and feedUrl are null</para>
        /// <para>              Try to use feed from local package, if feed from local package also null, fallback to default feed</para>
        /// <para>              Check if version from query is same as local package</para>
        /// </summary>
        private async Task <bool> IsSiteExtensionInstalled(string id, string version, string feedUrl, string installationArgs)
        {
            JsonSettings siteExtensionSettings        = GetSettingManager(id);
            string       localPackageVersion          = siteExtensionSettings.GetValue(_versionSetting);
            string       localPackageFeedUrl          = siteExtensionSettings.GetValue(_feedUrlSetting);
            string       localPackageInstallationArgs = siteExtensionSettings.GetValue(_installationArgs);
            bool         isInstalled = false;

            // Shortcircuit check: if the installation arguments do not match, then we should return false here to avoid other checks which are now unnecessary.
            if (!string.Equals(localPackageInstallationArgs, installationArgs))
            {
                return(false);
            }

            // Try to use given feed
            // If given feed is null, try with feed that from local package
            // And GetRemoteRepository will fallback to use default feed if pass in feed param is null
            SourceRepository remoteRepo = GetRemoteRepository(feedUrl ?? localPackageFeedUrl);

            // case 1 and 2
            if (!string.IsNullOrWhiteSpace(version) &&
                version.Equals(localPackageVersion, StringComparison.OrdinalIgnoreCase) &&
                remoteRepo.PackageSource.Source.Equals(localPackageFeedUrl, StringComparison.OrdinalIgnoreCase))
            {
                isInstalled = true;
            }
            else if (string.IsNullOrWhiteSpace(version) && string.IsNullOrWhiteSpace(feedUrl))
            {
                // case 3
                UIPackageMetadata remotePackage = await remoteRepo.GetLatestPackageByIdFromSrcRepo(id);

                if (remotePackage != null)
                {
                    isInstalled = remotePackage.Identity.Version.ToNormalizedString().Equals(localPackageVersion, StringComparison.OrdinalIgnoreCase) && string.Equals(localPackageInstallationArgs, installationArgs);
                }
            }

            return(isInstalled);
        }
예제 #10
0
        public void ConstructorTest()
        {
            IFileSystem fileSystem = GetMockFileSystem(SettingsPath);

            var settings = new JsonSettings(SettingsPath);

            Assert.Equal(null, settings.GetValue("non_existing"));

            Assert.Equal(0, settings.GetValues().Count());

            Assert.False(settings.DeleteValue("non_existing"));

            Assert.False(FileSystemHelpers.FileExists(SettingsPath));
        }
예제 #11
0
        public HttpResponseMessage Get(string key)
        {
            if (String.IsNullOrEmpty(key))
            {
                return(Request.CreateResponse(HttpStatusCode.BadRequest));
            }

            string value = _settings.GetValue(key);

            if (value == null)
            {
                return(Request.CreateErrorResponse(HttpStatusCode.NotFound, String.Format(Resources.SettingDoesNotExist, key)));
            }

            return(Request.CreateResponse(HttpStatusCode.OK, value));
        }
예제 #12
0
        /// <summary>
        /// <para> Return false if the installation arguments are different. Otherwise,</para>
        /// <para> Return true if any of below cases is satisfied:</para>
        /// <para>      1) Package with same version and from same feed already exist in local repo</para>
        /// <para>      2) If given feedUrl is null</para>
        /// <para>              Try to use feed from local package, if feed from local package also null, fallback to default feed</para>
        /// <para>              Check if version from query is same as local package</para>
        /// <para>      3) If given version and feedUrl are null</para>
        /// <para>              Try to use feed from local package, if feed from local package also null, fallback to default feed</para>
        /// <para>              Check if version from query is same as local package</para>
        /// </summary>
        private async Task <bool> IsSiteExtensionInstalled(string id, string version, string feedUrl, string installationArgs)
        {
            ITracer      tracer = _traceFactory.GetTracer();
            JsonSettings siteExtensionSettings        = GetSettingManager(id);
            string       localPackageVersion          = siteExtensionSettings.GetValue(_versionSetting);
            string       localPackageFeedUrl          = siteExtensionSettings.GetValue(_feedUrlSetting);
            string       localPackageInstallationArgs = siteExtensionSettings.GetValue(_installationArgs);
            NuGetVersion localPkgVer  = null;
            NuGetVersion lastFoundVer = null;
            bool         isInstalled  = false;

            // Shortcircuit check: if the installation arguments do not match, then we should return false here to avoid other checks which are now unnecessary.
            if (!string.Equals(localPackageInstallationArgs, installationArgs))
            {
                return(false);
            }

            if (!string.IsNullOrEmpty(localPackageVersion))
            {
                localPkgVer = NuGetVersion.Parse(localPackageVersion);
            }

            // Try to use given feed
            // If given feed is null, try with feed that from local package
            // And GetRemoteRepositories will fallback to use default feed if pass in feed param is null
            IEnumerable <SourceRepository> remoteRepos = GetRemoteRepositories(feedUrl ?? localPackageFeedUrl);

            foreach (SourceRepository rr in remoteRepos)
            {
                // case 1 and 2
                if (!string.IsNullOrWhiteSpace(version) &&
                    version.Equals(localPackageVersion, StringComparison.OrdinalIgnoreCase) &&
                    rr.PackageSource.Source.Equals(localPackageFeedUrl, StringComparison.OrdinalIgnoreCase))
                {
                    isInstalled = true;
                }
                else if (string.IsNullOrWhiteSpace(version) &&
                         string.IsNullOrWhiteSpace(feedUrl) &&
                         string.Equals(localPackageInstallationArgs, installationArgs))
                {
                    // case 3
                    UIPackageMetadata remotePackage = await rr.GetLatestPackageByIdFromSrcRepo(id);

                    if (remotePackage != null)
                    {
                        tracer.Trace("Found version: {0} on feed: {1}",
                                     remotePackage.Identity.Version.ToNormalizedString(),
                                     rr.PackageSource.Source);
                        if (lastFoundVer == null || lastFoundVer < remotePackage.Identity.Version)
                        {
                            lastFoundVer = remotePackage.Identity.Version;
                        }
                    }
                }
            }

            if (lastFoundVer != null && localPkgVer != null && lastFoundVer <= localPkgVer)
            {
                isInstalled = true;
            }

            return(isInstalled);
        }
예제 #13
0
        private async Task <SiteExtensionInfo> TryInstallExtension(string id, string version, string feedUrl, SiteExtensionInfo.SiteExtensionType type, ITracer tracer, string installationArgs)
        {
            SiteExtensionInfo info   = null;
            HttpStatusCode    status = HttpStatusCode.OK; // final status when success
            bool alreadyInstalled    = false;

            try
            {
                // Check if site extension already installed (id, version, feedUrl), if already install with correct installation arguments then return right away
                if (await this.IsSiteExtensionInstalled(id, version, feedUrl, installationArgs))
                {
                    // package already installed, return package from local repo.
                    tracer.Trace("Package {0} with version {1} from {2} with installation arguments '{3}' already installed.", id, version, feedUrl, installationArgs);
                    info = await GetLocalExtension(id);

                    alreadyInstalled = true;
                }
                else
                {
                    JsonSettings siteExtensionSettings = GetSettingManager(id);
                    feedUrl = (string.IsNullOrEmpty(feedUrl) ? siteExtensionSettings.GetValue(_feedUrlSetting) : feedUrl);
                    IEnumerable <SourceRepository> remoteRepos = GetRemoteRepositories(feedUrl);
                    UIPackageMetadata localPackage             = null;
                    UIPackageMetadata repoPackage = null;
                    SourceRepository  remoteRepo  = null;

                    if (this.IsInstalledToWebRoot(id))
                    {
                        // override WebRoot type from setting
                        // WebRoot is a special type that install package to wwwroot, when perform update we need to update new content to wwwroot even if type is not specified
                        type = SiteExtensionInfo.SiteExtensionType.WebRoot;
                    }

                    if (string.IsNullOrWhiteSpace(version))
                    {
                        using (tracer.Step("Version is null, search latest package by id: {0}, will not search for unlisted package.", id))
                        {
                            foreach (SourceRepository rr in remoteRepos)
                            {
                                repoPackage = await rr.GetLatestPackageByIdFromSrcRepo(id);

                                if (repoPackage != null)
                                {
                                    remoteRepo = rr;
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        using (tracer.Step("Search package by id: {0} and version: {1}, will also search for unlisted package.", id, version))
                        {
                            foreach (SourceRepository rr in remoteRepos)
                            {
                                repoPackage = await rr.GetPackageByIdentity(id, version);

                                if (repoPackage != null)
                                {
                                    remoteRepo = rr;
                                    break;
                                }
                            }
                        }
                    }

                    if (repoPackage != null)
                    {
                        Debug.Assert(remoteRepo != null, "remote SourceRepository should not be null!");
                        using (tracer.Step("Install package: {0}.", id))
                        {
                            string installationDirectory = GetInstallationDirectory(id);
                            localPackage = await InstallExtension(repoPackage, installationDirectory, remoteRepo, type, tracer, installationArgs);

                            siteExtensionSettings.SetValues(new KeyValuePair <string, JToken>[] {
                                new KeyValuePair <string, JToken>(_versionSetting, localPackage.Identity.Version.ToNormalizedString()),
                                new KeyValuePair <string, JToken>(_feedUrlSetting, feedUrl),
                                new KeyValuePair <string, JToken>(_installUtcTimestampSetting, DateTime.UtcNow.ToString("u")),
                                new KeyValuePair <string, JToken>(_packageType, Enum.GetName(typeof(SiteExtensionInfo.SiteExtensionType), type)),
                                new KeyValuePair <string, JToken>(_installationArgs, installationArgs)
                            });
                        }
                    }

                    info = await ConvertLocalPackageToSiteExtensionInfo(localPackage, checkLatest : true, tracer : tracer);
                }
            }
            catch (FileNotFoundException ex)
            {
                _analytics.UnexpectedException(
                    ex,
                    method: "PUT",
                    path: string.Format(CultureInfo.InvariantCulture, "/api/siteextensions/{0}", id),
                    result: Constants.SiteExtensionProvisioningStateFailed,
                    message: string.Format(CultureInfo.InvariantCulture, "{{\"version\": {0}, \"feed_url\": {1}}}", version, feedUrl),
                    trace: false);

                tracer.TraceError(ex);
                info    = new SiteExtensionInfo();
                info.Id = id;
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = ex.ToString();
                status = HttpStatusCode.NotFound;
            }
            catch (WebException ex)
            {
                _analytics.UnexpectedException(
                    ex,
                    method: "PUT",
                    path: string.Format(CultureInfo.InvariantCulture, "/api/siteextensions/{0}", id),
                    result: Constants.SiteExtensionProvisioningStateFailed,
                    message: string.Format(CultureInfo.InvariantCulture, "{{\"version\": {0}, \"feed_url\": {1}}}", version, feedUrl),
                    trace: false);

                tracer.TraceError(ex);
                info    = new SiteExtensionInfo();
                info.Id = id;
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = ex.ToString();
                status = HttpStatusCode.BadRequest;
            }
            catch (InvalidEndpointException ex)
            {
                _analytics.UnexpectedException(ex, trace: false);

                tracer.TraceError(ex);
                info    = new SiteExtensionInfo();
                info.Id = id;
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = ex.ToString();
                status = HttpStatusCode.BadRequest;
            }
            catch (Exception ex)
            {
                _analytics.UnexpectedException(
                    ex,
                    method: "PUT",
                    path: string.Format(CultureInfo.InvariantCulture, "/api/siteextensions/{0}", id),
                    result: Constants.SiteExtensionProvisioningStateFailed,
                    message: string.Format(CultureInfo.InvariantCulture, "{{\"version\": {0}, \"feed_url\": {1}}}", version, feedUrl),
                    trace: false);

                tracer.TraceError(ex);
                info    = new SiteExtensionInfo();
                info.Id = id;
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = ex.ToString();
                status = HttpStatusCode.BadRequest;
            }

            if (info == null)
            {
                // treat this as an error case since no result return from repo
                _analytics.UnexpectedException(
                    new FileNotFoundException(id),
                    method: "PUT",
                    path: string.Format(CultureInfo.InvariantCulture, "/api/siteextensions/{0}", id),
                    result: Constants.SiteExtensionProvisioningStateFailed,
                    message: string.Format(CultureInfo.InvariantCulture, "{{\"version\": {0}, \"feed_url\": {1}}}", version, feedUrl),
                    trace: false);

                info = new SiteExtensionInfo();
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = string.Format(Constants.SiteExtensionProvisioningStateNotFoundMessageFormat, id);
                status = HttpStatusCode.NotFound;
            }
            else if (!string.Equals(Constants.SiteExtensionProvisioningStateFailed, info.ProvisioningState, StringComparison.OrdinalIgnoreCase))
            {
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateSucceeded;
                info.Comment           = null;
            }

            using (tracer.Step("Update arm settings for {0} installation. Status: {1}", id, status))
            {
                SiteExtensionStatus armSettings = new SiteExtensionStatus(_environment.SiteExtensionSettingsPath, id, tracer);
                armSettings.ReadSiteExtensionInfo(info);
                armSettings.Status    = status;
                armSettings.Operation = alreadyInstalled ? null : Constants.SiteExtensionOperationInstall;
            }

            return(info);
        }
예제 #14
0
        private async Task <SiteExtensionInfo> TryInstallExtension(string id, string version, string feedUrl, SiteExtensionInfo.SiteExtensionType type, ITracer tracer)
        {
            SiteExtensionInfo info   = null;
            HttpStatusCode    status = HttpStatusCode.OK; // final status when success
            bool alreadyInstalled    = false;

            if (_preInstalledExtensionDictionary.ContainsKey(id))
            {
                tracer.Trace("Pre-installed site extension found: {0}, not going to perform new installation.", id);
                info             = EnablePreInstalledExtension(_preInstalledExtensionDictionary[id], tracer);
                alreadyInstalled = true;
            }
            else
            {
                try
                {
                    // Check if site extension already installed (id, version, feedUrl), if already install return right away
                    if (await this.IsSiteExtensionInstalled(id, version, feedUrl))
                    {
                        // package already installed, return package from local repo.
                        tracer.Trace("Package {0} with version {1} from {2} already installed.", id, version, feedUrl);
                        info = await GetLocalExtension(id);

                        alreadyInstalled = true;
                    }
                    else
                    {
                        JsonSettings siteExtensionSettings = GetSettingManager(id);
                        feedUrl = (string.IsNullOrEmpty(feedUrl) ? siteExtensionSettings.GetValue(_feedUrlSetting) : feedUrl);
                        SourceRepository  remoteRepo   = GetRemoteRepository(feedUrl);
                        UIPackageMetadata localPackage = null;
                        UIPackageMetadata repoPackage  = null;

                        if (string.IsNullOrWhiteSpace(version))
                        {
                            using (tracer.Step("Version is null, search latest package by id: {0}, will not search for unlisted package.", id))
                            {
                                repoPackage = await remoteRepo.GetLatestPackageById(id);
                            }
                        }
                        else
                        {
                            using (tracer.Step("Search package by id: {0} and version: {1}, will also search for unlisted package.", id, version))
                            {
                                repoPackage = await remoteRepo.GetPackageByIdentity(id, version);
                            }
                        }

                        if (repoPackage != null)
                        {
                            using (tracer.Step("Install package: {0}.", id))
                            {
                                string installationDirectory = GetInstallationDirectory(id);
                                localPackage = await InstallExtension(repoPackage, installationDirectory, feedUrl, type, tracer);

                                siteExtensionSettings.SetValues(new KeyValuePair <string, JToken>[] {
                                    new KeyValuePair <string, JToken>(_versionSetting, localPackage.Identity.Version.ToNormalizedString()),
                                    new KeyValuePair <string, JToken>(_feedUrlSetting, feedUrl),
                                    new KeyValuePair <string, JToken>(_installUtcTimestampSetting, DateTime.UtcNow.ToString("u")),
                                    new KeyValuePair <string, JToken>(_packageType, Enum.GetName(typeof(SiteExtensionInfo.SiteExtensionType), type))
                                });
                            }
                        }

                        info = await ConvertLocalPackageToSiteExtensionInfo(localPackage, checkLatest : true, tracer : tracer);
                    }
                }
                catch (FileNotFoundException ex)
                {
                    _analytics.UnexpectedException(
                        ex,
                        method: "PUT",
                        path: string.Format(CultureInfo.InvariantCulture, "/api/siteextensions/{0}", id),
                        result: Constants.SiteExtensionProvisioningStateFailed,
                        message: string.Format(CultureInfo.InvariantCulture, "{{\"version\": {0}, \"feed_url\": {1}}}", version, feedUrl),
                        trace: false);

                    tracer.TraceError(ex);
                    info    = new SiteExtensionInfo();
                    info.Id = id;
                    info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                    info.Comment           = string.Format(Constants.SiteExtensionProvisioningStateNotFoundMessageFormat, id);
                    status = HttpStatusCode.NotFound;
                }
                catch (WebException ex)
                {
                    _analytics.UnexpectedException(
                        ex,
                        method: "PUT",
                        path: string.Format(CultureInfo.InvariantCulture, "/api/siteextensions/{0}", id),
                        result: Constants.SiteExtensionProvisioningStateFailed,
                        message: string.Format(CultureInfo.InvariantCulture, "{{\"version\": {0}, \"feed_url\": {1}}}", version, feedUrl),
                        trace: false);

                    tracer.TraceError(ex);
                    info    = new SiteExtensionInfo();
                    info.Id = id;
                    info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                    info.Comment           = string.Format(Constants.SiteExtensionProvisioningStateDownloadFailureMessageFormat, id);
                    status = HttpStatusCode.BadRequest;
                }
                catch (InvalidEndpointException ex)
                {
                    _analytics.UnexpectedException(ex, trace: false);

                    tracer.TraceError(ex);
                    info    = new SiteExtensionInfo();
                    info.Id = id;
                    info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                    info.Comment           = ex.Message;
                    status = HttpStatusCode.BadRequest;
                }
                catch (Exception ex)
                {
                    _analytics.UnexpectedException(
                        ex,
                        method: "PUT",
                        path: string.Format(CultureInfo.InvariantCulture, "/api/siteextensions/{0}", id),
                        result: Constants.SiteExtensionProvisioningStateFailed,
                        message: string.Format(CultureInfo.InvariantCulture, "{{\"version\": {0}, \"feed_url\": {1}}}", version, feedUrl),
                        trace: false);

                    tracer.TraceError(ex);
                    info    = new SiteExtensionInfo();
                    info.Id = id;
                    info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                    info.Comment           = string.Format(Constants.SiteExtensionProvisioningStateInvalidPackageMessageFormat, id);
                    status = HttpStatusCode.BadRequest;
                }
            }

            if (info == null)
            {
                // treat this as an error case since no result return from repo
                _analytics.UnexpectedException(
                    new FileNotFoundException(id),
                    method: "PUT",
                    path: string.Format(CultureInfo.InvariantCulture, "/api/siteextensions/{0}", id),
                    result: Constants.SiteExtensionProvisioningStateFailed,
                    message: string.Format(CultureInfo.InvariantCulture, "{{\"version\": {0}, \"feed_url\": {1}}}", version, feedUrl),
                    trace: false);

                info = new SiteExtensionInfo();
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = string.Format(Constants.SiteExtensionProvisioningStateNotFoundMessageFormat, id);
                status = HttpStatusCode.NotFound;
            }
            else if (!string.Equals(Constants.SiteExtensionProvisioningStateFailed, info.ProvisioningState, StringComparison.OrdinalIgnoreCase))
            {
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateSucceeded;
                info.Comment           = null;
            }

            using (tracer.Step("Update arm settings for {0} installation. Status: {1}", id, status))
            {
                SiteExtensionStatus armSettings = new SiteExtensionStatus(_environment.SiteExtensionSettingsPath, id, tracer);
                armSettings.ReadSiteExtensionInfo(info);
                armSettings.Status    = status;
                armSettings.Operation = alreadyInstalled ? null : Constants.SiteExtensionOperationInstall;
            }

            return(info);
        }
예제 #15
0
        // <inheritdoc />
        public async Task <SiteExtensionInfo> InstallExtension(string id, string version, string feedUrl)
        {
            ITracer tracer = _traceFactory.GetTracer();

            if (_preInstalledExtensionDictionary.ContainsKey(id))
            {
                tracer.Trace("Pre-installed site extension found: {0}, not going to perform new installation.", id);
                return(EnablePreInstalledExtension(_preInstalledExtensionDictionary[id]));
            }
            else
            {
                // Check if site extension already installed (id, version, feedUrl), if already install return right away
                if (await this.IsSiteExtensionInstalled(id, version, feedUrl))
                {
                    // package already installed, return package from local repo.
                    tracer.Trace("Site extension {0} with version {1} from {2} already installed.", id, version, feedUrl);
                    return(await GetLocalExtension(id));
                }

                JsonSettings siteExtensionSettings = GetSettingManager(id);

                if (String.IsNullOrEmpty(feedUrl))
                {
                    feedUrl = siteExtensionSettings.GetValue(_feedUrlSetting);
                }

                SourceRepository  remoteRepo   = GetRemoteRepository(feedUrl);
                UIPackageMetadata localPackage = null;
                UIPackageMetadata repoPackage  = null;

                if (string.IsNullOrWhiteSpace(version))
                {
                    using (tracer.Step("Version is null, search latest package by id: {0}", id))
                    {
                        repoPackage = await remoteRepo.GetLatestPackageById(id);
                    }
                }
                else
                {
                    using (tracer.Step("Search package by id: {0} and version: {1}", id, version))
                    {
                        repoPackage = await remoteRepo.GetPackageByIdentity(id, version);
                    }
                }

                if (repoPackage != null)
                {
                    using (tracer.Step("Install package: {0}.", id))
                    {
                        string installationDirectory = GetInstallationDirectory(id);
                        localPackage = await InstallExtension(repoPackage, installationDirectory, feedUrl);

                        siteExtensionSettings.SetValues(new KeyValuePair <string, JToken>[] {
                            new KeyValuePair <string, JToken>(_versionSetting, localPackage.Identity.Version.ToNormalizedString()),
                            new KeyValuePair <string, JToken>(_feedUrlSetting, feedUrl),
                            new KeyValuePair <string, JToken>(_installUtcTimestampSetting, DateTime.UtcNow.ToString("u"))
                        });
                    }
                }

                return(await ConvertLocalPackageToSiteExtensionInfo(localPackage, checkLatest : true));
            }
        }
예제 #16
0
        private async Task <SiteExtensionInfo> TryInstallExtension(string id, SiteExtensionInfo requestInfo, ITracer tracer)
        {
            SiteExtensionInfo info   = null;
            HttpStatusCode    status = HttpStatusCode.OK; // final status when success
            bool alreadyInstalled    = false;
            var  version             = requestInfo.Version;
            var  feedUrl             = requestInfo.FeedUrl;
            var  type             = requestInfo.Type;
            var  installationArgs = requestInfo.InstallationArgs;
            var  packageUri       = requestInfo.PackageUri;

            try
            {
                // Check if site extension already installed (id, version, feedUrl), if already install with correct installation arguments then return right away
                if (await IsSiteExtensionInstalled(id, requestInfo))
                {
                    // package already installed, return package from local repo.
                    tracer.Trace("Package {0} with version {1} from {2} with installation arguments '{3}' already installed.", id, version, feedUrl, installationArgs);
                    info = await GetLocalExtension(id);

                    alreadyInstalled = true;
                }
                else
                {
                    JsonSettings siteExtensionSettings = GetSettingManager(id);
                    feedUrl = (string.IsNullOrEmpty(feedUrl) ? siteExtensionSettings.GetValue(_feedUrlSetting) : feedUrl);
                    info    = !string.IsNullOrEmpty(packageUri) ? requestInfo : await GetSiteExtensionInfoFromRemote(id, version, tracer);

                    if (info != null)
                    {
                        using (tracer.Step("Install package: {0}.", id))
                        {
                            string installationDirectory = GetInstallationDirectory(id);
                            info = await InstallExtension(info, installationDirectory, type, tracer, installationArgs);

                            siteExtensionSettings.SetValues(new KeyValuePair <string, JToken>[]
                            {
                                new KeyValuePair <string, JToken>(_versionSetting, info.Version),
                                new KeyValuePair <string, JToken>(_feedUrlSetting, feedUrl),
                                new KeyValuePair <string, JToken>(_packageUriSetting, packageUri),
                                new KeyValuePair <string, JToken>(_installUtcTimestampSetting, DateTime.UtcNow.ToString("u")),
                                new KeyValuePair <string, JToken>(_packageType, Enum.GetName(typeof(SiteExtensionInfo.SiteExtensionType), type)),
                                new KeyValuePair <string, JToken>(_installationArgs, installationArgs)
                            });
                        }
                    }
                }

                if (info != null)
                {
                    await SetLocalInfo(info);
                }
            }
            catch (FileNotFoundException ex)
            {
                _analytics.UnexpectedException(
                    ex,
                    method: "PUT",
                    path: string.Format(CultureInfo.InvariantCulture, "/api/siteextensions/{0}", id),
                    result: Constants.SiteExtensionProvisioningStateFailed,
                    message: string.Format(CultureInfo.InvariantCulture, "{{\"version\": {0}, \"feed_url\": {1}}}", version, feedUrl),
                    trace: false);

                tracer.TraceError(ex);
                info    = new SiteExtensionInfo();
                info.Id = id;
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = ex.ToString();
                status = HttpStatusCode.NotFound;
            }
            catch (WebException ex)
            {
                _analytics.UnexpectedException(
                    ex,
                    method: "PUT",
                    path: string.Format(CultureInfo.InvariantCulture, "/api/siteextensions/{0}", id),
                    result: Constants.SiteExtensionProvisioningStateFailed,
                    message: string.Format(CultureInfo.InvariantCulture, "{{\"version\": {0}, \"feed_url\": {1}}}", version, feedUrl),
                    trace: false);

                tracer.TraceError(ex);
                info    = new SiteExtensionInfo();
                info.Id = id;
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = ex.ToString();
                status = HttpStatusCode.BadRequest;
            }
            catch (InvalidEndpointException ex)
            {
                _analytics.UnexpectedException(ex, trace: false);

                tracer.TraceError(ex);
                info    = new SiteExtensionInfo();
                info.Id = id;
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = ex.ToString();
                status = HttpStatusCode.BadRequest;
            }
            catch (Exception ex)
            {
                _analytics.UnexpectedException(
                    ex,
                    method: "PUT",
                    path: string.Format(CultureInfo.InvariantCulture, "/api/siteextensions/{0}", id),
                    result: Constants.SiteExtensionProvisioningStateFailed,
                    message: string.Format(CultureInfo.InvariantCulture, "{{\"version\": {0}, \"feed_url\": {1}}}", version, feedUrl),
                    trace: false);

                tracer.TraceError(ex);
                info    = new SiteExtensionInfo();
                info.Id = id;
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = ex.ToString();
                status = HttpStatusCode.BadRequest;
            }

            if (info == null)
            {
                // treat this as an error case since no result return from repo
                _analytics.UnexpectedException(
                    new FileNotFoundException(id),
                    method: "PUT",
                    path: string.Format(CultureInfo.InvariantCulture, "/api/siteextensions/{0}", id),
                    result: Constants.SiteExtensionProvisioningStateFailed,
                    message: string.Format(CultureInfo.InvariantCulture, "{{\"version\": {0}, \"feed_url\": {1}}}", version, feedUrl),
                    trace: false);

                info = new SiteExtensionInfo();
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateFailed;
                info.Comment           = string.Format(Constants.SiteExtensionProvisioningStateNotFoundMessageFormat, id);
                status = HttpStatusCode.NotFound;
            }
            else if (!string.Equals(Constants.SiteExtensionProvisioningStateFailed, info.ProvisioningState, StringComparison.OrdinalIgnoreCase))
            {
                info.ProvisioningState = Constants.SiteExtensionProvisioningStateSucceeded;
                info.Comment           = null;
            }

            using (tracer.Step("Update arm settings for {0} installation. Status: {1}", id, status))
            {
                SiteExtensionStatus armSettings = new SiteExtensionStatus(_environment.SiteExtensionSettingsPath, id, tracer);
                armSettings.ReadSiteExtensionInfo(info);
                armSettings.Status    = status;
                armSettings.Operation = alreadyInstalled ? null : Constants.SiteExtensionOperationInstall;
            }

            return(info);
        }