diff --git a/pom.xml b/pom.xml
index 221b48bb05b994f0f88df1b2e0315ed4cd602e98..009b7dc57a6dcadbd10e59183d58c93a0fda2365 100644
--- a/pom.xml
+++ b/pom.xml
@@ -57,7 +57,7 @@
1.59
- 11.10.4-ce.0
+ 11.11.2-ce.0
true
true
8090
diff --git a/src/main/java/org/gitlab4j/api/GitLabApi.java b/src/main/java/org/gitlab4j/api/GitLabApi.java
index 93052e01f95adf44830ef935aef94522faa56da9..7889c6c27fdb0a68961e0765eeabbc28d8015838 100644
--- a/src/main/java/org/gitlab4j/api/GitLabApi.java
+++ b/src/main/java/org/gitlab4j/api/GitLabApi.java
@@ -63,6 +63,7 @@ public class GitLabApi {
private EventsApi eventsApi;
private GroupApi groupApi;
private HealthCheckApi healthCheckApi;
+ private ImportExportApi importExportApi;
private IssuesApi issuesApi;
private JobApi jobApi;
private LabelsApi labelsApi;
@@ -1123,11 +1124,30 @@ public class GitLabApi {
return (healthCheckApi);
}
+ /**
+ * Gets the ImportExportApi instance owned by this GitLabApi instance. The ImportExportApi is used
+ * to perform all project import/export related API calls.
+ *
+ * @return the ImportExportApi instance owned by this GitLabApi instance
+ */
+ public ImportExportApi getImportExportApi() {
+
+ if (importExportApi == null) {
+ synchronized (this) {
+ if (importExportApi == null) {
+ importExportApi = new ImportExportApi(this);
+ }
+ }
+ }
+
+ return (importExportApi);
+ }
+
/**
* Gets the IssuesApi instance owned by this GitLabApi instance. The IssuesApi is used
- * to perform all iossue related API calls.
+ * to perform all issue related API calls.
*
- * @return the CommitsApi instance owned by this GitLabApi instance
+ * @return the IssuesApi instance owned by this GitLabApi instance
*/
public IssuesApi getIssuesApi() {
diff --git a/src/main/java/org/gitlab4j/api/ImportExportApi.java b/src/main/java/org/gitlab4j/api/ImportExportApi.java
new file mode 100644
index 0000000000000000000000000000000000000000..44881bda6fc5534907325bd993c45e6031ff1e24
--- /dev/null
+++ b/src/main/java/org/gitlab4j/api/ImportExportApi.java
@@ -0,0 +1,218 @@
+package org.gitlab4j.api;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.util.Map;
+
+import javax.ws.rs.core.Form;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.gitlab4j.api.models.ExportStatus;
+import org.gitlab4j.api.models.ImportStatus;
+import org.gitlab4j.api.models.Project;
+
+/**
+ * This class provides an entry point to all the GitLab API project import/export calls.
+ * @see Project import/export API at GitLab
+ */
+public class ImportExportApi extends AbstractApi {
+
+ public ImportExportApi(GitLabApi gitLabApi) {
+ super(gitLabApi);
+ }
+
+ /**
+ * Schedule an export.
+ *
+ *
GitLab Endpoint: POST /projects/:id/export
+ *
+ * @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
+ * @throws GitLabApiException if any exception occurs
+ */
+ public void scheduleExport(Object projectIdOrPath) throws GitLabApiException {
+ scheduleExport(projectIdOrPath, null, null, null, null);
+ }
+
+ /**
+ * Schedule an export.
+ *
+ * GitLab Endpoint: POST /projects/:id/export
+ *
+ * @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
+ * @param description overrides the project description, optional
+ * @throws GitLabApiException if any exception occurs
+ */
+ public void scheduleExport(Object projectIdOrPath, String description) throws GitLabApiException {
+ scheduleExport(projectIdOrPath, description, null, null, null);
+ }
+
+ /**
+ * Schedule an export.
+ *
+ * GitLab Endpoint: POST /projects/:id/export
+ *
+ * @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
+ * @param description overrides the project description, optional
+ * @param upload Mao that contains the information to upload the exported project to a web server
+ * @param uploadUrl the URL to upload the project
+ * @param uploadHttpMethod the HTTP method to upload the exported project.
+ * Only PUT and POST methods allowed. Default is PUT
+ * @throws GitLabApiException if any exception occurs
+ */
+ public void scheduleExport(Object projectIdOrPath, String description,
+ Map upload, String uploadUrl, String uploadHttpMethod) throws GitLabApiException {
+
+ Form formData = new GitLabApiForm()
+ .withParam("description", description)
+ .withParam("upload", upload)
+ .withParam("upload[url]", uploadUrl)
+ .withParam("upload[http_method]", uploadHttpMethod);
+ post(Response.Status.ACCEPTED, formData, "projects", getProjectIdOrPath(projectIdOrPath), "export");
+ }
+
+ /**
+ * Get the status of export.
+ *
+ * GitLab Endpoint: GET /projects/:id/export
+ *
+ * @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
+ * @return an ExportStatus instance holding information on the export status
+ * @throws GitLabApiException if any exception occurs
+ */
+ public ExportStatus getExportStatus(Object projectIdOrPath) throws GitLabApiException {
+ Response response = get(Response.Status.OK, null, "projects", getProjectIdOrPath(projectIdOrPath), "export");
+ return (response.readEntity(ExportStatus.class));
+ }
+
+ /**
+ * Download the finished export.
+ *
+ * GitLab Endpoint: GET /projects/:id/export/download
+ *
+ * @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
+ * @param directory the File instance of the directory to save the export file to, if null will use "java.io.tmpdir"
+ * @return a File instance pointing to the download of the project export file
+ * @throws GitLabApiException if any exception occurs
+ */
+ public File downloadExport(Object projectIdOrPath, File directory) throws GitLabApiException {
+
+ Response response = getWithAccepts(Response.Status.OK, null, MediaType.MEDIA_TYPE_WILDCARD,
+ "projects", getProjectIdOrPath(projectIdOrPath), "export", "download");
+ try {
+
+ if (directory == null)
+ directory = new File(System.getProperty("java.io.tmpdir"));
+
+ String disposition = response.getHeaderString("Content-Disposition");
+ String filename = disposition.replaceFirst("(?i)^.*filename=\"?([^\"]+)\"?.*$", "$1");
+ File file = new File(directory, filename);
+
+ InputStream in = response.readEntity(InputStream.class);
+ Files.copy(in, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
+ return (file);
+
+ } catch (IOException ioe) {
+ throw new GitLabApiException(ioe);
+ }
+ }
+
+ /**
+ * Import an exported project. The following properties on the Project instance
+ * are utilized in the creation of the new project:
+ *
+ * - defaultBranch (optional) - master by default
+ * - description (optional) - short project description
+ * - visibility (optional) - Limit by visibility public, internal, or private
+ * - visibilityLevel (optional)
+ * - issuesEnabled (optional) - Enable issues for this project
+ * - mergeMethod (optional) - Set the merge method used
+ * - mergeRequestsEnabled (optional) - Enable merge requests for this project
+ * - wikiEnabled (optional) - Enable wiki for this project
+ * - snippetsEnabled (optional) - Enable snippets for this project
+ * - jobsEnabled (optional) - Enable jobs for this project
+ * - containerRegistryEnabled (optional) - Enable container registry for this project
+ * - sharedRunnersEnabled (optional) - Enable shared runners for this project
+ * - publicJobs (optional) - If true, jobs can be viewed by non-project-members
+ * - onlyAllowMergeIfPipelineSucceeds (optional) - Set whether merge requests can only be merged with successful jobs
+ * - onlyAllowMergeIfAllDiscussionsAreResolved (optional) - Set whether merge requests can only be merged when all the discussions are resolved
+ * - lLfsEnabled (optional) - Enable LFS
+ * - requestAccessEnabled (optional) - Allow users to request member access
+ * - repositoryStorage (optional) - Which storage shard the repository is on. Available only to admins
+ * - approvalsBeforeMerge (optional) - How many approvers should approve merge request by default
+ * - printingMergeRequestLinkEnabled (optional) - Show link to create/view merge request when pushing from the command line
+ * - resolveOutdatedDiffDiscussions (optional) - Automatically resolve merge request diffs discussions on lines changed with a push
+ * - initialize_with_readme (optional) - Initialize project with README file
+ * - packagesEnabled (optional) - Enable or disable mvn packages repository feature
+ *
+ * GitLab Endpoint: POST /projects/import
+ *
+ * @param namespaceIdOrPath the ID or path of the namespace that the project will be imported to. Defaults to the current user’s namespace
+ * @param exportFile the project export file to be imported
+ * @param path the name and path for the new project
+ * @param overwrite if there is a project with the same path the import will overwrite it. Defaults to false
+ * @param overrideParams overriding project params, supports all fields defined by the ProjectApi, optional
+ * @return an Importstatus instance with info for the project being imported to
+ * @throws GitLabApiException if any exception occurs
+ */
+ public ImportStatus startImport(Object namespaceIdOrPath, File exportFile, String path, Boolean overwrite, Project overrideParams) throws GitLabApiException {
+
+ URL url;
+ try {
+ url = getApiClient().getApiUrl("projects", "import");
+ } catch (IOException ioe) {
+ throw new GitLabApiException(ioe);
+ }
+
+ GitLabApiForm formData = new GitLabApiForm()
+ .withParam("path", path, true)
+ .withParam("namespace", namespaceIdOrPath)
+ .withParam("overwrite", overwrite);
+
+ if (overrideParams != null) {
+ formData.withParam("default_branch", overrideParams.getDefaultBranch())
+ .withParam("description", overrideParams.getDescription())
+ .withParam("issues_enabled", overrideParams.getIssuesEnabled())
+ .withParam("merge_method", overrideParams.getMergeMethod())
+ .withParam("merge_requests_enabled", overrideParams.getMergeRequestsEnabled())
+ .withParam("jobs_enabled", overrideParams.getJobsEnabled())
+ .withParam("wiki_enabled", overrideParams.getWikiEnabled())
+ .withParam("container_registry_enabled", overrideParams.getContainerRegistryEnabled())
+ .withParam("snippets_enabled", overrideParams.getSnippetsEnabled())
+ .withParam("shared_runners_enabled", overrideParams.getSharedRunnersEnabled())
+ .withParam("public_jobs", overrideParams.getPublicJobs())
+ .withParam("visibility_level", overrideParams.getVisibilityLevel())
+ .withParam("only_allow_merge_if_pipeline_succeeds", overrideParams.getOnlyAllowMergeIfPipelineSucceeds())
+ .withParam("only_allow_merge_if_all_discussions_are_resolved", overrideParams.getOnlyAllowMergeIfAllDiscussionsAreResolved())
+ .withParam("lfs_enabled", overrideParams.getLfsEnabled())
+ .withParam("request_access_enabled", overrideParams.getRequestAccessEnabled())
+ .withParam("repository_storage", overrideParams.getRepositoryStorage())
+ .withParam("approvals_before_merge", overrideParams.getApprovalsBeforeMerge())
+ .withParam("printing_merge_request_link_enabled", overrideParams.getPrintingMergeRequestLinkEnabled())
+ .withParam("resolve_outdated_diff_discussions", overrideParams.getResolveOutdatedDiffDiscussions())
+ .withParam("initialize_with_readme", overrideParams.getInitializeWithReadme())
+ .withParam("packages_enabled", overrideParams.getPackagesEnabled());
+ }
+
+ Response response = upload(Response.Status.CREATED, "file", exportFile, null, formData, url);
+ return (response.readEntity(ImportStatus.class));
+ }
+
+ /**
+ * Get the status of an import.
+ *
+ * GitLab Endpoint: GET /projects/:id/import
+ *
+ * @param projectIdOrPath the new (imported) project identifier in the form of an Integer(ID), String(path), or Project instance
+ * @return an ImportStatus instance holding information on the import status
+ * @throws GitLabApiException if any exception occurs
+ */
+ public ImportStatus getImportStatus(Object projectIdOrPath) throws GitLabApiException {
+ Response response = get(Response.Status.OK, null, "projects", getProjectIdOrPath(projectIdOrPath), "import");
+ return (response.readEntity(ImportStatus.class));
+ }
+}
diff --git a/src/main/java/org/gitlab4j/api/models/ExportStatus.java b/src/main/java/org/gitlab4j/api/models/ExportStatus.java
new file mode 100644
index 0000000000000000000000000000000000000000..6efb892750c3601d83d6b26a254abc4a30a26a03
--- /dev/null
+++ b/src/main/java/org/gitlab4j/api/models/ExportStatus.java
@@ -0,0 +1,145 @@
+package org.gitlab4j.api.models;
+
+import java.util.Date;
+import java.util.Map;
+
+import org.gitlab4j.api.utils.JacksonJson;
+import org.gitlab4j.api.utils.JacksonJsonEnumHelper;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+public class ExportStatus {
+
+ /**
+ * Enum representing the status of the export.
+ */
+ public enum Status {
+
+ NONE, STARTED, FINISHED,
+
+ /**
+ * Represents that the export process has been completed successfully and the platform is
+ * performing some actions on the resulted file. For example, sending an email notifying
+ * the user to download the file, uploading the exported file to a web server, etc.
+ */
+ AFTER_EXPORT_ACTION;
+
+ private static JacksonJsonEnumHelper enumHelper = new JacksonJsonEnumHelper<>(Status.class);
+
+ @JsonCreator
+ public static Status forValue(String value) {
+ return enumHelper.forValue(value);
+ }
+
+ @JsonValue
+ public String toValue() {
+ return (enumHelper.toString(this));
+ }
+
+ @Override
+ public String toString() {
+ return (enumHelper.toString(this));
+ }
+ }
+
+ private Integer id;
+ private String description;
+ private String name;
+ private String nameWithNamespace;
+ private String path;
+ private String pathWithNamespace;
+ private Date createdAt;
+ private Status exportStatus;
+
+ @JsonProperty("_links")
+ private Map links;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getNameWithNamespace() {
+ return nameWithNamespace;
+ }
+
+ public void setNameWithNamespace(String nameWithNamespace) {
+ this.nameWithNamespace = nameWithNamespace;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public String getPathWithNamespace() {
+ return pathWithNamespace;
+ }
+
+ public void setPathWithNamespace(String pathWithNamespace) {
+ this.pathWithNamespace = pathWithNamespace;
+ }
+
+ public Date getCreatedAt() {
+ return createdAt;
+ }
+
+ public void setCreatedAt(Date createdAt) {
+ this.createdAt = createdAt;
+ }
+
+ public Status getExportStatus() {
+ return exportStatus;
+ }
+
+ public void setExportStatus(Status exportStatus) {
+ this.exportStatus = exportStatus;
+ }
+
+ public Map getLinks() {
+ return links;
+ }
+
+ public void setLinks(Map links) {
+ this.links = links;
+ }
+
+ @JsonIgnore
+ public String getLinkByName(String name) {
+ if (links == null || links.isEmpty()) {
+ return (null);
+ }
+
+ return (links.get(name));
+ }
+
+ @Override
+ public String toString() {
+ return (JacksonJson.toJsonString(this));
+ }
+}
diff --git a/src/main/java/org/gitlab4j/api/models/ImportStatus.java b/src/main/java/org/gitlab4j/api/models/ImportStatus.java
new file mode 100644
index 0000000000000000000000000000000000000000..5945456b4a31410e953449e44a540514e1c80d33
--- /dev/null
+++ b/src/main/java/org/gitlab4j/api/models/ImportStatus.java
@@ -0,0 +1,124 @@
+package org.gitlab4j.api.models;
+
+import java.util.Date;
+
+import org.gitlab4j.api.utils.JacksonJson;
+import org.gitlab4j.api.utils.JacksonJsonEnumHelper;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+public class ImportStatus {
+
+ /**
+ * Enum representing the status of the import.
+ */
+ public enum Status {
+
+ NONE, SCHEDULED, FAILED, STARTED, FINISHED;
+
+ private static JacksonJsonEnumHelper enumHelper = new JacksonJsonEnumHelper<>(Status.class);
+
+ @JsonCreator
+ public static Status forValue(String value) {
+ return enumHelper.forValue(value);
+ }
+
+ @JsonValue
+ public String toValue() {
+ return (enumHelper.toString(this));
+ }
+
+ @Override
+ public String toString() {
+ return (enumHelper.toString(this));
+ }
+ }
+
+ private Integer id;
+ private String description;
+ private String name;
+ private String nameWithNamespace;
+ private String path;
+ private String pathWithNamespace;
+ private Date createdAt;
+ private Status importStatus;
+ private String importError;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getNameWithNamespace() {
+ return nameWithNamespace;
+ }
+
+ public void setNameWithNamespace(String nameWithNamespace) {
+ this.nameWithNamespace = nameWithNamespace;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public String getPathWithNamespace() {
+ return pathWithNamespace;
+ }
+
+ public void setPathWithNamespace(String pathWithNamespace) {
+ this.pathWithNamespace = pathWithNamespace;
+ }
+
+ public Date getCreatedAt() {
+ return createdAt;
+ }
+
+ public void setCreatedAt(Date createdAt) {
+ this.createdAt = createdAt;
+ }
+
+ public Status getImportStatus() {
+ return importStatus;
+ }
+
+ public void setImportStatus(Status importStatus) {
+ this.importStatus = importStatus;
+ }
+
+ public String getImportError() {
+ return importError;
+ }
+
+ public void setImportError(String importError) {
+ this.importError = importError;
+ }
+
+ @Override
+ public String toString() {
+ return (JacksonJson.toJsonString(this));
+ }
+}
diff --git a/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java b/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java
index facefe57a55b37564db823dfc6c389a32eb08efd..735a6565550d793e0a4239a156e78b68aa033143 100644
--- a/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java
+++ b/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java
@@ -51,10 +51,12 @@ import org.gitlab4j.api.models.Email;
import org.gitlab4j.api.models.Epic;
import org.gitlab4j.api.models.EpicIssue;
import org.gitlab4j.api.models.Event;
+import org.gitlab4j.api.models.ExportStatus;
import org.gitlab4j.api.models.FileUpload;
import org.gitlab4j.api.models.Group;
import org.gitlab4j.api.models.HealthCheckInfo;
import org.gitlab4j.api.models.ImpersonationToken;
+import org.gitlab4j.api.models.ImportStatus;
import org.gitlab4j.api.models.Issue;
import org.gitlab4j.api.models.Job;
import org.gitlab4j.api.models.Key;
@@ -192,6 +194,12 @@ public class TestGitLabApiBeans {
assertTrue(compareJson(event, "event.json"));
}
+ @Test
+ public void testExportStatus() throws Exception {
+ ExportStatus exportStatus = unmarshalResource(ExportStatus.class, "export-status.json");
+ assertTrue(compareJson(exportStatus, "export-status.json"));
+ }
+
@Test
public void testFileUpload() throws Exception {
FileUpload fileUpload = unmarshalResource(FileUpload.class, "file-upload.json");
@@ -210,6 +218,12 @@ public class TestGitLabApiBeans {
assertTrue(compareJson(healthCheck, "health-check.json"));
}
+ @Test
+ public void testImportStatus() throws Exception {
+ ImportStatus importStatus = unmarshalResource(ImportStatus.class, "import-status.json");
+ assertTrue(compareJson(importStatus, "import-status.json"));
+ }
+
@Test
public void testIssue() throws Exception {
Issue issue = unmarshalResource(Issue.class, "issue.json");
diff --git a/src/test/java/org/gitlab4j/api/TestImportExportApi.java b/src/test/java/org/gitlab4j/api/TestImportExportApi.java
new file mode 100644
index 0000000000000000000000000000000000000000..df675589b246eb9456270aa7807c94168208a291
--- /dev/null
+++ b/src/test/java/org/gitlab4j/api/TestImportExportApi.java
@@ -0,0 +1,200 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Greg Messner
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package org.gitlab4j.api;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNotNull;
+
+import java.io.File;
+import java.util.Optional;
+
+import org.gitlab4j.api.models.ExportStatus;
+import org.gitlab4j.api.models.ImportStatus;
+import org.gitlab4j.api.models.Project;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runners.MethodSorters;
+
+/**
+ * In order for these tests to run you must set the following properties in ~/test-gitlab4j.properties
+ *
+ * TEST_NAMESPACE
+ * TEST_PROJECT_NAME
+ * TEST_HOST_URL
+ * TEST_PRIVATE_TOKEN
+ *
+ * If any of the above are NULL, all tests in this class will be skipped.
+ */
+@Category(IntegrationTest.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestImportExportApi extends AbstractIntegrationTest {
+
+ private static final String TEST_IMPORT_PROJECT_NAME = "test-import-project";
+ private static GitLabApi gitLabApi;
+ private static Project testProject;
+
+ public TestImportExportApi() {
+ super();
+ }
+
+ @BeforeClass
+ public static void setup() {
+
+ // Must setup the connection to the GitLab test server
+ gitLabApi = baseTestSetup();
+ testProject = getTestProject();
+
+ deleteAllTestProjects();
+ }
+
+ @AfterClass
+ public static void teardown() throws GitLabApiException {
+ deleteAllTestProjects();
+ }
+
+ private static void deleteAllTestProjects() {
+ if (gitLabApi == null) {
+ return;
+ }
+
+ try {
+ Project project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_IMPORT_PROJECT_NAME);
+ gitLabApi.getProjectApi().deleteProject(project);
+ } catch (GitLabApiException ignore) {}
+ }
+
+ @Before
+ public void beforeMethod() {
+ assumeNotNull(gitLabApi);
+ }
+
+
+ @Test
+ public void testScheduleExport() throws GitLabApiException {
+
+ // Arrange
+ assumeNotNull(testProject);
+
+ // Act
+ gitLabApi.getImportExportApi().scheduleExport(testProject);
+ ExportStatus exportStatus = gitLabApi.getImportExportApi().getExportStatus(testProject);
+
+ // Assert
+ assertNotNull(exportStatus);
+ ExportStatus.Status status = exportStatus.getExportStatus();
+ assertNotEquals(ExportStatus.Status.NONE, status);
+ }
+
+ @Test
+ public void testExportDownloadAndImport() throws GitLabApiException {
+
+ // Arrange
+ assumeNotNull(testProject);
+
+ // Act
+ gitLabApi.getImportExportApi().scheduleExport(testProject);
+
+ // Wait up to 20 seconds for the export to complete
+ System.out.print("Waiting for export to complete");
+ int retries = 0;
+ while (true) {
+
+ System.out.print(".");
+ ExportStatus exportStatus = gitLabApi.getImportExportApi().getExportStatus(testProject);
+ if (exportStatus.getExportStatus() == ExportStatus.Status.FINISHED) {
+ System.out.println("done");
+ break;
+ }
+
+ if (retries >= 20) {
+ System.out.println("aborting!");
+ fail("Project export is taking too long, failing test.");
+ }
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+
+ retries++;
+ }
+
+ File exportDownload = null;
+ try {
+
+ System.out.println("Downloading exported project");
+ exportDownload = gitLabApi.getImportExportApi().downloadExport(testProject, null);
+ assertNotNull(exportDownload);
+ assertTrue(exportDownload.length() > 10000);
+
+ ImportStatus importStatus = gitLabApi.getImportExportApi().startImport(null, exportDownload,
+ TEST_IMPORT_PROJECT_NAME, true, null);
+ assertNotNull(importStatus);
+ Integer newProjectId = importStatus.getId();
+
+ // Wait up to 20 seconds for the import to complete
+ System.out.print("Waiting for import to complete");
+ retries = 0;
+ while (true) {
+
+ System.out.print(".");
+ importStatus = gitLabApi.getImportExportApi().getImportStatus(newProjectId);
+ if (importStatus.getImportStatus() == ImportStatus.Status.FINISHED) {
+ System.out.println("done");
+ break;
+ }
+
+ if (retries >= 20) {
+ System.out.println("aborting!");
+ fail("Project import is taking too long, failing test.");
+ }
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+
+ retries++;
+ }
+
+ Optional newProject = gitLabApi.getProjectApi().getOptionalProject(newProjectId);
+ assertTrue(newProject.isPresent());
+ assertEquals(newProjectId, newProject.get().getId());
+ assertEquals(TEST_IMPORT_PROJECT_NAME, newProject.get().getName());
+
+ } finally {
+ if (exportDownload != null) {
+ exportDownload.delete();
+ }
+ }
+ }
+}
diff --git a/src/test/resources/org/gitlab4j/api/export-status.json b/src/test/resources/org/gitlab4j/api/export-status.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d3dfb5e6015805182bbad7560ab57fcec388ac4
--- /dev/null
+++ b/src/test/resources/org/gitlab4j/api/export-status.json
@@ -0,0 +1,14 @@
+{
+ "id": 1,
+ "description": "Itaque perspiciatis minima aspernatur corporis consequatur.",
+ "name": "Gitlab Test",
+ "name_with_namespace": "Gitlab Org / Gitlab Test",
+ "path": "gitlab-test",
+ "path_with_namespace": "gitlab-org/gitlab-test",
+ "created_at": "2017-08-29T04:36:44.383Z",
+ "export_status": "finished",
+ "_links": {
+ "api_url": "https://gitlab.example.com/api/v4/projects/1/export/download",
+ "web_url": "https://gitlab.example.com/gitlab-org/gitlab-test/download_export"
+ }
+}
diff --git a/src/test/resources/org/gitlab4j/api/import-status.json b/src/test/resources/org/gitlab4j/api/import-status.json
new file mode 100644
index 0000000000000000000000000000000000000000..ea1afc0ea0a231151bf7dd28da00d1ead979c463
--- /dev/null
+++ b/src/test/resources/org/gitlab4j/api/import-status.json
@@ -0,0 +1,9 @@
+{
+ "id": 1,
+ "name": "api-project",
+ "name_with_namespace": "Administrator / api-project",
+ "path": "api-project",
+ "path_with_namespace": "root/api-project",
+ "created_at": "2018-02-13T09:05:58.023Z",
+ "import_status": "scheduled"
+}
\ No newline at end of file