diff options
author | Frank Becker | 2016-01-23 14:44:29 +0000 |
---|---|---|
committer | Gerrit Code Review @ Eclipse.org | 2016-02-11 04:08:15 +0000 |
commit | cc6f1b4b44f00e696f7f5aaecbedab9cd6baa869 (patch) | |
tree | 978fd88e534c50554a8d1f8d9db62c9b5a6e9aaf | |
parent | 8902a34bff4c8a8ccf6b80ff2401f05447d8e2e6 (diff) | |
download | org.eclipse.mylyn.tasks-cc6f1b4b44f00e696f7f5aaecbedab9cd6baa869.tar.gz org.eclipse.mylyn.tasks-cc6f1b4b44f00e696f7f5aaecbedab9cd6baa869.tar.xz org.eclipse.mylyn.tasks-cc6f1b4b44f00e696f7f5aaecbedab9cd6baa869.zip |
414360: add support for add attachments to REST API
Change-Id: Ia1c37808e77b2a8a802dab2a44644cac605b02c6
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=414360
16 files changed, 510 insertions, 63 deletions
diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestClientTest.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestClientTest.java index 0865a81f8..38d002001 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestClientTest.java +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestClientTest.java @@ -19,17 +19,24 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import org.apache.commons.io.IOUtils; +import org.eclipse.core.runtime.CoreException; import org.eclipse.mylyn.commons.repositories.core.RepositoryLocation; import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationType; import org.eclipse.mylyn.commons.repositories.core.auth.UserCredentials; @@ -41,6 +48,7 @@ import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestConfiguration; import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestConnector; import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestCreateTaskSchema; import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestException; +import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestTaskAttachmentHandler; import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestTaskSchema; import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestVersion; import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.Field; @@ -51,16 +59,18 @@ import org.eclipse.mylyn.internal.bugzilla.rest.test.support.BugzillaRestHarness import org.eclipse.mylyn.internal.bugzilla.rest.test.support.BugzillaRestTestFixture; import org.eclipse.mylyn.internal.commons.core.operations.NullOperationMonitor; import org.eclipse.mylyn.internal.commons.repositories.core.InMemoryCredentialsStore; -import org.eclipse.mylyn.tasks.core.RepositoryResponse; +import org.eclipse.mylyn.internal.tasks.core.TaskTask; +import org.eclipse.mylyn.internal.tasks.core.data.FileTaskAttachmentSource; +import org.eclipse.mylyn.tasks.core.ITask; import org.eclipse.mylyn.tasks.core.RepositoryResponse; import org.eclipse.mylyn.tasks.core.RepositoryResponse.ResponseKind; import org.eclipse.mylyn.tasks.core.TaskMapping; -import org.eclipse.mylyn.tasks.core.TaskMapping; import org.eclipse.mylyn.tasks.core.TaskRepository; import org.eclipse.mylyn.tasks.core.data.AbstractTaskDataHandler; import org.eclipse.mylyn.tasks.core.data.TaskAttribute; import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper; import org.eclipse.mylyn.tasks.core.data.TaskData; +import org.eclipse.mylyn.tasks.core.data.TaskDataCollector; import org.eclipse.mylyn.tasks.core.data.TaskMapper; import org.junit.Before; import org.junit.Rule; @@ -570,4 +580,197 @@ public class BugzillaRestClientTest { assertThat(commentAttribute.getValue(), is("false")); } + @Test + public void testGifAttachment() throws Exception { + TaskRepository repository = actualFixture.repository(); + + final TaskMapping taskMappingInit = new TaskMapping() { + @Override + public String getSummary() { + return "Bug for Gif Attachment"; + } + + @Override + public String getDescription() { + return "The bug is used to test that gif attachments can be put and get correctly!"; + } + + @Override + public String getProduct() { + return "ManualTest"; + } + + @Override + public String getComponent() { + return "ManualC1"; + } + + @Override + public String getVersion() { + return "R1"; + } + }; + AbstractTaskDataHandler taskDataHandler = connector.getTaskDataHandler(); + TaskAttributeMapper mapper = taskDataHandler.getAttributeMapper(actualFixture.repository()); + TaskData taskData = new TaskData(mapper, actualFixture.repository().getConnectorKind(), + actualFixture.repository().getRepositoryUrl(), ""); + taskDataHandler.initializeTaskData(actualFixture.repository(), taskData, taskMappingInit, null); + taskData.getRoot().getAttribute("cf_dropdown").setValue("one"); + taskData.getRoot() + .getAttribute(BugzillaRestCreateTaskSchema.getDefault().TARGET_MILESTONE.getKey()) + .setValue("M2"); + RepositoryResponse response = connector.getClient(actualFixture.repository()).postTaskData(taskData, null, + null); + assertEquals(ResponseKind.TASK_CREATED, response.getReposonseKind()); + + final String taskId = response.getTaskId(); + TaskAttribute attachmentAttribute = null; + taskData = getTaskData(taskId); + assertNotNull(taskData); + for (Entry<String, TaskAttribute> entry : taskData.getRoot().getAttributes().entrySet()) { + if (TaskAttribute.TYPE_ATTACHMENT.equals(entry.getValue().getMetaData().getType())) { + attachmentAttribute = entry.getValue(); + } + } + assertNull(attachmentAttribute); + BugzillaRestTaskAttachmentHandler attachmentHandler = new BugzillaRestTaskAttachmentHandler(connector); + ITask task = new TaskTask(actualFixture.repository().getConnectorKind(), + actualFixture.repository().getRepositoryUrl(), taskId); + + InputStream in = CommonTestUtil.getResource(this, "testdata/icons/bugzilla-logo.gif"); + File file = File.createTempFile("attachment", null); + file.deleteOnExit(); + OutputStream out = new FileOutputStream(file); + try { + IOUtils.copy(in, out); + } finally { + in.close(); + out.close(); + } + + FileTaskAttachmentSource attachment = new FileTaskAttachmentSource(file); + attachment.setContentType("image/gif"); + attachment.setDescription("My Attachment 2"); + attachment.setName("Attachment 2.gif"); + attachmentHandler.postContent(repository, task, attachment, "comment", null, null); + taskData = getTaskData(taskId); + assertNotNull(taskData); + for (Entry<String, TaskAttribute> entry : taskData.getRoot().getAttributes().entrySet()) { + if (TaskAttribute.TYPE_ATTACHMENT.equals(entry.getValue().getMetaData().getType())) { + attachmentAttribute = entry.getValue(); + } + } + assertNotNull(attachmentAttribute); + InputStream instream = attachmentHandler.getContent(actualFixture.repository(), task, attachmentAttribute, + null); + InputStream instream2 = CommonTestUtil.getResource(this, "testdata/icons/bugzilla-logo.gif"); + assertTrue(IOUtils.contentEquals(instream, instream2)); + } + + @Test + public void testTextAttachment() throws Exception { + TaskRepository repository = actualFixture.repository(); + + final TaskMapping taskMappingInit = new TaskMapping() { + @Override + public String getSummary() { + return "Bug for Text Attachment"; + } + + @Override + public String getDescription() { + return "The bug is used to test that text attachments can be put and get correctly!"; + } + + @Override + public String getProduct() { + return "ManualTest"; + } + + @Override + public String getComponent() { + return "ManualC1"; + } + + @Override + public String getVersion() { + return "R1"; + } + }; + AbstractTaskDataHandler taskDataHandler = connector.getTaskDataHandler(); + TaskAttributeMapper mapper = taskDataHandler.getAttributeMapper(actualFixture.repository()); + TaskData taskData = new TaskData(mapper, actualFixture.repository().getConnectorKind(), + actualFixture.repository().getRepositoryUrl(), ""); + taskDataHandler.initializeTaskData(actualFixture.repository(), taskData, taskMappingInit, null); + taskData.getRoot().getAttribute("cf_dropdown").setValue("one"); + taskData.getRoot() + .getAttribute(BugzillaRestCreateTaskSchema.getDefault().TARGET_MILESTONE.getKey()) + .setValue("M2"); + RepositoryResponse response = connector.getClient(actualFixture.repository()).postTaskData(taskData, null, + null); + assertEquals(ResponseKind.TASK_CREATED, response.getReposonseKind()); + + final String taskId = response.getTaskId(); + TaskAttribute attachmentAttribute = null; + taskData = getTaskData(taskId); + assertNotNull(taskData); + for (Entry<String, TaskAttribute> entry : taskData.getRoot().getAttributes().entrySet()) { + if (TaskAttribute.TYPE_ATTACHMENT.equals(entry.getValue().getMetaData().getType())) { + attachmentAttribute = entry.getValue(); + } + } + assertNull(attachmentAttribute); + BugzillaRestTaskAttachmentHandler attachmentHandler = new BugzillaRestTaskAttachmentHandler(connector); + ITask task = new TaskTask(actualFixture.repository().getConnectorKind(), + actualFixture.repository().getRepositoryUrl(), taskId); + + InputStream in = CommonTestUtil.getResource(this, "testdata/AttachmentTest.txt"); + File file = File.createTempFile("attachment", null); + file.deleteOnExit(); + OutputStream out = new FileOutputStream(file); + try { + IOUtils.copy(in, out); + } finally { + in.close(); + out.close(); + } + + FileTaskAttachmentSource attachment = new FileTaskAttachmentSource(file); + attachment.setContentType("text/plain"); + attachment.setDescription("My Attachment 2"); + attachment.setName("Attachment 2.txt"); + attachmentHandler.postContent(repository, task, attachment, "comment", null, null); + taskData = getTaskData(taskId); + assertNotNull(taskData); + for (Entry<String, TaskAttribute> entry : taskData.getRoot().getAttributes().entrySet()) { + if (TaskAttribute.TYPE_ATTACHMENT.equals(entry.getValue().getMetaData().getType())) { + attachmentAttribute = entry.getValue(); + } + } + assertNotNull(attachmentAttribute); + InputStream instream = attachmentHandler.getContent(actualFixture.repository(), task, attachmentAttribute, + null); + InputStream instream2 = CommonTestUtil.getResource(this, "testdata/AttachmentTest.txt"); + assertTrue(IOUtils.contentEquals(instream, instream2)); + } + + private TaskData getTaskData(final String taskId) throws CoreException, BugzillaRestException { + BugzillaRestClient client = connector.getClient(actualFixture.repository()); + final Map<String, TaskData> results = new HashMap<String, TaskData>(); + client.getTaskData(new HashSet<String>() { + private static final long serialVersionUID = 1L; + + { + add(taskId); + } + }, actualFixture.repository(), new TaskDataCollector() { + + @Override + public void accept(TaskData taskData) { + results.put(taskData.getTaskId(), taskData); + } + }, null); + return results.get(taskId); + } + } diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/testdata/AttachmentTest.txt b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/testdata/AttachmentTest.txt new file mode 100644 index 000000000..a8da59171 --- /dev/null +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/testdata/AttachmentTest.txt @@ -0,0 +1 @@ +This is a testfile!
\ No newline at end of file diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/testdata/icons/bugzilla-logo.gif b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/testdata/icons/bugzilla-logo.gif Binary files differnew file mode 100644 index 000000000..1ac3a0327 --- /dev/null +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/testdata/icons/bugzilla-logo.gif diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/META-INF/MANIFEST.MF b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/META-INF/MANIFEST.MF index 5ff8abc1c..cca8f595c 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/META-INF/MANIFEST.MF +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/META-INF/MANIFEST.MF @@ -13,7 +13,8 @@ Require-Bundle: org.eclipse.core.runtime, com.google.gson;bundle-version="2.1.0", org.eclipse.mylyn.commons.net, org.eclipse.equinox.security, - com.google.guava + com.google.guava, + org.apache.commons.io Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.mylyn.internal.bugzilla.rest.core, diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedGetRequest.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedGetRequest.java index ef42c1666..34bbcd0d8 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedGetRequest.java +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedGetRequest.java @@ -77,19 +77,9 @@ public class BugzillaRestAuthenticatedGetRequest<T> extends BugzillaRestRequest< } @Override - protected HttpRequestBase createHttpRequestBase() { - String bugUrl = getUrlSuffix(); - LoginToken token = ((BugzillaRestHttpClient) getClient()).getLoginToken(); - if ((!(this instanceof BugzillaRestValidateRequest) && !(this instanceof BugzillaRestUnauthenticatedGetRequest)) - && token != null && bugUrl.length() > 0) { - if (!bugUrl.endsWith("?")) { //$NON-NLS-1$ - bugUrl += "&"; //$NON-NLS-1$ - } - bugUrl += "token=" + token.getToken(); //$NON-NLS-1$ - } - HttpRequestBase request = new HttpGet(baseUrl() + bugUrl); + protected HttpRequestBase createHttpRequestBase(String url) { + HttpRequestBase request = new HttpGet(url); request.setHeader(CONTENT_TYPE, TEXT_XML_CHARSET_UTF_8); - request.setHeader(ACCEPT, APPLICATION_JSON); return request; } @@ -99,6 +89,7 @@ public class BugzillaRestAuthenticatedGetRequest<T> extends BugzillaRestRequest< authenticate(monitor); } HttpRequestBase request = createHttpRequestBase(); + addHttpRequestEntities(request); CommonHttpResponse response = execute(request, monitor); return processAndRelease(response, monitor); } diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedPostRequest.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedPostRequest.java index 5f6cf45da..a8f683a42 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedPostRequest.java +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedPostRequest.java @@ -12,12 +12,12 @@ package org.eclipse.mylyn.internal.bugzilla.rest.core; import java.io.IOException; +import java.io.InputStreamReader; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.eclipse.mylyn.commons.core.operations.IOperationMonitor; import org.eclipse.mylyn.commons.repositories.http.core.CommonHttpResponse; -import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.LoginToken; public abstract class BugzillaRestAuthenticatedPostRequest<T> extends BugzillaRestRequest<T> { @@ -26,29 +26,31 @@ public abstract class BugzillaRestAuthenticatedPostRequest<T> extends BugzillaRe } @Override - protected HttpRequestBase createHttpRequestBase() throws IOException { - String bugUrl = getUrlSuffix(); - LoginToken token = ((BugzillaRestHttpClient) getClient()).getLoginToken(); - if (token != null && bugUrl.length() > 0) { - if (bugUrl.endsWith("?")) { //$NON-NLS-1$ - bugUrl += ("token=" + token.getToken()); //$NON-NLS-1$ - } else { - bugUrl += ("&token=" + token.getToken()); //$NON-NLS-1$ - } - } - - HttpPost request = new HttpPost(baseUrl() + bugUrl); + protected HttpRequestBase createHttpRequestBase(String url) { + HttpPost request = new HttpPost(url); request.setHeader(CONTENT_TYPE, APPLICATION_JSON); - request.setHeader(ACCEPT, APPLICATION_JSON); return request; } @Override + protected T parseFromJson(InputStreamReader in) throws BugzillaRestException { + // ignore + return null; + } + + @Override + protected String createHttpRequestURL() { + String bugUrl = getUrlSuffix(); + return baseUrl() + bugUrl; + } + + @Override protected T execute(IOperationMonitor monitor) throws IOException, BugzillaRestException { if (needsAuthentication() && ((BugzillaRestHttpClient) getClient()).getLoginToken() == null) { authenticate(monitor); } HttpRequestBase request = createHttpRequestBase(); + addHttpRequestEntities(request); CommonHttpResponse response = execute(request, monitor); return processAndRelease(response, monitor); } diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedPutRequest.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedPutRequest.java index d31d46fe7..25a6b5f86 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedPutRequest.java +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedPutRequest.java @@ -76,25 +76,15 @@ public abstract class BugzillaRestAuthenticatedPutRequest<T> extends BugzillaRes authenticate(monitor); } HttpRequestBase request = createHttpRequestBase(); + addHttpRequestEntities(request); CommonHttpResponse response = execute(request, monitor); return processAndRelease(response, monitor); } @Override - protected HttpRequestBase createHttpRequestBase() { - String bugUrl = getUrlSuffix(); - LoginToken token = ((BugzillaRestHttpClient) getClient()).getLoginToken(); - if (token != null && bugUrl.length() > 0) { - if (bugUrl.endsWith("?")) { //$NON-NLS-1$ - bugUrl += ("token=" + token.getToken()); //$NON-NLS-1$ - } else { - bugUrl += ("&token=" + token.getToken()); //$NON-NLS-1$ - } - } - - HttpPut request = new HttpPut(baseUrl() + bugUrl); + protected HttpRequestBase createHttpRequestBase(String url) { + HttpPut request = new HttpPut(url); request.setHeader(CONTENT_TYPE, APPLICATION_JSON); - request.setHeader(ACCEPT, APPLICATION_JSON); return request; } diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestClient.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestClient.java index 347699b9f..93378f285 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestClient.java +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestClient.java @@ -41,6 +41,7 @@ import org.eclipse.mylyn.tasks.core.IRepositoryQuery; import org.eclipse.mylyn.tasks.core.RepositoryResponse; import org.eclipse.mylyn.tasks.core.RepositoryResponse.ResponseKind; import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource; import org.eclipse.mylyn.tasks.core.data.TaskAttribute; import org.eclipse.mylyn.tasks.core.data.TaskData; import org.eclipse.mylyn.tasks.core.data.TaskDataCollector; @@ -218,4 +219,10 @@ public class BugzillaRestClient { return new BugzillaRestGetTaskAttachmentData(client, attachmentAttribute).run(monitor); } + public void addAttachment(String bugReportID, String comment, AbstractTaskAttachmentSource source, + TaskAttribute attachmentAttribute, IOperationMonitor monitor) throws BugzillaRestException { + new BugzillaRestPostNewAttachment(client, bugReportID, comment, source, attachmentAttribute, monitor) + .run(monitor); + } + } diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestPostNewAttachment.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestPostNewAttachment.java new file mode 100644 index 000000000..16c9f5c8e --- /dev/null +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestPostNewAttachment.java @@ -0,0 +1,187 @@ +/******************************************************************************* + * Copyright (c) 2015 Frank Becker and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Frank Becker - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.bugzilla.rest.core; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.util.List; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpStatus; +import org.apache.http.NameValuePair; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.entity.StringEntity; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.mylyn.commons.core.operations.IOperationMonitor; +import org.eclipse.mylyn.commons.repositories.http.core.CommonHttpResponse; +import org.eclipse.mylyn.commons.repositories.http.core.HttpUtil; +import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.BugzillaRestIdsResult; +import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.LoginToken; +import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource; +import org.eclipse.mylyn.tasks.core.data.TaskAttachmentMapper; +import org.eclipse.mylyn.tasks.core.data.TaskAttribute; +import org.eclipse.osgi.util.NLS; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +public class BugzillaRestPostNewAttachment extends BugzillaRestAuthenticatedPostRequest<BugzillaRestIdsResult> { + private final String bugReportID; + + private final String comment; + + private final AbstractTaskAttachmentSource source; + + private final TaskAttribute attachmentAttribute; + + public BugzillaRestPostNewAttachment(BugzillaRestHttpClient client, String bugReportID, String comment, + AbstractTaskAttachmentSource source, TaskAttribute attachmentAttribute, IOperationMonitor monitor) { + super(client); + this.bugReportID = bugReportID; + this.comment = comment; + this.source = source; + this.attachmentAttribute = attachmentAttribute; + } + + @Override + protected String getUrlSuffix() { + return "/bug/" + bugReportID + "/attachment"; //$NON-NLS-1$ + } + + List<NameValuePair> requestParameters; + + @Override + protected void addHttpRequestEntities(HttpRequestBase request) throws BugzillaRestException { + super.addHttpRequestEntities(request); + + LoginToken token = ((BugzillaRestHttpClient) getClient()).getLoginToken(); + String description = source.getDescription(); + String contentType = source.getContentType(); + String filename = source.getName(); + boolean isPatch = false; + + if (attachmentAttribute != null) { + TaskAttachmentMapper mapper = TaskAttachmentMapper.createFrom(attachmentAttribute); + + if (mapper.getDescription() != null) { + description = mapper.getDescription(); + } + + if (mapper.getContentType() != null) { + contentType = mapper.getContentType(); + } + + if (mapper.getFileName() != null) { + filename = mapper.getFileName(); + } + + if (mapper.isPatch() != null) { + isPatch = mapper.isPatch(); + } + } + Assert.isNotNull(bugReportID); + Assert.isNotNull(source); + Assert.isNotNull(contentType); + ByteArrayOutputStream outb = new ByteArrayOutputStream(); + InputStream is = null; + + try { + is = source.createInputStream(null); + IOUtils.copy(is, outb); + } catch (CoreException | IOException e) { + throw new BugzillaRestException( + "BugzillaRestPostNewAttachment.createHttpRequestBase could not get stream form source", e); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + throw new BugzillaRestException( + "BugzillaRestPostNewAttachment.createHttpRequestBase could not cloase stream form source", + e); + } + } + } + + if (description == null) { + throw new BugzillaRestException(new CoreException(new Status(IStatus.WARNING, BugzillaRestCore.ID_PLUGIN, + "Description required when submitting attachments"))); + } + Base64 base64 = new Base64(); + String dataBase64 = base64.encodeAsString(outb.toByteArray()); + try { + String gsonString = "{\"Bugzilla_token\":\"" + token.getToken() + "\", \"ids\" : [ " + bugReportID + " ]," //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + " \"is_patch\" : " + Boolean.toString(isPatch) + "," + " \"summary\" : \"" + description + "\"," //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$ + + " \"content_type\" : \"" + contentType + "\"," + " \"data\" : \"" + dataBase64 + "\"," //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$ + + " \"file_name\" : \"" + filename + "\"," + " \"is_private\" : false}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + StringEntity requestEntity = new StringEntity(gsonString); + ((HttpPost) request).setEntity(requestEntity); + } catch (UnsupportedEncodingException e) { + throw new BugzillaRestException( + "BugzillaRestPostNewAttachment.createHttpRequestBase could not create StringEntity", e); + } + } + + @Override + protected BugzillaRestIdsResult parseFromJson(InputStreamReader in) { + TypeToken<BugzillaRestIdsResult> type = new TypeToken<BugzillaRestIdsResult>() { + }; + return new Gson().fromJson(in, type.getType()); + } + + protected BugzillaRestStatus parseErrorFromJson(InputStreamReader in) { + TypeToken<BugzillaRestStatus> type = new TypeToken<BugzillaRestStatus>() { + }; + return new Gson().fromJson(in, type.getType()); + } + + @Override + protected void doValidate(CommonHttpResponse response, IOperationMonitor monitor) + throws IOException, BugzillaRestException { + int statusCode = response.getStatusCode(); + if (statusCode != 400 && statusCode != 201) { + if (statusCode == HttpStatus.SC_NOT_FOUND) { + throw new BugzillaRestResourceNotFoundException( + NLS.bind("Requested resource ''{0}'' does not exist", response.getRequestPath())); + } + throw new BugzillaRestException(NLS.bind("Unexpected response from Bugzilla REST server for ''{0}'': {1}", + response.getRequestPath(), HttpUtil.getStatusText(statusCode))); + } + + } + + @Override + protected BugzillaRestIdsResult doProcess(CommonHttpResponse response, IOperationMonitor monitor) + throws IOException, BugzillaRestException { + InputStream is = response.getResponseEntityAsStream(); + InputStreamReader in = new InputStreamReader(is); + switch (response.getStatusCode()) { + case HttpURLConnection.HTTP_OK: + case HttpURLConnection.HTTP_CREATED: + return parseFromJson(in); + default: + BugzillaRestStatus status = parseErrorFromJson(in); + throw new BugzillaRestException( + NLS.bind("{2} (status: {1} from {0})", new String[] { response.getRequestPath(), + HttpUtil.getStatusText(response.getStatusCode()), status.getMessage() })); + } + } +}
\ No newline at end of file diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestPostNewTask.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestPostNewTask.java index 8fe3c11b5..d693cd298 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestPostNewTask.java +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestPostNewTask.java @@ -110,23 +110,18 @@ public class BugzillaRestPostNewTask extends BugzillaRestAuthenticatedPostReques } @Override - protected HttpRequestBase createHttpRequestBase() throws IOException { - String bugUrl = getUrlSuffix(); + protected void addHttpRequestEntities(HttpRequestBase request) throws BugzillaRestException { + super.addHttpRequestEntities(request); LoginToken token = ((BugzillaRestHttpClient) getClient()).getLoginToken(); - - HttpPost request = new HttpPost(baseUrl() + bugUrl); - request.setHeader(CONTENT_TYPE, APPLICATION_JSON); - request.setHeader(ACCEPT, APPLICATION_JSON); try { // set form parameters Gson gson = new GsonBuilder().registerTypeAdapter(TaskData.class, new TaskAttributeTypeAdapter(token)) .create(); StringEntity requestEntity = new StringEntity(gson.toJson(taskData)); - request.setEntity(requestEntity); + ((HttpPost) request).setEntity(requestEntity); } catch (UnsupportedEncodingException e) { - throw new IOException("could not build REST String", e); //$NON-NLS-1$ + throw new BugzillaRestException("could not build REST String", e); //$NON-NLS-1$ } - return request; } @Override diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestPutUpdateTask.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestPutUpdateTask.java index 09682c8dc..6a790f358 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestPutUpdateTask.java +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestPutUpdateTask.java @@ -168,24 +168,24 @@ public class BugzillaRestPutUpdateTask extends BugzillaRestAuthenticatedPutReque List<NameValuePair> requestParameters; @Override - protected HttpRequestBase createHttpRequestBase() { + protected String createHttpRequestURL() { String bugUrl = getUrlSuffix(); - LoginToken token = ((BugzillaRestHttpClient) getClient()).getLoginToken(); - - HttpPut request = new HttpPut(baseUrl() + bugUrl); - request.setHeader(CONTENT_TYPE, APPLICATION_JSON); - request.setHeader(ACCEPT, APPLICATION_JSON); + return baseUrl() + bugUrl; + } + @Override + protected void addHttpRequestEntities(HttpRequestBase request) throws BugzillaRestException { + super.addHttpRequestEntities(request); + LoginToken token = ((BugzillaRestHttpClient) getClient()).getLoginToken(); try { Gson gson = new GsonBuilder().registerTypeAdapter(OldAttributes.class, new TaskAttributeTypeAdapter(token)) .create(); StringEntity requestEntity = new StringEntity(gson.toJson(oldAttributes)); - request.setEntity(requestEntity); + ((HttpPut) request).setEntity(requestEntity); } catch (UnsupportedEncodingException e) { com.google.common.base.Throwables.propagate(new CoreException( new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, "Can not build HttpRequest", e))); //$NON-NLS-1$ } - return request; } public static String convert(String str) { diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestRequest.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestRequest.java index 1755a7b85..812216cfe 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestRequest.java +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestRequest.java @@ -26,6 +26,7 @@ import org.eclipse.mylyn.commons.repositories.core.auth.UserCredentials; import org.eclipse.mylyn.commons.repositories.http.core.CommonHttpOperation; import org.eclipse.mylyn.commons.repositories.http.core.CommonHttpResponse; import org.eclipse.mylyn.commons.repositories.http.core.HttpUtil; +import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.LoginToken; import org.eclipse.osgi.util.NLS; public abstract class BugzillaRestRequest<T> extends CommonHttpOperation<T> { @@ -45,7 +46,12 @@ public abstract class BugzillaRestRequest<T> extends CommonHttpOperation<T> { protected abstract T parseFromJson(InputStreamReader in) throws BugzillaRestException; - protected abstract HttpRequestBase createHttpRequestBase() throws IOException; + protected abstract HttpRequestBase createHttpRequestBase(String url); + + protected HttpRequestBase createHttpRequestBase() { + HttpRequestBase request = createHttpRequestBase(createHttpRequestURL()); + return request; + } protected String baseUrl() { String url = getClient().getLocation().getUrl(); @@ -59,6 +65,22 @@ public abstract class BugzillaRestRequest<T> extends CommonHttpOperation<T> { return ""; //$NON-NLS-1$ } + protected String createHttpRequestURL() { + String bugUrl = getUrlSuffix(); + LoginToken token = ((BugzillaRestHttpClient) getClient()).getLoginToken(); + if (token != null && bugUrl.length() > 0) { + if (!bugUrl.endsWith("?")) { //$NON-NLS-1$ + bugUrl += "&"; //$NON-NLS-1$ + } + bugUrl += "token=" + token.getToken(); //$NON-NLS-1$ + } + return baseUrl() + bugUrl; + } + + protected void addHttpRequestEntities(HttpRequestBase request) throws BugzillaRestException { + request.setHeader(ACCEPT, APPLICATION_JSON); + } + public T run(IOperationMonitor monitor) throws BugzillaRestException { try { return execute(monitor); diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskAttachmentHandler.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskAttachmentHandler.java index 42de36be5..6fa255d65 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskAttachmentHandler.java +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskAttachmentHandler.java @@ -20,7 +20,6 @@ import org.eclipse.core.runtime.Status; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.mylyn.commons.core.operations.IOperationMonitor; -import org.eclipse.mylyn.commons.core.operations.IOperationMonitor.OperationFlag; import org.eclipse.mylyn.commons.core.operations.OperationUtil; import org.eclipse.mylyn.commons.net.Policy; import org.eclipse.mylyn.tasks.core.ITask; @@ -43,7 +42,7 @@ public class BugzillaRestTaskAttachmentHandler extends AbstractTaskAttachmentHan @Override public boolean canPostContent(TaskRepository repository, ITask task) { - return false; + return true; } @Override @@ -56,7 +55,6 @@ public class BugzillaRestTaskAttachmentHandler extends AbstractTaskAttachmentHan BugzillaRestClient client = connector.getClient(repository); try { IOperationMonitor progress = OperationUtil.convert(monitor, "get Attachment Data", 3); //$NON-NLS-1$ - progress.addFlag(OperationFlag.BACKGROUND); return client.getAttachmentData(attachmentAttribute, progress); } catch (BugzillaRestException e) { throw new CoreException(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, 2, @@ -71,6 +69,20 @@ public class BugzillaRestTaskAttachmentHandler extends AbstractTaskAttachmentHan public void postContent(@NonNull TaskRepository repository, @NonNull ITask task, @NonNull AbstractTaskAttachmentSource source, @Nullable String comment, @Nullable TaskAttribute attachmentAttribute, @Nullable IProgressMonitor monitor) throws CoreException { + try { + monitor = Policy.monitorFor(monitor); + monitor.beginTask("addAttachment Data", IProgressMonitor.UNKNOWN); + BugzillaRestClient client = connector.getClient(repository); + try { + IOperationMonitor progress = OperationUtil.convert(monitor, "get Attachment Data", 3); + client.addAttachment(task.getTaskId(), comment, source, attachmentAttribute, progress); + } catch (BugzillaRestException e) { + throw new CoreException(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, 2, + "Error add attachment data.\n\n" + e.getMessage(), e)); + } + } finally { + monitor.done(); + } } } diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestUnauthenticatedGetRequest.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestUnauthenticatedGetRequest.java index e28e0dd9f..d9dfb9389 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestUnauthenticatedGetRequest.java +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestUnauthenticatedGetRequest.java @@ -25,4 +25,10 @@ public class BugzillaRestUnauthenticatedGetRequest<T> extends BugzillaRestAuthen return false; } + @Override + protected String createHttpRequestURL() { + String bugUrl = getUrlSuffix(); + return baseUrl() + bugUrl; + } + }
\ No newline at end of file diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestValidateRequest.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestValidateRequest.java index b3d516673..de2fd3346 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestValidateRequest.java +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestValidateRequest.java @@ -56,4 +56,10 @@ public class BugzillaRestValidateRequest extends BugzillaRestAuthenticatedGetReq return new Gson().fromJson(jsonString, a.getType()); } + @Override + protected String createHttpRequestURL() { + String bugUrl = getUrlSuffix(); + return baseUrl() + bugUrl; + } + } diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/response/data/BugzillaRestIdsResult.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/response/data/BugzillaRestIdsResult.java new file mode 100644 index 000000000..e055c594e --- /dev/null +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/response/data/BugzillaRestIdsResult.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2015 Frank Becker and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Frank Becker - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.bugzilla.rest.core.response.data; + +public class BugzillaRestIdsResult { + private String[] ids; + + public String[] getIds() { + return ids; + } + + public void setIds(String[] ids) { + this.ids = ids; + } +}
\ No newline at end of file |