/// <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)); }
/// <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)); }
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()); }
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)); } }
/// <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); }
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)); }
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)); }
/// <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); }
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); }
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); }
// <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)); } }
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); }