-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for creation/download of Support Zip #197
base: master
Are you sure you want to change the base?
Changes from all commits
65a3d8f
7689062
39c70d1
bf3a0f8
3d2f99f
a97730d
39707c4
d3d2c8b
9313612
e96591f
611d00c
b40793d
eca9dcd
a3726ae
6d6b096
81e8958
e237b19
b26abdf
b64e3f3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.cdancy.bitbucket.rest.domain.support; | ||
|
||
import com.cdancy.bitbucket.rest.BitbucketUtils; | ||
import com.cdancy.bitbucket.rest.domain.common.Error; | ||
import com.cdancy.bitbucket.rest.domain.common.ErrorsHolder; | ||
import com.google.auto.value.AutoValue; | ||
import org.jclouds.javax.annotation.Nullable; | ||
import org.jclouds.json.SerializedNames; | ||
import java.util.List; | ||
|
||
@AutoValue | ||
public abstract class SupportZip implements ErrorsHolder { | ||
public abstract String taskId(); | ||
|
||
public abstract Integer progressPercentage(); | ||
|
||
public abstract String progressMessage(); | ||
|
||
public abstract List<String> warnings(); | ||
|
||
public abstract String status(); | ||
|
||
@Nullable | ||
public abstract String fileName(); | ||
|
||
@SerializedNames({"taskId", "progressPercentage", "progressMessage", | ||
"warnings", "status", "fileName", | ||
"errors"}) | ||
public static SupportZip create(final String taskId, | ||
final Integer progressPercentage, | ||
final String progressMessage, | ||
final List<String> warnings, | ||
final String status, | ||
final String fileName, | ||
final List<Error> errors) { | ||
return new AutoValue_SupportZip(BitbucketUtils.nullToEmpty(errors), | ||
taskId, | ||
progressPercentage, | ||
progressMessage, | ||
warnings, | ||
status, | ||
fileName); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.cdancy.bitbucket.rest.features; | ||
|
||
import com.cdancy.bitbucket.rest.annotations.Documentation; | ||
import com.cdancy.bitbucket.rest.domain.support.SupportZip; | ||
import com.cdancy.bitbucket.rest.filters.BitbucketAuthenticationFilter; | ||
import com.cdancy.bitbucket.rest.fallbacks.BitbucketFallbacks.SupportZipOnError; | ||
import org.jclouds.rest.annotations.Fallback; | ||
import org.jclouds.rest.annotations.RequestFilters; | ||
import javax.inject.Named; | ||
import javax.ws.rs.Consumes; | ||
import javax.ws.rs.GET; | ||
import javax.ws.rs.POST; | ||
import javax.ws.rs.Path; | ||
import javax.ws.rs.PathParam; | ||
import javax.ws.rs.Produces; | ||
import javax.ws.rs.core.MediaType; | ||
|
||
@Produces(MediaType.APPLICATION_JSON) | ||
@RequestFilters(BitbucketAuthenticationFilter.class) | ||
@Path("/rest/troubleshooting/latest/support-zip") | ||
@SuppressWarnings("PMD.AvoidDuplicateLiterals") | ||
public interface SupportApi { | ||
|
||
@Named("support-zip:create") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets put a line-break between the class name and this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
@Documentation("https://confluence.atlassian.com/support/create-a-support-zip-using-the-rest-api-in-server-applications-947857090.html#CreateasupportzipusingtheRESTAPIinServerapplications-Generateasupportzip") | ||
@Consumes(MediaType.APPLICATION_JSON) | ||
@Path("/local") | ||
@Fallback(SupportZipOnError.class) | ||
@POST | ||
SupportZip createSupportZip(); | ||
|
||
@Named("support-zip:status") | ||
@Documentation("https://confluence.atlassian.com/support/create-a-support-zip-using-the-rest-api-in-server-applications-947857090.html#CreateasupportzipusingtheRESTAPIinServerapplications-Checktheprogressofthetask") | ||
@Consumes(MediaType.APPLICATION_JSON) | ||
@Path("/status/task/{taskId}") | ||
@Fallback(SupportZipOnError.class) | ||
@GET | ||
SupportZip getSupportZipStatus(@PathParam("taskId") String taskId); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.cdancy.bitbucket.rest.features; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import com.cdancy.bitbucket.rest.BaseBitbucketApiLiveTest; | ||
import com.cdancy.bitbucket.rest.domain.support.SupportZip; | ||
import org.testng.annotations.Test; | ||
|
||
@Test(groups = "live", testName = "SupportApiLiveTest", singleThreaded = true) | ||
public class SupportApiLiveTest extends BaseBitbucketApiLiveTest { | ||
private String taskIdRegex = "^\\w+\\-+\\w+\\-+\\w+\\-+\\w+\\-+\\w+$"; | ||
|
||
private SupportApi api() { | ||
return api.supportApi(); | ||
} | ||
|
||
@Test | ||
public void testSupportZipCreation() { | ||
final SupportZip supportZipTask = api().createSupportZip(); | ||
assertIntegrity(supportZipTask); | ||
} | ||
|
||
@Test | ||
public void testSupportZipStatus() { | ||
SupportZip supportZipTask = api().createSupportZip(); | ||
supportZipTask = api().getSupportZipStatus(supportZipTask.taskId()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets also test the case where things fail. Meaning we can pass in a taskId which does not exist and the returned |
||
assertIntegrity(supportZipTask); | ||
assertThat(supportZipTask.fileName()).isNotNull(); | ||
} | ||
|
||
private void assertIntegrity(final SupportZip supportZipTask) { | ||
assertTaskId(supportZipTask.taskId()); | ||
assertTaskProgressPercentage(supportZipTask.progressPercentage()); | ||
assertTaskProgressMessage(supportZipTask.progressMessage()); | ||
assertTaskStatus(supportZipTask.status()); | ||
assertErrors(supportZipTask); | ||
} | ||
|
||
private void assertErrors(final SupportZip supportZip) { | ||
assertThat(supportZip.errors().isEmpty()).isTrue(); | ||
} | ||
|
||
private void assertTaskProgressMessage(final String progressMessage) { | ||
assertThat(progressMessage).isNotNull(); | ||
} | ||
|
||
private void assertTaskStatus(final String status) { | ||
assertThat(!status.isEmpty()).isTrue(); | ||
} | ||
|
||
private void assertTaskId(final String taskId) { | ||
assertThat(taskId).isNotNull(); | ||
assertThat(taskId.matches(taskIdRegex)).isTrue(); | ||
} | ||
|
||
private void assertTaskProgressPercentage(final Integer progressPercentage) { | ||
assertThat(progressPercentage).isNotNull(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.cdancy.bitbucket.rest.features; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import com.cdancy.bitbucket.rest.BaseBitbucketMockTest; | ||
import com.cdancy.bitbucket.rest.domain.support.SupportZip; | ||
import com.squareup.okhttp.mockwebserver.MockResponse; | ||
import com.squareup.okhttp.mockwebserver.MockWebServer; | ||
import org.testng.Assert; | ||
import org.testng.annotations.Test; | ||
|
||
/** | ||
* Mock tests for the {@link SupportApi} class. | ||
*/ | ||
@Test(groups = "unit", testName = "SupportApiMockTest") | ||
public class SupportApiMockTest extends BaseBitbucketMockTest { | ||
|
||
private String taskIdRegex = "^\\w+\\-+\\w+\\-+\\w+\\-+\\w+\\-+\\w+$"; | ||
private String supportZipRestApiPath = "/rest/troubleshooting/latest/support-zip" ; | ||
|
||
public void testSupportZipCreation() throws Exception { | ||
final MockWebServer mockWebServer = mockWebServer(); | ||
mockWebServer.enqueue(new MockResponse().setBody(payloadFromResource("/support-zip-create.json")).setResponseCode(200)); | ||
try { | ||
final SupportApi supportApi = api(mockWebServer.getUrl("/")).supportApi() ; | ||
final SupportZip supportZip = supportApi.createSupportZip(); | ||
|
||
assertSupportZipCreateRequest(mockWebServer); | ||
assertIntegrity(supportZip); | ||
} finally { | ||
mockWebServer.shutdown(); | ||
} | ||
} | ||
|
||
public void testSupportZipStatus() throws Exception { | ||
final MockWebServer mockWebServer = mockWebServer(); | ||
mockWebServer.enqueue(new MockResponse().setBody(payloadFromResource("/support-zip-create.json")).setResponseCode(200)); | ||
mockWebServer.enqueue(new MockResponse().setBody(payloadFromResource("/support-zip-request-status.json")).setResponseCode(200)); | ||
try { | ||
final SupportApi supportApi = api(mockWebServer.getUrl("/")).supportApi() ; | ||
SupportZip supportZip = supportApi.createSupportZip(); | ||
supportZip = supportApi.getSupportZipStatus(supportZip.taskId()); | ||
|
||
assertSupportZipCreateRequest(mockWebServer); | ||
assertIntegritySupportZipStatus(supportZip); | ||
assertSupportZipStatusRequest(mockWebServer, supportZip.taskId()); | ||
} finally { | ||
mockWebServer.shutdown(); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We also need mock tests for when things fail on both endpoints. To trigger the failure you could use a non-existent taskId for one, combined with an error code of whatever that is supposed to return, and the other I would use an error code response of say |
||
|
||
private void assertIntegritySupportZipStatus(final SupportZip supportZip) { | ||
assertIntegrity(supportZip); | ||
Assert.assertNotNull(supportZip.fileName()); | ||
} | ||
|
||
private void assertIntegrity(final SupportZip supportZip) { | ||
Assert.assertNotNull(supportZip.progressMessage()); | ||
assertThat(supportZip.taskId().matches(taskIdRegex)).isTrue(); | ||
Assert.assertNotNull(supportZip.progressPercentage()); | ||
Assert.assertNotNull(supportZip.status()); | ||
} | ||
|
||
private void assertSupportZipCreateRequest(final MockWebServer mockWebServer) | ||
throws InterruptedException { | ||
assertSent(mockWebServer, "POST", supportZipRestApiPath + "/local"); | ||
} | ||
|
||
private void assertSupportZipStatusRequest(final MockWebServer mockWebServer, final String taskId) | ||
throws InterruptedException { | ||
assertSent(mockWebServer, "GET", supportZipRestApiPath + "/status/task/" + taskId); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"taskId": "cf27e653-d3af-4202-bcc8-79d836432b0b", | ||
"progressPercentage": 0, | ||
"progressMessage": "", | ||
"warnings": [], | ||
"status": "IN_PROGRESS" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"taskId": "cf27e653-d3af-4202-bcc8-79d836432b0b", | ||
"progressPercentage": 100, | ||
"progressMessage": "It was saved to C:\\Atlassian\\ApplicationData\\Bitbucket\\shared\\export\\Bitbucket_support_2019-06-17-00-23-13.zip.", | ||
"fileName": "Bitbucket_support_2019-06-17-00-23-13.zip", | ||
"warnings": [], | ||
"status": "COMPLETE_WITH_WARNING" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't actually work if none of the fields are annotated with @nullable.