Skip to content

Commit c569239

Browse files
committed
💣 flavour-specific options functionality done (... and let's see later on if it works)
1 parent 51b7768 commit c569239

8 files changed

+68
-42
lines changed

‎jwl.core/AppConfigFactory.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,22 @@ public static AppConfig ReadConfig()
6767

6868
result!.JiraServer.FlavourOptions = flavour switch
6969
{
70+
JiraServerFlavour.Vanilla => flavourConfig.Get<VanillaJiraFlavourOptions>(opt =>
71+
{
72+
opt.BindNonPublicProperties = false;
73+
opt.ErrorOnUnknownConfiguration = true;
74+
}),
75+
JiraServerFlavour.TempoTimeSheets => flavourConfig.Get<TempoTimesheetsFlavourOptions>(opt =>
76+
{
77+
opt.BindNonPublicProperties = false;
78+
opt.ErrorOnUnknownConfiguration = true;
79+
}),
7080
JiraServerFlavour.ICTime => flavourConfig.Get<ICTimeFlavourOptions>(opt =>
7181
{
7282
opt.BindNonPublicProperties = false;
7383
opt.ErrorOnUnknownConfiguration = true;
7484
}),
75-
JiraServerFlavour.Vanilla or JiraServerFlavour.TempoTimeSheets => null,
76-
_ => throw new ArgumentOutOfRangeException(nameof(result.JiraServer.Flavour))
85+
_ => throw new ArgumentOutOfRangeException(nameof(result.JiraServer.Flavour), $"Don't know how to read flavour {flavour} specific options config")
7786
};
7887
}
7988

‎jwl.jira/Flavours/IFlavourOptions.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,4 @@
33
public interface IFlavourOptions
44
{
55
string PluginBaseUri { get; init; }
6-
string DateFormat { get; init; }
7-
string TimeSpanFormat { get; init; }
86
}

‎jwl.jira/Flavours/JiraWithICTimePluginApi.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,19 @@
11
namespace jwl.jira;
22

3-
using System.Diagnostics;
43
using System.Globalization;
5-
using System.Net.Http.Json;
6-
using System.Xml.Linq;
74
using System.Xml.Serialization;
85
using jwl.infra;
96
using jwl.jira.api.rest.request;
107
using jwl.jira.Flavours;
118
using jwl.wadl;
129

1310
// https://interconcept.atlassian.net/wiki/spaces/ICTIME/pages/31686672/API
14-
// https://interconcept.atlassian.net/wiki/spaces/ICBIZ/pages/34701333/REST+Services
1511
public class JiraWithICTimePluginApi
1612
: IJiraClient
1713
{
1814
public string UserName { get; }
1915
public api.rest.common.JiraUserInfo UserInfo => _vanillaJiraApi.UserInfo;
2016

21-
public string PluginBaseUri { get; } = "rest/ictime/1.0";
2217
public Lazy<Dictionary<string, wadl.ComposedWadlMethodDefinition>> Endpoints =>
2318
new Lazy<Dictionary<string, ComposedWadlMethodDefinition>>(() => this.GetWADL().Result
2419
.AsEnumerable()
@@ -42,7 +37,7 @@ public JiraWithICTimePluginApi(HttpClient httpClient, string userName, ICTimeFla
4237
_httpClient = httpClient;
4338
UserName = userName;
4439
_flavourOptions = flavourOptions ?? _defaultFlavourOptions;
45-
_vanillaJiraApi = new VanillaJiraClient(httpClient, userName);
40+
_vanillaJiraApi = new VanillaJiraClient(httpClient, userName, null);
4641
}
4742

4843
public async Task<WorkLogType[]> GetAvailableActivities(string issueKey)
@@ -213,7 +208,7 @@ public async Task UpdateWorkLog(string issueKey, long worklogId, DateOnly day, i
213208

214209
private async Task<WadlApplication> GetWADL()
215210
{
216-
Uri uri = new Uri($"{PluginBaseUri}/application.wadl", UriKind.Relative);
211+
Uri uri = new Uri($"{_flavourOptions.PluginBaseUri}/application.wadl", UriKind.Relative);
217212
using Stream response = await _httpClient.GetStreamAsync(uri);
218213
if (response == null || response.Length <= 0)
219214
throw new HttpRequestException($"Empty content received from ${uri}");

‎jwl.jira/Flavours/JiraWithTempoPluginApi.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ namespace jwl.jira;
22
using System.Net.Http.Json;
33
using jwl.infra;
44
using jwl.jira.api.rest.common;
5+
using jwl.jira.Flavours;
56
using NoP77svk.Linq;
67

78
// https://www.tempo.io/server-api-documentation/timesheets
@@ -11,21 +12,23 @@ public class JiraWithTempoPluginApi
1112
private const string WorklogTypeAttributeKey = @"_WorklogType_";
1213

1314
private readonly HttpClient _httpClient;
15+
private readonly TempoTimesheetsFlavourOptions _flavourOptions;
1416
private readonly VanillaJiraClient _vanillaJiraApi;
1517

1618
public string UserName { get; }
1719
public api.rest.common.JiraUserInfo UserInfo => _vanillaJiraApi.UserInfo;
1820

19-
public JiraWithTempoPluginApi(HttpClient httpClient, string userName)
21+
public JiraWithTempoPluginApi(HttpClient httpClient, string userName, TempoTimesheetsFlavourOptions? flavourOptions)
2022
{
2123
_httpClient = httpClient;
2224
UserName = userName;
23-
_vanillaJiraApi = new VanillaJiraClient(httpClient, userName);
25+
_flavourOptions = flavourOptions ?? new TempoTimesheetsFlavourOptions();
26+
_vanillaJiraApi = new VanillaJiraClient(httpClient, userName, null);
2427
}
2528

2629
public async Task<api.rest.response.TempoWorklogAttributeDefinition[]> GetWorklogAttributeDefinitions()
2730
{
28-
return await _httpClient.GetAsJsonAsync<api.rest.response.TempoWorklogAttributeDefinition[]>(@"rest/tempo-core/1/work-attribute");
31+
return await _httpClient.GetAsJsonAsync<api.rest.response.TempoWorklogAttributeDefinition[]>($"{_flavourOptions.PluginCoreUri}/work-attribute");
2932
}
3033

3134
public async Task<WorkLogType[]> GetAvailableActivities(string issueKey)
@@ -77,7 +80,7 @@ public async Task<WorkLog[]> GetIssueWorkLogs(DateOnly from, DateOnly to, IEnume
7780
IssueKey = issueKeys?.ToArray(),
7881
UserKey = new string[] { userKey }
7982
};
80-
var response = await _httpClient.PostAsJsonAsync(@"rest/tempo-timesheets/4/worklogs/search", request);
83+
var response = await _httpClient.PostAsJsonAsync($"{_flavourOptions.PluginBaseUri}/worklogs/search", request);
8184
var tempoWorkLogs = await HttpClientJsonExt.DeserializeJsonStreamAsync<api.rest.response.TempoWorklog[]>(await response.Content.ReadAsStreamAsync());
8285

8386
var result = tempoWorkLogs
@@ -129,15 +132,15 @@ public async Task AddWorkLogPeriod(string issueKey, DateOnly dayFrom, DateOnly d
129132
}
130133
};
131134

132-
HttpResponseMessage response = await _httpClient.PostAsJsonAsync(@"rest/tempo-timesheets/4/worklogs", request);
135+
HttpResponseMessage response = await _httpClient.PostAsJsonAsync($"{_flavourOptions.PluginBaseUri}/worklogs", request);
133136
await VanillaJiraClient.CheckHttpResponseForErrorMessages(response);
134137
}
135138

136139
public async Task DeleteWorkLog(long issueId, long worklogId, bool notifyUsers = false)
137140
{
138141
UriBuilder uriBuilder = new UriBuilder()
139142
{
140-
Path = new UriPathBuilder(@"rest/tempo-timesheets/4/worklogs")
143+
Path = new UriPathBuilder($"{_flavourOptions.PluginBaseUri}/worklogs")
141144
.Add(worklogId.ToString())
142145
};
143146

@@ -154,7 +157,7 @@ private async Task UpdateWorklogPeriod(string issueKey, long worklogId, DateOnly
154157
{
155158
UriBuilder uriBuilder = new UriBuilder()
156159
{
157-
Path = new UriPathBuilder(@"rest/tempo-timesheets/4/worklogs")
160+
Path = new UriPathBuilder($"{_flavourOptions.PluginBaseUri}/worklogs")
158161
.Add(worklogId.ToString())
159162
};
160163
var request = new api.rest.request.TempoUpdateWorklog()

‎jwl.jira/Flavours/ServerApiFactory.cs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,36 @@
22

33
public static class ServerApiFactory
44
{
5-
public static IJiraClient CreateApi(HttpClient httpClient, string userName, JiraServerFlavour serverClass, object? flavourOptions)
5+
public static IJiraClient CreateApi(HttpClient httpClient, string userName, JiraServerFlavour serverFlavour, IFlavourOptions? flavourOptions)
66
{
7-
return serverClass switch
7+
try
88
{
9-
JiraServerFlavour.Vanilla => new VanillaJiraClient(httpClient, userName),
10-
JiraServerFlavour.TempoTimeSheets => new JiraWithTempoPluginApi(httpClient, userName),
11-
JiraServerFlavour.ICTime => new JiraWithICTimePluginApi(
12-
httpClient,
13-
userName,
14-
flavourOptions is ICTimeFlavourOptions opt ? opt : throw new ArgumentOutOfRangeException(nameof(flavourOptions), "Unexpected flavour options class")
15-
),
16-
_ => throw new NotImplementedException($"Jira server class {nameof(serverClass)} not yet implemented")
17-
};
9+
return serverFlavour switch
10+
{
11+
JiraServerFlavour.Vanilla => new VanillaJiraClient(httpClient, userName, (VanillaJiraFlavourOptions?)flavourOptions),
12+
JiraServerFlavour.TempoTimeSheets => new JiraWithTempoPluginApi(httpClient, userName, (TempoTimesheetsFlavourOptions?)flavourOptions),
13+
JiraServerFlavour.ICTime => new JiraWithICTimePluginApi(httpClient, userName, (ICTimeFlavourOptions?)flavourOptions),
14+
_ => throw new NotImplementedException($"Jira server flavour {nameof(serverFlavour)} not yet implemented")
15+
};
16+
}
17+
catch (InvalidCastException ex)
18+
{
19+
throw new ArgumentOutOfRangeException($"Don't know how to instantiate client API for flavour {serverFlavour}", ex);
20+
}
1821
}
1922

20-
public static JiraServerFlavour? DecodeServerClass(string? serverClass)
23+
public static JiraServerFlavour? DecodeServerClass(string? serverFlavour)
2124
{
2225
JiraServerFlavour? result;
2326

24-
if (string.IsNullOrEmpty(serverClass))
27+
if (string.IsNullOrEmpty(serverFlavour))
2528
result = null;
26-
else if (int.TryParse(serverClass, out int serverClassIntId))
27-
result = (JiraServerFlavour)serverClassIntId;
28-
else if (Enum.TryParse(serverClass, true, out JiraServerFlavour serverClassEnumId))
29-
result = serverClassEnumId;
29+
else if (int.TryParse(serverFlavour, out int serverFlavourIntId))
30+
result = (JiraServerFlavour)serverFlavourIntId;
31+
else if (Enum.TryParse(serverFlavour, true, out JiraServerFlavour serverFlavourEnumId))
32+
result = serverFlavourEnumId;
3033
else
31-
throw new ArgumentOutOfRangeException(nameof(serverClass), serverClass, "Invalid server class configured");
34+
throw new ArgumentOutOfRangeException(nameof(serverFlavour), serverFlavour, "Invalid server flavour configured");
3235

3336
return result;
3437
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace jwl.jira.Flavours;
2+
3+
public class TempoTimesheetsFlavourOptions
4+
: IFlavourOptions
5+
{
6+
public string PluginBaseUri { get; init; } = @"rest/tempo-timesheets/4";
7+
public string PluginCoreUri { get; init; } = @"rest/tempo-core/1";
8+
}

‎jwl.jira/Flavours/VanillaJiraClient.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace jwl.jira;
66
using System.Text;
77
using jwl.infra;
88
using jwl.jira.api.rest.response;
9+
using jwl.jira.Flavours;
910

1011
public class VanillaJiraClient
1112
: IJiraClient
@@ -15,12 +16,14 @@ public class VanillaJiraClient
1516

1617
private readonly HttpClient _httpClient;
1718
private readonly Lazy<jwl.jira.api.rest.common.JiraUserInfo> _lazyUserInfo;
19+
private readonly VanillaJiraFlavourOptions _flavourOptions;
1820

19-
public VanillaJiraClient(HttpClient httpClient, string userName)
21+
public VanillaJiraClient(HttpClient httpClient, string userName, VanillaJiraFlavourOptions? flavourOptions)
2022
{
2123
_httpClient = httpClient;
2224
UserName = userName;
2325
_lazyUserInfo = new Lazy<api.rest.common.JiraUserInfo>(() => GetUserInfo().Result);
26+
_flavourOptions = flavourOptions ?? new VanillaJiraFlavourOptions();
2427
}
2528

2629
public static async Task CheckHttpResponseForErrorMessages(HttpResponseMessage responseMessage)
@@ -60,7 +63,7 @@ public async Task<WorkLog[]> GetIssueWorkLogs(DateOnly from, DateOnly to, string
6063
{
6164
UriBuilder uriBuilder = new UriBuilder()
6265
{
63-
Path = new UriPathBuilder(@"rest/api/2/issue")
66+
Path = new UriPathBuilder($"{_flavourOptions.PluginBaseUri}/issue")
6467
.Add(issueKey)
6568
.Add(@"worklog")
6669
};
@@ -111,7 +114,7 @@ public async Task AddWorkLog(string issueKey, DateOnly day, int timeSpentSeconds
111114
{
112115
UriBuilder uriBuilder = new UriBuilder()
113116
{
114-
Path = new UriPathBuilder(@"rest/api/2/issue")
117+
Path = new UriPathBuilder($"{_flavourOptions.PluginBaseUri}/issue")
115118
.Add(issueKey)
116119
.Add(@"worklog")
117120
};
@@ -158,7 +161,7 @@ public async Task DeleteWorkLog(long issueId, long worklogId, bool notifyUsers =
158161
{
159162
UriBuilder uriBuilder = new UriBuilder()
160163
{
161-
Path = new UriPathBuilder(@"rest/api/2/issue")
164+
Path = new UriPathBuilder($"{_flavourOptions.PluginBaseUri}/issue")
162165
.Add(issueId.ToString())
163166
.Add(@"worklog")
164167
.Add(worklogId.ToString()),
@@ -174,7 +177,7 @@ public async Task UpdateWorkLog(string issueKey, long worklogId, DateOnly day, i
174177
{
175178
UriBuilder uriBuilder = new UriBuilder()
176179
{
177-
Path = new UriPathBuilder(@"rest/api/2/issue")
180+
Path = new UriPathBuilder($"{_flavourOptions.PluginBaseUri}/issue")
178181
.Add(issueKey)
179182
.Add(@"worklog")
180183
.Add(worklogId.ToString())
@@ -197,7 +200,7 @@ public async Task UpdateWorkLog(string issueKey, long worklogId, DateOnly day, i
197200
{
198201
UriBuilder uriBuilder = new UriBuilder()
199202
{
200-
Path = @"rest/api/2/user",
203+
Path = $"{_flavourOptions.PluginBaseUri}/user",
201204
Query = new UriQueryBuilder()
202205
.Add(@"username", UserName)
203206
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace jwl.jira.Flavours;
2+
3+
public class VanillaJiraFlavourOptions
4+
: IFlavourOptions
5+
{
6+
public string PluginBaseUri { get; init; } = @"rest/api/2";
7+
}

0 commit comments

Comments
 (0)