Commit 958ef4c2 authored by Greg Messner's avatar Greg Messner
Browse files

Added support for V4 of the GitLab API (#19).

parent a5aa83e4
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<groupId>org.gitlab4j</groupId> <groupId>org.gitlab4j</groupId>
<artifactId>gitlab4j-api</artifactId> <artifactId>gitlab4j-api</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>4.1.7-SNAPSHOT</version> <version>4.2.0-SNAPSHOT</version>
<name>GitLab API Java Client</name> <name>GitLab API Java Client</name>
<description>GitLab API for Java (gitlab4j-api) provides a full featured Java API for working with GitLab repositories via the GitLab REST API</description> <description>GitLab API for Java (gitlab4j-api) provides a full featured Java API for working with GitLab repositories via the GitLab REST API</description>
<url>http://www.messners.com/#gitlab4j-api/gitlab4j-api.html</url> <url>http://www.messners.com/#gitlab4j-api/gitlab4j-api.html</url>
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
<properties> <properties>
<jdk.version>1.7</jdk.version> <jdk.version>1.7</jdk.version>
<jersey.version>2.25.1</jersey.version> <jersey.version>2.25.1</jersey.version>
<jackson.version>2.8.6</jackson.version> <jackson.version>2.8.8</jackson.version>
<junit.version>4.12</junit.version> <junit.version>4.12</junit.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
......
...@@ -4,7 +4,11 @@ import javax.ws.rs.NotAuthorizedException; ...@@ -4,7 +4,11 @@ import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.core.Form; import javax.ws.rs.core.Form;
import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import org.gitlab4j.api.GitLabApi.ApiVersion;
import java.net.URL; import java.net.URL;
import java.net.URLEncoder;
/** /**
* This class is the base class for all the sub API classes. It provides implementations of * This class is the base class for all the sub API classes. It provides implementations of
...@@ -18,10 +22,26 @@ public abstract class AbstractApi { ...@@ -18,10 +22,26 @@ public abstract class AbstractApi {
this.gitLabApi = gitLabApi; this.gitLabApi = gitLabApi;
} }
protected ApiVersion getApiVersion() {
return (gitLabApi.getApiVersion());
}
protected boolean isApiVersion(ApiVersion apiVersion) {
return (gitLabApi.getApiVersion() == apiVersion);
}
protected GitLabApiClient getApiClient() { protected GitLabApiClient getApiClient() {
return (gitLabApi.getApiClient()); return (gitLabApi.getApiClient());
} }
protected String urlEncode(String s) throws GitLabApiException {
try {
return (URLEncoder.encode(s, "UTF-8"));
} catch (Exception e) {
throw new GitLabApiException(e);
}
}
/** /**
* Perform an HTTP GET call with the specified query parameters and path objects, returning * Perform an HTTP GET call with the specified query parameters and path objects, returning
* a ClientResponse instance with the data returned from the endpoint. * a ClientResponse instance with the data returned from the endpoint.
......
...@@ -10,7 +10,16 @@ import org.gitlab4j.api.models.Session; ...@@ -10,7 +10,16 @@ import org.gitlab4j.api.models.Session;
*/ */
public class GitLabApi { public class GitLabApi {
public enum ApiVersion {
V3, V4;
public String getApiNamespace() {
return ("/api/" + name().toLowerCase());
}
}
GitLabApiClient apiClient; GitLabApiClient apiClient;
private ApiVersion apiVersion;
private CommitsApi commitsApi; private CommitsApi commitsApi;
private GroupApi groupApi; private GroupApi groupApi;
private MergeRequestApi mergeRequestApi; private MergeRequestApi mergeRequestApi;
...@@ -25,22 +34,54 @@ public class GitLabApi { ...@@ -25,22 +34,54 @@ public class GitLabApi {
private Session session; private Session session;
/** /**
* Logs into GitLab using provided {@code username} and {@code password}, and creates a new {@code GitLabApi} instance using returned private token * Logs into GitLab using provided {@code username} and {@code password}, and creates a new {@code GitLabApi} instance
* * using returned private token and the specified GitLab API version.
*
* @param apiVersion the ApiVersion specifying which version of the API to use
* @param url GitLab URL * @param url GitLab URL
* @param username user name for which private token should be obtained * @param username user name for which private token should be obtained
* @param password password for a given {@code username} * @param password password for a given {@code username}
* @return new {@code GitLabApi} instance configured for a user-specific token * @return new {@code GitLabApi} instance configured for a user-specific token
* @throws GitLabApiException GitLabApiException if any exception occurs during execution * @throws GitLabApiException GitLabApiException if any exception occurs during execution
*/ */
public static GitLabApi create(String url, String username, String password) throws GitLabApiException { public static GitLabApi login(ApiVersion apiVersion, String url, String username, String password) throws GitLabApiException {
SessionApi sessionApi = new SessionApi(new GitLabApi(url, (String)null)); SessionApi sessionApi = new SessionApi(new GitLabApi(apiVersion, url, (String)null));
Session session = sessionApi.login(username, null, password); Session session = sessionApi.login(username, null, password);
return (new GitLabApi(url, session)); return (new GitLabApi(url, session));
} }
/** /**
* If this instance was created with {@link #create(String, String, String)} this method will * Logs into GitLab using provided {@code username} and {@code password}, and creates a new {@code GitLabApi} instance
* using returned private token using GitLab API version 4.
*
* @param url GitLab URL
* @param username user name for which private token should be obtained
* @param password password for a given {@code username}
* @return new {@code GitLabApi} instance configured for a user-specific token
* @throws GitLabApiException GitLabApiException if any exception occurs during execution
*/
public static GitLabApi login(String url, String username, String password) throws GitLabApiException {
return (login(ApiVersion.V4, url, username, password));
}
/**
* Logs into GitLab using provided {@code username} and {@code password}, and creates a new {@code GitLabApi} instance
* using returned private token and specified GitLab API version.
*
* @param url GitLab URL
* @param username user name for which private token should be obtained
* @param password password for a given {@code username}
* @return new {@code GitLabApi} instance configured for a user-specific token
* @throws GitLabApiException GitLabApiException if any exception occurs during execution
* @deprecated As of release 4.2.0, replaced by {@link #login(String, String, String)}
*/
@Deprecated
public static GitLabApi create(String url, String username, String password) throws GitLabApiException {
return (login(url, username, password));
}
/**
* If this instance was created with {@link #login(String, String, String)} this method will
* return the Session instance returned by the GitLab API on login, otherwise returns null. * return the Session instance returned by the GitLab API on login, otherwise returns null.
* *
* @return the Session instance * @return the Session instance
...@@ -50,42 +91,83 @@ public class GitLabApi { ...@@ -50,42 +91,83 @@ public class GitLabApi {
} }
/** /**
* Constructs a GitLabApi instance set up to interact with the GitLab server * Constructs a GitLabApi instance set up to interact with the GitLab server using the specified GitLab API version.
* specified by hostUrl. *
* @param apiVersion the ApiVersion specifying which version of the API to use
* @param hostUrl the URL of the GitLab server
* @param privateToken to private token to use for access to the API
*/
public GitLabApi(ApiVersion apiVersion, String hostUrl, String privateToken) {
this(apiVersion, hostUrl, privateToken, null);
}
/**
* Constructs a GitLabApi instance set up to interact with the GitLab server using GitLab API version 4.
* *
* @param hostUrl the URL of the GitLab server * @param hostUrl the URL of the GitLab server
* @param privateToken to private token to use for access to the API * @param privateToken to private token to use for access to the API
*/ */
public GitLabApi(String hostUrl, String privateToken) { public GitLabApi(String hostUrl, String privateToken) {
this(hostUrl, privateToken, null); this(ApiVersion.V4, hostUrl, privateToken, null);
} }
/** /**
* Constructs a GitLabApi instance set up to interact with the GitLab server * Constructs a GitLabApi instance set up to interact with the GitLab server using the specified GitLab API version.
* specified by hostUrl. *
* @param apiVersion the ApiVersion specifying which version of the API to use
* @param hostUrl the URL of the GitLab server
* @param session the Session instance obtained by logining into the GitLab server
*/
public GitLabApi(ApiVersion apiVersion, String hostUrl, Session session) {
this(apiVersion, hostUrl, session.getPrivateToken(), null);
this.session = session;
}
/**
* Constructs a GitLabApi instance set up to interact with the GitLab server using GitLab API version 4.
* *
* @param hostUrl the URL of the GitLab server * @param hostUrl the URL of the GitLab server
* @param session the Session instance obtained by logining into the GitLab server * @param session the Session instance obtained by logining into the GitLab server
*/ */
public GitLabApi(String hostUrl, Session session) { public GitLabApi(String hostUrl, Session session) {
this(hostUrl, session.getPrivateToken(), null); this(ApiVersion.V4, hostUrl, session);
this.session = session; }
/**
* Constructs a GitLabApi instance set up to interact with the GitLab server using the specified GitLab API version.
*
* @param apiVersion the ApiVersion specifying which version of the API to use
* @param hostUrl the URL of the GitLab server
* @param privateToken to private token to use for access to the API
* @param secretToken use this token to validate received payloads
*/
public GitLabApi(ApiVersion apiVersion, String hostUrl, String privateToken, String secretToken) {
this(apiVersion, hostUrl, privateToken, secretToken, null);
} }
/** /**
* Constructs a GitLabApi instance set up to interact with the GitLab server * Constructs a GitLabApi instance set up to interact with the GitLab server using GitLab API version 4.
* specified by hostUrl.
* *
* @param hostUrl the URL of the GitLab server * @param hostUrl the URL of the GitLab server
* @param privateToken to private token to use for access to the API * @param privateToken to private token to use for access to the API
* @param secretToken use this token to validate received payloads * @param secretToken use this token to validate received payloads
*/ */
public GitLabApi(String hostUrl, String privateToken, String secretToken) { public GitLabApi(String hostUrl, String privateToken, String secretToken) {
this(hostUrl, privateToken, secretToken, null); this(ApiVersion.V4, hostUrl, privateToken, secretToken);
} }
public GitLabApi(String hostUrl, String privateToken, String secretToken, Map<String, Object> clientConfigProperties) { /**
apiClient = new GitLabApiClient(hostUrl, privateToken, secretToken, clientConfigProperties); * Constructs a GitLabApi instance set up to interact with the GitLab server specified by GitLab API version.
*
* @param apiVersion the ApiVersion specifying which version of the API to use
* @param hostUrl the URL of the GitLab server
* @param privateToken to private token to use for access to the API
* @param secretToken use this token to validate received payloads
* @param clientConfigProperties Map instance with additional properties for the Jersey client connection
*/
public GitLabApi(ApiVersion apiVersion, String hostUrl, String privateToken, String secretToken, Map<String, Object> clientConfigProperties) {
this.apiVersion = apiVersion;
apiClient = new GitLabApiClient(apiVersion, hostUrl, privateToken, secretToken, clientConfigProperties);
commitsApi = new CommitsApi(this); commitsApi = new CommitsApi(this);
groupApi = new GroupApi(this); groupApi = new GroupApi(this);
mergeRequestApi = new MergeRequestApi(this); mergeRequestApi = new MergeRequestApi(this);
...@@ -98,6 +180,27 @@ public class GitLabApi { ...@@ -98,6 +180,27 @@ public class GitLabApi {
repositoryFileApi = new RepositoryFileApi(this); repositoryFileApi = new RepositoryFileApi(this);
} }
/**
* Constructs a GitLabApi instance set up to interact with the GitLab server using GitLab API version 4.
*
* @param hostUrl the URL of the GitLab server
* @param privateToken to private token to use for access to the API
* @param secretToken use this token to validate received payloads
* @param clientConfigProperties Map instance with additional properties for the Jersey client connection
*/
public GitLabApi(String hostUrl, String privateToken, String secretToken, Map<String, Object> clientConfigProperties) {
this(ApiVersion.V4, hostUrl, privateToken, secretToken, clientConfigProperties);
}
/**
* Return the GitLab API version that this instance is using.
*
* @return the GitLab API version that this instance is using
*/
public ApiVersion getApiVersion() {
return (apiVersion);
}
/** /**
* Return the GitLabApiClient associated with this instance. This is used by all the sub API classes * Return the GitLabApiClient associated with this instance. This is used by all the sub API classes
* to communicate with the GitLab API. * to communicate with the GitLab API.
......
package org.gitlab4j.api; package org.gitlab4j.api;
import org.gitlab4j.api.utils.JacksonJson; import java.io.IOException;
import org.glassfish.jersey.client.ClientConfig; import java.net.URL;
import org.glassfish.jersey.client.ClientProperties; import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;
import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
...@@ -20,15 +26,11 @@ import javax.ws.rs.core.Form; ...@@ -20,15 +26,11 @@ import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.io.IOException;
import java.net.URL; import org.gitlab4j.api.GitLabApi.ApiVersion;
import java.security.GeneralSecurityException; import org.gitlab4j.api.utils.JacksonJson;
import java.security.NoSuchAlgorithmException; import org.glassfish.jersey.client.ClientConfig;
import java.security.SecureRandom; import org.glassfish.jersey.client.ClientProperties;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;
/** /**
* This class utilizes the Jersey client package to communicate with a GitLab API endpoint. * This class utilizes the Jersey client package to communicate with a GitLab API endpoint.
...@@ -37,7 +39,6 @@ public class GitLabApiClient { ...@@ -37,7 +39,6 @@ public class GitLabApiClient {
protected static final String PRIVATE_TOKEN_HEADER = "PRIVATE-TOKEN"; protected static final String PRIVATE_TOKEN_HEADER = "PRIVATE-TOKEN";
protected static final String X_GITLAB_TOKEN_HEADER = "X-Gitlab-Token"; protected static final String X_GITLAB_TOKEN_HEADER = "X-Gitlab-Token";
protected static final String API_NAMESPACE = "/api/v3";
private ClientConfig clientConfig; private ClientConfig clientConfig;
private Client apiClient; private Client apiClient;
...@@ -48,18 +49,43 @@ public class GitLabApiClient { ...@@ -48,18 +49,43 @@ public class GitLabApiClient {
private static SSLSocketFactory defaultSocketFactory; private static SSLSocketFactory defaultSocketFactory;
/** /**
* Construct an instance to communicate with a GitLab API server using the specified * Construct an instance to communicate with a GitLab API server using the specified GitLab API version,
* server URL, private token, and secret token.
*
* @param apiVersion the ApiVersion specifying which version of the API to use
* @param hostUrl the URL to the GitLab API server
* @param privateToken the private token to authenticate with
*/
public GitLabApiClient(ApiVersion apiVersion, String hostUrl, String privateToken) {
this(apiVersion, hostUrl, privateToken, null);
}
/**
* Construct an instance to communicate with a GitLab API server using GitLab API version 4, and the specified
* server URL, private token, and secret token. * server URL, private token, and secret token.
* *
* @param hostUrl the URL to the GitLab API server * @param hostUrl the URL to the GitLab API server
* @param privateToken the private token to authenticate with * @param privateToken the private token to authenticate with
*/ */
public GitLabApiClient(String hostUrl, String privateToken) { public GitLabApiClient(String hostUrl, String privateToken) {
this(hostUrl, privateToken, null); this(ApiVersion.V4, hostUrl, privateToken, null);
}
/**
* Construct an instance to communicate with a GitLab API server using the specified GitLab API version,
* server URL, private token, and secret token.
*
* @param apiVersion the ApiVersion specifying which version of the API to use
* @param hostUrl the URL to the GitLab API server
* @param privateToken the private token to authenticate with
* @param secretToken use this token to validate received payloads
*/
public GitLabApiClient(ApiVersion apiVersion, String hostUrl, String privateToken, String secretToken) {
this(apiVersion, hostUrl, privateToken, secretToken, null);
} }
/** /**
* Construct an instance to communicate with a GitLab API server using the specified * Construct an instance to communicate with a GitLab API server using GitLab API version 4, and the specified
* server URL, private token, and secret token. * server URL, private token, and secret token.
* *
* @param hostUrl the URL to the GitLab API server * @param hostUrl the URL to the GitLab API server
...@@ -67,22 +93,23 @@ public class GitLabApiClient { ...@@ -67,22 +93,23 @@ public class GitLabApiClient {
* @param secretToken use this token to validate received payloads * @param secretToken use this token to validate received payloads
*/ */
public GitLabApiClient(String hostUrl, String privateToken, String secretToken) { public GitLabApiClient(String hostUrl, String privateToken, String secretToken) {
this(hostUrl, privateToken, secretToken, null); this(ApiVersion.V4, hostUrl, privateToken, secretToken, null);
} }
/** /**
* Construct an instance to communicate with a GitLab API server using the specified * Construct an instance to communicate with a GitLab API server using the specified GitLab API version,
* server URL and private token. * server URL and private token.
* *
* @param apiVersion the ApiVersion specifying which version of the API to use
* @param hostUrl the URL to the GitLab API server * @param hostUrl the URL to the GitLab API server
* @param privateToken the private token to authenticate with * @param privateToken the private token to authenticate with
* @param secretToken use this token to validate received payloads * @param secretToken use this token to validate received payloads
* @param clientConfigProperties the properties given to Jersey's clientconfig * @param clientConfigProperties the properties given to Jersey's clientconfig
*/ */
public GitLabApiClient(String hostUrl, String privateToken, String secretToken, Map<String, Object> clientConfigProperties) { public GitLabApiClient(ApiVersion apiVersion, String hostUrl, String privateToken, String secretToken, Map<String, Object> clientConfigProperties) {
// Remove the trailing "/" from the hostUrl if present // Remove the trailing "/" from the hostUrl if present
this.hostUrl = (hostUrl.endsWith("/") ? hostUrl.replaceAll("/$", "") : hostUrl) + API_NAMESPACE; this.hostUrl = (hostUrl.endsWith("/") ? hostUrl.replaceAll("/$", "") : hostUrl) + apiVersion.getApiNamespace();
this.privateToken = privateToken; this.privateToken = privateToken;
if (secretToken != null) { if (secretToken != null) {
...@@ -100,6 +127,19 @@ public class GitLabApiClient { ...@@ -100,6 +127,19 @@ public class GitLabApiClient {
clientConfig.register(JacksonJson.class); clientConfig.register(JacksonJson.class);
} }
/**
* Construct an instance to communicate with a GitLab API server using GitLab API version 4, and the specified
* server URL and private token.
*
* @param hostUrl the URL to the GitLab API server
* @param privateToken the private token to authenticate with
* @param secretToken use this token to validate received payloads
* @param clientConfigProperties the properties given to Jersey's clientconfig
*/
public GitLabApiClient(String hostUrl, String privateToken, String secretToken, Map<String, Object> clientConfigProperties) {
this(ApiVersion.V4, hostUrl, privateToken, secretToken, clientConfigProperties);
}
/** /**
* Returns true if the API is setup to ignore SSL certificate errors, otherwise returns false. * Returns true if the API is setup to ignore SSL certificate errors, otherwise returns false.
* *
......
package org.gitlab4j.api; package org.gitlab4j.api;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import org.gitlab4j.api.GitLabApi.ApiVersion;
import org.gitlab4j.api.models.Event; import org.gitlab4j.api.models.Event;
import org.gitlab4j.api.models.Issue; import org.gitlab4j.api.models.Issue;
import org.gitlab4j.api.models.Member; import org.gitlab4j.api.models.Member;
import org.gitlab4j.api.models.Project; import org.gitlab4j.api.models.Project;
import org.gitlab4j.api.models.ProjectHook; import org.gitlab4j.api.models.ProjectHook;
import org.gitlab4j.api.models.Visibility;
import org.glassfish.jersey.uri.UriComponent; import org.glassfish.jersey.uri.UriComponent;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
/** /**
* This class provides an entry point to all the GitLab API project calls. * This class provides an entry point to all the GitLab API project calls.
*/ */
...@@ -37,6 +40,21 @@ public class ProjectApi extends AbstractApi { ...@@ -37,6 +40,21 @@ public class ProjectApi extends AbstractApi {
})); }));
} }
/**
* Get a list of projects that the authenticated user is a member of.
*
* GET /projects
*
* @return a list of projects that the authenticated user is a member of
* @throws GitLabApiException if any exception occurs
*/
public List<Project> getMemberProjects() throws GitLabApiException {
Form formData = new GitLabApiForm().withParam("membership", true);
Response response = get(Response.Status.OK, formData.asMap(), "projects");
return (response.readEntity(new GenericType<List<Project>>() {
}));
}
/** /**
* Get a list of all GitLab projects (admin only). * Get a list of all GitLab projects (admin only).
* *
...@@ -60,6 +78,7 @@ public class ProjectApi extends AbstractApi { ...@@ -60,6 +78,7 @@ public class ProjectApi extends AbstractApi {
* @throws GitLabApiException if any exception occurs * @throws GitLabApiException if any exception occurs
*/ */
public List<Project> getOwnedProjects() throws GitLabApiException { public List<Project> getOwnedProjects() throws GitLabApiException {
Form formData = new GitLabApiForm().withParam("owned", true); Form formData = new GitLabApiForm().withParam("owned", true);
Response response = get(Response.Status.OK, formData.asMap(), "projects"); Response response = get(Response.Status.OK, formData.asMap(), "projects");
return (response.readEntity(new GenericType<List<Project>>() { return (response.readEntity(new GenericType<List<Project>>() {
...@@ -164,7 +183,7 @@ public class ProjectApi extends AbstractApi { ...@@ -164,7 +183,7 @@ public class ProjectApi extends AbstractApi {
* path (name or path are required) - new project path * path (name or path are required) - new project path
* defaultBranch (optional) - master by default * defaultBranch (optional) - master by default
* description (optional) - short project description * description (optional) - short project description
* public (optional) - if true same as setting visibility_level = 20 * visibility (optional) - Limit by visibility public, internal, or private
* visibilityLevel (optional) * visibilityLevel (optional)
* issuesEnabled (optional) - Enable issues for this project * issuesEnabled (optional) - Enable issues for this project
* mergeRequestsEnabled (optional) - Enable merge requests for this project * mergeRequestsEnabled (optional) - Enable merge requests for this project
...@@ -212,7 +231,6 @@ public class ProjectApi extends AbstractApi { ...@@ -212,7 +231,6 @@ public class ProjectApi extends AbstractApi {
.withParam("snippets_enabled", project.getSnippetsEnabled()) .withParam("snippets_enabled", project.getSnippetsEnabled())
.withParam("shared_runners_enabled", project.getSharedRunnersEnabled()) .withParam("shared_runners_enabled", project.getSharedRunnersEnabled())
.withParam("public_jobs", project.getPublicJobs()) .withParam("public_jobs", project.getPublicJobs())
.withParam("public", project.getPublic())
.withParam("visibility_level", project.getVisibilityLevel()) .withParam("visibility_level", project.getVisibilityLevel())
.withParam("only_allow_merge_if_pipeline_succeeds", project.getOnlyAllowMergeIfPipelineSucceeds()) .withParam("only_allow_merge_if_pipeline_succeeds", project.getOnlyAllowMergeIfPipelineSucceeds())
.withParam("only_allow_merge_if_all_discussions_are_resolved", project.getOnlyAllowMergeIfAllDiscussionsAreResolved()) .withParam("only_allow_merge_if_all_discussions_are_resolved", project.getOnlyAllowMergeIfAllDiscussionsAreResolved())
...@@ -221,7 +239,16 @@ public class ProjectApi extends AbstractApi { ...@@ -221,7 +239,16 @@ public class ProjectApi extends AbstractApi {
.withParam("repository_storage", project.getRepositoryStorage()) .withParam("repository_storage", project.getRepositoryStorage())
.withParam("approvals_before_merge", project.getApprovalsBeforeMerge()) .withParam("approvals_before_merge", project.getApprovalsBeforeMerge())
.withParam("import_url", importUrl); .withParam("import_url", importUrl);
if (isApiVersion(ApiVersion.V3)) {
boolean isPublic = (project.getPublic() != null ? project.getPublic() : project.getVisibility() == Visibility.PUBLIC);
formData.withParam("public", isPublic);
} else {
Visibility visibility = (project.getVisibility() != null ? project.getVisibility() :
project.getPublic() == Boolean.TRUE ? Visibility.PUBLIC : null);
formData.withParam("visibility", visibility);
}
if (project.getNamespace() != null) { if (project.getNamespace() != null) {
formData.withParam("namespace_id", project.getNamespace().getId()); formData.withParam("namespace_id", project.getNamespace().getId());
} }
...@@ -230,6 +257,51 @@ public class ProjectApi extends AbstractApi { ...@@ -230,6 +257,51 @@ public class ProjectApi extends AbstractApi {
return (response.readEntity(Project.class)); return (response.readEntity(Project.class));
} }
/**
* Creates a Project
*
* @param name The name of the project
* @param namespaceId The Namespace for the new project, otherwise null indicates to use the GitLab default (user)
* @param description A description for the project, null otherwise
* @param issuesEnabled Whether Issues should be enabled, otherwise null indicates to use GitLab default
* @param mergeRequestsEnabled Whether Merge Requests should be enabled, otherwise null indicates to use GitLab default
* @param wikiEnabled Whether a Wiki should be enabled, otherwise null indicates to use GitLab default
* @param snippetsEnabled Whether Snippets should be enabled, otherwise null indicates to use GitLab default
* @param visibility The visibility of the project, otherwise null indicates to use GitLab default
* @param visibilityLevel The visibility level of the project, otherwise null indicates to use GitLab default
* @param importUrl The Import URL for the project, otherwise null
* @return the GitLab Project
* @throws GitLabApiException if any exception occurs
*/
public Project createProject(String name, Integer namespaceId, String description, Boolean issuesEnabled, Boolean mergeRequestsEnabled,
Boolean wikiEnabled, Boolean snippetsEnabled, Visibility visibility, Integer visibilityLevel, String importUrl) throws GitLabApiException {
if (isApiVersion(ApiVersion.V3)) {
Boolean isPublic = Visibility.PUBLIC == visibility;
return (createProject(name, namespaceId, description, issuesEnabled, mergeRequestsEnabled,
wikiEnabled, snippetsEnabled, isPublic, visibilityLevel, importUrl));
}
if (name == null || name.trim().length() == 0) {
return (null);
}
GitLabApiForm formData = new GitLabApiForm()
.withParam("name", name, true)
.withParam("namespace_id", namespaceId)
.withParam("description", description)
.withParam("issues_enabled", issuesEnabled)
.withParam("merge_requests_enabled", mergeRequestsEnabled)
.withParam("wiki_enabled", wikiEnabled)
.withParam("snippets_enabled", snippetsEnabled)
.withParam("visibility_level", visibilityLevel)
.withParam("visibility", visibility)
.withParam("import_url", importUrl);
Response response = post(Response.Status.CREATED, formData, "projects");
return (response.readEntity(Project.class));
}
/** /**
* Creates a Project * Creates a Project
* *
...@@ -245,7 +317,10 @@ public class ProjectApi extends AbstractApi { ...@@ -245,7 +317,10 @@ public class ProjectApi extends AbstractApi {
* @param importUrl The Import URL for the project, otherwise null * @param importUrl The Import URL for the project, otherwise null
* @return the GitLab Project * @return the GitLab Project
* @throws GitLabApiException if any exception occurs * @throws GitLabApiException if any exception occurs
* @deprecated As of release 4.2.0, replaced by {@link #createProject(String, Integer, String, Boolean, Boolean,
* Boolean, Boolean, Visibility, Integer, String)}
*/ */
@Deprecated
public Project createProject(String name, Integer namespaceId, String description, Boolean issuesEnabled, Boolean mergeRequestsEnabled, public Project createProject(String name, Integer namespaceId, String description, Boolean issuesEnabled, Boolean mergeRequestsEnabled,
Boolean wikiEnabled, Boolean snippetsEnabled, Boolean isPublic, Integer visibilityLevel, String importUrl) throws GitLabApiException { Boolean wikiEnabled, Boolean snippetsEnabled, Boolean isPublic, Integer visibilityLevel, String importUrl) throws GitLabApiException {
...@@ -261,10 +336,15 @@ public class ProjectApi extends AbstractApi { ...@@ -261,10 +336,15 @@ public class ProjectApi extends AbstractApi {
.withParam("merge_requests_enabled", mergeRequestsEnabled) .withParam("merge_requests_enabled", mergeRequestsEnabled)
.withParam("wiki_enabled", wikiEnabled) .withParam("wiki_enabled", wikiEnabled)
.withParam("snippets_enabled", snippetsEnabled) .withParam("snippets_enabled", snippetsEnabled)
.withParam("public", isPublic)
.withParam("visibility_level", visibilityLevel) .withParam("visibility_level", visibilityLevel)
.withParam("import_url", importUrl); .withParam("import_url", importUrl);
if (isApiVersion(ApiVersion.V3)) {
formData.withParam("public", isPublic);
} else if (isPublic) {
formData.withParam("visibility", Visibility.PUBLIC);
}
Response response = post(Response.Status.CREATED, formData, "projects"); Response response = post(Response.Status.CREATED, formData, "projects");
return (response.readEntity(Project.class)); return (response.readEntity(Project.class));
} }
...@@ -283,7 +363,8 @@ public class ProjectApi extends AbstractApi { ...@@ -283,7 +363,8 @@ public class ProjectApi extends AbstractApi {
throw new RuntimeException("projectId cannot be null"); throw new RuntimeException("projectId cannot be null");
} }
delete(Response.Status.OK, null, "projects", projectId); Response.Status expectedStatus = (isApiVersion(ApiVersion.V3) ? Response.Status.OK : Response.Status.ACCEPTED);
delete(expectedStatus, null, "projects", projectId);
} }
/** /**
......
...@@ -11,6 +11,7 @@ import javax.ws.rs.core.Form; ...@@ -11,6 +11,7 @@ import javax.ws.rs.core.Form;
import javax.ws.rs.core.GenericType; import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import org.gitlab4j.api.GitLabApi.ApiVersion;
import org.gitlab4j.api.models.Branch; import org.gitlab4j.api.models.Branch;
import org.gitlab4j.api.models.Tag; import org.gitlab4j.api.models.Tag;
import org.gitlab4j.api.models.TreeItem; import org.gitlab4j.api.models.TreeItem;
...@@ -69,7 +70,7 @@ public class RepositoryApi extends AbstractApi { ...@@ -69,7 +70,7 @@ public class RepositoryApi extends AbstractApi {
public Branch createBranch(Integer projectId, String branchName, String ref) throws GitLabApiException { public Branch createBranch(Integer projectId, String branchName, String ref) throws GitLabApiException {
Form formData = new GitLabApiForm() Form formData = new GitLabApiForm()
.withParam("branch_name", branchName, true) .withParam(isApiVersion(ApiVersion.V3) ? "branch_name" : "branch", branchName, true)
.withParam("ref", ref, true); .withParam("ref", ref, true);
Response response = post(Response.Status.CREATED, formData.asMap(), "projects", projectId, "repository", "branches"); Response response = post(Response.Status.CREATED, formData.asMap(), "projects", projectId, "repository", "branches");
return (response.readEntity(Branch.class)); return (response.readEntity(Branch.class));
...@@ -87,7 +88,8 @@ public class RepositoryApi extends AbstractApi { ...@@ -87,7 +88,8 @@ public class RepositoryApi extends AbstractApi {
* @throws GitLabApiException if any exception occurs * @throws GitLabApiException if any exception occurs
*/ */
public void deleteBranch(Integer projectId, String branchName) throws GitLabApiException { public void deleteBranch(Integer projectId, String branchName) throws GitLabApiException {
delete(Response.Status.OK, null, "projects", projectId, "repository", "branches", branchName); Response.Status expectedStatus = (isApiVersion(ApiVersion.V3) ? Response.Status.OK : Response.Status.NO_CONTENT);
delete(expectedStatus, null, "projects", projectId, "repository", "branches", urlEncode(branchName));
} }
/** /**
......
...@@ -3,6 +3,7 @@ package org.gitlab4j.api; ...@@ -3,6 +3,7 @@ package org.gitlab4j.api;
import javax.ws.rs.core.Form; import javax.ws.rs.core.Form;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import org.gitlab4j.api.GitLabApi.ApiVersion;
import org.gitlab4j.api.models.RepositoryFile; import org.gitlab4j.api.models.RepositoryFile;
/** /**
...@@ -27,6 +28,31 @@ public class RepositoryFileApi extends AbstractApi { ...@@ -27,6 +28,31 @@ public class RepositoryFileApi extends AbstractApi {
* @throws GitLabApiException if any exception occurs * @throws GitLabApiException if any exception occurs
*/ */
public RepositoryFile getFile(String filePath, Integer projectId, String ref) throws GitLabApiException { public RepositoryFile getFile(String filePath, Integer projectId, String ref) throws GitLabApiException {
if (isApiVersion(ApiVersion.V3)) {
return (getFileV3(filePath, projectId, ref));
}
Form form = new Form();
addFormParam(form, "ref", ref, true);
Response response = get(Response.Status.OK, form.asMap(),
"projects", projectId, "repository", "files", urlEncode(filePath));
return (response.readEntity(RepositoryFile.class));
}
/**
* Get file from repository. Allows you to receive information about file in repository like name, size, content.
* Note that file content is Base64 encoded.
*
* GET /projects/:id/repository/files
*
* @param filePath (required) - Full path to new file. Ex. lib/class.rb
* @param projectId (required) - the project ID
* @param ref (required) - The name of branch, tag or commit
* @return a RepositoryFile instance with the file info
* @throws GitLabApiException if any exception occurs
*/
protected RepositoryFile getFileV3(String filePath, Integer projectId, String ref) throws GitLabApiException {
Form form = new Form(); Form form = new Form();
addFormParam(form, "file_path", filePath, true); addFormParam(form, "file_path", filePath, true);
addFormParam(form, "ref", ref, true); addFormParam(form, "ref", ref, true);
...@@ -105,7 +131,7 @@ public class RepositoryFileApi extends AbstractApi { ...@@ -105,7 +131,7 @@ public class RepositoryFileApi extends AbstractApi {
Form form = new Form(); Form form = new Form();
addFormParam(form, "file_path", filePath, true); addFormParam(form, "file_path", filePath, true);
addFormParam(form, "branch_name", branchName, true); addFormParam(form, isApiVersion(ApiVersion.V3) ? "branch_name" : "branch", branchName, true);
addFormParam(form, "commit_message", commitMessage, true); addFormParam(form, "commit_message", commitMessage, true);
delete(Response.Status.OK, form.asMap(), "projects", projectId, "repository", "files"); delete(Response.Status.OK, form.asMap(), "projects", projectId, "repository", "files");
} }
...@@ -113,7 +139,7 @@ public class RepositoryFileApi extends AbstractApi { ...@@ -113,7 +139,7 @@ public class RepositoryFileApi extends AbstractApi {
private Form file2form(RepositoryFile file, String branchName, String commitMessage) { private Form file2form(RepositoryFile file, String branchName, String commitMessage) {
Form form = new Form(); Form form = new Form();
addFormParam(form, "file_path", file.getFilePath(), true); addFormParam(form, "file_path", file.getFilePath(), true);
addFormParam(form, "branch_name", branchName, true); addFormParam(form, isApiVersion(ApiVersion.V3) ? "branch_name" : "branch", branchName, true);
addFormParam(form, "encoding", file.getEncoding(), false); addFormParam(form, "encoding", file.getEncoding(), false);
addFormParam(form, "content", file.getContent(), true); addFormParam(form, "content", file.getContent(), true);
addFormParam(form, "commit_message", commitMessage, true); addFormParam(form, "commit_message", commitMessage, true);
......
...@@ -10,7 +10,7 @@ public enum AccessLevel { ...@@ -10,7 +10,7 @@ public enum AccessLevel {
NONE(0), GUEST(10), REPORTER(20), DEVELOPER(30), MASTER(40), OWNER(50); NONE(0), GUEST(10), REPORTER(20), DEVELOPER(30), MASTER(40), OWNER(50);
public final int value; public final Integer value;
AccessLevel(int value) { AccessLevel(int value) {
this.value = value; this.value = value;
...@@ -31,4 +31,9 @@ public enum AccessLevel { ...@@ -31,4 +31,9 @@ public enum AccessLevel {
public Integer toValue() { public Integer toValue() {
return (value); return (value);
} }
@Override
public String toString() {
return (value.toString());
}
} }
...@@ -25,4 +25,9 @@ public enum Visibility { ...@@ -25,4 +25,9 @@ public enum Visibility {
public String toValue() { public String toValue() {
return (name().toLowerCase()); return (name().toLowerCase());
} }
@Override
public String toString() {
return (name().toLowerCase());
}
} }
...@@ -12,6 +12,7 @@ import java.nio.file.Path; ...@@ -12,6 +12,7 @@ import java.nio.file.Path;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.util.List; import java.util.List;
import org.gitlab4j.api.GitLabApi.ApiVersion;
import org.gitlab4j.api.models.Branch; import org.gitlab4j.api.models.Branch;
import org.gitlab4j.api.models.Project; import org.gitlab4j.api.models.Project;
import org.junit.AfterClass; import org.junit.AfterClass;
...@@ -80,7 +81,7 @@ public class TestGitLabApi { ...@@ -80,7 +81,7 @@ public class TestGitLabApi {
} }
if (problems.isEmpty()) { if (problems.isEmpty()) {
gitLabApi = new GitLabApi(TEST_HOST_URL, TEST_PRIVATE_TOKEN); gitLabApi = new GitLabApi(ApiVersion.V3, TEST_HOST_URL, TEST_PRIVATE_TOKEN);
} else { } else {
System.err.print(problems); System.err.print(problems);
} }
......
...@@ -4,6 +4,7 @@ import static org.junit.Assert.assertEquals; ...@@ -4,6 +4,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assume.assumeTrue; import static org.junit.Assume.assumeTrue;
import org.gitlab4j.api.GitLabApi.ApiVersion;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
...@@ -76,7 +77,7 @@ public class TestGitLabSession { ...@@ -76,7 +77,7 @@ public class TestGitLabSession {
@Test @Test
public void testSession() throws GitLabApiException { public void testSession() throws GitLabApiException {
GitLabApi gitLabApi = GitLabApi.create(TEST_HOST_URL, TEST_USERNAME, TEST_PASSWORD); GitLabApi gitLabApi = GitLabApi.login(ApiVersion.V3, TEST_HOST_URL, TEST_USERNAME, TEST_PASSWORD);
assertNotNull(gitLabApi); assertNotNull(gitLabApi);
assertNotNull(gitLabApi.getSession()); assertNotNull(gitLabApi.getSession());
assertEquals(TEST_PRIVATE_TOKEN, gitLabApi.getSession().getPrivateToken()); assertEquals(TEST_PRIVATE_TOKEN, gitLabApi.getSession().getPrivateToken());
......
...@@ -6,6 +6,7 @@ import static org.junit.Assume.assumeTrue; ...@@ -6,6 +6,7 @@ import static org.junit.Assume.assumeTrue;
import java.util.List; import java.util.List;
import org.gitlab4j.api.GitLabApi.ApiVersion;
import org.gitlab4j.api.models.Namespace; import org.gitlab4j.api.models.Namespace;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
...@@ -61,7 +62,7 @@ public class TestNamespaceApi { ...@@ -61,7 +62,7 @@ public class TestNamespaceApi {
} }
if (problems.isEmpty()) { if (problems.isEmpty()) {
gitLabApi = new GitLabApi(TEST_HOST_URL, TEST_PRIVATE_TOKEN); gitLabApi = new GitLabApi(ApiVersion.V3, TEST_HOST_URL, TEST_PRIVATE_TOKEN);
} else { } else {
System.err.print(problems); System.err.print(problems);
} }
......
...@@ -2,9 +2,12 @@ package org.gitlab4j.api; ...@@ -2,9 +2,12 @@ package org.gitlab4j.api;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue; import static org.junit.Assume.assumeTrue;
import org.gitlab4j.api.GitLabApi.ApiVersion;
import org.gitlab4j.api.models.Project; import org.gitlab4j.api.models.Project;
import org.gitlab4j.api.models.Visibility;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
...@@ -42,6 +45,7 @@ public class TestProjectApi { ...@@ -42,6 +45,7 @@ public class TestProjectApi {
} }
private static final String TEST_PROJECT_NAME = "test-gitlab4j-create-project"; private static final String TEST_PROJECT_NAME = "test-gitlab4j-create-project";
private static final String TEST_PROJECT_NAME_2 = "test-gitlab4j-create-project-2";
private static GitLabApi gitLabApi; private static GitLabApi gitLabApi;
public TestProjectApi() { public TestProjectApi() {
...@@ -65,15 +69,17 @@ public class TestProjectApi { ...@@ -65,15 +69,17 @@ public class TestProjectApi {
} }
if (problems.isEmpty()) { if (problems.isEmpty()) {
gitLabApi = new GitLabApi(TEST_HOST_URL, TEST_PRIVATE_TOKEN); gitLabApi = new GitLabApi(ApiVersion.V3, TEST_HOST_URL, TEST_PRIVATE_TOKEN);
} else { } else {
System.err.print(problems); System.err.print(problems);
} }
if (gitLabApi != null) { if (gitLabApi != null) {
try { try {
Project project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME); Project project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME);
gitLabApi.getProjectApi().deleteProject(project); gitLabApi.getProjectApi().deleteProject(project);
project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME_2);
gitLabApi.getProjectApi().deleteProject(project);
} catch (GitLabApiException ignore) { } catch (GitLabApiException ignore) {
} }
} }
...@@ -85,6 +91,8 @@ public class TestProjectApi { ...@@ -85,6 +91,8 @@ public class TestProjectApi {
try { try {
Project project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME); Project project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME);
gitLabApi.getProjectApi().deleteProject(project); gitLabApi.getProjectApi().deleteProject(project);
project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME_2);
gitLabApi.getProjectApi().deleteProject(project);
} catch (GitLabApiException ignore) { } catch (GitLabApiException ignore) {
} }
} }
...@@ -105,7 +113,7 @@ public class TestProjectApi { ...@@ -105,7 +113,7 @@ public class TestProjectApi {
.withMergeRequestsEnabled(true) .withMergeRequestsEnabled(true)
.withWikiEnabled(true) .withWikiEnabled(true)
.withSnippetsEnabled(true) .withSnippetsEnabled(true)
.withPublic(true); .withVisibility(Visibility.PUBLIC);
Project newProject = gitLabApi.getProjectApi().createProject(project); Project newProject = gitLabApi.getProjectApi().createProject(project);
assertNotNull(newProject); assertNotNull(newProject);
...@@ -115,7 +123,7 @@ public class TestProjectApi { ...@@ -115,7 +123,7 @@ public class TestProjectApi {
assertEquals(project.getMergeRequestsEnabled(), newProject.getMergeRequestsEnabled()); assertEquals(project.getMergeRequestsEnabled(), newProject.getMergeRequestsEnabled());
assertEquals(project.getWikiEnabled(), newProject.getWikiEnabled()); assertEquals(project.getWikiEnabled(), newProject.getWikiEnabled());
assertEquals(project.getSnippetsEnabled(), newProject.getSnippetsEnabled()); assertEquals(project.getSnippetsEnabled(), newProject.getSnippetsEnabled());
assertEquals(project.getPublic(), newProject.getPublic()); assertTrue(Visibility.PUBLIC == newProject.getVisibility() || Boolean.TRUE == newProject.getPublic());
} }
@Test @Test
...@@ -128,15 +136,15 @@ public class TestProjectApi { ...@@ -128,15 +136,15 @@ public class TestProjectApi {
public void testParameterBasedCreate() throws GitLabApiException { public void testParameterBasedCreate() throws GitLabApiException {
Project newProject = gitLabApi.getProjectApi().createProject( Project newProject = gitLabApi.getProjectApi().createProject(
TEST_PROJECT_NAME + "-2", null, "GitLab4J test project.", true, true, true, true, true, null, null); TEST_PROJECT_NAME_2, null, "GitLab4J test project.", true, true, true, true, Visibility.PUBLIC, null, null);
assertNotNull(newProject); assertNotNull(newProject);
assertEquals(TEST_PROJECT_NAME + "-2", newProject.getName()); assertEquals(TEST_PROJECT_NAME_2, newProject.getName());
assertEquals("GitLab4J test project.", newProject.getDescription()); assertEquals("GitLab4J test project.", newProject.getDescription());
assertEquals(true, newProject.getIssuesEnabled()); assertEquals(true, newProject.getIssuesEnabled());
assertEquals(true, newProject.getMergeRequestsEnabled()); assertEquals(true, newProject.getMergeRequestsEnabled());
assertEquals(true, newProject.getWikiEnabled()); assertEquals(true, newProject.getWikiEnabled());
assertEquals(true, newProject.getSnippetsEnabled()); assertEquals(true, newProject.getSnippetsEnabled());
assertEquals(true, newProject.getPublic()); assertTrue(Visibility.PUBLIC == newProject.getVisibility() || Boolean.TRUE == newProject.getPublic());
try { try {
gitLabApi.getProjectApi().deleteProject(newProject); gitLabApi.getProjectApi().deleteProject(newProject);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment