/******************************************************************************* * Copyright (c) 2012-2016 Codenvy, S.A. * 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: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.ide.ext.github.server.rest; import org.eclipse.che.api.core.ApiException; import org.eclipse.che.api.core.NotFoundException; import org.eclipse.che.api.core.ServerException; import org.eclipse.che.api.git.GitException; import org.eclipse.che.api.ssh.server.SshServiceClient; import org.eclipse.che.api.ssh.shared.dto.GenerateSshPairRequest; import org.eclipse.che.api.ssh.shared.model.SshPair; import org.eclipse.che.ide.ext.github.server.GitHubDTOFactory; import org.eclipse.che.ide.ext.github.server.GitHubFactory; import org.eclipse.che.ide.ext.github.server.GitHubKeyUploader; import org.eclipse.che.ide.ext.github.shared.Collaborators; import org.eclipse.che.ide.ext.github.shared.GitHubIssueCommentInput; import org.eclipse.che.ide.ext.github.shared.GitHubPullRequest; import org.eclipse.che.ide.ext.github.shared.GitHubPullRequestCreationInput; import org.eclipse.che.ide.ext.github.shared.GitHubPullRequestList; import org.eclipse.che.ide.ext.github.shared.GitHubRepository; import org.eclipse.che.ide.ext.github.shared.GitHubRepositoryList; import org.eclipse.che.ide.ext.github.shared.GitHubUser; import org.kohsuke.github.GHIssueState; import org.kohsuke.github.GHOrganization; import org.kohsuke.github.GHPersonSet; import org.kohsuke.github.GHPullRequest; import org.kohsuke.github.GHRepository; import org.kohsuke.github.GitHub; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; 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.QueryParam; import javax.ws.rs.core.MediaType; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.eclipse.che.dto.server.DtoFactory.newDto; /** * REST service to get the list of repositories from GitHub (where sample projects are located). * * @author Oksana Vereshchaka * @author Stéphane Daviet * @author Kevin Pollet * @author Igor vinokur */ @Path("/github/{ws-id}") public class GitHubService { @Inject private GitHubFactory gitHubFactory; @Inject private GitHubDTOFactory gitHubDTOFactory; @Inject private GitHubKeyUploader githubKeyUploader; @Inject private SshServiceClient sshServiceClient; private static final Logger LOG = LoggerFactory.getLogger(GitHubService.class); @GET @Path("repositories/{user}/{repository}") @Produces(MediaType.APPLICATION_JSON) public GitHubRepository getUserRepository(@PathParam("user") String user, @PathParam("repository") String repository) throws ApiException { try { return gitHubDTOFactory.createRepository(gitHubFactory.connect().getUser(user).getRepository(repository)); } catch (IOException e) { LOG.error("Get user info error", e); throw new ServerException(e.getMessage()); } } @GET @Path("list/user") @Produces(MediaType.APPLICATION_JSON) public GitHubRepositoryList listRepositoriesByUser(@QueryParam("username") String userName) throws ApiException { try { return gitHubDTOFactory.createRepositoriesList(gitHubFactory.connect().getUser(userName).listRepositories()); } catch (IOException e) { LOG.error("Get list repositories by user fail", e); throw new ServerException(e.getMessage()); } } @GET @Path("list/org") @Produces(MediaType.APPLICATION_JSON) public GitHubRepositoryList listRepositoriesByOrganization(@QueryParam("organization") String organization) throws ApiException { try { return gitHubDTOFactory.createRepositoriesList(gitHubFactory.connect().getOrganization(organization).listRepositories()); } catch (IOException e) { LOG.error("Get list repositories by organization fail", e); throw new ServerException(e.getMessage()); } } @GET @Path("list/account") @Produces(MediaType.APPLICATION_JSON) public GitHubRepositoryList listRepositoriesByAccount(@QueryParam("account") String account) throws ApiException { GitHub gitHub = gitHubFactory.connect(); try { //First, try to retrieve organization repositories: return gitHubDTOFactory.createRepositoriesList(gitHub.getOrganization(account).listRepositories()); } catch (IOException ioException) { LOG.error("Get list repositories by account fail", ioException); //If account is not organization, then try by user name: try { return gitHubDTOFactory.createRepositoriesList(gitHub.getUser(account).listRepositories()); } catch (IOException exception) { LOG.error("Get list repositories by account fail", exception); throw new ServerException(exception.getMessage()); } } } @GET @Path("list") @Produces(MediaType.APPLICATION_JSON) public GitHubRepositoryList listRepositories() throws ApiException { try { return gitHubDTOFactory.createRepositoriesList(gitHubFactory.connect().getMyself().listRepositories()); } catch (IOException e) { LOG.error("Get list repositories fail", e); throw new ServerException(e.getMessage()); } } @GET @Path("forks/{user}/{repository}") @Produces(MediaType.APPLICATION_JSON) public GitHubRepositoryList forks(@PathParam("user") String user, @PathParam("repository") String repository) throws ApiException { GitHubRepositoryList gitHubRepositoryList; try { gitHubRepositoryList = gitHubDTOFactory.createRepositoriesList(); for (GHRepository ghRepository : gitHubFactory.connect().getMyself().listRepositories()) { if (ghRepository.isFork() && ghRepository.getName().equals(repository)) { gitHubRepositoryList = gitHubDTOFactory.createRepositoriesList(ghRepository); break; } } } catch (IOException e) { LOG.error("Get forks fail", e); throw new ServerException(e.getMessage()); } return gitHubRepositoryList; } @GET @Path("createfork/{user}/{repository}") @Produces(MediaType.APPLICATION_JSON) public GitHubRepository fork(@PathParam("user") String user, @PathParam("repository") String repository) throws ApiException { try { return gitHubDTOFactory.createRepository(gitHubFactory.connect().getUser(user).getRepository(repository).fork()); } catch (IOException e) { LOG.error("Fork fail", e); throw new ServerException(e.getMessage()); } } @POST @Path("issuecomments/{user}/{repository}/{issue}") @Produces(MediaType.APPLICATION_JSON) public void commentIssue(@PathParam("user") String user, @PathParam("repository") String repository, @PathParam("issue") String issue, GitHubIssueCommentInput input) throws ApiException { try { gitHubFactory.connect().getUser(user).getRepository(repository).getIssue(Integer.getInteger(issue)).comment(input.getBody()); } catch (IOException e) { LOG.error("Comment issue fail", e); throw new ServerException(e.getMessage()); } } @GET @Path("pullrequests/{user}/{repository}") @Produces(MediaType.APPLICATION_JSON) public GitHubPullRequestList listPullRequestsByRepository(@PathParam("user") String user, @PathParam("repository") String repository) throws ApiException { try { return gitHubDTOFactory.createPullRequestsList(gitHubFactory.connect().getUser(user).getRepository(repository) .listPullRequests(GHIssueState.OPEN)); } catch (IOException e) { LOG.error("Getting list of pull request by repositories", e); throw new ServerException(e.getMessage()); } } @GET @Path("pullrequests/{user}/{repository}/{pullRequestId}") @Produces(MediaType.APPLICATION_JSON) public GitHubPullRequestList getPullRequestsById(@PathParam("user") String user, @PathParam("repository") String repository, @PathParam("pullRequestId") String pullRequestId) throws ApiException { try { return gitHubDTOFactory.createPullRequestsList(gitHubFactory.connect().getUser(user).getRepository(repository) .getPullRequest(Integer.valueOf(pullRequestId))); } catch (IOException e) { LOG.error("Getting list of pull request by id", e); throw new ServerException(e.getMessage()); } } @POST @Path("pullrequest/{user}/{repository}") @Produces(MediaType.APPLICATION_JSON) public GitHubPullRequest createPullRequest(@PathParam("user") String user, @PathParam("repository") String repository, GitHubPullRequestCreationInput input) throws ApiException { try { GHPullRequest pullRequest = gitHubFactory.connect().getUser(user).getRepository(repository).createPullRequest( input.getTitle(), input.getHead(), input.getBase(), input.getBody()); return gitHubDTOFactory.createPullRequest(pullRequest); } catch (Exception e) { LOG.error("Creating pull request fail", e); throw new ServerException(e.getMessage()); } } @GET @Path("list/available") @Produces(MediaType.APPLICATION_JSON) public Map<String, List<GitHubRepository>> availableRepositories() throws ApiException { Map<String, List<GitHubRepository>> repoList = new HashMap<>(); try { GitHub gitHub = gitHubFactory.connect(); //Get users' repositories GitHubRepositoryList gitHubRepositoryList = gitHubDTOFactory.createRepositoriesList(gitHub.getMyself().listRepositories()); repoList.put(getUserInfo().getLogin(), gitHubRepositoryList.getRepositories()); //Get other repositories from all organizations that user's belong to for (GHOrganization ghOrganization : gitHub.getMyself().getAllOrganizations()) { String organizationName = ghOrganization.getLogin(); repoList.put(organizationName, gitHubDTOFactory.createRepositoriesList( gitHub.getOrganization(organizationName).listRepositories()) .getRepositories()); } } catch (IOException e) { LOG.error("Getting list of available repositories fail", e); throw new ServerException(e.getMessage()); } return repoList; } @GET @Path("orgs") @Produces(MediaType.APPLICATION_JSON) public List<String> listOrganizations() throws ApiException { List<String> organizations = new ArrayList<>(); GHPersonSet<GHOrganization> myOrganizations; try { myOrganizations = gitHubFactory.connect().getMyself().getAllOrganizations(); } catch (IOException e) { LOG.error("Getting list of available organizations fail", e); throw new ServerException(e.getMessage()); } for (GHOrganization ghOrganization : myOrganizations) { organizations.add(ghOrganization.getLogin()); } return organizations; } @GET @Path("user") @Produces(MediaType.APPLICATION_JSON) public GitHubUser getUserInfo() throws ApiException { try { return gitHubDTOFactory.createUser(gitHubFactory.connect().getMyself()); } catch (IOException e) { LOG.error("Getting user info fail", e); throw new ServerException(e.getMessage()); } } @GET @Path("collaborators/{user}/{repository}") @Produces(MediaType.APPLICATION_JSON) public Collaborators collaborators(@PathParam("user") String user, @PathParam("repository") String repository) throws ApiException { try { return gitHubDTOFactory.createCollaborators(gitHubFactory.connect().getUser(user).getRepository(repository).getCollaborators()); } catch (IOException e) { LOG.error("Get collaborators fail", e); throw new ServerException(e.getMessage()); } } @POST @Path("ssh/generate") public void updateSSHKey() throws ApiException { final String host = "github.com"; SshPair sshPair = null; try { sshPair = sshServiceClient.getPair("git", host); } catch (NotFoundException ignored) { } if (sshPair != null) { if (sshPair.getPublicKey() == null) { sshServiceClient.removePair("git", host); sshPair = sshServiceClient.generatePair(newDto(GenerateSshPairRequest.class).withService("git") .withName(host)); } } else { sshPair = sshServiceClient.generatePair(newDto(GenerateSshPairRequest.class).withService("git") .withName(host)); } // update public key try { githubKeyUploader.uploadKey(sshPair.getPublicKey()); } catch (IOException e) { LOG.error("Upload github ssh key fail", e); throw new GitException(e.getMessage(), e); } } }