-
Notifications
You must be signed in to change notification settings - Fork 103
Expand file tree
/
Copy pathSimpleBugStrategy.cs
More file actions
223 lines (187 loc) · 8.68 KB
/
SimpleBugStrategy.cs
File metadata and controls
223 lines (187 loc) · 8.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using log4net;
using Mail2Bug.Email;
using Mail2Bug.Helpers;
using Mail2Bug.WorkItemManagement;
namespace Mail2Bug.MessageProcessingStrategies
{
public class SimpleBugStrategy : IMessageProcessingStrategy, IDisposable
{
private const int TfsTextFieldMaxLength = 255;
private readonly Config.InstanceConfig _config;
private readonly IWorkItemManager _workItemManager;
private readonly AckEmailHandler _ackEmailHandler;
private readonly MessageToWorkItemMapper _messageToWorkItemMapper;
public SimpleBugStrategy(Config.InstanceConfig config)
{
_config = config;
_workItemManager = InitWorkItemManager();
_ackEmailHandler = new AckEmailHandler(config);
_messageToWorkItemMapper =
new MessageToWorkItemMapper(
_config.EmailSettings.AppendOnlyEmailTitleRegex,
_config.EmailSettings.AppendOnlyEmailBodyRegex,
_workItemManager.WorkItemsCache);
}
public SimpleBugStrategy(Config.InstanceConfig config, IWorkItemManager WitManager)
{
_config = config;
_workItemManager = WitManager;
_ackEmailHandler = new AckEmailHandler(config);
_messageToWorkItemMapper =
new MessageToWorkItemMapper(
_config.EmailSettings.AppendOnlyEmailTitleRegex,
_config.EmailSettings.AppendOnlyEmailBodyRegex,
_workItemManager.WorkItemsCache);
}
public void ProcessInboxMessage(IIncomingEmailMessage message)
{
var workItemId = _messageToWorkItemMapper.GetWorkItemId(message);
if (!workItemId.HasValue) // thread not found, new work item
{
NewWorkItem(message);
return;
}
UpdateWorkItem(message, workItemId.Value);
}
private void NewWorkItem(IIncomingEmailMessage message)
{
var workItemUpdates = new Dictionary<string, string>();
InitWorkItemFields(message, workItemUpdates);
var workItemId = _workItemManager.CreateWorkItem(workItemUpdates);
Logger.InfoFormat("Added new work item {0} for message with subject: {1} (conversation index:{2})",
workItemId, message.Subject, message.ConversationId);
try
{
// Since the work item *has* been created, failures in this stage are not treated as critical
var overrides = new OverridesExtractor(_config).GetOverrides(message);
TryApplyFieldOverrides(overrides, workItemId);
ProcessAttachments(message, workItemId);
if (_config.WorkItemSettings.AttachOriginalMessage)
{
AttachMessageToWorkItem(message, workItemId, "OriginalMessage");
}
}
catch (Exception ex)
{
Logger.ErrorFormat("Exception caught while applying settings to work item {0}\n{1}", workItemId, ex);
}
var workItem = _workItemManager.GetWorkItemFields(workItemId);
_ackEmailHandler.SendAckEmail(message, workItem);
}
private void AttachMessageToWorkItem(IIncomingEmailMessage message, int workItemId, string prefix)
{
using (var tfc = new TempFileCollection())
{
var fileName = string.Format("{0}_{1}_{2}.eml", prefix, DateTime.Now.ToString("yyyyMMdd_hhmmss"), new Random().Next());
var filePath = Path.Combine(Path.GetTempPath(), fileName);
message.SaveToFile(filePath);
// Remove the file once we're done attaching it
tfc.AddFile(filePath, false);
_workItemManager.AttachFiles(workItemId, new List<string> { filePath });
}
}
private void InitWorkItemFields(IIncomingEmailMessage message, Dictionary<string, string> workItemUpdates)
{
var resolver = new SpecialValueResolver(message, _workItemManager.GetNameResolver());
workItemUpdates["Title"] = resolver.Subject;
var rawConversationIndex = message.ConversationId;
workItemUpdates[_config.WorkItemSettings.ConversationIndexFieldName] =
rawConversationIndex.Substring(0, Math.Min(rawConversationIndex.Length, TfsTextFieldMaxLength));
foreach (var defaultFieldValue in _config.WorkItemSettings.DefaultFieldValues)
{
workItemUpdates[defaultFieldValue.Field] = resolver.Resolve(defaultFieldValue.Value);
}
}
private void TryApplyFieldOverrides(Dictionary<string, string> overrides, int workItemId)
{
if (overrides.Count == 0)
{
Logger.DebugFormat("No overrides found. Skipping applying overrides.");
return;
}
try
{
Logger.DebugFormat("Overrides found. Calling 'ModifyWorkItem'");
_workItemManager.ModifyWorkItem(workItemId, "", overrides);
}
catch (Exception ex)
{
Logger.ErrorFormat("Exception caught while trying to apply overrides to work item {0}. Overrides: {1}\n{2}",
workItemId, overrides, ex);
}
}
private void UpdateWorkItem(IIncomingEmailMessage message, int workItemId)
{
Logger.InfoFormat("Modifying work item {0} subject: {1}", workItemId, message.Subject);
var resolver = new SpecialValueResolver(message, _workItemManager.GetNameResolver());
var workItemUpdates = new Dictionary<string, string>();
if (_config.WorkItemSettings.OverrideChangedBy)
{
workItemUpdates["Changed By"] = resolver.Sender;
}
if (_config.WorkItemSettings.ApplyOverridesDuringUpdate)
{
var extractor = new OverridesExtractor(_config);
var overrides = extractor.GetOverrides(message.GetLastMessageText());
Logger.DebugFormat("Found {0} overrides for update message", overrides.Count);
overrides.ToList().ForEach(x => workItemUpdates[x.Key] = x.Value);
}
// Construct the text to be appended
_workItemManager.ModifyWorkItem(workItemId, message.GetLastMessageText(), workItemUpdates);
ProcessAttachments(message, workItemId);
if (_config.WorkItemSettings.AttachUpdateMessages)
{
AttachMessageToWorkItem(message, workItemId, "ReplyMessage");
}
}
private void ProcessAttachments(IIncomingEmailMessage message, int workItemId)
{
var attachmentFiles = SaveAttachments(message);
_workItemManager.AttachFiles(workItemId, (from object file in attachmentFiles select file.ToString()).ToList());
attachmentFiles.Delete();
}
/// <summary>
/// Take attachments from the current mail message and put them in a work item
/// </summary>
/// <param name="message"></param>
private static TempFileCollection SaveAttachments(IIncomingEmailMessage message)
{
var attachmentFiles = new TempFileCollection();
foreach (var attachment in message.Attachments)
{
var filename = attachment.SaveAttachmentToFile();
if (filename != null)
{
attachmentFiles.AddFile(filename, false);
Logger.InfoFormat("Attachment saved to file {0}", filename);
}
}
return attachmentFiles;
}
private IWorkItemManager InitWorkItemManager() {
IWorkItemManager workItemManager;
if (_config.TfsServerConfig.SimulationMode)
{
Logger.InfoFormat("Working in simulation mode. Using WorkItemManagerMock");
workItemManager = new WorkItemManagerMock(_config.WorkItemSettings.ConversationIndexFieldName);
}
else
{
Logger.InfoFormat("Working in standard mode, using TFSWorkItemManager");
workItemManager = new TFSWorkItemManager(_config);
}
return workItemManager;
}
private static readonly ILog Logger = LogManager.GetLogger(typeof(SimpleBugStrategy));
public void Dispose()
{
DisposeUtils.DisposeIfDisposable(_workItemManager);
}
}
}