private void ReadJobSettings(TeamFoundationRequestContext requestContext) { var registry = requestContext.GetService <TeamFoundationRegistryService>(); emailEnabled = registry.GetValue(requestContext, emailEnabledSetting, true, false); // Since we're tied to the TFS email service, we only run if the email system has been enabled if (emailEnabled) { collectionName = requestContext.ServiceHost.CollectionServiceHost.Name; var locationService = requestContext.GetService <TeamFoundationLocationService>(); serverName = locationService.GetSelfReferenceUri(requestContext, locationService.GetPublicAccessMapping(requestContext)).DnsSafeHost; var registryEntries = registry.ReadEntriesFallThru(requestContext, workspaceCleanupRootPath + "/*"); templateSearchPath = registryEntries["EmailTemplateSearchPath"].GetValue("Transforms"); emailTemplate = registryEntries["EmailTemplate"].GetValue("WorkspaceCleanupTemplate.xsl"); warningAgeInDays = registryEntries["WarningAgeInDays"].GetValue(300); deleteAgeInDays = registryEntries["DeleteAgeInDays"].GetValue(360); emailSubject = registryEntries["EmailSubject"].GetValue("ACTION REQUIRED - Workspace Cleanup Warning"); emailPriority = registryEntries["EmailPriority"].GetValue(MailPriority.High); warnIfNoEmailAddress = registryEntries["WarnIfNoEmailAddress"].GetValue(true); deleteIfNoEmailAddress = registryEntries["DeleteIfNoEmailAddress"].GetValue(false); // Expand paths to the email template if (!Path.IsPathRooted(templateSearchPath)) { emailTemplate = Path.Combine(requestContext.ServiceHost.PhysicalDirectory, templateSearchPath, emailTemplate); } } }
protected override IEnumerable <INotification> CreateNotifications(TeamFoundationRequestContext requestContext, BuildCompletionNotificationEvent buildNotification, int maxLines) { BuildDetail build = buildNotification.Build; var locationService = requestContext.GetService <ILocationService>(); var buildService = requestContext.GetService <TeamFoundationBuildService>(); using (var buildReader = buildService.QueryQueuedBuildsById(requestContext, build.QueueIds, new[] { "*" }, QueryOptions.None)) { var result = buildReader.Current <BuildQueueQueryResult>(); QueuedBuild qb = result.QueuedBuilds.FirstOrDefault(); string buildUrl = string.Format("{0}/{1}/{2}/_build#_a=summary&buildId={3}", locationService.GetAccessMapping(requestContext, "PublicAccessMapping").AccessPoint, requestContext.ServiceHost.Name, build.TeamProject, qb.BuildId); var notification = new BuildCompletionNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, BuildUrl = buildUrl, ProjectName = build.TeamProject, BuildNumber = build.BuildNumber, BuildStatus = build.Status, BuildReason = build.Reason, StartTime = build.StartTime, FinishTime = build.FinishTime, RequestedForUniqueName = qb.RequestedFor, RequestedForDisplayName = qb.RequestedForDisplayName, BuildDefinition = build.Definition.Name, DropLocation = build.DropLocation, TeamNames = GetUserTeamsByProjectName(requestContext, build.TeamProject, qb.RequestedFor) }; yield return(notification); } }
protected override IEnumerable <Notifications.INotification> CreateNotifications(TeamFoundationRequestContext requestContext, RepositoryCreatedNotification ev, int maxLines) { var repositoryService = requestContext.GetService <TeamFoundationGitRepositoryService>(); var identityService = requestContext.GetService <ITeamFoundationIdentityService>(); var commonService = requestContext.GetService <CommonStructureService>(); var identity = identityService.ReadIdentity(requestContext, IdentitySearchFactor.Identifier, ev.Creator.Identifier); using (TfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, ev.RepositoryId)) { string repoUri = repository.GetRepositoryUri(requestContext); var notification = new Notifications.RepositoryCreatedNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, UniqueName = identity.UniqueName, DisplayName = identity.DisplayName, ProjectName = commonService.GetProject(requestContext, ev.TeamProjectUri).Name, RepoUri = repoUri, RepoName = ev.RepositoryName, TeamNames = GetUserTeamsByProjectUri(requestContext, ev.TeamProjectUri, identity.Descriptor) }; yield return(notification); } }
public static TfsTeamProjectCollection GetImpersonatedCollection(this TeamFoundationRequestContext requestContext, string userToImpersonate) { var service = requestContext.GetService <ILocationService>(); Uri selfReferenceUri = service.GetSelfReferenceUri(requestContext, service.GetServerAccessMapping(requestContext)); return(ImpersonatedCollection.CreateImpersonatedCollection(selfReferenceUri, userToImpersonate)); }
public static Changeset GetChangeset(this TeamFoundationRequestContext requestContext, int changesetId) { TeamFoundationVersionControlService service = requestContext.GetService <TeamFoundationVersionControlService>(); TeamFoundationDataReader teamFoundationDataReader = service.QueryChangeset(requestContext, changesetId, true, false, true); return(teamFoundationDataReader.Current <Changeset>()); }
public TeamFoundationJobExecutionResult Run(TeamFoundationRequestContext requestContext, TeamFoundationJobDefinition jobDefinition, DateTime queueTime, out string resultMessage) { resultMessage = ""; try { var service = requestContext.GetService <TeamFoundationIdentityService>(); var identities = service.ReadFilteredIdentities(requestContext, "Microsoft.TeamFoundation.Identity.DisplayName CONTAINS '' AND Microsoft.TeamFoundation.Identity.Type == 'User'", 5000, null, true, MembershipQuery.None); if (identities != null) { foreach (var identity in identities.Items) { UpdateImageFromAD(requestContext, identity, service); } } } catch (Exception e) { resultMessage = e.Message + e.StackTrace; return(TeamFoundationJobExecutionResult.Failed); } return(TeamFoundationJobExecutionResult.Succeeded); }
private void DeleteShelvesets(TeamFoundationRequestContext requestContext) { var now = DateTime.Now; var vcs = requestContext.GetService <TeamFoundationVersionControlService>(); var shelvesets = from s in vcs.QueryShelvesets(requestContext, null, null) where now.Subtract(s.CreationDate).TotalDays >= deleteAgeInDays orderby s.Owner select s; string currentOwner = null; string toAddress = null; foreach (var shelveset in shelvesets) { if (string.Compare(currentOwner, shelveset.Owner, StringComparison.OrdinalIgnoreCase) != 0) { currentOwner = shelveset.Owner; toAddress = GetPreferredEmailAddress(requestContext, currentOwner); } if (!string.IsNullOrEmpty(toAddress) || deleteIfNoEmailAddress) { vcs.DeleteShelveset(requestContext, shelveset.Name, shelveset.Owner); } } }
private void DeleteWorkspaces(TeamFoundationRequestContext requestContext) { var now = DateTime.Now; var vcs = requestContext.GetService <TeamFoundationVersionControlService>(); var workspaces = from ws in vcs.QueryWorkspaces(requestContext, null, null, 0) where now.Subtract(ws.LastAccessDate).TotalDays >= deleteAgeInDays orderby ws.OwnerName select ws; string currentOwner = null; string toAddress = null; foreach (var workspace in workspaces) { if (string.Compare(currentOwner, workspace.OwnerName, StringComparison.OrdinalIgnoreCase) != 0) { currentOwner = workspace.OwnerName; toAddress = GetPreferredEmailAddress(requestContext, currentOwner); } if (!string.IsNullOrEmpty(toAddress) || deleteIfNoEmailAddress) { vcs.DeleteWorkspace(requestContext, workspace.Name, workspace.OwnerName); } } }
public Task NotifyAsync(TeamFoundationRequestContext requestContext, INotification notification, BotElement bot, EventRuleElement matchingRule) { if (!notification.TargetUserNames.Any()) { return(Task.FromResult(0)); } var config = TfsNotificationRelaySection.Instance; string host = bot.GetSetting("host", "127.0.0.1"); int port = bot.GetIntSetting("port", 25); string fromAddress = bot.GetSetting("fromAddress"); string fromName = bot.GetSetting("fromName"); string subjectTextId = bot.GetSetting("subjectTextId", "plaintext"); bool isHtml = bot.GetSetting("isHtml") == "true"; var subjectTextElement = config.Texts.FirstOrDefault(t => t.Id == subjectTextId) ?? bot.Text; string subject = notification.ToMessage(bot, subjectTextElement, s => s).First(); var client = new SmtpClient(host, port); var message = new MailMessage(); message.From = new MailAddress(fromAddress, fromName, Encoding.UTF8); message.SubjectEncoding = Encoding.UTF8; message.Subject = subject; message.IsBodyHtml = isHtml; message.BodyEncoding = Encoding.UTF8; message.Body = string.Join(isHtml ? "<br/>": "\n", notification.ToMessage(bot, s => s)); var identityService = requestContext.GetService <ITeamFoundationIdentityService>(); foreach (var username in notification.TargetUserNames) { var identity = identityService.ReadIdentity(requestContext, IdentitySearchFactor.AccountName, username); var email = identityService.GetPreferredEmailAddress(requestContext, identity.TeamFoundationId); if (string.IsNullOrEmpty(email)) { string errmsg = $"TfsNotificationRelay.Smtp.SmtpNotifier: User {username} doesn't have an email address."; TeamFoundationApplicationCore.Log(requestContext, errmsg, 0, EventLogEntryType.Warning); } else { message.To.Add(email); } } if (message.To.Any()) { requestContext.Trace(0, TraceLevel.Info, Constants.TraceArea, "SmtpNotifier", string.Format("Sending {0} email notification to: {1}.", notification.GetType(), string.Join(", ", message.To.Select(m => m.Address)))); return(client.SendMailAsync(message)); } else { requestContext.Trace(0, TraceLevel.Warning, Constants.TraceArea, "SmtpNotifier", string.Format("No recipients to send {0} email notification to.", notification.GetType())); return(Task.FromResult(0)); } }
public static TfsTeamProjectCollection GetCollection(this TeamFoundationRequestContext requestContext) { var service = requestContext.GetService <ILocationService>(); var accessMapping = service.GetServerAccessMapping(requestContext); Uri selfReferenceUri = service.GetSelfReferenceUri(requestContext, accessMapping); return(new TfsTeamProjectCollection(selfReferenceUri)); }
private static IRegistration GetRegistrationService(TeamFoundationRequestContext requestContext) { var locationService = requestContext.GetService <TeamFoundationLocationService>(); var tfsUri = new Uri(locationService.GetServerAccessMapping(requestContext).AccessPoint + "/" + requestContext.ServiceHost.Name); var teamProjectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(tfsUri); return(teamProjectCollection.GetService <IRegistration>()); }
/// <summary> /// Gets the team names by project name and user display name /// Could be moved into base class? /// </summary> /// <param name="requestContext"></param> /// <param name="projectName">Name of the team project</param> /// <param name="displayName">Name of the user</param> /// <returns>A dictionary of teams the user is a member of</returns> private Dictionary <string, string> GetTeamsByUser(TeamFoundationRequestContext requestContext, string projectName, string displayName) { var teamList = new Dictionary <string, string>(); var teamService = requestContext.GetService <TeamFoundationTeamService>(); this.Trace(requestContext, "Getting Project by name"); // Get the project URI var project = this.ProjectsNames.Where(p => p.Value.Equals(projectName, StringComparison.InvariantCultureIgnoreCase)) .Select(p => new { Uri = p.Key, Name = p.Value }) .FirstOrDefault(); if (project == null) { this.Trace(requestContext, "Failed to locate project"); return(teamList); } this.Trace(requestContext, "Looking for teams in {0}", projectName); // Get the teams in the project for this checkin // Todo: Cache these? var allTeams = teamService.QueryTeams(requestContext, project.Uri); if (allTeams != null) { var allTeamsList = allTeams as IList <TeamFoundationTeam> ?? allTeams.ToList(); this.Trace(requestContext, "Found teams [{0}]", allTeamsList.Count()); foreach (var team in allTeamsList) { this.Trace(requestContext, "Getting Team Members in team [{0}]", team.Name); var members = teamService.ReadTeamMembers(requestContext, team, MembershipQuery.Direct, ReadIdentityOptions.None, null); this.Trace(requestContext, "Found Team Members [{0}]", members.Count()); foreach (var member in members) { this.Trace(requestContext, "Comparing [{0}] to [{1}]", member.DisplayName, displayName); if (member.DisplayName.Equals(displayName)) { this.Trace(requestContext, "Match"); teamList.Add(team.Name, team.Identity.TeamFoundationId.ToString()); } } } } else { this.Trace(requestContext, "No Teams found"); } return(teamList); }
protected override IEnumerable <Notifications.INotification> CreateNotifications(TeamFoundationRequestContext requestContext, ReviewerVoteNotification ev, int maxLines) { var repositoryService = requestContext.GetService <TeamFoundationGitRepositoryService>(); var identityService = requestContext.GetService <ITeamFoundationIdentityService>(); var commonService = requestContext.GetService <ICommonStructureService>(); var identity = identityService.ReadIdentity(requestContext, IdentitySearchFactor.Identifier, ev.Reviewer.Identifier); using (TfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, ev.RepositoryId)) { var pullRequestService = requestContext.GetService <ITeamFoundationGitPullRequestService>(); TfsGitPullRequest pullRequest; if (pullRequestService.TryGetPullRequestDetails(requestContext, repository, ev.PullRequestId, out pullRequest)) { string repoUri = repository.GetRepositoryUri(requestContext); var creator = identityService.ReadIdentities(requestContext, new[] { pullRequest.Creator }).First(); var reviewers = identityService.ReadIdentities(requestContext, pullRequest.Reviewers.Select(r => r.Reviewer).ToArray()); var notification = new Notifications.PullRequestReviewerVoteNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, CreatorUserName = creator.UniqueName, Vote = ev.ReviewerVote, UniqueName = identity.UniqueName, DisplayName = identity.DisplayName, ProjectName = commonService.GetProject(requestContext, ev.TeamProjectUri).Name, RepoUri = repoUri, RepoName = ev.RepositoryName, PrId = pullRequest.PullRequestId, PrUrl = string.Format("{0}/pullrequest/{1}#view=discussion", repoUri, ev.PullRequestId), PrTitle = pullRequest.Title, TeamNames = GetUserTeamsByProjectUri(requestContext, ev.TeamProjectUri, ev.Reviewer), SourceBranch = new Notifications.GitRef(pullRequest.SourceBranchName), TargetBranch = new Notifications.GitRef(pullRequest.TargetBranchName), ReviewerUserNames = reviewers.Select(r => r.UniqueName) }; yield return(notification); } else { throw new TfsNotificationRelayException("Unable to get pull request " + ev.PullRequestId); } } }
private TeamFoundationJobService GetJobService() { TeamFoundationServiceHostProperties deploymentHostProperties = new TeamFoundationServiceHostProperties(); deploymentHostProperties.HostType = TeamFoundationHostType.Deployment | TeamFoundationHostType.Application; deploymentHostProperties.Id = Guid.Empty; deploymentHostProperties.PlugInDirectory = Path.Combine(tfsInstallPath, TFS_JOB_EXTENSIONS_PATH); deploymentHostProperties.PhysicalDirectory = string.Empty; deploymentHostProperties.VirtualDirectory = string.Empty; DeploymentServiceHost host = null; ISqlConnectionInfo connInfo = SqlConnectionInfoFactory.Create(connectionString, null, null); deploymentHostProperties.ConnectionInfo = connInfo; host = new DeploymentServiceHost(deploymentHostProperties, true); if (collectionContext != null) { collectionContext.Dispose(); collectionContext = null; } if (deploymentContext != null) { deploymentContext.Dispose(); } deploymentContext = host.CreateSystemContext(); if (rbServer.Checked) { currentContext = deploymentContext; return(deploymentContext.GetService <TeamFoundationJobService>()); } else { var hms = deploymentContext.GetService <TeamFoundationHostManagementService>(); collectionContext = hms.BeginRequest(deploymentContext, tpc.InstanceId, RequestContextType.SystemContext); currentContext = collectionContext; return(collectionContext.GetService <TeamFoundationJobService>()); } }
protected override void Execute(CodeActivityContext context) { TeamFoundationRequestContext requestContext = context.GetValue(this.requestContext); #if UsingILocationService ILocationService tfLocationService = requestContext.GetService <ILocationService>(); Uri uriRequestContext = new Uri(tfLocationService.GetLocationData(requestContext, Guid.Empty).GetServerAccessMapping(requestContext).AccessPoint + "/" + requestContext.ServiceHost.Name); #else var tfLocationService = requestContext.GetService <TeamFoundationLocationService>(); var accessMapping = tfLocationService.GetServerAccessMapping(requestContext); Uri uriRequestContext = new Uri(tfLocationService.GetHostLocation(requestContext, accessMapping)); #endif string strHost = System.Environment.MachineName; string strFQDN = System.Net.Dns.GetHostEntry(strHost).HostName; UriBuilder uriBuilderRequestContext = new UriBuilder(uriRequestContext.Scheme, strFQDN, uriRequestContext.Port, uriRequestContext.PathAndQuery); string teamProjectCollectionUrl = uriBuilderRequestContext.Uri.AbsoluteUri; var teamProjectCollection = new TfsTeamProjectCollection(new Uri(teamProjectCollectionUrl)); context.SetValue(this.teamProjectCollectionUrl, teamProjectCollectionUrl); context.SetValue(this.teamProjectCollection, teamProjectCollection); }
protected override IEnumerable <INotification> CreateNotifications(TeamFoundationRequestContext requestContext, TFVC.CheckinNotification checkin, int maxLines) { var locationService = requestContext.GetService <TeamFoundationLocationService>(); string baseUrl = String.Format("{0}/{1}/", locationService.GetAccessMapping(requestContext, "PublicAccessMapping").AccessPoint, requestContext.ServiceHost.Name); var teamNames = new HashSet <string>(); var projects = new Dictionary <string, string>(); var submittedItems = checkin.GetSubmittedItems(requestContext).ToList(); const string pattern = @"^\$\/([^\/]*)\/"; foreach (string item in submittedItems) { Match match = Regex.Match(item, pattern); if (match.Success) { string projectName = match.Groups[1].Value; if (projects.ContainsKey(projectName)) { continue; } string projectUrl = baseUrl + projectName; projects.Add(projectName, projectUrl); foreach (var team in GetUserTeamsByProjectName(requestContext, projectName, checkin.ChangesetOwner.Descriptor)) { teamNames.Add(team); } } } var notification = new CheckinNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, UniqueName = checkin.ChangesetOwner.UniqueName, DisplayName = checkin.ChangesetOwner.DisplayName, ChangesetUrl = $"{baseUrl}_versionControl/changeset/{checkin.Changeset}", ChangesetId = checkin.Changeset, Projects = projects, Comment = TextHelper.Truncate(checkin.Comment, Settings.CommentMaxLength, true), TeamNames = teamNames, SubmittedItems = submittedItems }; yield return(notification); }
private string GetPreferredEmailAddress(TeamFoundationRequestContext requestContext, string owner) { var identityService = requestContext.GetService <TeamFoundationIdentityService>(); var identity = identityService.ReadIdentity(requestContext, IdentitySearchFactor.AccountName, owner); if (identity == null) { LogError(string.Format("Team Foundation Identity for user {0} could not be found!", owner), null); return(null); } return(identityService.GetPreferredEmailAddress(requestContext, identity.TeamFoundationId, true)); }
protected override INotification CreateNotification(TeamFoundationRequestContext requestContext, BuildQualityChangedNotificationEvent buildNotification, int maxLines) { BuildDetail build = buildNotification.Build; var locationService = requestContext.GetService <TeamFoundationLocationService>(); var buildService = requestContext.GetService <TeamFoundationBuildService>(); using (var buildReader = buildService.QueryQueuedBuildsById(requestContext, build.QueueIds, new[] { "*" }, QueryOptions.None)) { var result = buildReader.Current <BuildQueueQueryResult>(); QueuedBuild qb = result.QueuedBuilds.FirstOrDefault(); string buildUrl = String.Format("{0}/{1}/{2}/_build#buildUri={3}&_a=summary", locationService.GetAccessMapping(requestContext, "PublicAccessMapping").AccessPoint, requestContext.ServiceHost.Name, build.TeamProject, build.Uri); var notification = new BuildQualityChangedNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, BuildUrl = buildUrl, ProjectName = build.TeamProject, BuildNumber = build.BuildNumber, BuildStatus = build.Status, BuildReason = build.Reason, StartTime = build.StartTime, FinishTime = build.FinishTime, RequestedFor = qb.RequestedFor, RequestedForDisplayName = qb.RequestedForDisplayName, BuildDefinition = build.Definition.Name, DropLocation = build.DropLocation, OldValue = buildNotification.OldValue, NewValue = buildNotification.NewValue }; return(notification); } }
/// <summary> /// Processes the event. /// </summary> /// <param name="requestContext">The request context.</param> /// <param name="notificationType">Type of the notification.</param> /// <param name="notificationEventArgs">The notification event args.</param> /// <param name="statusCode">The status code.</param> /// <param name="statusMessage">The status message.</param> /// <param name="properties">The properties.</param> /// <returns></returns> public EventNotificationStatus ProcessEvent( TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs, out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties) { statusCode = 0; statusMessage = "TFSEventWorkflow executed successfully"; properties = null; // we only handle notifications if (notificationType != NotificationType.Notification) { return(EventNotificationStatus.ActionPermitted); } string strConfigFile = this.workflowRunner.ExecutionPath.FullName + ".config"; XmlConfigurator.Configure(new Uri(strConfigFile)); if (notificationEventArgs.GetType() == typeof(WorkItemChangedEvent)) { // run workflow asynchronously in a TFS job var workItemChangedEvent = (WorkItemChangedEvent)notificationEventArgs; var xmlData = WorkItemChangedEventSerializer.SerializeXml(workItemChangedEvent); this.LogInfo(string.Format("Queuing Job for WorkitemChangedEvent")); // Handle the notification by queueing the information we need for a job var jobService = requestContext.GetService <TeamFoundationJobService>(); jobService.QueueOneTimeJob( requestContext, "TFSEventWorkflow Job", "artiso.TFSEventWorkflows.TFSEventWorkflowsServerPlugin.WorkflowRunnerJob", xmlData, false); } else { // run workflow synchronously in the Server PLugin itself return(this.workflowRunner.ProcessEvent(requestContext, notificationEventArgs)); } return(EventNotificationStatus.ActionPermitted); }
protected override IEnumerable <INotification> CreateNotifications(TeamFoundationRequestContext requestContext, TFVC.CheckinNotification checkin, int maxLines) { var locationService = requestContext.GetService <TeamFoundationLocationService>(); string baseUrl = String.Format("{0}/{1}/", locationService.GetAccessMapping(requestContext, "PublicAccessMapping").AccessPoint, requestContext.ServiceHost.Name); var notification = new CheckinNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, UniqueName = checkin.ChangesetOwner.UniqueName, DisplayName = checkin.ChangesetOwner.DisplayName, ChangesetUrl = String.Format("{0}_versionControl/changeset/{1}", baseUrl, checkin.Changeset), ChangesetId = checkin.Changeset, Projects = new Dictionary <string, string>(), Comment = checkin.Comment, Teams = new Dictionary <string, string>() }; string pattern = @"^\$\/([^\/]*)\/"; foreach (string item in checkin.GetSubmittedItems(requestContext)) { Match match = Regex.Match(item, pattern); if (match.Success) { string projectName = match.Groups[1].Value; if (notification.Projects.ContainsKey(projectName)) { continue; } string projectUrl = baseUrl + projectName; notification.Projects.Add(projectName, projectUrl); // Add the teams to the notification foreach (var team in this.GetTeamsByUser(requestContext, projectName, notification.DisplayName)) { if (notification.Teams.ContainsKey(team.Key)) { continue; } notification.Teams.Add(team.Key, team.Value); } } } yield return(notification); }
protected override Notifications.INotification CreateNotification(TeamFoundationRequestContext requestContext, ReviewerVoteNotification ev, int maxLines) { var repositoryService = requestContext.GetService <TeamFoundationGitRepositoryService>(); var identityService = requestContext.GetService <ITeamFoundationIdentityService>(); var commonService = requestContext.GetService <ICommonStructureService>(); var identity = identityService.ReadIdentity(requestContext, IdentitySearchFactor.Identifier, ev.Reviewer.Identifier); using (TfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, ev.RepositoryId)) { var pullRequestService = requestContext.GetService <ITeamFoundationGitPullRequestService>(); TfsGitPullRequest pullRequest; if (pullRequestService.TryGetPullRequestDetails(requestContext, repository, ev.PullRequestId, out pullRequest)) { string repoUri = repository.GetRepositoryUri(requestContext); var notification = new Notifications.PullRequestReviewerVoteNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, Vote = ev.ReviewerVote, UniqueName = identity.UniqueName, DisplayName = identity.DisplayName, ProjectName = commonService.GetProject(requestContext, ev.TeamProjectUri).Name, RepoUri = repoUri, RepoName = ev.RepositoryName, PrId = pullRequest.PullRequestId, PrUrl = string.Format("{0}/pullrequest/{1}#view=discussion", repoUri, ev.PullRequestId), PrTitle = pullRequest.Title }; return(notification); } else { throw new TfsNotificationRelayException("Unable to get pull request " + ev.PullRequestId); } } }
protected override INotification CreateNotification(TeamFoundationRequestContext requestContext, ProjectCreatedEvent ev, int maxLines) { var locationService = requestContext.GetService <TeamFoundationLocationService>(); string projectUrl = String.Format("{0}/{1}/{2}", locationService.GetAccessMapping(requestContext, "PublicAccessMapping").AccessPoint, requestContext.ServiceHost.Name, ev.Name); if (!this.ProjectsNames.ContainsKey(ev.Uri)) { this.ProjectsNames.Add(ev.Uri, ev.Name); } return(new ProjectCreatedNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, ProjectUrl = projectUrl, ProjectName = ev.Name }); }
private Policy GetPolicy(TeamFoundationRequestContext requestContext, PushNotification pushNotification) { // HACK string collectionName = requestContext.ServiceHost.VirtualDirectory.Replace("/tfs/", "").Replace("/", ""); // HACK is this cheap? var commonService = requestContext.GetService <CommonStructureService>(); string projectName = commonService.GetProject(requestContext, pushNotification.TeamProjectUri).Name; string repositoryName = pushNotification.RepositoryName; foreach (var policy in PluginConfiguration.Instance.Policies) { if (policy.AppliesTo(collectionName, projectName, repositoryName)) { return(policy); } }//for return(null); }
protected override void Execute(CodeActivityContext context) { object notificationEventArgs = context.GetValue(this.notificationEventArgs); XmlNode xmlData = SerializeXml(notificationEventArgs); TeamFoundationRequestContext requestContext = context.GetValue(this.requestContext); // Handle the notification by queueing the information we need for a job var jobService = requestContext.GetService <TeamFoundationJobService>(); var jobGuid = jobService.QueueOneTimeJob( requestContext, "TFSEventWorkflow Job", "artiso.TFSEventWorkflows.TFSEventWorkflowsServerPlugin.WorkflowRunnerJob", xmlData, false); int result = jobService.QueueJobsNow(requestContext, new List <Guid>() { jobGuid }, true); }
protected override INotification CreateNotification(TeamFoundationRequestContext requestContext, WorkItemChangedEvent ev, int maxLines) { var identityService = requestContext.GetService <TeamFoundationIdentityService>(); var identity = identityService.ReadIdentity(requestContext, IdentitySearchFactor.Identifier, ev.ChangerSid); var notification = new WorkItemChangedNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, IsNew = ev.ChangeType == ChangeTypes.New, UniqueName = identity.UniqueName, DisplayName = identity.DisplayName, WiUrl = ev.DisplayUrl, WiType = ev.CoreFields.StringFields.Single(f => f.ReferenceName == "System.WorkItemType").NewValue, WiId = ev.CoreFields.IntegerFields.Single(f => f.ReferenceName == "System.Id").NewValue, WiTitle = ev.WorkItemTitle, ProjectName = ev.PortfolioProject, IsStateChanged = ev.ChangedFields.StringFields.Any(f => f.ReferenceName == "System.State"), IsAssignmentChanged = ev.ChangedFields.StringFields.Any(f => f.ReferenceName == "System.AssignedTo"), State = ev.CoreFields.StringFields.Single(f => f.ReferenceName == "System.State").NewValue, AssignedTo = ev.CoreFields.StringFields.Single(f => f.ReferenceName == "System.AssignedTo").NewValue }; return(notification); }
protected override IEnumerable <INotification> CreateNotifications(TeamFoundationRequestContext requestContext, PushNotification pushNotification, int maxLines) { var repositoryService = requestContext.GetService <TeamFoundationGitRepositoryService>(); var commonService = requestContext.GetService <CommonStructureService>(); var commitService = requestContext.GetService <TeamFoundationGitCommitService>(); var identityService = requestContext.GetService <TeamFoundationIdentityService>(); var identity = identityService.ReadIdentity(requestContext, IdentitySearchFactor.Identifier, pushNotification.Pusher.Identifier); var teamNames = GetUserTeamsByProjectUri(requestContext, pushNotification.TeamProjectUri, pushNotification.Pusher); using (TfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, pushNotification.RepositoryId)) { var pushRow = new PushRow() { UniqueName = pushNotification.AuthenticatedUserName, DisplayName = identity.DisplayName, RepoName = pushNotification.RepositoryName, RepoUri = repository.GetRepositoryUri(requestContext), ProjectName = commonService.GetProject(requestContext, pushNotification.TeamProjectUri).Name, IsForcePush = settings.IdentifyForcePush ? pushNotification.IsForceRequired(requestContext, repository) : false }; var notification = new GitPushNotification(requestContext.ServiceHost.Name, pushRow.ProjectName, pushRow.RepoName, teamNames); notification.Add(pushRow); notification.TotalLineCount++; var refNames = new Dictionary <byte[], List <string> >(new ByteArrayComparer()); var oldCommits = new HashSet <byte[]>(new ByteArrayComparer()); var unknowns = new List <RefUpdateResultGroup>(); // Associate refs (branch, lightweight and annotated tag) with corresponding commit var refUpdateResultGroups = pushNotification.RefUpdateResults .Where(r => r.Succeeded) .GroupBy(r => r.NewObjectId, (key, items) => new RefUpdateResultGroup(key, items), new ByteArrayComparer()); foreach (var refUpdateResultGroup in refUpdateResultGroups) { byte[] newObjectId = refUpdateResultGroup.NewObjectId; byte[] commitId = null; if (newObjectId.IsZero()) { commitId = newObjectId; } else { TfsGitObject gitObject = repository.LookupObject(requestContext, newObjectId); if (gitObject.ObjectType == TfsGitObjectType.Commit) { commitId = newObjectId; } else if (gitObject.ObjectType == TfsGitObjectType.Tag) { var tag = (TfsGitTag)gitObject; var commit = tag.TryResolveToCommit(requestContext); if (commit != null) { commitId = commit.ObjectId; } } } if (commitId != null) { List <string> names; if (!refNames.TryGetValue(commitId, out names)) { names = new List <string>(); refNames.Add(commitId, names); } names.AddRange(RefsToStrings(refUpdateResultGroup.RefUpdateResults)); if (commitId.IsZero() || !pushNotification.IncludedCommits.Any(r => r.SequenceEqual(commitId))) { oldCommits.Add(commitId); } } else { unknowns.Add(refUpdateResultGroup); } } notification.TotalLineCount += pushNotification.IncludedCommits.Count() + oldCommits.Count + unknowns.Count; // Add new commits with refs foreach (byte[] commitId in pushNotification.IncludedCommits.TakeWhile(c => notification.Count < maxLines)) { TfsGitCommit gitCommit = (TfsGitCommit)repository.LookupObject(requestContext, commitId); notification.Add(CreateCommitRow(requestContext, commitService, gitCommit, CommitRowType.Commit, pushNotification, refNames)); } // Add updated refs to old commits foreach (byte[] commitId in oldCommits.TakeWhile(c => notification.Count < maxLines)) { if (commitId.IsZero()) { notification.Add(new DeleteRow() { RefNames = refNames[commitId] }); } else { TfsGitCommit gitCommit = (TfsGitCommit)repository.LookupObject(requestContext, commitId); notification.Add(CreateCommitRow(requestContext, commitService, gitCommit, CommitRowType.RefUpdate, pushNotification, refNames)); } } // Add "unknown" refs foreach (var refUpdateResultGroup in unknowns.TakeWhile(c => notification.Count < maxLines)) { byte[] newObjectId = refUpdateResultGroup.NewObjectId; TfsGitObject gitObject = repository.LookupObject(requestContext, newObjectId); notification.Add(new RefUpdateRow() { NewObjectId = newObjectId, ObjectType = gitObject.ObjectType, RefNames = RefsToStrings(refUpdateResultGroup.RefUpdateResults) }); } yield return(notification); } }
private Uri GetCollectionUriFromContext(TeamFoundationRequestContext requestContext) { ILocationService service = requestContext.GetService<ILocationService>(); return service.GetSelfReferenceUri(requestContext, service.GetDefaultAccessMapping(requestContext)); }
public TeamFoundationBuildServiceAdapter(TeamFoundationRequestContext requestContext) { _requestContext = requestContext; _buildService = _requestContext.GetService<TeamFoundationBuildService>(); }
protected override IEnumerable <INotification> CreateNotifications(TeamFoundationRequestContext requestContext, DiscussionsNotification args, int maxLines) { var locationService = requestContext.GetService <ILocationService>(); var linkingService = requestContext.GetService <TeamFoundationLinkingService>(); var hyperlinkService = requestContext.GetService <TswaServerHyperlinkService>(); var identityService = requestContext.GetService <ITeamFoundationIdentityService>(); var commonService = requestContext.GetService <ICommonStructureService>(); var discussionService = requestContext.GetService <ITeamFoundationDiscussionService>(); var notifications = new List <INotification>(); foreach (var thread in args.Threads) { if (thread.Comments == null) { continue; // e.g. when a comment is deleted } var artifactId = LinkingUtilities.DecodeUri(thread.ArtifactUri); int discussionId = thread.DiscussionId <= 0 ? thread.Comments[0].DiscussionId : thread.DiscussionId; if (artifactId.ArtifactType.Equals("Commit", StringComparison.OrdinalIgnoreCase)) { var repositoryService = requestContext.GetService <TeamFoundationGitRepositoryService>(); var commitService = requestContext.GetService <TeamFoundationGitCommitService>(); Guid projectGuid; Guid repositoryId; Sha1Id commitId; GitCommitArtifactId.Decode(artifactId, out projectGuid, out repositoryId, out commitId); using (TfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, repositoryId)) { var project = commonService.GetProject(requestContext, projectGuid); var repoUri = repository.GetRepositoryUri(requestContext); var commitUri = repoUri + "/commit/" + commitId.ToHexString(); string itemPath; if (thread.Properties.TryGetValue <string>("Microsoft.TeamFoundation.Discussion.ItemPath", out itemPath)) { commitUri += string.Format("#path={0}&discussionId={1}&_a=contents", Uri.EscapeDataString(itemPath), discussionId); } var commitManifest = commitService.GetCommitManifest(requestContext, repository, commitId); var pusher = identityService.ReadIdentities(requestContext, new[] { commitManifest.PusherId }).FirstOrDefault(); foreach (var comment in thread.Comments) { var commenter = identityService.ReadIdentities(requestContext, new[] { comment.Author }).First(); var notification = new Notifications.CommitCommentNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, PusherUniqueName = pusher?.UniqueName, UniqueName = commenter.UniqueName, DisplayName = comment.AuthorDisplayName, ProjectName = project.Name, RepoUri = repoUri, RepoName = repository.Name, CommitId = commitId, CommitUri = commitUri, Comment = TextHelper.Truncate(comment.Content, Settings.DiscussionCommentMaxLength), TeamNames = GetUserTeamsByProjectUri(requestContext, project.Uri, commenter.Descriptor), }; notifications.Add(notification); } } } else if (artifactId.ArtifactType.Equals("CodeReviewId", StringComparison.OrdinalIgnoreCase)) { Guid projectGuid; int pullRequestId; LegacyCodeReviewArtifactId.Decode(artifactId, out projectGuid, out pullRequestId); var pullRequestService = requestContext.GetService <ITeamFoundationGitPullRequestService>(); var pullRequest = pullRequestService.GetPullRequestDetails(requestContext, pullRequestId); var repositoryService = requestContext.GetService <TeamFoundationGitRepositoryService>(); using (TfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, pullRequest.RepositoryId)) { var project = commonService.GetProject(requestContext, projectGuid); string repoUri = repository.GetRepositoryUri(requestContext); var creator = identityService.ReadIdentities(requestContext, new[] { pullRequest.Creator }).FirstOrDefault(); foreach (var comment in thread.Comments) { var commenter = identityService.ReadIdentities(requestContext, new[] { comment.Author }).First(); var notification = new Notifications.PullRequestCommentNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, CreatorUniqueName = creator?.UniqueName, UniqueName = commenter.UniqueName, DisplayName = commenter.DisplayName, ProjectName = project.Name, RepoUri = repoUri, RepoName = repository.Name, PrId = pullRequest.PullRequestId, PrUrl = $"{repoUri}/pullrequest/{pullRequest.PullRequestId}#view=discussion", PrTitle = pullRequest.Title, TeamNames = GetUserTeamsByProjectUri(requestContext, project.Uri, commenter.Descriptor), SourceBranch = new GitRef(pullRequest.SourceBranchName), TargetBranch = new GitRef(pullRequest.TargetBranchName), Comment = TextHelper.Truncate(comment.Content, Settings.DiscussionCommentMaxLength) }; notifications.Add(notification); } } } else if (artifactId.ArtifactType.Equals("Changeset", StringComparison.OrdinalIgnoreCase)) { var versionControlService = requestContext.GetService <TeamFoundationVersionControlService>(); var uri = new VersionControlIntegrationUri(thread.ArtifactUri); var changesetId = int.Parse(uri.ArtifactName); var reader = versionControlService.QueryChangeset(requestContext, changesetId, true, false, false); var changeset = reader.Current <Changeset>(); var changesetUrl = hyperlinkService.GetChangesetDetailsUrl(changesetId).AbsoluteUri; string baseUrl = String.Format("{0}/{1}/", locationService.GetAccessMapping(requestContext, "PublicAccessMapping").AccessPoint, requestContext.ServiceHost.Name); string itemPath = string.Empty; string projectName = string.Empty; const string projectNamePattern = @"^\$\/([^\/]*)\/"; if (thread.Properties != null && thread.Properties.TryGetValue <string>("Microsoft.TeamFoundation.Discussion.ItemPath", out itemPath)) { changesetUrl += string.Format("#path={0}&discussionId={1}&_a=contents", Uri.EscapeDataString(itemPath), discussionId); Match match = Regex.Match(itemPath, projectNamePattern); if (match.Success) { projectName = match.Groups[1].Value; } } else { // This assumes changeset doesn't span multiple projects. var serverItem = changeset.Changes.FirstOrDefault()?.Item.ServerItem; if (serverItem != null) { Match match = Regex.Match(serverItem, projectNamePattern); if (match.Success) { projectName = match.Groups[1].Value; } } } var commiter = identityService.ReadIdentity(requestContext, IdentitySearchFactor.AccountName, changeset.Committer); foreach (var comment in thread.Comments) { var commenter = identityService.ReadIdentities(requestContext, new[] { comment.Author }).First(); var notification = new Notifications.ChangesetCommentNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, CreatorUniqueName = commiter?.UniqueName, UniqueName = commenter.UniqueName, DisplayName = commenter.DisplayName, ProjectUrl = baseUrl + projectName, ProjectName = projectName, ChangesetId = changesetId, ChangesetUrl = changesetUrl, TeamNames = GetUserTeamsByProjectName(requestContext, projectName, commenter.Descriptor), SourcePath = itemPath, Comment = TextHelper.Truncate(comment.Content, Settings.DiscussionCommentMaxLength) }; notifications.Add(notification); } } } return(notifications); }
TfsTeamProjectCollection getTeamProjectCollectionFromRequestContext(TeamFoundationRequestContext requestContext) { //todo: Avoid hardcoding credentials. System.Net.ICredentials cred = new System.Net.NetworkCredential("John", "cheese"); IdentityDescriptor id; requestContext.GetAuthenticatedIdentity(out id); //ICredentialsProvider c = requestContext.GetAuthenticatedIdentity TeamFoundationLocationService service = requestContext.GetService<TeamFoundationLocationService>(); Uri selfReferenceUri = service.GetSelfReferenceUri(requestContext, service.GetDefaultAccessMapping(requestContext)); return new TfsTeamProjectCollection(selfReferenceUri, cred); }
public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs, out int statusCode, out string statusMessage, out Microsoft.TeamFoundation.Common.ExceptionPropertyCollection properties) { statusCode = 0; statusMessage = string.Empty; properties = null; try { if (notificationType == NotificationType.Notification && notificationEventArgs is PushNotification) { Stopwatch timer = new Stopwatch(); timer.Start(); PushNotification pushNotification = notificationEventArgs as PushNotification; var repositoryService = requestContext.GetService<TeamFoundationGitRepositoryService>(); var commonService = requestContext.GetService<CommonStructureService>(); using (TfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, pushNotification.RepositoryId)) { string repoName = pushNotification.RepositoryName; string projectName = commonService.GetProject(requestContext, pushNotification.TeamProjectUri).Name; string userName = pushNotification.AuthenticatedUserName.Replace(DOMAIN_PREFIX, ""); var lines = new List<string>(); string pushText = pushNotification.IsForceRequired(requestContext, repository) ? "FORCE push" : "push"; lines.Add(String.Format("{0} by {1} to {2}/{3}", pushText, userName, projectName, repoName)); var refNames = new Dictionary<byte[], List<string>>(new ByteArrayComparer()); var oldCommits = new HashSet<byte[]>(new ByteArrayComparer()); var unknowns = new List<RefUpdateResultGroup>(); // Associate refs (branch, ligtweight and annotated tag) with corresponding commit var refUpdateResultGroups = pushNotification.RefUpdateResults .Where(r => r.Succeeded) .GroupBy(r => r.NewObjectId, (key, items) => new RefUpdateResultGroup(key, items), new ByteArrayComparer()); foreach (var refUpdateResultGroup in refUpdateResultGroups) { byte[] newObjectId = refUpdateResultGroup.NewObjectId; byte[] commitId = null; if (newObjectId.IsZero()) { commitId = newObjectId; } else { TfsGitObject gitObject = repository.LookupObject(requestContext, newObjectId); if (gitObject.ObjectType == TfsGitObjectType.Commit) { commitId = newObjectId; } else if (gitObject.ObjectType == TfsGitObjectType.Tag) { var tag = (TfsGitTag)gitObject; var commit = tag.TryResolveToCommit(requestContext); if (commit != null) { commitId = commit.ObjectId; } } } if (commitId != null) { List<string> names; if (!refNames.TryGetValue(commitId, out names)) { names = new List<string>(); refNames.Add(commitId, names); } names.AddRange(RefsToStrings(refUpdateResultGroup.RefUpdateResults)); if (commitId.IsZero() || !pushNotification.IncludedCommits.Any(r => r.SequenceEqual(commitId))) { oldCommits.Add(commitId); } } else { unknowns.Add(refUpdateResultGroup); } } // Display new commits with refs foreach (byte[] commitId in pushNotification.IncludedCommits) { TfsGitCommit gitCommit = (TfsGitCommit)repository.LookupObject(requestContext, commitId); string line = CommitToString(requestContext, gitCommit, "commit", pushNotification, refNames); lines.Add(line); } // Display updated refs to old commits foreach (byte[] commitId in oldCommits) { string line = null; if (commitId.IsZero()) { line = String.Format("{0} deleted", String.Join("", refNames[commitId])); } else { TfsGitCommit gitCommit = (TfsGitCommit)repository.LookupObject(requestContext, commitId); line = CommitToString(requestContext, gitCommit, "->", pushNotification, refNames); } lines.Add(line); } // Display "unknown" refs foreach (var refUpdateResultGroup in unknowns) { byte[] newObjectId = refUpdateResultGroup.NewObjectId; TfsGitObject gitObject = repository.LookupObject(requestContext, newObjectId); string line = String.Format("{0} -> {1} {2}", RefsToString(refUpdateResultGroup.RefUpdateResults), gitObject.ObjectType, newObjectId.ToHexString()); lines.Add(line); } //Log(lines); List<string> sendLines = lines; if (lines.Count > MAX_LINES) { sendLines = lines.Take(MAX_LINES).ToList(); sendLines.Add(String.Format("{0} more line(s) suppressed.", lines.Count - MAX_LINES)); } Task.Run(() => SendToBot(sendLines)); } timer.Stop(); //Log("Time spent in ProcessEvent: " + timer.Elapsed); } } catch (Exception ex) { Log(ex.Message); Log(ex.StackTrace); } return EventNotificationStatus.ActionPermitted; }
public static Uri GetTFSUri(TeamFoundationRequestContext requestContext) { return new Uri(requestContext.GetService<TeamFoundationLocationService>().GetServerAccessMapping(requestContext).AccessPoint.Replace("localhost", Environment.MachineName) + "/" + requestContext.ServiceHost.Name); }
private void SendEmail(TeamFoundationRequestContext requestContext) { var now = DateTime.Now; var vcs = requestContext.GetService <TeamFoundationVersionControlService>(); var workspaceGroups = from ws in vcs.QueryWorkspaces(requestContext, null, null, 0) where now.Subtract(ws.LastAccessDate).TotalDays >= warningAgeInDays group ws by new { Owner = ws.OwnerName, OwnerDisplayName = ws.OwnerDisplayName, Computer = ws.Computer } into g orderby g.Key.Owner, g.Key.Computer select g; string currentOwner = string.Empty; MemoryStream memStream = null; XmlWriter xmlWriter = null; foreach (var workspaceGroup in workspaceGroups) { if (currentOwner != workspaceGroup.Key.Owner) { if (memStream != null) { // Create XML document xmlWriter.WriteEndElement(); xmlWriter.Flush(); var doc = new XmlDocument(); memStream.Seek(0, SeekOrigin.Begin); doc.Load(memStream); // Send Email QueueEmail(requestContext, currentOwner, doc); // Clean up xmlWriter.Close(); xmlWriter.Dispose(); memStream.Dispose(); } memStream = new MemoryStream(); xmlWriter = XmlWriter.Create(memStream); currentOwner = workspaceGroup.Key.Owner; xmlWriter.WriteStartElement("WorkspaceCleanup"); xmlWriter.WriteAttributeString("server", serverName); xmlWriter.WriteAttributeString("collection", collectionName); xmlWriter.WriteAttributeString("ownerDisplayName", workspaceGroup.Key.OwnerDisplayName); xmlWriter.WriteAttributeString("owner", workspaceGroup.Key.Owner); xmlWriter.WriteAttributeString("dateGenerated", now.ToString()); xmlWriter.WriteAttributeString("warnAge", warningAgeInDays.ToString()); xmlWriter.WriteAttributeString("delAge", deleteAgeInDays.ToString()); } foreach (var workspace in workspaceGroup) { xmlWriter.WriteStartElement("Workspace"); xmlWriter.WriteAttributeString("computer", workspace.Computer); xmlWriter.WriteAttributeString("name", workspace.Name); xmlWriter.WriteAttributeString("comment", workspace.Comment); xmlWriter.WriteAttributeString("type", workspace.IsLocal ? "Local" : "Server"); xmlWriter.WriteAttributeString("lastAccessed", workspace.LastAccessDate.ToString()); xmlWriter.WriteAttributeString("age", now.Subtract(workspace.LastAccessDate).TotalDays.ToString("#")); xmlWriter.WriteEndElement(); } } if (memStream != null) { // Create XML document xmlWriter.WriteEndElement(); xmlWriter.Flush(); var doc = new XmlDocument(); memStream.Seek(0, SeekOrigin.Begin); doc.Load(memStream); // Send Email QueueEmail(requestContext, currentOwner, doc); // Clean up xmlWriter.Close(); xmlWriter.Dispose(); memStream.Dispose(); } }
protected override IEnumerable <INotification> CreateNotifications(TeamFoundationRequestContext requestContext, WorkItemChangedEvent ev, int maxLines) { var notifications = new List <INotification>(); var identityService = requestContext.GetService <TeamFoundationIdentityService>(); var identity = identityService.ReadIdentity(requestContext, IdentitySearchFactor.Identifier, ev.ChangerSid); if (ev.CoreFields == null) { throw new TfsNotificationRelayException("ev.CoreFields is null"); } if (ev.CoreFields.StringFields == null) { throw new TfsNotificationRelayException("ev.CoreFields.StringFields is null"); } if (ev.CoreFields.IntegerFields == null) { throw new TfsNotificationRelayException("ev.CoreFields.IntegerFields is null"); } var typeField = ev.CoreFields.StringFields.SingleOrDefault(f => f.ReferenceName == "System.WorkItemType"); if (typeField == null) { throw new TfsNotificationRelayException("missing System.WorkItemType"); } string type = typeField.NewValue; var idField = ev.CoreFields.IntegerFields.Single(f => f.ReferenceName == "System.Id"); if (idField == null) { throw new TfsNotificationRelayException("missing System.Id"); } int id = idField.NewValue; if (ev.TextFields != null) { var comment = ev.TextFields.FirstOrDefault(f => f.ReferenceName == "System.History" && !String.IsNullOrEmpty(f.Value)); if (comment != null) { var commentNotification = new WorkItemCommentNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, UniqueName = identity.UniqueName, DisplayName = identity.DisplayName, WiUrl = ev.DisplayUrl, WiType = type, WiId = id, WiTitle = ev.WorkItemTitle, ProjectName = ev.PortfolioProject, AreaPath = ev.AreaPath, CommentHtml = comment.Value, Comment = TextHelper.HtmlToText(comment.Value) }; notifications.Add(commentNotification); } } var changeNotification = new WorkItemChangedNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, IsNew = ev.ChangeType == ChangeTypes.New, UniqueName = identity.UniqueName, DisplayName = identity.DisplayName, WiUrl = ev.DisplayUrl, WiType = type, WiId = id, WiTitle = ev.WorkItemTitle, ProjectName = ev.PortfolioProject, AreaPath = ev.AreaPath, IsStateChanged = ev.ChangedFields != null && ev.ChangedFields.StringFields != null && ev.ChangedFields.StringFields.Any(f => f.ReferenceName == "System.State"), IsAssignmentChanged = ev.ChangedFields != null && ev.ChangedFields.StringFields != null && ev.ChangedFields.StringFields.Any(f => f.ReferenceName == "System.AssignedTo"), State = ev.CoreFields.StringFields.GetFieldValue("System.State", f => f.NewValue), AssignedTo = ev.CoreFields.StringFields.GetFieldValue("System.AssignedTo", f => f.NewValue), CoreFields = ev.CoreFields, ChangedFields = ev.ChangedFields }; notifications.Add(changeNotification); return(notifications); }
public async Task NotifyAsync(TeamFoundationRequestContext requestContext, INotification notification, BotElement bot, EventRuleElement matchingRule) { string URL = bot.GetSetting("spiraURL"); string user = bot.GetSetting("spiraUser"); string password = bot.GetSetting("spiraPassw"); string projVers = bot.GetSetting("spiraPvers"); string projNumber = bot.GetSetting("spiraPnumber"); int status = 0; int projectId; Int32.TryParse(projNumber, out projectId); //Check that it is the correct kind of notification if (notification is BuildCompletionNotification) { BuildCompletionNotification buildCompletionNotification = (BuildCompletionNotification)notification; if (buildCompletionNotification.IsSuccessful) { status = 2; //sucess } else if (buildCompletionNotification.BuildStatus.ToString() == "Failed") { status = 1; //failed } else if (buildCompletionNotification.BuildStatus.ToString() == "PartiallySucceeded") { status = 3; //unstable } else if (buildCompletionNotification.BuildStatus.ToString() == "Stopped") { status = 4; //aborted } else { TeamFoundationApplicationCore.Log(requestContext, ":: SpiraTeam Plugin for TFS:: The current build finished with a not supported" + " status, please check TFS logs to see detailed information.", 0, EventLogEntryType.Warning); } DateTime date = buildCompletionNotification.StartTime; String sname = buildCompletionNotification.ProjectName + " #" + buildCompletionNotification.BuildNumber; String description = ("Information retrieved from TFS : Build requested by " + buildCompletionNotification.UserName + "<br/> from Team " + buildCompletionNotification.TeamNames + "<br/> and project collection " + buildCompletionNotification.TeamProjectCollection + "<br/> for " + sname + "<br/> with URL " + buildCompletionNotification.BuildUrl + "<br/> located at " + buildCompletionNotification.DropLocation + "<br/> Build Started at " + buildCompletionNotification.StartTime + "<br/> Build finished at " + buildCompletionNotification.FinishTime + "<br/> Status " + buildCompletionNotification.BuildStatus); //List<int> incidentIds; var locationService = requestContext.GetService <TeamFoundationLocationService>(); string baseUrl = String.Format("{0}/", locationService.GetAccessMapping(requestContext, "PublicAccessMapping").AccessPoint); TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(baseUrl)); VersionControlServer sourceControl = tpc.GetService <VersionControlServer>(); int revisionId = sourceControl.GetLatestChangesetId(); //SPIRA CODE Uri uri = new Uri(URL + URL_SUFFIX); ImportExportClient spiraClient = SpiraClientFactory.CreateClient(uri); bool success = spiraClient.Connection_Authenticate2(user, password, "TFS Notifier for SpiraTeam v. 1.0.0"); if (!success) { TeamFoundationApplicationCore.Log(requestContext, ":: SpiraTeam Plugin for TFS :: Unable to connect to the Spira server, please verify" + " the provided information in the configuration file.", 0, EventLogEntryType.Error); } success = spiraClient.Connection_ConnectToProject(projectId); if (!success) { TeamFoundationApplicationCore.Log(requestContext, ":: SpiraTeam Plugin for TFS :: The project Id you specified either does not exist," + "or your user does not have access to it! Please verify the configuration file.", 0, EventLogEntryType.Error); } RemoteRelease[] releases = spiraClient.Release_Retrieve(true); RemoteRelease release = releases.FirstOrDefault(r => r.VersionNumber == projVers); if (release != null) { List <RemoteBuildSourceCode> revisions = new List <RemoteBuildSourceCode>(); RemoteBuildSourceCode revision = new RemoteBuildSourceCode(); revision.RevisionKey = revisionId.ToString(); revisions.Add(revision); RemoteBuild newBuild = new RemoteBuild(); newBuild.Name = sname; newBuild.BuildStatusId = status; newBuild.Description = description; newBuild.CreationDate = date; newBuild.Revisions = revisions.ToArray(); newBuild.ReleaseId = release.ReleaseId.Value; spiraClient.Build_Create(newBuild); await Task.Delay(10); } else { TeamFoundationApplicationCore.Log(requestContext, ":: SpiraTeam Plugin for TFS :: The release version number you specified does not " + "exist in the current project! Please verify the configuration file.", 0, EventLogEntryType.Error); } } }
private Policy GetPolicy(TeamFoundationRequestContext requestContext, PushNotification pushNotification) { // HACK string collectionName = requestContext.ServiceHost.VirtualDirectory.Replace("/tfs/", "").Replace("/", ""); // HACK is this cheap? var commonService = requestContext.GetService<CommonStructureService>(); string projectName = commonService.GetProject(requestContext, pushNotification.TeamProjectUri).Name; string repositoryName = pushNotification.RepositoryName; foreach (var policy in PluginConfiguration.Instance.Policies) { if (policy.AppliesTo(collectionName, projectName, repositoryName)) return policy; }//for return null; }
public EventNotificationStatus ProcessEvent( TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs, out int statusCode, out string statusMessage, out Microsoft.TeamFoundation.Common.ExceptionPropertyCollection properties) { statusCode = 0; statusMessage = string.Empty; properties = null; try { if (notificationType == NotificationType.DecisionPoint && notificationEventArgs is PushNotification) { PushNotification pushNotification = notificationEventArgs as PushNotification; // validation applies? var policy = GetPolicy(requestContext, pushNotification); if (policy != null) { Logger.LogStart("Request controlled by policy"); var gitRepoService = requestContext.GetService<TeamFoundationGitRepositoryService>(); using (var repository = gitRepoService.FindRepositoryById(requestContext, pushNotification.RepositoryId)) { Logger.LogRequest(requestContext, pushNotification, repository); var validationResults = policy.CheckRules(requestContext, pushNotification, repository); //TODO accumulate failures var failsAt = validationResults.FirstOrDefault(v => v.Fails); if (failsAt != null) { if (PluginConfiguration.Instance.ShouldSendEmail) { try { string email = GetEmailAddress(requestContext, pushNotification); if (string.IsNullOrWhiteSpace(email)) // no email for user -> notify admin email = PluginConfiguration.Instance.AdministratorEmail; UserAlerter.InformUserOfFailure(email, requestContext, pushNotification, validationResults); } catch (Exception e) { Logger.Log(string.Format("Error: failed to notify user {0}, reason {1}", pushNotification.AuthenticatedUserName, e.Message)); }//try }//if Logger.LogDenied(failsAt.ReasonMessage); statusCode = failsAt.ReasonCode; statusMessage = failsAt.ReasonMessage; return EventNotificationStatus.ActionDenied; }//if }//using }//if }//if } catch (Exception ex) { Logger.LogException(ex); throw; // TFS will disable plugin }//try /* * from https://msdn.microsoft.com/en-us/library/Gg214903%28v=vs.120%29.aspx * ActionDenied Action denied; do not notify other subscribers. * ActionPermitted Action permitted; continue with subscriber notification. * ActionApproved Like ActionPermitted, but do not notify other subscribers. */ return EventNotificationStatus.ActionPermitted; }