Example #1
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;

            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 (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))
                        {
                            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           = 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 (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))
                            {
                                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 = 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;
        }
Example #3
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);
        }