1
|
package pl.com.it_crowd.youtrack.api;
|
1
|
package pl.com.it_crowd.youtrack.api;
|
2
|
|
2
|
|
|
|
3
|
+import org.apache.commons.logging.Log;
|
|
|
4
|
+import org.apache.commons.logging.LogFactory;
|
3
|
import org.apache.http.Header;
|
5
|
import org.apache.http.Header;
|
4
|
import org.apache.http.HttpEntity;
|
6
|
import org.apache.http.HttpEntity;
|
5
|
import org.apache.http.HttpHeaders;
|
7
|
import org.apache.http.HttpHeaders;
|
|
@@ -17,7 +19,6 @@ import org.apache.http.client.methods.HttpGet; |
|
@@ -17,7 +19,6 @@ import org.apache.http.client.methods.HttpGet; |
17
|
import org.apache.http.client.methods.HttpPost;
|
19
|
import org.apache.http.client.methods.HttpPost;
|
18
|
import org.apache.http.client.methods.HttpPut;
|
20
|
import org.apache.http.client.methods.HttpPut;
|
19
|
import org.apache.http.client.methods.HttpUriRequest;
|
21
|
import org.apache.http.client.methods.HttpUriRequest;
|
20
|
-import org.apache.http.client.utils.URIBuilder;
|
|
|
21
|
import org.apache.http.conn.ClientConnectionManager;
|
22
|
import org.apache.http.conn.ClientConnectionManager;
|
22
|
import org.apache.http.conn.scheme.Scheme;
|
23
|
import org.apache.http.conn.scheme.Scheme;
|
23
|
import org.apache.http.conn.scheme.SchemeRegistry;
|
24
|
import org.apache.http.conn.scheme.SchemeRegistry;
|
|
@@ -60,6 +61,8 @@ import java.util.List; |
|
@@ -60,6 +61,8 @@ import java.util.List; |
60
|
import java.util.regex.Matcher;
|
61
|
import java.util.regex.Matcher;
|
61
|
import java.util.regex.Pattern;
|
62
|
import java.util.regex.Pattern;
|
62
|
|
63
|
|
|
|
64
|
+import static pl.com.it_crowd.youtrack.api.URIUtils.buildURI;
|
|
|
65
|
+
|
63
|
public class YoutrackAPI {
|
66
|
public class YoutrackAPI {
|
64
|
// ------------------------------ FIELDS ------------------------------
|
67
|
// ------------------------------ FIELDS ------------------------------
|
65
|
|
68
|
|
|
@@ -67,10 +70,14 @@ public class YoutrackAPI { |
|
@@ -67,10 +70,14 @@ public class YoutrackAPI { |
67
|
|
70
|
|
68
|
private final static QName Issue_QNAME = new QName("", "issue");
|
71
|
private final static QName Issue_QNAME = new QName("", "issue");
|
69
|
|
72
|
|
|
|
73
|
+ private static Log LOG = LogFactory.getLog(YoutrackAPI.class);
|
|
|
74
|
+
|
70
|
private HttpClient httpClient;
|
75
|
private HttpClient httpClient;
|
71
|
|
76
|
|
72
|
private String serviceLocation;
|
77
|
private String serviceLocation;
|
73
|
|
78
|
|
|
|
79
|
+ private URI serviceLocationURI;
|
|
|
80
|
+
|
74
|
// -------------------------- STATIC METHODS --------------------------
|
81
|
// -------------------------- STATIC METHODS --------------------------
|
75
|
|
82
|
|
76
|
private static HttpClient getDefaultHttpClient()
|
83
|
private static HttpClient getDefaultHttpClient()
|
|
@@ -134,7 +141,15 @@ public class YoutrackAPI { |
|
@@ -134,7 +141,15 @@ public class YoutrackAPI { |
134
|
|
141
|
|
135
|
public YoutrackAPI(String serviceLocation, HttpClient httpClient)
|
142
|
public YoutrackAPI(String serviceLocation, HttpClient httpClient)
|
136
|
{
|
143
|
{
|
|
|
144
|
+ if (serviceLocation == null) {
|
|
|
145
|
+ throw new IllegalArgumentException("serviceLocation cannot be null");
|
|
|
146
|
+ }
|
137
|
this.serviceLocation = serviceLocation;
|
147
|
this.serviceLocation = serviceLocation;
|
|
|
148
|
+ try {
|
|
|
149
|
+ serviceLocationURI = new URI(this.serviceLocation);
|
|
|
150
|
+ } catch (URISyntaxException e) {
|
|
|
151
|
+ throw new RuntimeException(e);
|
|
|
152
|
+ }
|
138
|
this.httpClient = httpClient == null ? getDefaultHttpClient() : httpClient;
|
153
|
this.httpClient = httpClient == null ? getDefaultHttpClient() : httpClient;
|
139
|
}
|
154
|
}
|
140
|
|
155
|
|
|
@@ -170,7 +185,7 @@ public class YoutrackAPI { |
|
@@ -170,7 +185,7 @@ public class YoutrackAPI { |
170
|
|
185
|
|
171
|
public void command(String issueId, String command, String comment, String group, Boolean disableNotifications, String runAs) throws IOException
|
186
|
public void command(String issueId, String command, String comment, String group, Boolean disableNotifications, String runAs) throws IOException
|
172
|
{
|
187
|
{
|
173
|
- final HttpPost request = new HttpPost(serviceLocation + "/rest/issue/" + issueId + "/execute");
|
188
|
+ final HttpPost request = new HttpPost(buildURI(serviceLocationURI, "/rest/issue/" + issueId + "/execute"));
|
174
|
final List<BasicNameValuePair> parameters = new ArrayList<BasicNameValuePair>();
|
189
|
final List<BasicNameValuePair> parameters = new ArrayList<BasicNameValuePair>();
|
175
|
parameters.add(new BasicNameValuePair("command", command));
|
190
|
parameters.add(new BasicNameValuePair("command", command));
|
176
|
if (!isBlank(comment)) {
|
191
|
if (!isBlank(comment)) {
|
|
@@ -202,14 +217,8 @@ public class YoutrackAPI { |
|
@@ -202,14 +217,8 @@ public class YoutrackAPI { |
202
|
*/
|
217
|
*/
|
203
|
public String createIssue(String project, String summary, String description) throws IOException
|
218
|
public String createIssue(String project, String summary, String description) throws IOException
|
204
|
{
|
219
|
{
|
205
|
- final URI uri;
|
|
|
206
|
- try {
|
|
|
207
|
- uri = new URIBuilder(serviceLocation + "/rest/issue").build();
|
|
|
208
|
- } catch (URISyntaxException e) {
|
|
|
209
|
- throw new RuntimeException(e);
|
|
|
210
|
- }
|
|
|
211
|
- final HttpPut request = createPutRequest(uri, new BasicNameValuePair("project", project), new BasicNameValuePair("summary", summary),
|
|
|
212
|
- new BasicNameValuePair("description", description));
|
220
|
+ final HttpPut request = createPutRequest(buildURI(serviceLocationURI, "/rest/issue"), new BasicNameValuePair("project", project),
|
|
|
221
|
+ new BasicNameValuePair("summary", summary), new BasicNameValuePair("description", description));
|
213
|
final HttpResponse response = httpClient.execute(request);
|
222
|
final HttpResponse response = httpClient.execute(request);
|
214
|
final StatusLine statusLine = response.getStatusLine();
|
223
|
final StatusLine statusLine = response.getStatusLine();
|
215
|
final HttpEntity entity = response.getEntity();
|
224
|
final HttpEntity entity = response.getEntity();
|
|
@@ -230,24 +239,12 @@ public class YoutrackAPI { |
|
@@ -230,24 +239,12 @@ public class YoutrackAPI { |
230
|
|
239
|
|
231
|
public void deleteIssue(String issueId) throws IOException
|
240
|
public void deleteIssue(String issueId) throws IOException
|
232
|
{
|
241
|
{
|
233
|
- final URI uri;
|
|
|
234
|
- try {
|
|
|
235
|
- uri = new URIBuilder(serviceLocation + "/rest/issue/" + issueId).build();
|
|
|
236
|
- } catch (URISyntaxException e) {
|
|
|
237
|
- throw new RuntimeException(e);
|
|
|
238
|
- }
|
|
|
239
|
- execute(new HttpDelete(uri));
|
242
|
+ execute(new HttpDelete(buildURI(serviceLocationURI, "/rest/issue/" + issueId)));
|
240
|
}
|
243
|
}
|
241
|
|
244
|
|
242
|
public AssigneeList getAssignees(String project) throws IOException, JAXBException
|
245
|
public AssigneeList getAssignees(String project) throws IOException, JAXBException
|
243
|
{
|
246
|
{
|
244
|
- final URI uri;
|
|
|
245
|
- try {
|
|
|
246
|
- uri = new URIBuilder(serviceLocation + "/rest/admin/project/" + project + "/assignee").build();
|
|
|
247
|
- } catch (URISyntaxException e) {
|
|
|
248
|
- throw new RuntimeException(e);
|
|
|
249
|
- }
|
|
|
250
|
- final String responseString = execute(new HttpGet(uri));
|
247
|
+ final String responseString = execute(new HttpGet(buildURI(serviceLocationURI, "/rest/admin/project/" + project + "/assignee")));
|
251
|
final Object result = YoutrackUnmarshaller.unmarshall(responseString);
|
248
|
final Object result = YoutrackUnmarshaller.unmarshall(responseString);
|
252
|
if (result instanceof AssigneeList) {
|
249
|
if (result instanceof AssigneeList) {
|
253
|
return (AssigneeList) result;
|
250
|
return (AssigneeList) result;
|
|
@@ -258,13 +255,7 @@ public class YoutrackAPI { |
|
@@ -258,13 +255,7 @@ public class YoutrackAPI { |
258
|
|
255
|
|
259
|
public Enumeration getBundle(String customField) throws IOException, JAXBException
|
256
|
public Enumeration getBundle(String customField) throws IOException, JAXBException
|
260
|
{
|
257
|
{
|
261
|
- final URI uri;
|
|
|
262
|
- try {
|
|
|
263
|
- uri = new URIBuilder(serviceLocation + "/rest/admin/customfield/bundle/" + customField).build();
|
|
|
264
|
- } catch (URISyntaxException e) {
|
|
|
265
|
- throw new RuntimeException(e);
|
|
|
266
|
- }
|
|
|
267
|
- final Object result = YoutrackUnmarshaller.unmarshall(execute(new HttpGet(uri)));
|
258
|
+ final Object result = YoutrackUnmarshaller.unmarshall(execute(new HttpGet(buildURI(serviceLocationURI, "/rest/admin/customfield/bundle/" + customField))));
|
268
|
if (result instanceof Enumeration) {
|
259
|
if (result instanceof Enumeration) {
|
269
|
return (Enumeration) result;
|
260
|
return (Enumeration) result;
|
270
|
} else if (result instanceof JAXBElement) {
|
261
|
} else if (result instanceof JAXBElement) {
|
|
@@ -281,13 +272,7 @@ public class YoutrackAPI { |
|
@@ -281,13 +272,7 @@ public class YoutrackAPI { |
281
|
|
272
|
|
282
|
public List<User> getIndividualAssignees(String project) throws IOException, JAXBException
|
273
|
public List<User> getIndividualAssignees(String project) throws IOException, JAXBException
|
283
|
{
|
274
|
{
|
284
|
- final URI uri;
|
|
|
285
|
- try {
|
|
|
286
|
- uri = new URIBuilder(serviceLocation + "/rest/admin/project/" + project + "/assignee/individual").build();
|
|
|
287
|
- } catch (URISyntaxException e) {
|
|
|
288
|
- throw new RuntimeException(e);
|
|
|
289
|
- }
|
|
|
290
|
- final String responseString = execute(new HttpGet(uri));
|
275
|
+ final String responseString = execute(new HttpGet(buildURI(serviceLocationURI, "/rest/admin/project/" + project + "/assignee/individual")));
|
291
|
final Object result = YoutrackUnmarshaller.unmarshall(responseString);
|
276
|
final Object result = YoutrackUnmarshaller.unmarshall(responseString);
|
292
|
if (result instanceof UserRefs) {
|
277
|
if (result instanceof UserRefs) {
|
293
|
return ((UserRefs) result).getUsers();
|
278
|
return ((UserRefs) result).getUsers();
|
|
@@ -298,15 +283,9 @@ public class YoutrackAPI { |
|
@@ -298,15 +283,9 @@ public class YoutrackAPI { |
298
|
|
283
|
|
299
|
public IssueWrapper getIssue(String issueId) throws IOException, JAXBException
|
284
|
public IssueWrapper getIssue(String issueId) throws IOException, JAXBException
|
300
|
{
|
285
|
{
|
301
|
- final URI uri;
|
|
|
302
|
- try {
|
|
|
303
|
- uri = new URIBuilder(serviceLocation + "/rest/issue/" + issueId).build();
|
|
|
304
|
- } catch (URISyntaxException e) {
|
|
|
305
|
- throw new RuntimeException(e);
|
|
|
306
|
- }
|
|
|
307
|
final String responseString;
|
286
|
final String responseString;
|
308
|
try {
|
287
|
try {
|
309
|
- responseString = execute(new HttpGet(uri));
|
288
|
+ responseString = execute(new HttpGet(buildURI(serviceLocationURI, "/rest/issue/" + issueId)));
|
310
|
} catch (YoutrackErrorException e) {
|
289
|
} catch (YoutrackErrorException e) {
|
311
|
if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
|
290
|
if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
|
312
|
throw new NoResultFoundException(e.getMessage(), e);
|
291
|
throw new NoResultFoundException(e.getMessage(), e);
|
|
@@ -331,15 +310,15 @@ public class YoutrackAPI { |
|
@@ -331,15 +310,15 @@ public class YoutrackAPI { |
331
|
|
310
|
|
332
|
public void login(String username, String password) throws IOException, JAXBException
|
311
|
public void login(String username, String password) throws IOException, JAXBException
|
333
|
{
|
312
|
{
|
334
|
- final HttpPost request = new HttpPost(serviceLocation + "/rest/user/login");
|
313
|
+ final HttpPost request = new HttpPost(buildURI(serviceLocationURI, "/rest/user/login"));
|
335
|
request.setEntity(new UrlEncodedFormEntity(Arrays.asList(new BasicNameValuePair("login", username), new BasicNameValuePair("password", password))));
|
314
|
request.setEntity(new UrlEncodedFormEntity(Arrays.asList(new BasicNameValuePair("login", username), new BasicNameValuePair("password", password))));
|
336
|
execute(request);
|
315
|
execute(request);
|
337
|
}
|
316
|
}
|
338
|
|
317
|
|
339
|
public List<IssueWrapper> searchIssuesByProject(String project, Object filter) throws JAXBException, IOException
|
318
|
public List<IssueWrapper> searchIssuesByProject(String project, Object filter) throws JAXBException, IOException
|
340
|
{
|
319
|
{
|
341
|
- final String url = serviceLocation + "/rest/issue/byproject/" + project + "?filter=" + (filter == null ? "" : filter);
|
|
|
342
|
- final Object result = YoutrackUnmarshaller.unmarshall(execute(new HttpGet(url)));
|
320
|
+ final Object result = YoutrackUnmarshaller.unmarshall(
|
|
|
321
|
+ execute(new HttpGet(buildURI(serviceLocationURI, "/rest/issue/byproject/" + project, "filter=" + (filter == null ? "" : filter)))));
|
343
|
if (!(result instanceof Issues)) {
|
322
|
if (!(result instanceof Issues)) {
|
344
|
throw new YoutrackAPIException("Unmarshalling problem. Expected Issues, received: " + result.getClass() + " " + result);
|
323
|
throw new YoutrackAPIException("Unmarshalling problem. Expected Issues, received: " + result.getClass() + " " + result);
|
345
|
}
|
324
|
}
|
|
@@ -353,13 +332,7 @@ public class YoutrackAPI { |
|
@@ -353,13 +332,7 @@ public class YoutrackAPI { |
353
|
|
332
|
|
354
|
public void updateIssue(String issueId, String summary, String description) throws IOException
|
333
|
public void updateIssue(String issueId, String summary, String description) throws IOException
|
355
|
{
|
334
|
{
|
356
|
- final URI uri;
|
|
|
357
|
- try {
|
|
|
358
|
- uri = new URIBuilder(serviceLocation + "/rest/issue/" + issueId).build();
|
|
|
359
|
- } catch (URISyntaxException e) {
|
|
|
360
|
- throw new RuntimeException(e);
|
|
|
361
|
- }
|
|
|
362
|
- final HttpPost request = createPostRequest(uri, new BasicNameValuePair(Fields.summary.name(), summary),
|
335
|
+ final HttpPost request = createPostRequest(buildURI(serviceLocationURI, "/rest/issue/" + issueId), new BasicNameValuePair(Fields.summary.name(), summary),
|
363
|
new BasicNameValuePair(Fields.description.name(), description));
|
336
|
new BasicNameValuePair(Fields.description.name(), description));
|
364
|
final HttpResponse response = httpClient.execute(request);
|
337
|
final HttpResponse response = httpClient.execute(request);
|
365
|
final StatusLine statusLine = response.getStatusLine();
|
338
|
final StatusLine statusLine = response.getStatusLine();
|
|
@@ -389,7 +362,7 @@ public class YoutrackAPI { |
|
@@ -389,7 +362,7 @@ public class YoutrackAPI { |
389
|
final String error = ErrorUnmarshaller.unmarshal(responseText);
|
362
|
final String error = ErrorUnmarshaller.unmarshal(responseText);
|
390
|
throw new YoutrackErrorException(error, statusLine.getStatusCode());
|
363
|
throw new YoutrackErrorException(error, statusLine.getStatusCode());
|
391
|
} catch (JAXBException e) {
|
364
|
} catch (JAXBException e) {
|
392
|
- // TODO we should log on debug level the JAXBException
|
365
|
+ LOG.error("Cannot unmarshal following response text:\n" + responseText, e);
|
393
|
throw new HttpResponseException(statusLine.getStatusCode(), responseText);
|
366
|
throw new HttpResponseException(statusLine.getStatusCode(), responseText);
|
394
|
}
|
367
|
}
|
395
|
}
|
368
|
}
|