コード例 #1
0
        public async Task <TResponse?> SendAsync <TResponse>(ReloadlyRequest <TResponse> request)
            where TResponse : class
        {
            var reqMessage = request.CreateHttpRequestMessage();

            if (!_disableTelemetry)
            {
                var telemetry = TelemetryUtility.Create(_apiVersion).HttpHeaderValue();
                reqMessage.Headers.TryAddWithoutValidation(TelemetryHeaderName, telemetry);
            }

            var httpClient = _httpClientFactory.CreateClient();
            var resMessage = await httpClient.SendAsync(reqMessage);

            return(await ParseResponse(request, resMessage));
        }
コード例 #2
0
 public SearchPageTelemetryEvent(
     Guid parentId,
     int pageIndex,
     int resultCount,
     TimeSpan duration,
     IEnumerable <TimeSpan> sourceTimings,
     TimeSpan aggregationTime,
     LoadingStatus loadingStatus) : base("SearchPage")
 {
     base["ParentId"]    = parentId.ToString();
     base["PageIndex"]   = pageIndex;
     base["ResultCount"] = resultCount;
     base["Duration"]    = duration.TotalSeconds;
     base["IndividualSourceDurations"]  = TelemetryUtility.ToJsonArrayOfTimingsInSeconds(sourceTimings);
     base["ResultsAggregationDuration"] = aggregationTime.TotalSeconds;
     base["LoadingStatus"] = loadingStatus.ToString();
 }
コード例 #3
0
        public static void VerifyTelemetryEventData(string operationId, ActionEventBase expected, TelemetryEvent actual)
        {
            Assert.Equal(operationId, actual["OperationId"].ToString());
            Assert.Equal(expected.ProjectsCount, (int)actual["ProjectsCount"]);
            Assert.Equal(expected.PackagesCount, (int)actual["PackagesCount"]);
            Assert.Equal(expected.Status.ToString(), actual["Status"].ToString());
            Assert.Equal(expected.StartTime, actual["StartTime"]);
            Assert.Equal(expected.EndTime, actual["EndTime"]);
            Assert.Equal(expected.Duration, (double)actual["Duration"]);

            TelemetryUtility.VerifyDateTimeFormat(actual["StartTime"] as string);
            TelemetryUtility.VerifyDateTimeFormat(actual["EndTime"] as string);

            for (var i = 0; i < expected.ProjectsCount; i++)
            {
                Assert.Equal(expected.ProjectIds[i], actual["ProjectId" + (i + 1)].ToString());
            }
        }
コード例 #4
0
        protected override void ProcessRecordCore()
        {
            var startTime = DateTimeOffset.Now;

            // Set to log telemetry granular events for this install operation
            TelemetryService = new TelemetryServiceHelper();

            // start timer for telemetry event
            TelemetryUtility.StartorResumeTimer();

            using (var lck = _lockService.AcquireLock())
            {
                Preprocess();

                SubscribeToProgressEvents();
                if (!_readFromPackagesConfig &&
                    !_readFromDirectPackagePath &&
                    _nugetVersion == null)
                {
                    Task.Run(InstallPackageByIdAsync);
                }
                else
                {
                    var identities = GetPackageIdentities();
                    Task.Run(() => InstallPackagesAsync(identities));
                }
                WaitAndLogPackageActions();
                UnsubscribeFromProgressEvents();
            }

            // stop timer for telemetry event and create action telemetry event instance
            TelemetryUtility.StopTimer();
            var actionTelemetryEvent = TelemetryUtility.GetActionTelemetryEvent(
                new[] { Project },
                NuGetOperationType.Install,
                OperationSource.PMC,
                startTime,
                _status,
                _packageCount,
                TelemetryUtility.GetTimerElapsedTimeInSeconds());

            // emit telemetry event along with granular level events
            ActionsTelemetryService.Instance.EmitActionEvent(actionTelemetryEvent, TelemetryService.TelemetryEvents);
        }
コード例 #5
0
        public static async Task <ProjectTelemetryEvent> GetProjectTelemetryEventAsync(NuGetProject nuGetProject)
        {
            if (nuGetProject == null)
            {
                throw new ArgumentNullException(nameof(nuGetProject));
            }
            string projectUniqueName          = string.Empty;
            ProjectTelemetryEvent returnValue = null;

            try
            {
                // Get the project details.
                projectUniqueName = nuGetProject.GetMetadata <string>(NuGetProjectMetadataKeys.UniqueName);
                string           projectId    = nuGetProject.GetMetadata <string>(NuGetProjectMetadataKeys.ProjectId);
                NuGetProjectType projectType  = GetProjectType(nuGetProject);
                bool             isUpgradable = await NuGetProjectUpgradeUtility.IsNuGetProjectUpgradeableAsync(nuGetProject);

                string fullPath = nuGetProject.GetMetadata <string>(NuGetProjectMetadataKeys.FullPath);

                returnValue = new ProjectTelemetryEvent(
                    NuGetVersion.Value,
                    projectId,
                    projectType,
                    isUpgradable,
                    fullPath);
            }
            catch (Exception ex)
            {
                // ArgumentException means project metadata is empty
                // DTE exceptions could mean VS process has a severe failure
                string message =
                    $"Failed to emit project information for project '{projectUniqueName}'. Exception:" +
                    Environment.NewLine +
                    ex.ToString();

                ActivityLog.LogWarning(ExceptionHelper.LogEntrySource, message);
                Debug.Fail(message);

                await TelemetryUtility.PostFaultAsync(ex, nameof(VSTelemetryServiceUtility), nameof(GetProjectTelemetryEventAsync));
            }

            return(returnValue);
        }
コード例 #6
0
        protected override void ProcessRecordCore()
        {
            var startTime = DateTimeOffset.Now;

            _packageCount = 1;

            // Enable granular level events for this uninstall operation
            TelemetryService = new TelemetryServiceHelper();
            TelemetryUtility.StartorResumeTimer();

            // Run Preprocess outside of JTF
            Preprocess();

            NuGetUIThreadHelper.JoinableTaskFactory.Run(async() =>
            {
                await _lockService.ExecuteNuGetOperationAsync(() =>
                {
                    SubscribeToProgressEvents();
                    Task.Run(UninstallPackageAsync);
                    WaitAndLogPackageActions();
                    UnsubscribeFromProgressEvents();

                    return(Task.FromResult(true));
                }, Token);
            });

            TelemetryUtility.StopTimer();
            var actionTelemetryEvent = TelemetryUtility.GetActionTelemetryEvent(
                new[] { Project },
                NuGetOperationType.Uninstall,
                OperationSource.PMC,
                startTime,
                _status,
                _packageCount,
                TelemetryUtility.GetTimerElapsedTimeInSeconds());

            // emit telemetry event with granular level events
            ActionsTelemetryService.Instance.EmitActionEvent(actionTelemetryEvent, TelemetryService.TelemetryEvents);
        }
コード例 #7
0
        private void ShowManageLibraryPackageForSolutionDialog(object sender, EventArgs e)
        {
            NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async delegate
            {
                await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                if (ShouldMEFBeInitialized())
                {
                    await InitializeMEFAsync();
                }

                var windowFrame = await FindExistingSolutionWindowFrameAsync();
                if (windowFrame == null)
                {
                    // Create the window frame
                    windowFrame = await CreateDocWindowForSolutionAsync();
                }

                if (windowFrame != null)
                {
                    // process search string
                    string parameterString = null;
                    var args = e as OleMenuCmdEventArgs;
                    if (args != null)
                    {
                        parameterString = args.InValue as string;
                    }
                    var searchText = GetSearchText(parameterString);
                    Search(windowFrame, searchText);

                    windowFrame.Show();
                }
            }).FileAndForget(
                TelemetryUtility.CreateFileAndForgetEventName(
                    nameof(NuGetPackage),
                    nameof(ShowManageLibraryPackageForSolutionDialog)));
        }
コード例 #8
0
        private void StartAsyncDefaultProjectUpdate()
        {
            Assumes.Present(_solutionManager.Value);

            NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async() =>
            {
                await TaskScheduler.Default;

                NuGetProject project = await _solutionManager.Value.GetDefaultNuGetProjectAsync();

                var oldValue = DefaultProject;
                string newValue;

                if (oldValue == null && project == null)
                {
                    return;
                }
                else if (project == null)
                {
                    newValue = null;
                }
                else
                {
                    newValue = await GetDisplayNameAsync(project);
                }

                bool isInvalidationRequired = oldValue != newValue;

                if (isInvalidationRequired)
                {
                    DefaultProject = newValue;

                    await CommandUiUtilities.InvalidateDefaultProjectAsync();
                }
            })
            .FileAndForget(TelemetryUtility.CreateFileAndForgetEventName(nameof(PowerShellHost), nameof(StartAsyncDefaultProjectUpdate)));
        }
コード例 #9
0
        public void CreateFileAndForgetEventName_WhenArgumentsAreValid_ReturnsString()
        {
            string actualResult = TelemetryUtility.CreateFileAndForgetEventName("a", "b");

            Assert.Equal("VS/NuGet/fileandforget/a/b", actualResult);
        }
コード例 #10
0
        public void IsHttpV3_WhenSourceIsNull_Throws()
        {
            var exception = Assert.Throws <ArgumentNullException>(() => TelemetryUtility.IsHttpV3(source: null));

            Assert.Equal("source", exception.ParamName);
        }
コード例 #11
0
 public void ToJsonArrayOfTimingsInSeconds_WithOneValue_ReturnsTimingsInSeconds()
 {
     TimeSpan[] values = new[] { new TimeSpan(hours: 0, minutes: 0, seconds: 5) };
     TelemetryUtility.ToJsonArrayOfTimingsInSeconds(values).Should().Be("[5]");
 }
コード例 #12
0
        private void EmitRestoreTelemetryEvent(IEnumerable <NuGetProject> projects,
                                               bool forceRestore,
                                               RestoreOperationSource source,
                                               DateTimeOffset startTime,
                                               double duration,
                                               PackageSourceTelemetry.Totals protocolDiagnosticTotals,
                                               IntervalTracker intervalTimingTracker)
        {
            var sortedProjects = projects.OrderBy(
                project => project.GetMetadata <string>(NuGetProjectMetadataKeys.UniqueName));
            var projectIds = sortedProjects.Select(
                project => project.GetMetadata <string>(NuGetProjectMetadataKeys.ProjectId)).ToArray();
            var projectDictionary = sortedProjects
                                    .GroupBy(x => x.ProjectStyle)
                                    .ToDictionary(x => x.Key, y => y.Count());

            var  packageSourceMapping          = PackageSourceMapping.GetPackageSourceMapping(_settings);
            bool isPackageSourceMappingEnabled = packageSourceMapping?.IsEnabled ?? false;
            var  packageSources = _sourceRepositoryProvider.PackageSourceProvider.LoadPackageSources().ToList();

            int  NumHTTPFeeds     = 0;
            int  NumLocalFeeds    = 0;
            bool hasVSOfflineFeed = false;
            bool hasNuGetOrg      = false;

            foreach (var packageSource in packageSources)
            {
                if (packageSource.IsEnabled)
                {
                    if (packageSource.IsHttp)
                    {
                        NumHTTPFeeds++;
                        hasNuGetOrg |= TelemetryUtility.IsNuGetOrg(packageSource.Source);
                    }
                    else
                    {
                        hasVSOfflineFeed |= TelemetryUtility.IsVsOfflineFeed(packageSource);
                        NumLocalFeeds++;
                    }
                }
            }

            var restoreTelemetryEvent = new RestoreTelemetryEvent(
                _nuGetProjectContext.OperationId.ToString(),
                projectIds,
                forceRestore,
                source,
                startTime,
                _status,
                packageCount: _packageCount,
                noOpProjectsCount: _noOpProjectsCount,
                upToDateProjectsCount: _upToDateProjectCount,
                unknownProjectsCount: projectDictionary.GetValueOrDefault(ProjectStyle.Unknown, 0), // appears in DependencyGraphRestoreUtility
                projectJsonProjectsCount: projectDictionary.GetValueOrDefault(ProjectStyle.ProjectJson, 0),
                packageReferenceProjectsCount: projectDictionary.GetValueOrDefault(ProjectStyle.PackageReference, 0),
                legacyPackageReferenceProjectsCount: sortedProjects.Where(x => x.ProjectStyle == ProjectStyle.PackageReference && x is LegacyPackageReferenceProject).Count(),
                cpsPackageReferenceProjectsCount: sortedProjects.Where(x => x.ProjectStyle == ProjectStyle.PackageReference && x is CpsPackageReferenceProject).Count(),
                dotnetCliToolProjectsCount: projectDictionary.GetValueOrDefault(ProjectStyle.DotnetCliTool, 0), // appears in DependencyGraphRestoreUtility
                packagesConfigProjectsCount: projectDictionary.GetValueOrDefault(ProjectStyle.PackagesConfig, 0),
                DateTimeOffset.Now,
                duration,
                _trackingData,
                intervalTimingTracker,
                isPackageSourceMappingEnabled,
                NumHTTPFeeds,
                NumLocalFeeds,
                hasNuGetOrg,
                hasVSOfflineFeed);

            TelemetryActivity.EmitTelemetryEvent(restoreTelemetryEvent);

            var sourceEvent = SourceTelemetry.GetRestoreSourceSummaryEvent(_nuGetProjectContext.OperationId, packageSources, protocolDiagnosticTotals);

            TelemetryActivity.EmitTelemetryEvent(sourceEvent);
        }
コード例 #13
0
 public void ToJsonArrayOfTimingsInSeconds_WithMultipleValues_AppendsValuesWithComma()
 {
     TimeSpan[] values = new[] { new TimeSpan(hours: 0, minutes: 0, seconds: 5), new TimeSpan(days: 0, hours: 0, minutes: 1, seconds: 0, milliseconds: 500) };
     TelemetryUtility.ToJsonArrayOfTimingsInSeconds(values).Should().Be("[5,60.5]");
 }
コード例 #14
0
        /// <summary>
        /// This is where the nominate calls for the IVs1 and IVS3 APIs combine. The reason for this method is to avoid duplication and potential issues
        /// The issue with this method is that it has some weird custom logging to ensure backward compatibility. It's on the implementer to ensure these calls are correct.
        /// <param name="projectUniqueName">projectUniqueName</param>
        /// <param name="projectRestoreInfo">projectRestoreInfo. Can be null</param>
        /// <param name="projectRestoreInfo2">proectRestoreInfo2. Can be null</param>
        /// <param name="token"></param>
        /// <remarks>Exactly one of projectRestoreInfos has to null.</remarks>
        /// <returns>The task that scheduled restore</returns>
        private Task <bool> NominateProjectAsync(string projectUniqueName, IVsProjectRestoreInfo projectRestoreInfo, IVsProjectRestoreInfo2 projectRestoreInfo2, CancellationToken token)
        {
            if (string.IsNullOrEmpty(projectUniqueName))
            {
                throw new ArgumentException(Resources.Argument_Cannot_Be_Null_Or_Empty, nameof(projectUniqueName));
            }

            if (projectRestoreInfo == null && projectRestoreInfo2 == null)
            {
                throw new ArgumentNullException(nameof(projectRestoreInfo));
            }

            if (projectRestoreInfo != null && projectRestoreInfo2 != null)
            {
                throw new ArgumentException($"Internal error: Both {nameof(projectRestoreInfo)} and {nameof(projectRestoreInfo2)} cannot have values. Please file an issue at NuGet/Home if you see this exception.");
            }

            if (projectRestoreInfo != null)
            {
                if (projectRestoreInfo.TargetFrameworks == null)
                {
                    throw new InvalidOperationException("TargetFrameworks cannot be null.");
                }
            }
            else
            {
                if (projectRestoreInfo2.TargetFrameworks == null)
                {
                    throw new InvalidOperationException("TargetFrameworks cannot be null.");
                }
            }

            try
            {
                _logger.LogInformation(
                    $"The nominate API is called for '{projectUniqueName}'.");

                var projectNames = ProjectNames.FromFullProjectPath(projectUniqueName);
                DependencyGraphSpec dgSpec;
                IReadOnlyList <IAssetsLogMessage> nominationErrors = null;
                try
                {
                    dgSpec = ToDependencyGraphSpec(projectNames, projectRestoreInfo, projectRestoreInfo2);
                }
                catch (Exception e)
                {
                    var restoreLogMessage = RestoreLogMessage.CreateError(NuGetLogCode.NU1105, string.Format(Resources.NU1105, projectNames.ShortName, e.Message));
                    restoreLogMessage.LibraryId = projectUniqueName;

                    nominationErrors = new List <IAssetsLogMessage>()
                    {
                        AssetsLogMessage.Create(restoreLogMessage)
                    };

                    var    projectDirectory        = Path.GetDirectoryName(projectUniqueName);
                    string projectIntermediatePath = projectRestoreInfo == null
                        ? projectRestoreInfo2.BaseIntermediatePath
                        : projectRestoreInfo.BaseIntermediatePath;
                    var dgSpecOutputPath = GetProjectOutputPath(projectDirectory, projectIntermediatePath);
                    dgSpec = CreateMinimalDependencyGraphSpec(projectUniqueName, dgSpecOutputPath);
                }

                _projectSystemCache.AddProjectRestoreInfo(projectNames, dgSpec, nominationErrors);

                // returned task completes when scheduled restore operation completes.
                var restoreTask = _restoreWorker.ScheduleRestoreAsync(
                    SolutionRestoreRequest.OnUpdate(),
                    token);

                return(restoreTask);
            }
            catch (OperationCanceledException)
            {
                throw;
            }
            catch (Exception e)
            {
                _logger.LogError(e.ToString());
                TelemetryUtility.EmitException(nameof(VsSolutionRestoreService), nameof(NominateProjectAsync), e);
                return(Task.FromResult(false));
            }
        }
コード例 #15
0
        /// <summary>
        /// Create a SourceSummaryEvent event with counts of local vs http and v2 vs v3 feeds.
        /// </summary>
        private static TelemetryEvent GetSourceSummaryEvent(
            string eventName,
            Guid parentId,
            IEnumerable <PackageSource> packageSources,
            PackageSourceTelemetry.Totals protocolDiagnosticTotals)
        {
            var local             = 0;
            var httpV2            = 0;
            var httpV3            = 0;
            var nugetOrg          = HttpStyle.NotPresent;
            var vsOfflinePackages = false;
            var dotnetCuratedFeed = false;

            if (packageSources != null)
            {
                foreach (var source in packageSources)
                {
                    // Ignore disabled sources
                    if (source.IsEnabled)
                    {
                        if (source.IsHttp)
                        {
                            if (TelemetryUtility.IsHttpV3(source))
                            {
                                // Http V3 feed
                                httpV3++;

                                if (TelemetryUtility.IsNuGetOrg(source.Source))
                                {
                                    nugetOrg |= HttpStyle.YesV3;
                                }
                            }
                            else
                            {
                                // Http V2 feed
                                httpV2++;

                                if (TelemetryUtility.IsNuGetOrg(source.Source))
                                {
                                    if (source.Source.IndexOf(
                                            "api/v2/curated-feeds/microsoftdotnet",
                                            StringComparison.OrdinalIgnoreCase) >= 0)
                                    {
                                        dotnetCuratedFeed = true;
                                    }
                                    else
                                    {
                                        nugetOrg |= HttpStyle.YesV2;
                                    }
                                }
                            }
                        }
                        else
                        {
                            // Local or UNC feed
                            local++;

                            if (TelemetryUtility.IsVsOfflineFeed(source))
                            {
                                vsOfflinePackages = true;
                            }
                        }
                    }
                }
            }

            return(new SourceSummaryTelemetryEvent(
                       eventName,
                       parentId,
                       local,
                       httpV2,
                       httpV3,
                       nugetOrg.ToString(),
                       vsOfflinePackages,
                       dotnetCuratedFeed,
                       protocolDiagnosticTotals));
        }
コード例 #16
0
 private void Run(Func <Task> action, [CallerMemberName] string methodName = null)
 {
     NuGetUIThreadHelper.JoinableTaskFactory
     .RunAsync(() => _semaphore.ExecuteAsync(action))
     .FileAndForget(TelemetryUtility.CreateFileAndForgetEventName(nameof(OutputConsoleLogger), methodName));
 }
コード例 #17
0
        public static async Task RunAsync([QueueTrigger("actions")] ProvisioningActionModel action, TextWriter log)
        {
            var startProvisioning = DateTime.Now;

            String provisioningEnvironment = ConfigurationManager.AppSettings["SPPA:ProvisioningEnvironment"];

            log.WriteLine($"Processing queue trigger function for tenant {action.TenantId}");
            log.WriteLine($"PnP Correlation ID: {action.CorrelationId.ToString()}");

            // Instantiate and use the telemetry model
            TelemetryUtility telemetry = new TelemetryUtility((s) => {
                log.WriteLine(s);
            });
            Dictionary <string, string> telemetryProperties = new Dictionary <string, string>();

            // Configure telemetry properties
            // telemetryProperties.Add("UserPrincipalName", action.UserPrincipalName);
            telemetryProperties.Add("TenantId", action.TenantId);
            telemetryProperties.Add("PnPCorrelationId", action.CorrelationId.ToString());
            telemetryProperties.Add("TargetSiteAlreadyExists", action.TargetSiteAlreadyExists.ToString());
            telemetryProperties.Add("TargetSiteBaseTemplateId", action.TargetSiteBaseTemplateId);

            // Get a reference to the data context
            ProvisioningAppDBContext dbContext = new ProvisioningAppDBContext();

            try
            {
                // Log telemetry event
                telemetry?.LogEvent("ProvisioningFunction.Start");

                if (CheckIfActionIsAlreadyRunning(action, dbContext))
                {
                    throw new ConcurrentProvisioningException("The requested package is currently provisioning in the selected target tenant and cannot be applied in parallel. Please wait for the previous provisioning action to complete.");
                }

                var tokenId = $"{action.TenantId}-{action.UserPrincipalName.ToLower().GetHashCode()}-{action.ActionType.ToString().ToLower()}-{provisioningEnvironment}";

                // Retrieve the SPO target tenant via Microsoft Graph
                var graphAccessToken = await ProvisioningAppManager.AccessTokenProvider.GetAccessTokenAsync(
                    tokenId, "https://graph.microsoft.com/",
                    ConfigurationManager.AppSettings[$"{action.ActionType}:ClientId"],
                    ConfigurationManager.AppSettings[$"{action.ActionType}:ClientSecret"],
                    ConfigurationManager.AppSettings[$"{action.ActionType}:AppUrl"]);

                log.WriteLine($"Retrieved target Microsoft Graph Access Token.");

                if (!String.IsNullOrEmpty(graphAccessToken))
                {
                    #region Get current context data (User, SPO Tenant, SPO Access Token)

                    // Get the currently connected user name and email (UPN)
                    var jwtAccessToken = new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(graphAccessToken);

                    String delegatedUPN = String.Empty;
                    var    upnClaim     = jwtAccessToken.Claims.FirstOrDefault(c => c.Type == "upn");
                    if (upnClaim != null && !String.IsNullOrEmpty(upnClaim.Value))
                    {
                        delegatedUPN = upnClaim.Value;
                    }

                    String delegatedUserName = String.Empty;
                    var    nameClaim         = jwtAccessToken.Claims.FirstOrDefault(c => c.Type == "name");
                    if (nameClaim != null && !String.IsNullOrEmpty(nameClaim.Value))
                    {
                        delegatedUserName = nameClaim.Value;
                    }

                    // Determine the URL of the root SPO site for the current tenant
                    var            rootSiteJson = HttpHelper.MakeGetRequestForString("https://graph.microsoft.com/v1.0/sites/root", graphAccessToken);
                    SharePointSite rootSite     = JsonConvert.DeserializeObject <SharePointSite>(rootSiteJson);

                    String spoTenant = rootSite.WebUrl;

                    log.WriteLine($"Target SharePoint Online Tenant: {spoTenant}");

                    // Configure telemetry properties
                    telemetryProperties.Add("SPOTenant", spoTenant);

                    // Retrieve the SPO Access Token
                    var spoAccessToken = await ProvisioningAppManager.AccessTokenProvider.GetAccessTokenAsync(
                        tokenId, rootSite.WebUrl,
                        ConfigurationManager.AppSettings[$"{action.ActionType}:ClientId"],
                        ConfigurationManager.AppSettings[$"{action.ActionType}:ClientSecret"],
                        ConfigurationManager.AppSettings[$"{action.ActionType}:AppUrl"]);

                    log.WriteLine($"Retrieved target SharePoint Online Access Token.");

                    #endregion

                    // Connect to SPO, create and provision site
                    AuthenticationManager authManager = new AuthenticationManager();
                    using (ClientContext context = authManager.GetAzureADAccessTokenAuthenticatedContext(spoTenant, spoAccessToken))
                    {
                        // Telemetry and startup
                        var web = context.Web;
                        context.ClientTag = $"SPDev:ProvisioningPortal-{provisioningEnvironment}";
                        context.Load(web, w => w.Title, w => w.Id);
                        await context.ExecuteQueryAsync();

                        // Save the current SPO Correlation ID
                        telemetryProperties.Add("SPOCorrelationId", context.TraceCorrelationId);

                        log.WriteLine($"SharePoint Online Root Site Collection title: {web.Title}");

                        #region Store the main site URL in KeyVault

                        // Store the main site URL in the vault
                        var vault = ProvisioningAppManager.SecurityTokensServiceProvider;

                        // Read any existing properties for the current tenantId
                        var properties = await vault.GetAsync(tokenId);

                        if (properties == null)
                        {
                            // If there are no properties, create a new dictionary
                            properties = new Dictionary <String, String>();
                        }

                        // Set/Update the RefreshToken value
                        properties["SPORootSite"] = spoTenant;

                        // Add or Update the Key Vault accordingly
                        await vault.AddOrUpdateAsync(tokenId, properties);

                        #endregion

                        #region Provision the package

                        var package = dbContext.Packages.FirstOrDefault(p => p.Id == new Guid(action.PackageId));

                        if (package != null)
                        {
                            // Update the Popularity of the package
                            package.TimesApplied++;
                            dbContext.SaveChanges();

                            #region Get the Provisioning Hierarchy file

                            // Determine reference path variables
                            var blobConnectionString = ConfigurationManager.AppSettings["BlobTemplatesProvider:ConnectionString"];
                            var blobContainerName    = ConfigurationManager.AppSettings["BlobTemplatesProvider:ContainerName"];

                            var packageFileName           = package.PackageUrl.Substring(package.PackageUrl.LastIndexOf('/') + 1);
                            var packageFileUri            = new Uri(package.PackageUrl);
                            var packageFileRelativePath   = packageFileUri.AbsolutePath.Substring(2 + blobContainerName.Length);
                            var packageFileRelativeFolder = packageFileRelativePath.Substring(0, packageFileRelativePath.LastIndexOf('/'));

                            // Configure telemetry properties
                            telemetryProperties.Add("PackageFileName", packageFileName);
                            telemetryProperties.Add("PackageFileUri", packageFileUri.ToString());

                            // Read the main provisioning file from the Blob Storage
                            CloudStorageAccount csa;
                            if (!CloudStorageAccount.TryParse(blobConnectionString, out csa))
                            {
                                throw new ArgumentException("Cannot create cloud storage account from given connection string.");
                            }

                            CloudBlobClient    blobClient    = csa.CreateCloudBlobClient();
                            CloudBlobContainer blobContainer = blobClient.GetContainerReference(blobContainerName);

                            var blockBlob = blobContainer.GetBlockBlobReference(packageFileRelativePath);

                            // Crate an in-memory copy of the source stream
                            MemoryStream mem = new MemoryStream();
                            await blockBlob.DownloadToStreamAsync(mem);

                            mem.Position = 0;

                            // Prepare the output hierarchy
                            ProvisioningHierarchy hierarchy = null;

                            if (packageFileName.EndsWith(".xml", StringComparison.InvariantCultureIgnoreCase))
                            {
                                // That's an XML Provisioning Template file

                                XDocument xml = XDocument.Load(mem);
                                mem.Position = 0;

                                // Deserialize the stream into a provisioning hierarchy reading any
                                // dependecy with the Azure Blob Storage connector
                                var formatter           = XMLPnPSchemaFormatter.GetSpecificFormatter(xml.Root.Name.NamespaceName);
                                var templateLocalFolder = $"{blobContainerName}/{packageFileRelativeFolder}";

                                var provider = new XMLAzureStorageTemplateProvider(
                                    blobConnectionString,
                                    templateLocalFolder);
                                formatter.Initialize(provider);

                                // Get the full hierarchy
                                hierarchy           = ((IProvisioningHierarchyFormatter)formatter).ToProvisioningHierarchy(mem);
                                hierarchy.Connector = provider.Connector;
                            }
                            else if (packageFileName.EndsWith(".pnp", StringComparison.InvariantCultureIgnoreCase))
                            {
                                // That's a PnP Package file

                                // Get a provider based on the in-memory .PNP Open XML file
                                OpenXMLConnector    openXmlConnector = new OpenXMLConnector(mem);
                                XMLTemplateProvider provider         = new XMLOpenXMLTemplateProvider(
                                    openXmlConnector);

                                // Get the .xml provisioning template file name
                                var xmlTemplateFileName = openXmlConnector.Info?.Properties?.TemplateFileName ??
                                                          packageFileName.Substring(packageFileName.LastIndexOf('/') + 1)
                                                          .ToLower().Replace(".pnp", ".xml");

                                // Get the full hierarchy
                                hierarchy           = provider.GetHierarchy(xmlTemplateFileName);
                                hierarchy.Connector = provider.Connector;
                            }

                            #endregion

                            #region Apply the template

                            // Prepare variable to collect provisioned sites
                            var provisionedSites = new List <Tuple <String, String> >();

                            // If we have a hierarchy with at least one Sequence
                            if (hierarchy != null) // && hierarchy.Sequences != null && hierarchy.Sequences.Count > 0)
                            {
                                Console.WriteLine($"Provisioning hierarchy \"{hierarchy.DisplayName}\"");

                                var tenantUrl = UrlUtilities.GetTenantAdministrationUrl(context.Url);

                                // Retrieve the SPO Access Token
                                var spoAdminAccessToken = await ProvisioningAppManager.AccessTokenProvider.GetAccessTokenAsync(
                                    tokenId, tenantUrl,
                                    ConfigurationManager.AppSettings[$"{action.ActionType}:ClientId"],
                                    ConfigurationManager.AppSettings[$"{action.ActionType}:ClientSecret"],
                                    ConfigurationManager.AppSettings[$"{action.ActionType}:AppUrl"]);

                                log.WriteLine($"Retrieved target SharePoint Online Admin Center Access Token.");

                                using (var tenantContext = authManager.GetAzureADAccessTokenAuthenticatedContext(tenantUrl, spoAdminAccessToken))
                                {
                                    using (var pnpTenantContext = PnPClientContext.ConvertFrom(tenantContext))
                                    {
                                        var tenant = new Microsoft.Online.SharePoint.TenantAdministration.Tenant(pnpTenantContext);

                                        // Prepare a dictionary to hold the access tokens
                                        var accessTokens = new Dictionary <String, String>();

                                        // Prepare logging for hierarchy application
                                        var ptai = new ProvisioningTemplateApplyingInformation();
                                        ptai.MessagesDelegate += delegate(string message, ProvisioningMessageType messageType)
                                        {
                                            log.WriteLine($"{messageType} - {message}");
                                        };
                                        ptai.ProgressDelegate += delegate(string message, int step, int total)
                                        {
                                            log.WriteLine($"{step:00}/{total:00} - {message}");
                                        };
                                        ptai.SiteProvisionedDelegate += delegate(string title, string url)
                                        {
                                            log.WriteLine($"Fully provisioned site '{title}' with URL: {url}");
                                            var provisionedSite = new Tuple <string, string>(title, url);
                                            if (!provisionedSites.Contains(provisionedSite))
                                            {
                                                provisionedSites.Add(provisionedSite);
                                            }
                                        };

//#if !DEBUG
//                                        // Set the default delay for sites creations to 5 mins
//                                        ptai.DelayAfterModernSiteCreation = 60 * 5;
//#endif

                                        // Configure the OAuth Access Tokens for the client context
                                        accessTokens.Add(new Uri(tenantUrl).Authority, spoAdminAccessToken);
                                        accessTokens.Add(new Uri(spoTenant).Authority, spoAccessToken);

                                        // Configure the OAuth Access Tokens for the PnPClientContext, too
                                        pnpTenantContext.PropertyBag["AccessTokens"] = accessTokens;
                                        ptai.AccessTokens = accessTokens;

                                        #region Theme handling

                                        // Process the graphical Theme
                                        if (action.ApplyTheme)
                                        {
                                            // If we don't have any custom Theme
                                            if (!action.ApplyCustomTheme)
                                            {
                                                // Associate the selected already existing Theme to all the sites of the hierarchy
                                                foreach (var sc in hierarchy.Sequences[0].SiteCollections)
                                                {
                                                    sc.Theme = action.SelectedTheme;
                                                    foreach (var s in sc.Sites)
                                                    {
                                                        UpdateChildrenSitesTheme(s, action.SelectedTheme);
                                                    }
                                                }
                                            }
                                        }

                                        #endregion

                                        // Configure provisioning parameters
                                        if (action.PackageProperties != null)
                                        {
                                            foreach (var key in action.PackageProperties.Keys)
                                            {
                                                if (hierarchy.Parameters.ContainsKey(key.ToString()))
                                                {
                                                    hierarchy.Parameters[key.ToString()] = action.PackageProperties[key].ToString();
                                                }
                                                else
                                                {
                                                    hierarchy.Parameters.Add(key.ToString(), action.PackageProperties[key].ToString());
                                                }

                                                // Configure telemetry properties
                                                telemetryProperties.Add($"PackageProperty.{key}", action.PackageProperties[key].ToString());
                                            }
                                        }

                                        // Log telemetry event
                                        telemetry?.LogEvent("ProvisioningFunction.BeginProvisioning", telemetryProperties);

                                        // Define a PnPProvisioningContext scope to share the security context across calls
                                        using (var pnpProvisioningContext = new PnPProvisioningContext(async(r, s) =>
                                        {
                                            if (accessTokens.ContainsKey(r))
                                            {
                                                // In this scenario we just use the dictionary of access tokens
                                                // in fact the overall operation for sure will take less than 1 hour
                                                return(await Task.FromResult(accessTokens[r]));
                                            }
                                            else
                                            {
                                                // Try to get a fresh new Access Token
                                                var token = await ProvisioningAppManager.AccessTokenProvider.GetAccessTokenAsync(
                                                    tokenId, $"https://{r}",
                                                    ConfigurationManager.AppSettings[$"{action.ActionType}:ClientId"],
                                                    ConfigurationManager.AppSettings[$"{action.ActionType}:ClientSecret"],
                                                    ConfigurationManager.AppSettings[$"{action.ActionType}:AppUrl"]);

                                                accessTokens.Add(r, token);

                                                return(token);
                                            }
                                        }))
                                        {
                                            // Configure the webhooks, if any
                                            if (action.Webhooks != null && action.Webhooks.Count > 0)
                                            {
                                                foreach (var t in hierarchy.Templates)
                                                {
                                                    foreach (var wh in action.Webhooks)
                                                    {
                                                        AddProvisioningTemplateWebhook(t, wh, ProvisioningTemplateWebhookKind.ProvisioningTemplateStarted);
                                                        AddProvisioningTemplateWebhook(t, wh, ProvisioningTemplateWebhookKind.ObjectHandlerProvisioningStarted);
                                                        AddProvisioningTemplateWebhook(t, wh, ProvisioningTemplateWebhookKind.ObjectHandlerProvisioningCompleted);
                                                        AddProvisioningTemplateWebhook(t, wh, ProvisioningTemplateWebhookKind.ProvisioningTemplateCompleted);
                                                        AddProvisioningTemplateWebhook(t, wh, ProvisioningTemplateWebhookKind.ExceptionOccurred);
                                                    }
                                                }

                                                foreach (var wh in action.Webhooks)
                                                {
                                                    AddProvisioningWebhook(hierarchy, wh, ProvisioningTemplateWebhookKind.ProvisioningStarted);
                                                    AddProvisioningWebhook(hierarchy, wh, ProvisioningTemplateWebhookKind.ProvisioningCompleted);
                                                    AddProvisioningWebhook(hierarchy, wh, ProvisioningTemplateWebhookKind.ProvisioningExceptionOccurred);
                                                }
                                            }

                                            // Apply the hierarchy
                                            log.WriteLine($"Hierarchy Provisioning Started: {DateTime.Now:hh.mm.ss}");
                                            tenant.ApplyProvisionHierarchy(hierarchy,
                                                                           (hierarchy.Sequences != null && hierarchy.Sequences.Count > 0) ?
                                                                           hierarchy.Sequences[0].ID : null,
                                                                           ptai);
                                            log.WriteLine($"Hierarchy Provisioning Completed: {DateTime.Now:hh.mm.ss}");
                                        }

                                        if (action.ApplyTheme && action.ApplyCustomTheme)
                                        {
                                            if (!String.IsNullOrEmpty(action.ThemePrimaryColor) &&
                                                !String.IsNullOrEmpty(action.ThemeBodyTextColor) &&
                                                !String.IsNullOrEmpty(action.ThemeBodyBackgroundColor))
                                            {
                                                log.WriteLine($"Applying custom Theme to provisioned sites");

                                                #region Palette generation for Theme

                                                var jsonPalette = ThemeUtility.GetThemeAsJSON(
                                                    action.ThemePrimaryColor,
                                                    action.ThemeBodyTextColor,
                                                    action.ThemeBodyBackgroundColor);

                                                #endregion

                                                // Apply the custom theme to all of the provisioned sites
                                                foreach (var ps in provisionedSites)
                                                {
                                                    using (var provisionedSiteContext = authManager.GetAzureADAccessTokenAuthenticatedContext(ps.Item2, spoAccessToken))
                                                    {
                                                        if (provisionedSiteContext.Web.ApplyTheme(jsonPalette))
                                                        {
                                                            log.WriteLine($"Custom Theme applied on site '{ps.Item1}' with URL: {ps.Item2}");
                                                        }
                                                        else
                                                        {
                                                            log.WriteLine($"Failed to apply custom Theme on site '{ps.Item1}' with URL: {ps.Item2}");
                                                        }
                                                    }
                                                }
                                            }
                                        }

                                        // Log telemetry event
                                        telemetry?.LogEvent("ProvisioningFunction.EndProvisioning", telemetryProperties);

                                        // Notify user about the provisioning outcome
                                        if (!String.IsNullOrEmpty(action.NotificationEmail))
                                        {
                                            var appOnlyAccessToken = await ProvisioningAppManager.AccessTokenProvider.GetAppOnlyAccessTokenAsync(
                                                "https://graph.microsoft.com/",
                                                ConfigurationManager.AppSettings["OfficeDevPnP:TenantId"],
                                                ConfigurationManager.AppSettings["OfficeDevPnP:ClientId"],
                                                ConfigurationManager.AppSettings["OfficeDevPnP:ClientSecret"],
                                                ConfigurationManager.AppSettings["OfficeDevPnP:AppUrl"]);

                                            MailHandler.SendMailNotification(
                                                "ProvisioningCompleted",
                                                action.NotificationEmail,
                                                null,
                                                new
                                            {
                                                TemplateName     = action.DisplayName,
                                                ProvisionedSites = provisionedSites,
                                            },
                                                appOnlyAccessToken);
                                        }

                                        // Log reporting event (1 = Success)
                                        LogReporting(action, provisioningEnvironment, startProvisioning, package, 1);
                                    }
                                }
                            }
                            else
                            {
                                throw new ApplicationException($"The requested package does not contain a valid PnP Hierarchy!");
                            }

                            #endregion
                        }
                        else
                        {
                            throw new ApplicationException($"Cannot find the package with ID: {action.PackageId}");
                        }

                        #endregion

                        #region Process any children items

                        // If there are children items
                        if (action.ChildrenItems != null && action.ChildrenItems.Count > 0)
                        {
                            // Prepare any further child provisioning request
                            action.PackageId         = action.ChildrenItems[0].PackageId;
                            action.PackageProperties = action.ChildrenItems[0].Parameters;
                            action.ChildrenItems.RemoveAt(0);

                            // Enqueue any further child provisioning request
                            await ProvisioningAppManager.EnqueueProvisioningRequest(action);
                        }

                        #endregion

                        log.WriteLine($"Function successfully executed!");
                        // Log telemetry event
                        telemetry?.LogEvent("ProvisioningFunction.End", telemetryProperties);
                    }
                }
                else
                {
                    var noTokensErrorMessage = $"Cannot retrieve Refresh Token or Access Token for {action.CorrelationId} in tenant {action.TenantId}!";
                    log.WriteLine(noTokensErrorMessage);
                    throw new ApplicationException(noTokensErrorMessage);
                }
            }
            catch (Exception ex)
            {
                // Skip logging exception for Recycled Site
                if (ex is RecycledSiteException)
                {
                    // rather log an event
                    telemetry?.LogEvent("ProvisioningFunction.RecycledSite", telemetryProperties);

                    // Log reporting event (3 = RecycledSite)
                    LogReporting(action, provisioningEnvironment, startProvisioning, null, 3, ex.ToDetailedString());
                }
                // Skip logging exception for Concurrent Provisioning
                else if (ex is ConcurrentProvisioningException)
                {
                    // rather log an event
                    telemetry?.LogEvent("ProvisioningFunction.ConcurrentProvisioning", telemetryProperties);

                    // Log reporting event (4 = ConcurrentProvisioningException)
                    LogReporting(action, provisioningEnvironment, startProvisioning, null, 4, ex.ToDetailedString());
                }
                else
                {
                    // Log telemetry event
                    telemetry?.LogException(ex, "ProvisioningFunction.RunAsync", telemetryProperties);

                    // Log reporting event (2 = Failed)
                    LogReporting(action, provisioningEnvironment, startProvisioning, null, 2, ex.ToDetailedString());
                }

                if (!String.IsNullOrEmpty(action.NotificationEmail))
                {
                    var appOnlyAccessToken = await ProvisioningAppManager.AccessTokenProvider.GetAppOnlyAccessTokenAsync(
                        "https://graph.microsoft.com/",
                        ConfigurationManager.AppSettings["OfficeDevPnP:TenantId"],
                        ConfigurationManager.AppSettings["OfficeDevPnP:ClientId"],
                        ConfigurationManager.AppSettings["OfficeDevPnP:ClientSecret"],
                        ConfigurationManager.AppSettings["OfficeDevPnP:AppUrl"]);

                    // Notify user about the provisioning outcome
                    MailHandler.SendMailNotification(
                        "ProvisioningFailed",
                        action.NotificationEmail,
                        null,
                        new
                    {
                        TemplateName     = action.DisplayName,
                        ExceptionDetails = SimplifyException(ex),
                        PnPCorrelationId = action.CorrelationId.ToString(),
                    },
                        appOnlyAccessToken);
                }

                ProcessWebhooksExceptionNotification(action, ex);

                // Track the failure in the local action log
                MarkCurrentActionItemAsFailed(action, dbContext);

                throw ex;
            }
            finally
            {
                // Try to cleanup the pending action item, if any
                CleanupCurrentActionItem(action, dbContext);

                telemetry?.Flush();
            }
        }
コード例 #18
0
 public void ToJsonArrayOfTimingsInSeconds_WithNullArgument_ReturnsEmptyString()
 {
     TelemetryUtility.ToJsonArrayOfTimingsInSeconds(null).Should().Be(string.Empty);
 }
コード例 #19
0
        public void CreateFileAndForgetEventName_WhenMemberNameIsNullOrEmpty_Throws(string memberName)
        {
            ArgumentException exception = Assert.Throws <ArgumentException>(() => TelemetryUtility.CreateFileAndForgetEventName("typeName", memberName));

            Assert.Equal("memberName", exception.ParamName);
        }
コード例 #20
0
        /// <summary>
        /// Install package by Id
        /// </summary>
        /// <param name="project"></param>
        /// <param name="packageId"></param>
        /// <param name="resolutionContext"></param>
        /// <param name="projectContext"></param>
        /// <param name="isPreview"></param>
        /// <param name="isForce"></param>
        /// <param name="uninstallContext"></param>
        /// <returns></returns>
        protected async Task InstallPackageByIdAsync(NuGetProject project, string packageId, ResolutionContext resolutionContext, INuGetProjectContext projectContext, bool isPreview)
        {
            try
            {
                var actions = await PackageManager.PreviewInstallPackageAsync(project, packageId, resolutionContext, projectContext, PrimarySourceRepositories, null, CancellationToken.None);

                if (!actions.Any())
                {
                    // nuget operation status is set to NoOp to log under telemetry event when
                    // there is no preview action.
                    _status = NuGetOperationStatus.NoOp;
                }
                else
                {
                    // update packages count to be logged under telemetry event
                    _packageCount = actions.Select(
                        action => action.PackageIdentity.Id).Distinct().Count();
                }

                // stop telemetry event timer to avoid UI interaction
                TelemetryUtility.StopTimer();

                if (!ShouldContinueDueToDotnetDeprecation(actions, isPreview))
                {
                    // resume telemetry event timer after ui confirmation
                    TelemetryUtility.StartorResumeTimer();
                    return;
                }

                // resume telemetry event timer after ui confirmation
                TelemetryUtility.StartorResumeTimer();

                if (isPreview)
                {
                    PreviewNuGetPackageActions(actions);
                }
                else
                {
                    var identity = actions.Select(v => v.PackageIdentity).Where(p => p.Id.Equals(packageId, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
                    NuGetPackageManager.SetDirectInstall(identity, projectContext);
                    await PackageManager.ExecuteNuGetProjectActionsAsync(project, actions, this, resolutionContext.SourceCacheContext, CancellationToken.None);

                    NuGetPackageManager.ClearDirectInstall(projectContext);

                    // Refresh Manager UI if needed
                    RefreshUI(actions);
                }
            }
            catch (InvalidOperationException ex)
            {
                if (ex.InnerException is PackageAlreadyInstalledException)
                {
                    // Set nuget operation status to NoOp for telemetry event when package
                    // is already installed.
                    _status = NuGetOperationStatus.NoOp;
                    Log(MessageLevel.Info, ex.Message);
                }
                else
                {
                    throw ex;
                }
            }
        }
コード例 #21
0
        private async Task RestoreAsync(bool forceRestore, RestoreOperationSource restoreSource, CancellationToken token)
        {
            var startTime = DateTimeOffset.Now;

            _status = NuGetOperationStatus.NoOp;

            // start timer for telemetry event
            TelemetryUtility.StartorResumeTimer();

            var projects = Enumerable.Empty <NuGetProject>();

            _packageRestoreManager.PackageRestoredEvent      += PackageRestoreManager_PackageRestored;
            _packageRestoreManager.PackageRestoreFailedEvent += PackageRestoreManager_PackageRestoreFailedEvent;

            try
            {
                var solutionDirectory   = _solutionManager.SolutionDirectory;
                var isSolutionAvailable = _solutionManager.IsSolutionAvailable;

                if (solutionDirectory == null)
                {
                    await _logger.DoAsync((l, _) =>
                    {
                        _status = NuGetOperationStatus.Failed;
                        l.ShowError(Resources.SolutionIsNotSaved);
                        l.WriteLine(VerbosityLevel.Minimal, Resources.SolutionIsNotSaved);
                    });

                    return;
                }

                // Check if solution has deferred projects
                var deferredProjectsData = new DeferredProjectRestoreData(new Dictionary <PackageReference, List <string> >(), new List <PackageSpec>());
                if (await _solutionManager.SolutionHasDeferredProjectsAsync())
                {
                    var deferredProjectsPath = await _solutionManager.GetDeferredProjectsFilePathAsync();

                    deferredProjectsData = await DeferredProjectRestoreUtility.GetDeferredProjectsData(_deferredWorkspaceService, deferredProjectsPath, token);
                }

                // Get the projects from the SolutionManager
                // Note that projects that are not supported by NuGet, will not show up in this list
                projects = _solutionManager.GetNuGetProjects();

                // Check if there are any projects that are not INuGetIntegratedProject, that is,
                // projects with packages.config. OR
                // any of the deferred project is type of packages.config, If so, perform package restore on them
                if (projects.Any(project => !(project is INuGetIntegratedProject)) ||
                    deferredProjectsData.PackageReferenceDict.Count > 0)
                {
                    await RestorePackagesOrCheckForMissingPackagesAsync(
                        solutionDirectory,
                        isSolutionAvailable,
                        deferredProjectsData.PackageReferenceDict,
                        token);
                }

                var dependencyGraphProjects = projects
                                              .OfType <IDependencyGraphProject>()
                                              .ToList();

                await RestorePackageSpecProjectsAsync(
                    dependencyGraphProjects,
                    forceRestore,
                    isSolutionAvailable,
                    deferredProjectsData.PackageSpecs,
                    token);

                // TODO: To limit risk, we only publish the event when there is a cross-platform PackageReference
                // project in the solution. Extending this behavior to all solutions is tracked here:
                // https://github.com/NuGet/Home/issues/4478
#if !VS14
                if (projects.OfType <CpsPackageReferenceProject>().Any() &&
                    !string.IsNullOrEmpty(_dependencyGraphProjectCacheHash))
                {
                    // A no-op restore is considered successful. A cancellation is considered unsuccessful.
                    var args = new SolutionRestoredEventArgs(
                        isSuccess: _status == NuGetOperationStatus.Succeeded || _status == NuGetOperationStatus.NoOp,
                        solutionSpecHash: _dependencyGraphProjectCacheHash);
                    _restoreEventsPublisher.OnSolutionRestoreCompleted(args);
                }
#endif
            }
            finally
            {
                _packageRestoreManager.PackageRestoredEvent      -= PackageRestoreManager_PackageRestored;
                _packageRestoreManager.PackageRestoreFailedEvent -= PackageRestoreManager_PackageRestoreFailedEvent;

                TelemetryUtility.StopTimer();

                var duration = TelemetryUtility.GetTimerElapsedTime();
                await _logger.WriteSummaryAsync(_status, duration);

                // Emit telemetry event for restore operation
                EmitRestoreTelemetryEvent(
                    projects,
                    restoreSource,
                    startTime,
                    _status,
                    _packageCount,
                    duration.TotalSeconds);
            }
        }
コード例 #22
0
        private async Task RestoreAsync(bool forceRestore, RestoreOperationSource restoreSource, CancellationToken token)
        {
            var startTime = DateTimeOffset.Now;

            _status = NuGetOperationStatus.NoOp;

            // start timer for telemetry event
            TelemetryUtility.StartorResumeTimer();

            var projects = Enumerable.Empty <NuGetProject>();

            _packageRestoreManager.PackageRestoredEvent      += PackageRestoreManager_PackageRestored;
            _packageRestoreManager.PackageRestoreFailedEvent += PackageRestoreManager_PackageRestoreFailedEvent;

            try
            {
                var solutionDirectory   = _solutionManager.SolutionDirectory;
                var isSolutionAvailable = await _solutionManager.IsSolutionAvailableAsync();

                if (solutionDirectory == null)
                {
                    await _logger.DoAsync((l, _) =>
                    {
                        _status = NuGetOperationStatus.Failed;
                        l.ShowError(Resources.SolutionIsNotSaved);
                        l.WriteLine(VerbosityLevel.Minimal, Resources.SolutionIsNotSaved);
                    });

                    return;
                }

                // Get the projects from the SolutionManager
                // Note that projects that are not supported by NuGet, will not show up in this list
                projects = await _solutionManager.GetNuGetProjectsAsync();

                // Check if there are any projects that are not INuGetIntegratedProject, that is,
                // projects with packages.config. OR
                // any of the deferred project is type of packages.config, If so, perform package restore on them
                if (projects.Any(project => !(project is INuGetIntegratedProject)))
                {
                    await RestorePackagesOrCheckForMissingPackagesAsync(
                        solutionDirectory,
                        isSolutionAvailable,
                        restoreSource,
                        token);
                }

                var dependencyGraphProjects = projects
                                              .OfType <IDependencyGraphProject>()
                                              .ToList();

                await RestorePackageSpecProjectsAsync(
                    dependencyGraphProjects,
                    forceRestore,
                    isSolutionAvailable,
                    restoreSource,
                    token);

#if !VS14
                // TODO: To limit risk, we only publish the event when there is a cross-platform PackageReference
                // project in the solution. Extending this behavior to all solutions is tracked here:
                // NuGet/Home#4478
                if (projects.OfType <NetCorePackageReferenceProject>().Any())
                {
                    _restoreEventsPublisher.OnSolutionRestoreCompleted(
                        new SolutionRestoredEventArgs(_status, solutionDirectory));
                }
#endif
            }
            finally
            {
                _packageRestoreManager.PackageRestoredEvent      -= PackageRestoreManager_PackageRestored;
                _packageRestoreManager.PackageRestoreFailedEvent -= PackageRestoreManager_PackageRestoreFailedEvent;

                TelemetryUtility.StopTimer();
                var duration = TelemetryUtility.GetTimerElapsedTime();

                // Do not log any restore message if user disabled restore.
                if (_packageRestoreConsent.IsGranted)
                {
                    await _logger.WriteSummaryAsync(_status, duration);
                }
                else
                {
                    _logger.LogDebug(Resources.PackageRefNotRestoredBecauseOfNoConsent);
                }
                // Emit telemetry event for restore operation
                EmitRestoreTelemetryEvent(
                    projects,
                    restoreSource,
                    startTime,
                    duration.TotalSeconds);
            }
        }
コード例 #23
0
 public void ToJsonArrayOfTimingsInSeconds_WithEmptyArray_ReturnsEmptyString()
 {
     TelemetryUtility.ToJsonArrayOfTimingsInSeconds(Enumerable.Empty <TimeSpan>()).Should().Be(string.Empty);
 }