Showing
3 changed files
with
83 additions
and
56 deletions
1 | +package pl.com.it_crowd.youtrack.api; | |
2 | + | |
3 | +import java.net.URI; | |
4 | +import java.net.URISyntaxException; | |
5 | + | |
6 | +public class URIUtils { | |
7 | +// -------------------------- STATIC METHODS -------------------------- | |
8 | + | |
9 | + public static URI buildURI(URI base, String path) | |
10 | + { | |
11 | + return buildURI(base, path, null); | |
12 | + } | |
13 | + | |
14 | + public static URI buildURI(URI base, String path, String query) | |
15 | + { | |
16 | + try { | |
17 | + return new URI(base.getScheme(), base.getHost(), base.getPath().replaceAll("/+$", "") + path, query, null); | |
18 | + } catch (URISyntaxException e) { | |
19 | + throw new RuntimeException(e); | |
20 | + } | |
21 | + } | |
22 | +} | |
... | ... |
1 | 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 | 5 | import org.apache.http.Header; |
4 | 6 | import org.apache.http.HttpEntity; |
5 | 7 | import org.apache.http.HttpHeaders; |
... | ... | @@ -17,7 +19,6 @@ import org.apache.http.client.methods.HttpGet; |
17 | 19 | import org.apache.http.client.methods.HttpPost; |
18 | 20 | import org.apache.http.client.methods.HttpPut; |
19 | 21 | import org.apache.http.client.methods.HttpUriRequest; |
20 | -import org.apache.http.client.utils.URIBuilder; | |
21 | 22 | import org.apache.http.conn.ClientConnectionManager; |
22 | 23 | import org.apache.http.conn.scheme.Scheme; |
23 | 24 | import org.apache.http.conn.scheme.SchemeRegistry; |
... | ... | @@ -60,6 +61,8 @@ import java.util.List; |
60 | 61 | import java.util.regex.Matcher; |
61 | 62 | import java.util.regex.Pattern; |
62 | 63 | |
64 | +import static pl.com.it_crowd.youtrack.api.URIUtils.buildURI; | |
65 | + | |
63 | 66 | public class YoutrackAPI { |
64 | 67 | // ------------------------------ FIELDS ------------------------------ |
65 | 68 | |
... | ... | @@ -67,10 +70,14 @@ public class YoutrackAPI { |
67 | 70 | |
68 | 71 | private final static QName Issue_QNAME = new QName("", "issue"); |
69 | 72 | |
73 | + private static Log LOG = LogFactory.getLog(YoutrackAPI.class); | |
74 | + | |
70 | 75 | private HttpClient httpClient; |
71 | 76 | |
72 | 77 | private String serviceLocation; |
73 | 78 | |
79 | + private URI serviceLocationURI; | |
80 | + | |
74 | 81 | // -------------------------- STATIC METHODS -------------------------- |
75 | 82 | |
76 | 83 | private static HttpClient getDefaultHttpClient() |
... | ... | @@ -134,7 +141,15 @@ public class YoutrackAPI { |
134 | 141 | |
135 | 142 | public YoutrackAPI(String serviceLocation, HttpClient httpClient) |
136 | 143 | { |
144 | + if (serviceLocation == null) { | |
145 | + throw new IllegalArgumentException("serviceLocation cannot be null"); | |
146 | + } | |
137 | 147 | this.serviceLocation = serviceLocation; |
148 | + try { | |
149 | + serviceLocationURI = new URI(this.serviceLocation); | |
150 | + } catch (URISyntaxException e) { | |
151 | + throw new RuntimeException(e); | |
152 | + } | |
138 | 153 | this.httpClient = httpClient == null ? getDefaultHttpClient() : httpClient; |
139 | 154 | } |
140 | 155 | |
... | ... | @@ -170,7 +185,7 @@ public class YoutrackAPI { |
170 | 185 | |
171 | 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 | 189 | final List<BasicNameValuePair> parameters = new ArrayList<BasicNameValuePair>(); |
175 | 190 | parameters.add(new BasicNameValuePair("command", command)); |
176 | 191 | if (!isBlank(comment)) { |
... | ... | @@ -202,14 +217,8 @@ public class YoutrackAPI { |
202 | 217 | */ |
203 | 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 | 222 | final HttpResponse response = httpClient.execute(request); |
214 | 223 | final StatusLine statusLine = response.getStatusLine(); |
215 | 224 | final HttpEntity entity = response.getEntity(); |
... | ... | @@ -230,24 +239,12 @@ public class YoutrackAPI { |
230 | 239 | |
231 | 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 | 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 | 248 | final Object result = YoutrackUnmarshaller.unmarshall(responseString); |
252 | 249 | if (result instanceof AssigneeList) { |
253 | 250 | return (AssigneeList) result; |
... | ... | @@ -258,13 +255,7 @@ public class YoutrackAPI { |
258 | 255 | |
259 | 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 | 259 | if (result instanceof Enumeration) { |
269 | 260 | return (Enumeration) result; |
270 | 261 | } else if (result instanceof JAXBElement) { |
... | ... | @@ -281,13 +272,7 @@ public class YoutrackAPI { |
281 | 272 | |
282 | 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 | 276 | final Object result = YoutrackUnmarshaller.unmarshall(responseString); |
292 | 277 | if (result instanceof UserRefs) { |
293 | 278 | return ((UserRefs) result).getUsers(); |
... | ... | @@ -298,15 +283,9 @@ public class YoutrackAPI { |
298 | 283 | |
299 | 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 | 286 | final String responseString; |
308 | 287 | try { |
309 | - responseString = execute(new HttpGet(uri)); | |
288 | + responseString = execute(new HttpGet(buildURI(serviceLocationURI, "/rest/issue/" + issueId))); | |
310 | 289 | } catch (YoutrackErrorException e) { |
311 | 290 | if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) { |
312 | 291 | throw new NoResultFoundException(e.getMessage(), e); |
... | ... | @@ -331,15 +310,15 @@ public class YoutrackAPI { |
331 | 310 | |
332 | 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 | 314 | request.setEntity(new UrlEncodedFormEntity(Arrays.asList(new BasicNameValuePair("login", username), new BasicNameValuePair("password", password)))); |
336 | 315 | execute(request); |
337 | 316 | } |
338 | 317 | |
339 | 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 | 322 | if (!(result instanceof Issues)) { |
344 | 323 | throw new YoutrackAPIException("Unmarshalling problem. Expected Issues, received: " + result.getClass() + " " + result); |
345 | 324 | } |
... | ... | @@ -353,13 +332,7 @@ public class YoutrackAPI { |
353 | 332 | |
354 | 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 | 336 | new BasicNameValuePair(Fields.description.name(), description)); |
364 | 337 | final HttpResponse response = httpClient.execute(request); |
365 | 338 | final StatusLine statusLine = response.getStatusLine(); |
... | ... | @@ -389,7 +362,7 @@ public class YoutrackAPI { |
389 | 362 | final String error = ErrorUnmarshaller.unmarshal(responseText); |
390 | 363 | throw new YoutrackErrorException(error, statusLine.getStatusCode()); |
391 | 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 | 366 | throw new HttpResponseException(statusLine.getStatusCode(), responseText); |
394 | 367 | } |
395 | 368 | } |
... | ... |
1 | +package pl.com.it_crowd.youtrack.api.rest; | |
2 | + | |
3 | +import org.junit.Test; | |
4 | +import pl.com.it_crowd.youtrack.api.Filter; | |
5 | +import pl.com.it_crowd.youtrack.api.URIUtils; | |
6 | +import pl.com.it_crowd.youtrack.api.defaults.StateValues; | |
7 | + | |
8 | +import java.net.URI; | |
9 | +import java.net.URISyntaxException; | |
10 | + | |
11 | +import static org.junit.Assert.assertEquals; | |
12 | + | |
13 | +public class URIUtilsTest { | |
14 | +// -------------------------- OTHER METHODS -------------------------- | |
15 | + | |
16 | + @Test | |
17 | + public void buildURI() throws URISyntaxException | |
18 | + { | |
19 | +// Given | |
20 | + final URI base = new URI("http://localhost:8080/youtrack/"); | |
21 | + final String pathA = "/rest/admin/bundle/QA note types"; | |
22 | + final String queryA = "q=" + Filter.stateFilter(StateValues.NotWontFix).maxResults(20); | |
23 | + | |
24 | +// When | |
25 | + final URI uriA = URIUtils.buildURI(base, pathA); | |
26 | + final URI uriB = URIUtils.buildURI(base, pathA, queryA); | |
27 | + | |
28 | +// Then | |
29 | + assertEquals("http://localhost/youtrack/rest/admin/bundle/QA%20note%20types", uriA.toString()); | |
30 | + assertEquals("http://localhost/youtrack/rest/admin/bundle/QA%20note%20types?q=state:-%257BWon%2527t+fix%257D&max=20", uriB.toString()); | |
31 | + } | |
32 | +} | |
... | ... |
Please
register
or
login
to post a comment