diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/api/impl/BitbucketApiFactoryImpl.java b/bitbucket/src/main/java/com/arcbees/bitbucket/api/impl/BitbucketApiFactoryImpl.java deleted file mode 100644 index 80a2ea7..0000000 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/api/impl/BitbucketApiFactoryImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright 2014 ArcBees Inc. - * - * Licensed 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.arcbees.bitbucket.api.impl; - -import com.arcbees.bitbucket.BitbucketConstants; -import com.arcbees.bitbucket.BitbucketPropertiesHelper; -import com.arcbees.bitbucket.api.BitbucketApi; -import com.arcbees.bitbucket.api.BitbucketApiFactory; - -public class BitbucketApiFactoryImpl implements BitbucketApiFactory { - private final HttpClientWrapper httpClient; - private final BitbucketConstants bitbucketConstants; - - public BitbucketApiFactoryImpl(HttpClientWrapper httpClient, - BitbucketConstants bitbucketConstants) { - this.httpClient = httpClient; - this.bitbucketConstants = bitbucketConstants; - } - - @Override - public BitbucketApi create(BitbucketPropertiesHelper bitbucketPropertiesHelper) { - return new BitbucketApiImpl(httpClient, new BitbucketApiPaths(bitbucketConstants.getServerUrl()), - bitbucketPropertiesHelper.getUserName(), - bitbucketPropertiesHelper.getPassword(), - bitbucketPropertiesHelper.getRepositoryOwner(), - bitbucketPropertiesHelper.getRepositoryName()); - } -} diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/model/Links.java b/bitbucket/src/main/java/com/arcbees/bitbucket/model/Links.java deleted file mode 100644 index e8a6bcf..0000000 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/model/Links.java +++ /dev/null @@ -1,101 +0,0 @@ -/** - * Copyright 2014 ArcBees Inc. - * - * Licensed 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.arcbees.bitbucket.model; - -public class Links { - private Link decline; - private Link commits; - private Link self; - private Link accept; - private Link html; - private Link comments; - private Link activity; - private Link diff; - private Link approvals; - - public Link getDecline() { - return decline; - } - - public void setDecline(Link decline) { - this.decline = decline; - } - - public Link getCommits() { - return commits; - } - - public void setCommits(Link commits) { - this.commits = commits; - } - - public Link getSelf() { - return self; - } - - public void setSelf(Link self) { - this.self = self; - } - - public Link getAccept() { - return accept; - } - - public void setAccept(Link accept) { - this.accept = accept; - } - - public Link getHtml() { - return html; - } - - public void setHtml(Link html) { - this.html = html; - } - - public Link getComments() { - return comments; - } - - public void setComments(Link comments) { - this.comments = comments; - } - - public Link getActivity() { - return activity; - } - - public void setActivity(Link activity) { - this.activity = activity; - } - - public Link getDiff() { - return diff; - } - - public void setDiff(Link diff) { - this.diff = diff; - } - - public Link getApprovals() { - return approvals; - } - - public void setApprovals(Link approvals) { - this.approvals = approvals; - } -} diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/model/PullRequests.java b/bitbucket/src/main/java/com/arcbees/bitbucket/model/PullRequests.java deleted file mode 100644 index 09c66ae..0000000 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/model/PullRequests.java +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright 2014 ArcBees Inc. - * - * Licensed 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.arcbees.bitbucket.model; - -import java.util.List; - -import com.google.gson.annotations.SerializedName; - -public class PullRequests { - @SerializedName("pagelen") - private int pageLength; - private int page; - private int size; - @SerializedName("values") - private List pullRequests; - private String next; - - public List getPullRequests() { - return pullRequests; - } - - public void setPullRequests(List pullRequests) { - this.pullRequests = pullRequests; - } - - public int getPageLength() { - return pageLength; - } - - public void setPageLength(int pageLength) { - this.pageLength = pageLength; - } - - public int getPage() { - return page; - } - - public void setPage(int page) { - this.page = page; - } - - public int getSize() { - return size; - } - - public void setSize(int size) { - this.size = size; - } - - public String getNext() { - return next; - } - - public void setNext(String next) { - this.next = next; - } -} diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/model/User.java b/bitbucket/src/main/java/com/arcbees/bitbucket/model/User.java deleted file mode 100644 index 2ba8486..0000000 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/model/User.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Copyright 2014 ArcBees Inc. - * - * Licensed 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.arcbees.bitbucket.model; - -import com.google.gson.annotations.SerializedName; - -public class User { - @SerializedName("username") - private String userName; - @SerializedName("display_name") - private String displayName; - private Links links; - - public String getUserName() { - return userName; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public String getDisplayName() { - return displayName; - } - - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - - public Links getLinks() { - return links; - } - - public void setLinks(Links links) { - this.links = links; - } -} diff --git a/bitbucket/src/main/resources/META-INF/build-server-plugin-bitbucket.xml b/bitbucket/src/main/resources/META-INF/build-server-plugin-bitbucket.xml deleted file mode 100644 index e75d90e..0000000 --- a/bitbucket/src/main/resources/META-INF/build-server-plugin-bitbucket.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/pom.xml b/pom.xml index cfa663f..3a6fdde 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ Plugins - bitbucket + vcs-utils pullrequests staging diff --git a/pullrequests/pom.xml b/pullrequests/pom.xml index 6c236a1..4ddb120 100644 --- a/pullrequests/pom.xml +++ b/pullrequests/pom.xml @@ -16,7 +16,7 @@ com.arcbees.teamcity - bitbucket + vcs-utils ${project.version} diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/model/Link.java b/pullrequests/src/main/java/com/arcbees/pullrequest/Constants.java similarity index 63% rename from bitbucket/src/main/java/com/arcbees/bitbucket/model/Link.java rename to pullrequests/src/main/java/com/arcbees/pullrequest/Constants.java index dd2e4ef..2985097 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/model/Link.java +++ b/pullrequests/src/main/java/com/arcbees/pullrequest/Constants.java @@ -14,25 +14,17 @@ * the License. */ -package com.arcbees.bitbucket.model; +package com.arcbees.pullrequest; -public class Link { - private String href; - private String rel; +public class Constants { + private static final String BUILD_SUCCESS = "BUILD SUCCESS "; + private static final String BUILD_FAILURE = "BUILD FAILURE "; - public String getHref() { - return href; + public String getBuildSuccess() { + return BUILD_SUCCESS; } - public void setHref(String href) { - this.href = href; - } - - public String getRel() { - return rel; - } - - public void setRel(String rel) { - this.rel = rel; + public String getBuildFailure() { + return BUILD_FAILURE; } } diff --git a/pullrequests/src/main/java/com/arcbees/bitbucket/BitbucketPullRequestBuild.java b/pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestBuild.java similarity index 77% rename from pullrequests/src/main/java/com/arcbees/bitbucket/BitbucketPullRequestBuild.java rename to pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestBuild.java index cc126c1..c9801f7 100644 --- a/pullrequests/src/main/java/com/arcbees/bitbucket/BitbucketPullRequestBuild.java +++ b/pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestBuild.java @@ -14,21 +14,21 @@ * the License. */ -package com.arcbees.bitbucket; +package com.arcbees.pullrequest; -import com.arcbees.bitbucket.model.Comment; -import com.arcbees.bitbucket.model.Commit; -import com.arcbees.bitbucket.model.PullRequest; -import com.arcbees.bitbucket.model.PullRequestTarget; +import com.arcbees.vcs.model.Comment; +import com.arcbees.vcs.model.Commit; +import com.arcbees.vcs.model.PullRequest; +import com.arcbees.vcs.model.PullRequestTarget; import jetbrains.buildServer.messages.Status; -public class BitbucketPullRequestBuild { +public class PullRequestBuild { private final PullRequest pullRequest; private final Status lastStatus; private final Comment lastComment; - public BitbucketPullRequestBuild(PullRequest pullRequest, Status lastStatus, Comment lastComment) { + public PullRequestBuild(PullRequest pullRequest, Status lastStatus, Comment lastComment) { this.pullRequest = pullRequest; this.lastStatus = lastStatus; this.lastComment = lastComment; diff --git a/pullrequests/src/main/java/com/arcbees/bitbucket/PullRequestCommentHandler.java b/pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestCommentHandler.java similarity index 52% rename from pullrequests/src/main/java/com/arcbees/bitbucket/PullRequestCommentHandler.java rename to pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestCommentHandler.java index b8d7324..6faf63d 100644 --- a/pullrequests/src/main/java/com/arcbees/bitbucket/PullRequestCommentHandler.java +++ b/pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestCommentHandler.java @@ -14,18 +14,20 @@ * the License. */ -package com.arcbees.bitbucket; +package com.arcbees.pullrequest; import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.Map; -import com.arcbees.bitbucket.api.BitbucketApi; -import com.arcbees.bitbucket.api.BitbucketApiFactory; -import com.arcbees.bitbucket.model.Comment; -import com.arcbees.bitbucket.model.PullRequest; -import com.arcbees.bitbucket.util.JsonCustomDataStorage; +import com.arcbees.vcs.VcsApi; +import com.arcbees.vcs.VcsApiFactories; +import com.arcbees.vcs.VcsConstants; +import com.arcbees.vcs.VcsPropertiesHelper; +import com.arcbees.vcs.model.Comment; +import com.arcbees.vcs.model.PullRequest; +import com.arcbees.vcs.util.JsonCustomDataStorage; import com.google.common.collect.Lists; import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor; @@ -37,15 +39,18 @@ import jetbrains.buildServer.serverSide.WebLinks; public class PullRequestCommentHandler { - private final BitbucketApiFactory bitbucketApiFactory; - private final BitbucketConstants bitbucketConstants; + private final VcsApiFactories vcsApiFactories; + private final VcsConstants vcsConstants; + private final Constants constants; private final WebLinks webLinks; - public PullRequestCommentHandler(BitbucketApiFactory bitbucketApiFactory, - BitbucketConstants bitbucketConstants, + public PullRequestCommentHandler(VcsApiFactories vcsApiFactories, + VcsConstants vcsConstants, + Constants constants, WebLinks webLinks) { - this.bitbucketApiFactory = bitbucketApiFactory; - this.bitbucketConstants = bitbucketConstants; + this.vcsApiFactories = vcsApiFactories; + this.vcsConstants = vcsConstants; + this.constants = constants; this.webLinks = webLinks; } @@ -54,31 +59,30 @@ public void handle(SRunningBuild build, BuildTriggerDescriptor trigger) throws I if (branch != null) { SBuildType buildType = build.getBuildType(); - BitbucketPropertiesHelper bitbucketPropertiesHelper = new BitbucketPropertiesHelper(trigger.getProperties(), - bitbucketConstants); - BitbucketApi bitbucketApi = bitbucketApiFactory.create(bitbucketPropertiesHelper); + VcsPropertiesHelper vcsPropertiesHelper = new VcsPropertiesHelper(trigger.getProperties(), vcsConstants); + VcsApi vcsApi = vcsApiFactories.create(vcsPropertiesHelper); - PullRequest pullRequest = bitbucketApi.getPullRequestForBranch(branch.getName()); + PullRequest pullRequest = vcsApi.getPullRequestForBranch(branch.getName()); - JsonCustomDataStorage dataStorage = getJsonDataStorage(buildType, trigger); - BitbucketPullRequestBuild pullRequestBuild = - getBitbucketPullRequestBuild(bitbucketPropertiesHelper, pullRequest, dataStorage); + JsonCustomDataStorage dataStorage = getJsonDataStorage(buildType, trigger); + PullRequestBuild pullRequestBuild = + getPullRequestBuild(vcsPropertiesHelper, pullRequest, dataStorage); - Comment comment = postOrUpdateComment(build, bitbucketApi, pullRequest, pullRequestBuild); + Comment comment = postOrUpdateComment(build, vcsApi, pullRequest, pullRequestBuild); - pullRequestBuild = new BitbucketPullRequestBuild(pullRequest, build.getBuildStatus(), comment); - dataStorage.putValue(getPullRequestKey(bitbucketPropertiesHelper, pullRequest), pullRequestBuild); + pullRequestBuild = new PullRequestBuild(pullRequest, build.getBuildStatus(), comment); + dataStorage.putValue(getPullRequestKey(vcsPropertiesHelper, pullRequest), pullRequestBuild); } } private Comment postOrUpdateComment(SRunningBuild build, - BitbucketApi bitbucketApi, + VcsApi bitbucketApi, PullRequest pullRequest, - BitbucketPullRequestBuild pullRequestBuild) throws IOException { + PullRequestBuild pullRequestBuild) throws IOException { Comment comment = pullRequestBuild == null ? null : pullRequestBuild.getLastComment(); if (comment != null) { - deleteOldComment(bitbucketApi, comment); + deleteOldComment(bitbucketApi, pullRequest.getId(), comment); } comment = bitbucketApi.postComment(pullRequest.getId(), getComment(build)); @@ -86,36 +90,35 @@ private Comment postOrUpdateComment(SRunningBuild build, return comment; } - private void deleteOldComment(BitbucketApi bitbucketApi, + private void deleteOldComment(VcsApi vcsApi, + int pullRequestId, Comment oldComment) throws IOException { - bitbucketApi.deleteComment(oldComment.getPullRequestId(), oldComment.getCommentId()); + vcsApi.deleteComment(pullRequestId, oldComment.getCommentId()); } - private BitbucketPullRequestBuild getBitbucketPullRequestBuild(BitbucketPropertiesHelper bitbucketPropertiesHelper, - PullRequest pullRequest, - JsonCustomDataStorage - dataStorage) { - String pullRequestKey = getPullRequestKey(bitbucketPropertiesHelper.getRepositoryOwner(), - bitbucketPropertiesHelper.getRepositoryName(), pullRequest); + private PullRequestBuild getPullRequestBuild(VcsPropertiesHelper vcsPropertiesHelper, + PullRequest pullRequest, + JsonCustomDataStorage dataStorage) { + String pullRequestKey = getPullRequestKey(vcsPropertiesHelper.getRepositoryOwner(), + vcsPropertiesHelper.getRepositoryName(), pullRequest); return dataStorage.getValue(pullRequestKey); } - private JsonCustomDataStorage getJsonDataStorage(SBuildType buildType, - BuildTriggerDescriptor trigger) { + private JsonCustomDataStorage getJsonDataStorage(SBuildType buildType, + BuildTriggerDescriptor trigger) { String storageId = getStorageId(trigger); CustomDataStorage customDataStorage = buildType.getCustomDataStorage(storageId); - return JsonCustomDataStorage.create(customDataStorage, BitbucketPullRequestBuild.class); + return JsonCustomDataStorage.create(customDataStorage, PullRequestBuild.class); } - private String getPullRequestKey(BitbucketPropertiesHelper helper, PullRequest pullRequest) { + private String getPullRequestKey(VcsPropertiesHelper helper, PullRequest pullRequest) { return getPullRequestKey(helper.getRepositoryOwner(), helper.getRepositoryName(), pullRequest); } private String getPullRequestKey(String repositoryOwner, String repositoryName, PullRequest pullRequest) { - return bitbucketConstants.getPullRequestKey() + repositoryOwner + "_" + repositoryName + "_" + pullRequest - .getId(); + return vcsConstants.getPullRequestKey() + repositoryOwner + "_" + repositoryName + "_" + pullRequest.getId(); } private String getStorageId(BuildTriggerDescriptor triggerDescriptor) { @@ -143,9 +146,9 @@ private String getComment(SRunningBuild build) { private String getComment(Status status) { if (status.isSuccessful()) { - return bitbucketConstants.getBuildSuccess(); + return constants.getBuildSuccess(); } else { - return bitbucketConstants.getBuildFailure(); + return constants.getBuildFailure(); } } } diff --git a/pullrequests/src/main/java/com/arcbees/bitbucket/BitbucketBuildListener.java b/pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestsBuildListener.java similarity index 83% rename from pullrequests/src/main/java/com/arcbees/bitbucket/BitbucketBuildListener.java rename to pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestsBuildListener.java index e433749..d7bede6 100644 --- a/pullrequests/src/main/java/com/arcbees/bitbucket/BitbucketBuildListener.java +++ b/pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestsBuildListener.java @@ -14,7 +14,7 @@ * the License. */ -package com.arcbees.bitbucket; +package com.arcbees.pullrequest; import java.io.IOException; import java.util.logging.Level; @@ -28,13 +28,13 @@ import jetbrains.buildServer.serverSide.SRunningBuild; import jetbrains.buildServer.util.EventDispatcher; -public class BitbucketBuildListener { - private static final Logger LOGGER = Logger.getLogger(BitbucketBuildListener.class.getName()); +public class PullRequestsBuildListener { + private static final Logger LOGGER = Logger.getLogger(PullRequestsBuildListener.class.getName()); private final PullRequestCommentHandler commentHandler; - public BitbucketBuildListener(EventDispatcher listener, - PullRequestCommentHandler commentHandler) { + public PullRequestsBuildListener(EventDispatcher listener, + PullRequestCommentHandler commentHandler) { this.commentHandler = commentHandler; listener.addListener(new BuildServerAdapter() { @Override @@ -55,7 +55,7 @@ private void onBuildFinished(SRunningBuild build) throws IOException { } for (BuildTriggerDescriptor trigger : buildType.getResolvedSettings().getBuildTriggersCollection()) { - if (!trigger.getType().equals(BitbucketPullRequestFeature.NAME)) { + if (!trigger.getType().equals(PullRequestsFeature.NAME)) { continue; } diff --git a/pullrequests/src/main/java/com/arcbees/bitbucket/BitbucketPullRequestFeature.java b/pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestsFeature.java similarity index 74% rename from pullrequests/src/main/java/com/arcbees/bitbucket/BitbucketPullRequestFeature.java rename to pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestsFeature.java index cb20ba5..c22e675 100644 --- a/pullrequests/src/main/java/com/arcbees/bitbucket/BitbucketPullRequestFeature.java +++ b/pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestsFeature.java @@ -14,30 +14,32 @@ * the License. */ -package com.arcbees.bitbucket; +package com.arcbees.pullrequest; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import com.arcbees.vcs.VcsPropertiesProcessor; + import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor; import jetbrains.buildServer.buildTriggers.BuildTriggerService; import jetbrains.buildServer.buildTriggers.BuildTriggeringPolicy; import jetbrains.buildServer.serverSide.PropertiesProcessor; import jetbrains.buildServer.web.openapi.PluginDescriptor; -public class BitbucketPullRequestFeature extends BuildTriggerService { - public static final String NAME = "BitbucketPullRequest"; +public class PullRequestsFeature extends BuildTriggerService { + public static final String NAME = "PullRequests"; - private static final String DISPLAY_NAME = "Bitbucket Pull Requests"; - private static final String EDIT_URL = "bitbucket_pr.jsp"; + private static final String DISPLAY_NAME = "Pull Requests"; + private static final String EDIT_URL = "pullrequests.jsp"; - private final BitbucketPropertiesProcessor propertiesProcessor; - private final BitbucketPullRequestTrigger triggeringPolicy; + private final VcsPropertiesProcessor propertiesProcessor; + private final PullRequestsTrigger triggeringPolicy; private final PluginDescriptor pluginDescriptor; - public BitbucketPullRequestFeature(BitbucketPullRequestTrigger triggeringPolicy, - BitbucketPropertiesProcessor propertiesProcessor, - PluginDescriptor pluginDescriptor) { + public PullRequestsFeature(PullRequestsTrigger triggeringPolicy, + VcsPropertiesProcessor propertiesProcessor, + PluginDescriptor pluginDescriptor) { this.triggeringPolicy = triggeringPolicy; this.propertiesProcessor = propertiesProcessor; this.pluginDescriptor = pluginDescriptor; diff --git a/pullrequests/src/main/java/com/arcbees/bitbucket/BitbucketPullRequestTrigger.java b/pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestsTrigger.java similarity index 72% rename from pullrequests/src/main/java/com/arcbees/bitbucket/BitbucketPullRequestTrigger.java rename to pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestsTrigger.java index 6208641..279c137 100644 --- a/pullrequests/src/main/java/com/arcbees/bitbucket/BitbucketPullRequestTrigger.java +++ b/pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestsTrigger.java @@ -14,7 +14,7 @@ * the License. */ -package com.arcbees.bitbucket; +package com.arcbees.pullrequest; import java.io.IOException; import java.util.List; @@ -22,14 +22,16 @@ import org.jetbrains.annotations.NotNull; -import com.arcbees.bitbucket.api.BitbucketApi; -import com.arcbees.bitbucket.api.BitbucketApiFactory; -import com.arcbees.bitbucket.model.Comment; -import com.arcbees.bitbucket.model.Commit; -import com.arcbees.bitbucket.model.PullRequest; -import com.arcbees.bitbucket.model.PullRequestTarget; -import com.arcbees.bitbucket.model.PullRequests; -import com.arcbees.bitbucket.util.JsonCustomDataStorage; +import com.arcbees.vcs.VcsApi; +import com.arcbees.vcs.VcsApiFactories; +import com.arcbees.vcs.VcsConstants; +import com.arcbees.vcs.VcsPropertiesHelper; +import com.arcbees.vcs.model.Comment; +import com.arcbees.vcs.model.Commit; +import com.arcbees.vcs.model.PullRequest; +import com.arcbees.vcs.model.PullRequestTarget; +import com.arcbees.vcs.model.PullRequests; +import com.arcbees.vcs.util.JsonCustomDataStorage; import com.google.common.collect.Lists; import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor; @@ -46,19 +48,19 @@ import jetbrains.buildServer.vcs.SVcsModification; import jetbrains.buildServer.vcs.SelectPrevBuildPolicy; -public class BitbucketPullRequestTrigger extends PolledBuildTrigger { - private final BitbucketApiFactory apiFactory; +public class PullRequestsTrigger extends PolledBuildTrigger { + private final VcsApiFactories vcsApiFactories; private final BatchTrigger batchTrigger; - private final BitbucketConstants bitbucketConstants; + private final VcsConstants vcsConstants; private final BuildCustomizerFactory buildCustomizerFactory; - public BitbucketPullRequestTrigger(BitbucketApiFactory apiFactory, - BatchTrigger batchTrigger, - BitbucketConstants bitbucketConstants, - BuildCustomizerFactory buildCustomizerFactory) { - this.apiFactory = apiFactory; + public PullRequestsTrigger(VcsApiFactories vcsApiFactories, + BatchTrigger batchTrigger, + VcsConstants vcsConstants, + BuildCustomizerFactory buildCustomizerFactory) { + this.vcsApiFactories = vcsApiFactories; this.batchTrigger = batchTrigger; - this.bitbucketConstants = bitbucketConstants; + this.vcsConstants = vcsConstants; this.buildCustomizerFactory = buildCustomizerFactory; } @@ -67,20 +69,20 @@ public void triggerBuild(@NotNull PolledTriggerContext context) throws BuildTrig BuildTriggerDescriptor triggerDescriptor = context.getTriggerDescriptor(); Map properties = triggerDescriptor.getProperties(); - BitbucketPropertiesHelper bitbucketPropertiesHelper = new BitbucketPropertiesHelper(properties, bitbucketConstants); - String repositoryOwner = bitbucketPropertiesHelper.getRepositoryOwner(); - String repositoryName = bitbucketPropertiesHelper.getRepositoryName(); + VcsPropertiesHelper vcsPropertiesHelper = new VcsPropertiesHelper(properties, vcsConstants); + String repositoryOwner = vcsPropertiesHelper.getRepositoryOwner(); + String repositoryName = vcsPropertiesHelper.getRepositoryName(); - BitbucketApi bitbucketApi = apiFactory.create(bitbucketPropertiesHelper); + VcsApi vcsApi = vcsApiFactories.create(vcsPropertiesHelper); try { - PullRequests pullRequests = bitbucketApi.getOpenedPullRequests(); - JsonCustomDataStorage dataStorage = - JsonCustomDataStorage.create(context.getCustomDataStorage(), BitbucketPullRequestBuild.class); + PullRequests pullRequests = vcsApi.getOpenedPullRequests(); + JsonCustomDataStorage dataStorage = + JsonCustomDataStorage.create(context.getCustomDataStorage(), PullRequestBuild.class); List triggerTasks = Lists.newArrayList(); for (PullRequest pullRequest : pullRequests.getPullRequests()) { String pullRequestKey = getPullRequestKey(repositoryOwner, repositoryName, pullRequest); - BitbucketPullRequestBuild pullRequestBuild = dataStorage.getValue(pullRequestKey); + PullRequestBuild pullRequestBuild = dataStorage.getValue(pullRequestKey); String lastTriggeredCommitHash = ""; Status lastStatus = Status.UNKNOWN; @@ -94,7 +96,7 @@ public void triggerBuild(@NotNull PolledTriggerContext context) throws BuildTrig boolean buildAdded = addBuildTask(context, triggerTasks, pullRequest, lastTriggeredCommitHash); if (buildAdded) { - pullRequestBuild = new BitbucketPullRequestBuild(pullRequest, lastStatus, lastComment); + pullRequestBuild = new PullRequestBuild(pullRequest, lastStatus, lastComment); dataStorage.putValue(pullRequestKey, pullRequestBuild); } } @@ -149,6 +151,6 @@ private SVcsModification checkChanges(String commitHash, List } private String getPullRequestKey(String repositoryOwner, String repositoryName, PullRequest pullRequest) { - return bitbucketConstants.getPullRequestKey() + repositoryOwner + "_" + repositoryName + "_" + pullRequest.getId(); + return vcsConstants.getPullRequestKey() + repositoryOwner + "_" + repositoryName + "_" + pullRequest.getId(); } } diff --git a/pullrequests/src/main/resources/META-INF/build-server-plugin-pullrequests.xml b/pullrequests/src/main/resources/META-INF/build-server-plugin-pullrequests.xml index 2db41b5..beed120 100644 --- a/pullrequests/src/main/resources/META-INF/build-server-plugin-pullrequests.xml +++ b/pullrequests/src/main/resources/META-INF/build-server-plugin-pullrequests.xml @@ -1,8 +1,9 @@ - - - - + + + + + diff --git a/pullrequests/src/main/resources/buildServerResources/bitbucket_pr.jsp b/pullrequests/src/main/resources/buildServerResources/bitbucket_pr.jsp deleted file mode 100644 index 9ff59f7..0000000 --- a/pullrequests/src/main/resources/buildServerResources/bitbucket_pr.jsp +++ /dev/null @@ -1,69 +0,0 @@ -<%@ include file="/include.jsp" %> -<%@ include file="/include-internal.jsp" %> - - - - - - - - Specify Bitbucket repository name and credentials - - - - User Name: - - - - Bitbucket user name - - - - Password: - - - - Bitbucket password - - - - - - Owner: - - - - Bitbucket repository owner (user or organization) - - - - Repository: - - - - Bitbucket repository name - - - diff --git a/pullrequests/src/main/resources/buildServerResources/pullrequests.jsp b/pullrequests/src/main/resources/buildServerResources/pullrequests.jsp new file mode 100644 index 0000000..3b844ae --- /dev/null +++ b/pullrequests/src/main/resources/buildServerResources/pullrequests.jsp @@ -0,0 +1,30 @@ +<%@ include file="/include.jsp" %> +<%@ include file="/include-internal.jsp" %> + + + + + +<%@ include file="vcsSettings.jsp" %> diff --git a/pullrequests/src/test/java/com/arcbees/bitbucket/PullRequestCommentHandlerTest.java b/pullrequests/src/test/java/com/arcbees/vcs/bitbucket/PullRequestCommentHandlerTest.java similarity index 55% rename from pullrequests/src/test/java/com/arcbees/bitbucket/PullRequestCommentHandlerTest.java rename to pullrequests/src/test/java/com/arcbees/vcs/bitbucket/PullRequestCommentHandlerTest.java index 5729bcd..e932cad 100644 --- a/pullrequests/src/test/java/com/arcbees/bitbucket/PullRequestCommentHandlerTest.java +++ b/pullrequests/src/test/java/com/arcbees/vcs/bitbucket/PullRequestCommentHandlerTest.java @@ -14,18 +14,27 @@ * the License. */ -package com.arcbees.bitbucket; +package com.arcbees.vcs.bitbucket; import java.io.IOException; import org.junit.Before; import org.junit.Test; -import com.arcbees.bitbucket.api.BitbucketApi; -import com.arcbees.bitbucket.api.BitbucketApiFactory; -import com.arcbees.bitbucket.model.Comment; -import com.arcbees.bitbucket.model.PullRequest; +import com.arcbees.pullrequest.Constants; +import com.arcbees.pullrequest.PullRequestBuild; +import com.arcbees.pullrequest.PullRequestCommentHandler; +import com.arcbees.vcs.VcsApi; +import com.arcbees.vcs.VcsApiFactories; +import com.arcbees.vcs.VcsConstants; +import com.arcbees.vcs.VcsPropertiesHelper; +import com.arcbees.vcs.bitbucket.model.BitbucketComment; +import com.arcbees.vcs.bitbucket.model.BitbucketPullRequest; +import com.arcbees.vcs.model.Comment; +import com.arcbees.vcs.model.PullRequest; +import com.arcbees.vcs.util.PolymorphicTypeAdapter; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor; import jetbrains.buildServer.buildTriggers.BuildTriggerService; @@ -48,18 +57,19 @@ public class PullRequestCommentHandlerTest { private PullRequestCommentHandler commentHandler; - private BitbucketApi bitbucketApi; + private VcsApi vcsApi; private BuildTriggerDescriptor trigger; private CustomDataStorage dataStorage; private SRunningBuild build; @Before public void setUp() throws IOException { - BitbucketApiFactory apiFactory = mock(BitbucketApiFactory.class); - bitbucketApi = mock(BitbucketApi.class); - given(apiFactory.create(any(BitbucketPropertiesHelper.class))).willReturn(bitbucketApi); + VcsApiFactories apiFactory = mock(VcsApiFactories.class); + vcsApi = mock(VcsApi.class); + given(apiFactory.create(any(VcsPropertiesHelper.class))).willReturn(vcsApi); - commentHandler = new PullRequestCommentHandler(apiFactory, new BitbucketConstants(), mock(WebLinks.class)); + commentHandler = new PullRequestCommentHandler(apiFactory, new VcsConstants(), new Constants(), + mock(WebLinks.class)); trigger = mock(BuildTriggerDescriptor.class); @@ -72,7 +82,7 @@ public void setUp() throws IOException { given(build.getBranch()).willReturn(mock(Branch.class)); given(trigger.getBuildTriggerService()).willReturn(mock(BuildTriggerService.class)); - given(bitbucketApi.getPullRequestForBranch(anyString())).willReturn(createPullRequest()); + given(vcsApi.getPullRequestForBranch(anyString())).willReturn(createPullRequest()); } @Test @@ -81,56 +91,63 @@ public void firstBuild_postComment() throws IOException { commentHandler.handle(build, trigger); - verify(bitbucketApi, never()).deleteComment(anyInt(), anyLong()); - verify(bitbucketApi).postComment(anyInt(), anyString()); + verify(vcsApi, never()).deleteComment(anyInt(), anyLong()); + verify(vcsApi).postComment(anyInt(), anyString()); } @Test public void secondSuccess_newComment() throws IOException { given(build.getBuildStatus()).willReturn(Status.NORMAL); - BitbucketPullRequestBuild pullRequestBuild = - new BitbucketPullRequestBuild(createPullRequest(), Status.NORMAL, new Comment()); + PullRequestBuild pullRequestBuild = + new PullRequestBuild(createPullRequest(), Status.NORMAL, new BitbucketComment()); - given(dataStorage.getValue(anyString())).willReturn(new Gson().toJson(pullRequestBuild)); + given(dataStorage.getValue(anyString())).willReturn(getGson().toJson(pullRequestBuild)); commentHandler.handle(build, trigger); - verify(bitbucketApi, times(1)).deleteComment(anyInt(), anyLong()); - verify(bitbucketApi, times(1)).postComment(anyInt(), anyString()); + verify(vcsApi, times(1)).deleteComment(anyInt(), anyLong()); + verify(vcsApi, times(1)).postComment(anyInt(), anyString()); } @Test public void failureAfterSuccess_newComment() throws IOException { given(build.getBuildStatus()).willReturn(Status.FAILURE); - BitbucketPullRequestBuild pullRequestBuild = - new BitbucketPullRequestBuild(createPullRequest(), Status.NORMAL, new Comment()); + PullRequestBuild pullRequestBuild = + new PullRequestBuild(createPullRequest(), Status.NORMAL, new BitbucketComment()); - given(dataStorage.getValue(anyString())).willReturn(new Gson().toJson(pullRequestBuild)); + given(dataStorage.getValue(anyString())).willReturn(getGson().toJson(pullRequestBuild)); commentHandler.handle(build, trigger); - verify(bitbucketApi, times(1)).deleteComment(anyInt(), anyLong()); - verify(bitbucketApi, times(1)).postComment(anyInt(), anyString()); + verify(vcsApi, times(1)).deleteComment(anyInt(), anyLong()); + verify(vcsApi, times(1)).postComment(anyInt(), anyString()); } @Test public void failureAfterFailure_newComment() throws IOException { given(build.getBuildStatus()).willReturn(Status.FAILURE); - BitbucketPullRequestBuild pullRequestBuild = - new BitbucketPullRequestBuild(createPullRequest(), Status.FAILURE, new Comment()); + PullRequestBuild pullRequestBuild = + new PullRequestBuild(createPullRequest(), Status.FAILURE, new BitbucketComment()); - given(dataStorage.getValue(anyString())).willReturn(new Gson().toJson(pullRequestBuild)); + given(dataStorage.getValue(anyString())).willReturn(getGson().toJson(pullRequestBuild)); commentHandler.handle(build, trigger); - verify(bitbucketApi, times(1)).deleteComment(anyInt(), anyLong()); - verify(bitbucketApi, times(1)).postComment(anyInt(), anyString()); + verify(vcsApi, times(1)).deleteComment(anyInt(), anyLong()); + verify(vcsApi, times(1)).postComment(anyInt(), anyString()); } private PullRequest createPullRequest() { - PullRequest pullRequest = new PullRequest(); + PullRequest pullRequest = new BitbucketPullRequest(); pullRequest.setId(1); return pullRequest; } + + private Gson getGson() { + return new GsonBuilder() + .registerTypeAdapter(PullRequest.class, new PolymorphicTypeAdapter()) + .registerTypeAdapter(Comment.class, new PolymorphicTypeAdapter()) + .create(); + } } diff --git a/pullrequests/teamcity-plugin.xml b/pullrequests/teamcity-plugin.xml index ab3a250..b2b5575 100644 --- a/pullrequests/teamcity-plugin.xml +++ b/pullrequests/teamcity-plugin.xml @@ -1,8 +1,8 @@ - BitbucketPullRequestTrigger - Bitbucket Pull Request Trigger + PullRequestTrigger + Pull Request Trigger @Version@ diff --git a/staging/pom.xml b/staging/pom.xml index 491f358..f9838ea 100644 --- a/staging/pom.xml +++ b/staging/pom.xml @@ -25,7 +25,7 @@ com.arcbees.teamcity - bitbucket + vcs-utils ${project.version} diff --git a/staging/src/main/java/com/arcbees/staging/TomcatDeployHandler.java b/staging/src/main/java/com/arcbees/staging/TomcatDeployHandler.java index 1c3615f..a8b939b 100644 --- a/staging/src/main/java/com/arcbees/staging/TomcatDeployHandler.java +++ b/staging/src/main/java/com/arcbees/staging/TomcatDeployHandler.java @@ -32,13 +32,13 @@ import org.apache.tomcat.maven.common.deployer.TomcatManagerResponse; import org.jetbrains.annotations.NotNull; -import com.arcbees.bitbucket.BitbucketConstants; -import com.arcbees.bitbucket.BitbucketPropertiesHelper; -import com.arcbees.bitbucket.api.BitbucketApi; -import com.arcbees.bitbucket.api.BitbucketApiFactory; -import com.arcbees.bitbucket.model.Comment; -import com.arcbees.bitbucket.model.PullRequest; -import com.arcbees.bitbucket.util.JsonCustomDataStorage; +import com.arcbees.vcs.VcsApi; +import com.arcbees.vcs.VcsApiFactories; +import com.arcbees.vcs.VcsConstants; +import com.arcbees.vcs.VcsPropertiesHelper; +import com.arcbees.vcs.model.Comment; +import com.arcbees.vcs.model.PullRequest; +import com.arcbees.vcs.util.JsonCustomDataStorage; import com.google.common.collect.Lists; import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor; @@ -54,18 +54,18 @@ public class TomcatDeployHandler { private static final Logger LOGGER = Logger.getLogger(TomcatDeployHandler.class.getName()); private static final String COMMENT_WEBAPP = "WebApp URL : "; - private final BitbucketApiFactory bitbucketApiFactory; + private final VcsApiFactories vcsApiFactories; private final TomcatManagerFactory tomcatManagerFactory; - private final BitbucketConstants bitbucketConstants; + private final VcsConstants vcsConstants; private final Constants constants; - public TomcatDeployHandler(BitbucketApiFactory bitbucketApiFactory, + public TomcatDeployHandler(VcsApiFactories vcsApiFactories, TomcatManagerFactory tomcatManagerFactory, - BitbucketConstants bitbucketConstants, + VcsConstants vcsConstants, Constants constants) { - this.bitbucketApiFactory = bitbucketApiFactory; + this.vcsApiFactories = vcsApiFactories; this.tomcatManagerFactory = tomcatManagerFactory; - this.bitbucketConstants = bitbucketConstants; + this.vcsConstants = vcsConstants; this.constants = constants; } @@ -74,23 +74,22 @@ public void handle(SRunningBuild build, BuildTriggerDescriptor trigger) throws I if (branch != null && build.getBuildStatus().isSuccessful()) { SBuildType buildType = build.getBuildType(); - BitbucketPropertiesHelper bitbucketPropertiesHelper = - new BitbucketPropertiesHelper(trigger.getProperties(), bitbucketConstants); - BitbucketApi bitbucketApi = bitbucketApiFactory.create(bitbucketPropertiesHelper); + VcsPropertiesHelper vcsPropertiesHelper = new VcsPropertiesHelper(trigger.getProperties(), vcsConstants); + VcsApi vcsApi = vcsApiFactories.create(vcsPropertiesHelper); - PullRequest pullRequest = bitbucketApi.getPullRequestForBranch(branch.getName()); + PullRequest pullRequest = vcsApi.getPullRequestForBranch(branch.getName()); JsonCustomDataStorage dataStorage = getJsonDataStorage(buildType, trigger); StagingPropertiesHelper stagingPropertiesHelper = new StagingPropertiesHelper(trigger.getProperties(), constants); TomcatStagingDeploy stagingDeploy = - getTomcatStagingDeploy(bitbucketPropertiesHelper, pullRequest, dataStorage); + getTomcatStagingDeploy(vcsPropertiesHelper, pullRequest, dataStorage); deploy(build, stagingPropertiesHelper, stagingDeploy); - postComment(bitbucketApi, pullRequest, stagingDeploy); + postComment(vcsApi, pullRequest, stagingDeploy); - dataStorage.putValue(getPullRequestKey(bitbucketPropertiesHelper, pullRequest), stagingDeploy); + dataStorage.putValue(getPullRequestKey(vcsPropertiesHelper, pullRequest), stagingDeploy); } } @@ -155,24 +154,24 @@ private TomcatManager createTomcatManager(StagingPropertiesHelper propertiesHelp } } - private Comment postComment(BitbucketApi bitbucketApi, + private Comment postComment(VcsApi vcsApi, PullRequest pullRequest, TomcatStagingDeploy stagingDeploy) throws IOException { Comment comment = stagingDeploy.getComment(); if (comment == null && stagingDeploy.isDeployed()) { - comment = bitbucketApi.postComment(pullRequest.getId(), getComment(stagingDeploy)); + comment = vcsApi.postComment(pullRequest.getId(), getComment(stagingDeploy)); stagingDeploy.setComment(comment); } return comment; } - private TomcatStagingDeploy getTomcatStagingDeploy(BitbucketPropertiesHelper bitbucketPropertiesHelper, + private TomcatStagingDeploy getTomcatStagingDeploy(VcsPropertiesHelper vcsPropertiesHelper, PullRequest pullRequest, JsonCustomDataStorage dataStorage) { - String pullRequestKey = getPullRequestKey(bitbucketPropertiesHelper.getRepositoryOwner(), - bitbucketPropertiesHelper.getRepositoryName(), pullRequest); + String pullRequestKey = getPullRequestKey(vcsPropertiesHelper.getRepositoryOwner(), + vcsPropertiesHelper.getRepositoryName(), pullRequest); TomcatStagingDeploy stagingDeploy = dataStorage.getValue(pullRequestKey); @@ -191,12 +190,12 @@ private JsonCustomDataStorage getJsonDataStorage(SBuildType return JsonCustomDataStorage.create(customDataStorage, TomcatStagingDeploy.class); } - private String getPullRequestKey(BitbucketPropertiesHelper helper, PullRequest pullRequest) { + private String getPullRequestKey(VcsPropertiesHelper helper, PullRequest pullRequest) { return getPullRequestKey(helper.getRepositoryOwner(), helper.getRepositoryName(), pullRequest); } private String getPullRequestKey(String repositoryOwner, String repositoryName, PullRequest pullRequest) { - return bitbucketConstants.getPullRequestKey() + repositoryOwner + "_" + repositoryName + "_" + pullRequest + return vcsConstants.getPullRequestKey() + repositoryOwner + "_" + repositoryName + "_" + pullRequest .getId(); } diff --git a/staging/src/main/java/com/arcbees/staging/TomcatStagingDeploy.java b/staging/src/main/java/com/arcbees/staging/TomcatStagingDeploy.java index 7613117..f3d9c9d 100644 --- a/staging/src/main/java/com/arcbees/staging/TomcatStagingDeploy.java +++ b/staging/src/main/java/com/arcbees/staging/TomcatStagingDeploy.java @@ -16,8 +16,8 @@ package com.arcbees.staging; -import com.arcbees.bitbucket.model.Comment; -import com.arcbees.bitbucket.model.PullRequest; +import com.arcbees.vcs.model.Comment; +import com.arcbees.vcs.model.PullRequest; public class TomcatStagingDeploy { private final PullRequest pullRequest; diff --git a/staging/src/main/java/com/arcbees/staging/TomcatStagingTrigger.java b/staging/src/main/java/com/arcbees/staging/TomcatStagingTrigger.java index 74a7959..c6da885 100644 --- a/staging/src/main/java/com/arcbees/staging/TomcatStagingTrigger.java +++ b/staging/src/main/java/com/arcbees/staging/TomcatStagingTrigger.java @@ -29,14 +29,14 @@ import org.apache.tomcat.maven.common.deployer.TomcatManagerResponse; import org.jetbrains.annotations.NotNull; -import com.arcbees.bitbucket.BitbucketConstants; -import com.arcbees.bitbucket.BitbucketPropertiesHelper; -import com.arcbees.bitbucket.api.BitbucketApi; -import com.arcbees.bitbucket.api.BitbucketApiFactory; -import com.arcbees.bitbucket.model.PullRequest; -import com.arcbees.bitbucket.model.PullRequestTarget; -import com.arcbees.bitbucket.model.PullRequests; -import com.arcbees.bitbucket.util.JsonCustomDataStorage; +import com.arcbees.vcs.VcsApi; +import com.arcbees.vcs.VcsApiFactories; +import com.arcbees.vcs.VcsConstants; +import com.arcbees.vcs.VcsPropertiesHelper; +import com.arcbees.vcs.model.PullRequest; +import com.arcbees.vcs.model.PullRequestTarget; +import com.arcbees.vcs.model.PullRequests; +import com.arcbees.vcs.util.JsonCustomDataStorage; import com.google.common.base.Strings; import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor; @@ -47,19 +47,19 @@ public class TomcatStagingTrigger extends PolledBuildTrigger { private static final Logger LOGGER = Logger.getLogger(TomcatStagingTrigger.class.getName()); - private final BitbucketApiFactory apiFactory; + private final VcsApiFactories vcsApiFactories; private final TomcatManagerFactory tomcatManagerFactory; private final Constants constants; - private final BitbucketConstants bitbucketConstants; + private final VcsConstants vcsConstants; - public TomcatStagingTrigger(BitbucketApiFactory apiFactory, + public TomcatStagingTrigger(VcsApiFactories vcsApiFactories, TomcatManagerFactory tomcatManagerFactory, Constants constants, - BitbucketConstants bitbucketConstants) { - this.apiFactory = apiFactory; + VcsConstants vcsConstants) { + this.vcsApiFactories = vcsApiFactories; this.tomcatManagerFactory = tomcatManagerFactory; this.constants = constants; - this.bitbucketConstants = bitbucketConstants; + this.vcsConstants = vcsConstants; } @Override @@ -83,16 +83,15 @@ public void triggerBuild(@NotNull PolledTriggerContext context) throws BuildTrig private void checkBranchesToUndeploy(PolledTriggerContext context, Map properties, StagingPropertiesHelper stagingPropertiesHelper, String mergeBranch) throws IOException { - BitbucketPropertiesHelper bitbucketPropertiesHelper = - new BitbucketPropertiesHelper(properties, bitbucketConstants); - String repositoryOwner = bitbucketPropertiesHelper.getRepositoryOwner(); - String repositoryName = bitbucketPropertiesHelper.getRepositoryName(); + VcsPropertiesHelper vcsPropertiesHelper = new VcsPropertiesHelper(properties, vcsConstants); + String repositoryOwner = vcsPropertiesHelper.getRepositoryOwner(); + String repositoryName = vcsPropertiesHelper.getRepositoryName(); JsonCustomDataStorage dataStorage = JsonCustomDataStorage.create(context.getCustomDataStorage(), TomcatStagingDeploy.class); TomcatManager tomcatManager = createTomcatManager(stagingPropertiesHelper); - PullRequests pullRequests = getMergedPullRequests(bitbucketPropertiesHelper); + PullRequests pullRequests = getMergedPullRequests(vcsPropertiesHelper); for (PullRequest pullRequest : pullRequests.getPullRequests()) { if (isTargetMergeBranch(mergeBranch, pullRequest)) { String pullRequestKey = getPullRequestKey(repositoryOwner, repositoryName, pullRequest); @@ -106,10 +105,10 @@ private void checkBranchesToUndeploy(PolledTriggerContext context, Map dataStorage, @@ -148,6 +147,8 @@ private void undeploy(TomcatManager tomcatManager, TomcatStagingDeploy stagingDe TomcatManagerResponse response = tomcatManager.undeploy(webPath); int statusCode = response.getStatusCode(); + LOGGER.info("Undeploying Status : " + statusCode); + success = HttpStatus.SC_OK == statusCode || HttpStatus.SC_NOT_FOUND == statusCode; } catch (TomcatManagerException e) { LOGGER.log(Level.SEVERE, e.getMessage(), e); @@ -170,7 +171,7 @@ private String getBranchName(PullRequestTarget source) { } private String getPullRequestKey(String repositoryOwner, String repositoryName, PullRequest pullRequest) { - return bitbucketConstants.getPullRequestKey() + repositoryOwner + "_" + repositoryName + "_" + return vcsConstants.getPullRequestKey() + repositoryOwner + "_" + repositoryName + "_" + pullRequest.getId(); } } diff --git a/staging/src/main/resources/buildServerResources/staging_deploy.jsp b/staging/src/main/resources/buildServerResources/staging_deploy.jsp index 8d863e2..f5099f9 100644 --- a/staging/src/main/resources/buildServerResources/staging_deploy.jsp +++ b/staging/src/main/resources/buildServerResources/staging_deploy.jsp @@ -1,8 +1,7 @@ <%@ include file="/include.jsp" %> <%@ include file="/include-internal.jsp" %> - - + - - Specify Bitbucket repository name and credentials - - - - User Name: - - - - Bitbucket user name - - - - Password: - - - - Bitbucket password - - - - - - Owner: - - - - Bitbucket repository owner (user or organization) - - - - Repository: - - - - Bitbucket repository name - - - +<%@ include file="vcsSettings.jsp" %> Specify Tomcat Manager URL and credentials @@ -75,24 +36,24 @@ User Name: - - + + Manager user name Password: - - + + Manager password Manager URL: - - + + Tomcat Manager URL (ie: http://url.com/manager/text) @@ -101,16 +62,16 @@ Base Context Path: - - + + Base Context Path Undeploy Branch: - - + + Undeploy when merged into this branch diff --git a/bitbucket/pom.xml b/vcs-utils/pom.xml similarity index 92% rename from bitbucket/pom.xml rename to vcs-utils/pom.xml index 1540a84..f5b5c3b 100644 --- a/bitbucket/pom.xml +++ b/vcs-utils/pom.xml @@ -10,6 +10,6 @@ 1.0-SNAPSHOT - bitbucket + vcs-utils 1.0-SNAPSHOT diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/AbstractVcsApi.java b/vcs-utils/src/main/java/com/arcbees/vcs/AbstractVcsApi.java new file mode 100644 index 0000000..58a7f74 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/AbstractVcsApi.java @@ -0,0 +1,111 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * Licensed 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.arcbees.vcs; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.HttpURLConnection; + +import org.apache.commons.codec.CharEncoding; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHeaders; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.auth.Credentials; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.entity.ContentType; +import org.apache.http.impl.auth.BasicScheme; +import org.apache.http.message.BasicHeader; +import org.apache.http.util.EntityUtils; + +import com.arcbees.vcs.model.Branch; +import com.arcbees.vcs.model.PullRequest; +import com.arcbees.vcs.model.PullRequestTarget; +import com.arcbees.vcs.model.PullRequests; +import com.arcbees.vcs.util.HttpClientWrapper; +import com.arcbees.vcs.util.UnexpectedHttpStatusException; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import com.google.gson.Gson; + +public abstract class AbstractVcsApi implements VcsApi { + protected T processResponse(HttpClientWrapper httpClient, + HttpUriRequest request, + Credentials credentials, + Gson gson, + Class clazz) throws IOException { + includeAuthentication(request, credentials); + setDefaultHeaders(request); + try { + HttpResponse execute = httpClient.execute(request); + int statusCode = execute.getStatusLine().getStatusCode(); + if (statusCode != HttpURLConnection.HTTP_OK && statusCode != HttpURLConnection.HTTP_CREATED) { + throw new UnexpectedHttpStatusException(statusCode, + "Failed to complete request. Status: " + execute.getStatusLine()); + } + + HttpEntity entity = execute.getEntity(); + if (entity == null) { + throw new IOException("Failed to complete request. Empty response. Status: " + execute.getStatusLine()); + } + + try { + return readEntity(clazz, entity, gson); + } finally { + EntityUtils.consumeQuietly(entity); + } + } finally { + request.abort(); + } + } + + protected T readEntity(Class clazz, HttpEntity entity, Gson gson) throws IOException { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + entity.writeTo(outputStream); + String json = outputStream.toString(CharEncoding.UTF_8); + + return gson.fromJson(json, clazz); + } + + protected void includeAuthentication(HttpRequest request, + Credentials credentials) throws IOException { + try { + request.addHeader(new BasicScheme().authenticate(credentials, request, null)); + } catch (AuthenticationException e) { + throw new IOException("Failed to set authentication for request. " + e.getMessage(), e); + } + } + + protected void setDefaultHeaders(HttpUriRequest request) { + request.setHeader(new BasicHeader(HttpHeaders.ACCEPT_ENCODING, CharEncoding.UTF_8)); + request.setHeader(new BasicHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.getMimeType())); + } + + protected PullRequest findPullRequestForBranch(final String branchName, PullRequests pullRequests) { + return (PullRequest) Iterables.tryFind(pullRequests.getPullRequests(), new Predicate() { + @Override + public boolean apply(PullRequest pullRequest) { + PullRequestTarget source = pullRequest.getSource(); + Branch branch = source.getBranch(); + String pullRequestBranchName = branch.getName(); + + return pullRequestBranchName.equals(branchName); + } + }).orNull(); + } +} diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/api/BitbucketApi.java b/vcs-utils/src/main/java/com/arcbees/vcs/VcsApi.java similarity index 83% rename from bitbucket/src/main/java/com/arcbees/bitbucket/api/BitbucketApi.java rename to vcs-utils/src/main/java/com/arcbees/vcs/VcsApi.java index 0620734..481ea34 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/api/BitbucketApi.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/VcsApi.java @@ -14,15 +14,15 @@ * the License. */ -package com.arcbees.bitbucket.api; +package com.arcbees.vcs; import java.io.IOException; -import com.arcbees.bitbucket.model.Comment; -import com.arcbees.bitbucket.model.PullRequest; -import com.arcbees.bitbucket.model.PullRequests; +import com.arcbees.vcs.model.Comment; +import com.arcbees.vcs.model.PullRequest; +import com.arcbees.vcs.model.PullRequests; -public interface BitbucketApi { +public interface VcsApi { PullRequests getOpenedPullRequests() throws IOException; PullRequests getMergedPullRequests() throws IOException; diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/VcsApiFactories.java b/vcs-utils/src/main/java/com/arcbees/vcs/VcsApiFactories.java new file mode 100644 index 0000000..9b13b36 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/VcsApiFactories.java @@ -0,0 +1,41 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * Licensed 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.arcbees.vcs; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class VcsApiFactories { + @Autowired + private List factories; + @Autowired + private VcsTypes vcsTypes; + + public VcsApi create(VcsPropertiesHelper vcsPropertiesHelper) { + VcsType vcsType = vcsTypes.getVcsType(vcsPropertiesHelper.getVcsType()); + for (VcsApiFactory factory : factories) { + if (factory.handles(vcsType)) { + return factory.create(vcsPropertiesHelper); + } + } + + return null; + } +} diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/api/BitbucketApiFactory.java b/vcs-utils/src/main/java/com/arcbees/vcs/VcsApiFactory.java similarity index 74% rename from bitbucket/src/main/java/com/arcbees/bitbucket/api/BitbucketApiFactory.java rename to vcs-utils/src/main/java/com/arcbees/vcs/VcsApiFactory.java index 716fb78..bf2163c 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/api/BitbucketApiFactory.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/VcsApiFactory.java @@ -14,10 +14,10 @@ * the License. */ -package com.arcbees.bitbucket.api; +package com.arcbees.vcs; -import com.arcbees.bitbucket.BitbucketPropertiesHelper; +public interface VcsApiFactory { + VcsApi create(VcsPropertiesHelper vcsPropertiesHelper); -public interface BitbucketApiFactory { - BitbucketApi create(BitbucketPropertiesHelper bitbucketPropertiesHelper); + boolean handles(VcsType vcsType); } diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/BitbucketConstants.java b/vcs-utils/src/main/java/com/arcbees/vcs/VcsConstants.java similarity index 54% rename from bitbucket/src/main/java/com/arcbees/bitbucket/BitbucketConstants.java rename to vcs-utils/src/main/java/com/arcbees/vcs/VcsConstants.java index 680d98f..3bcec21 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/BitbucketConstants.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/VcsConstants.java @@ -14,30 +14,18 @@ * the License. */ -package com.arcbees.bitbucket; - -public class BitbucketConstants { - private static final String BUILD_SUCCESS = "BUILD SUCCESS "; - private static final String BUILD_FAILURE = "BUILD FAILURE "; - private static final String BITBUCKET_URL = "https://bitbucket.org"; - private static final String USERNAME_KEY = "bitbucket_username"; - private static final String PASSWORD_KEY = jetbrains.buildServer.agent.Constants.SECURE_PROPERTY_PREFIX + - "bitbucket_password"; - private static final String REPOSITORY_KEY = "bitbucket_repo"; - private static final String REPOSITORY_OWNER = "bitbucket_owner"; - private static final String PULLREQUEST_KEY = "bitbucket_pullrequest_"; - - public String getBuildSuccess() { - return BUILD_SUCCESS; - } +package com.arcbees.vcs; - public String getBuildFailure() { - return BUILD_FAILURE; - } +import static jetbrains.buildServer.agent.Constants.SECURE_PROPERTY_PREFIX; - public String getServerUrl() { - return BITBUCKET_URL; - } +public class VcsConstants { + private static final String USERNAME_KEY = "vcs_username"; + private static final String PASSWORD_KEY = SECURE_PROPERTY_PREFIX + "vcs_password"; + private static final String SERVER_URL = "vcs_server"; + private static final String REPOSITORY_KEY = "vcs_repo"; + private static final String REPOSITORY_OWNER = "vcs_owner"; + private static final String PULLREQUEST_KEY = "vcs_pullrequest_"; + private static final String VCS_TYPE = "vcs_type"; public String getUserNameKey() { return USERNAME_KEY; @@ -55,7 +43,15 @@ public String getRepositoryOwnerKey() { return REPOSITORY_OWNER; } + public String getServerUrl() { + return SERVER_URL; + } + public String getPullRequestKey() { return PULLREQUEST_KEY; } + + public String getVcsType() { + return VCS_TYPE; + } } diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/BitbucketPropertiesHelper.java b/vcs-utils/src/main/java/com/arcbees/vcs/VcsPropertiesHelper.java similarity index 55% rename from bitbucket/src/main/java/com/arcbees/bitbucket/BitbucketPropertiesHelper.java rename to vcs-utils/src/main/java/com/arcbees/vcs/VcsPropertiesHelper.java index a59b965..86f4e08 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/BitbucketPropertiesHelper.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/VcsPropertiesHelper.java @@ -14,33 +14,41 @@ * the License. */ -package com.arcbees.bitbucket; +package com.arcbees.vcs; import java.util.Map; -public class BitbucketPropertiesHelper { +public class VcsPropertiesHelper { private final Map properties; - private final BitbucketConstants bitbucketConstants; + private final VcsConstants vcsConstants; - public BitbucketPropertiesHelper(Map properties, - BitbucketConstants bitbucketConstants) { + public VcsPropertiesHelper(Map properties, + VcsConstants vcsConstants) { this.properties = properties; - this.bitbucketConstants = bitbucketConstants; + this.vcsConstants = vcsConstants; } public String getRepositoryName() { - return properties.get(bitbucketConstants.getRepositoryNameKey()); + return properties.get(vcsConstants.getRepositoryNameKey()); } public String getRepositoryOwner() { - return properties.get(bitbucketConstants.getRepositoryOwnerKey()); + return properties.get(vcsConstants.getRepositoryOwnerKey()); } public String getPassword() { - return properties.get(bitbucketConstants.getPasswordKey()); + return properties.get(vcsConstants.getPasswordKey()); } public String getUserName() { - return properties.get(bitbucketConstants.getUserNameKey()); + return properties.get(vcsConstants.getUserNameKey()); + } + + public String getVcsType() { + return properties.get(vcsConstants.getVcsType()); + } + + public String getServerUrl() { + return properties.get(vcsConstants.getServerUrl()); } } diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/BitbucketPropertiesProcessor.java b/vcs-utils/src/main/java/com/arcbees/vcs/VcsPropertiesProcessor.java similarity index 67% rename from bitbucket/src/main/java/com/arcbees/bitbucket/BitbucketPropertiesProcessor.java rename to vcs-utils/src/main/java/com/arcbees/vcs/VcsPropertiesProcessor.java index 2f62026..cc9b54b 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/BitbucketPropertiesProcessor.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/VcsPropertiesProcessor.java @@ -14,7 +14,7 @@ * the License. */ -package com.arcbees.bitbucket; +package com.arcbees.vcs; import java.util.ArrayList; import java.util.Collection; @@ -25,11 +25,11 @@ import jetbrains.buildServer.serverSide.InvalidProperty; import jetbrains.buildServer.serverSide.PropertiesProcessor; -public class BitbucketPropertiesProcessor implements PropertiesProcessor { - private final BitbucketConstants bitbucketConstants; +public class VcsPropertiesProcessor implements PropertiesProcessor { + private final VcsConstants vcsConstants; - public BitbucketPropertiesProcessor(BitbucketConstants bitbucketConstants) { - this.bitbucketConstants = bitbucketConstants; + public VcsPropertiesProcessor(VcsConstants vcsConstants) { + this.vcsConstants = vcsConstants; } @Override @@ -37,10 +37,10 @@ public Collection process(Map properties) { Collection result = new ArrayList(); if (properties == null) return result; - checkNotEmpty(properties, bitbucketConstants.getUserNameKey(), "Username must be specified", result); - checkNotEmpty(properties, bitbucketConstants.getPasswordKey(), "Password must be specified", result); - checkNotEmpty(properties, bitbucketConstants.getRepositoryOwnerKey(), "Repository owner must be specified", result); - checkNotEmpty(properties, bitbucketConstants.getRepositoryNameKey(), "Repository name must be specified", result); + checkNotEmpty(properties, vcsConstants.getUserNameKey(), "Username must be specified", result); + checkNotEmpty(properties, vcsConstants.getPasswordKey(), "Password must be specified", result); + checkNotEmpty(properties, vcsConstants.getRepositoryOwnerKey(), "Repository owner must be specified", result); + checkNotEmpty(properties, vcsConstants.getRepositoryNameKey(), "Repository name must be specified", result); return result; } diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/VcsType.java b/vcs-utils/src/main/java/com/arcbees/vcs/VcsType.java new file mode 100644 index 0000000..d141131 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/VcsType.java @@ -0,0 +1,21 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * Licensed 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.arcbees.vcs; + +public interface VcsType { + String getName(); +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/VcsTypes.java b/vcs-utils/src/main/java/com/arcbees/vcs/VcsTypes.java new file mode 100644 index 0000000..b7ef497 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/VcsTypes.java @@ -0,0 +1,38 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * Licensed 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.arcbees.vcs; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class VcsTypes { + @Autowired + private List vcsTypes; + + public VcsType getVcsType(String vcsType) { + for (VcsType type : vcsTypes) { + if (type.getName().equals(vcsType)) { + return type; + } + } + + return null; + } +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/BitbucketApiFactoryImpl.java b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/BitbucketApiFactoryImpl.java new file mode 100644 index 0000000..43c8607 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/BitbucketApiFactoryImpl.java @@ -0,0 +1,48 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * Licensed 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.arcbees.vcs.bitbucket; + +import com.arcbees.vcs.VcsApi; +import com.arcbees.vcs.VcsApiFactory; +import com.arcbees.vcs.VcsPropertiesHelper; +import com.arcbees.vcs.VcsType; +import com.arcbees.vcs.util.HttpClientWrapper; + +public class BitbucketApiFactoryImpl implements VcsApiFactory { + private final HttpClientWrapper httpClient; + private final BitbucketVcsType bitbucketVcsType; + + public BitbucketApiFactoryImpl(HttpClientWrapper httpClient, + BitbucketVcsType bitbucketVcsType) { + this.httpClient = httpClient; + this.bitbucketVcsType = bitbucketVcsType; + } + + @Override + public boolean handles(VcsType vcsType) { + return vcsType.equals(bitbucketVcsType); + } + + @Override + public VcsApi create(VcsPropertiesHelper vcsPropertiesHelper) { + return new BitbucketApiImpl(httpClient, new BitbucketApiPaths(vcsPropertiesHelper.getServerUrl()), + vcsPropertiesHelper.getUserName(), + vcsPropertiesHelper.getPassword(), + vcsPropertiesHelper.getRepositoryOwner(), + vcsPropertiesHelper.getRepositoryName()); + } +} diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/api/impl/BitbucketApiImpl.java b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/BitbucketApiImpl.java similarity index 54% rename from bitbucket/src/main/java/com/arcbees/bitbucket/api/impl/BitbucketApiImpl.java rename to vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/BitbucketApiImpl.java index 254f1f2..08632a7 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/api/impl/BitbucketApiImpl.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/BitbucketApiImpl.java @@ -14,47 +14,36 @@ * the License. */ -package com.arcbees.bitbucket.api.impl; +package com.arcbees.vcs.bitbucket; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.HttpURLConnection; import java.util.Date; import java.util.List; -import org.apache.commons.codec.CharEncoding; -import org.apache.http.HttpEntity; -import org.apache.http.HttpHeaders; -import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; -import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.entity.ContentType; -import org.apache.http.impl.auth.BasicScheme; -import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; -import com.arcbees.bitbucket.api.BitbucketApi; -import com.arcbees.bitbucket.model.Branch; -import com.arcbees.bitbucket.model.Comment; -import com.arcbees.bitbucket.model.PullRequest; -import com.arcbees.bitbucket.model.PullRequestTarget; -import com.arcbees.bitbucket.model.PullRequests; -import com.arcbees.bitbucket.util.GsonDateTypeAdapter; -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; +import com.arcbees.vcs.AbstractVcsApi; +import com.arcbees.vcs.bitbucket.model.BitbucketComment; +import com.arcbees.vcs.bitbucket.model.BitbucketPullRequests; +import com.arcbees.vcs.model.Comment; +import com.arcbees.vcs.model.PullRequest; +import com.arcbees.vcs.model.PullRequests; +import com.arcbees.vcs.util.GsonDateTypeAdapter; +import com.arcbees.vcs.util.HttpClientWrapper; import com.google.common.collect.Lists; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -public class BitbucketApiImpl implements BitbucketApi { +public class BitbucketApiImpl extends AbstractVcsApi { private final HttpClientWrapper httpClient; private final Gson gson; private final BitbucketApiPaths apiPaths; @@ -82,7 +71,7 @@ public PullRequests getOpenedPullRequests() throws IOException { HttpGet request = new HttpGet(requestUrl); - return processResponse(request, PullRequests.class); + return processResponse(httpClient, request, credentials, gson, BitbucketPullRequests.class); } @Override @@ -91,7 +80,7 @@ public PullRequests getMergedPullRequests() throws IOException { HttpGet request = new HttpGet(requestUrl); - return processResponse(request, PullRequests.class); + return processResponse(httpClient, request, credentials, gson, BitbucketPullRequests.class); } @Override @@ -105,26 +94,13 @@ public PullRequest getPullRequestForBranch(final String branchName) throws IOExc return pullRequestForBranch; } - private PullRequest findPullRequestForBranch(final String branchName, PullRequests pullRequests) { - return Iterables.tryFind(pullRequests.getPullRequests(), new Predicate() { - @Override - public boolean apply(PullRequest pullRequest) { - PullRequestTarget source = pullRequest.getSource(); - Branch branch = source.getBranch(); - String pullRequestBranchName = branch.getName(); - - return pullRequestBranchName.equals(branchName); - } - }).orNull(); - } - @Override public void deleteComment(Integer pullRequestId, Long commentId) throws IOException { String requestUrl = apiPaths.deleteComment(repositoryOwner, repositoryName, pullRequestId, commentId); HttpDelete request = new HttpDelete(requestUrl); - includeAuthentication(request); + includeAuthentication(request, credentials); setDefaultHeaders(request); HttpResponse response = null; @@ -152,53 +128,6 @@ public Comment postComment(Integer pullRequestId, request.setEntity(new UrlEncodedFormEntity(postParameters)); - return processResponse(request, Comment.class); - } - - private T processResponse(HttpUriRequest request, - Class clazz) throws IOException { - includeAuthentication(request); - setDefaultHeaders(request); - try { - HttpResponse execute = httpClient.execute(request); - if (execute.getStatusLine().getStatusCode() != HttpURLConnection.HTTP_OK) { - throw new IOException("Failed to complete request to Bitbucket. Status: " + execute.getStatusLine()); - } - - HttpEntity entity = execute.getEntity(); - if (entity == null) { - throw new IOException( - "Failed to complete request to Bitbucket. Empty response. Status: " + execute.getStatusLine()); - } - - try { - return readEntity(clazz, entity); - } finally { - EntityUtils.consumeQuietly(entity); - } - } finally { - request.abort(); - } - } - - private T readEntity(Class clazz, HttpEntity entity) throws IOException { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - entity.writeTo(outputStream); - String json = outputStream.toString(CharEncoding.UTF_8); - - return gson.fromJson(json, clazz); - } - - private void includeAuthentication(HttpRequest request) throws IOException { - try { - request.addHeader(new BasicScheme().authenticate(credentials, request, null)); - } catch (AuthenticationException e) { - throw new IOException("Failed to set authentication for request. " + e.getMessage(), e); - } - } - - private void setDefaultHeaders(HttpUriRequest request) { - request.setHeader(new BasicHeader(HttpHeaders.ACCEPT_ENCODING, CharEncoding.UTF_8)); - request.setHeader(new BasicHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.getMimeType())); + return processResponse(httpClient, request, credentials, gson, BitbucketComment.class); } } diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/api/impl/BitbucketApiPaths.java b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/BitbucketApiPaths.java similarity index 98% rename from bitbucket/src/main/java/com/arcbees/bitbucket/api/impl/BitbucketApiPaths.java rename to vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/BitbucketApiPaths.java index 4b5ed9a..ad35014 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/api/impl/BitbucketApiPaths.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/BitbucketApiPaths.java @@ -14,7 +14,7 @@ * the License. */ -package com.arcbees.bitbucket.api.impl; +package com.arcbees.vcs.bitbucket; public class BitbucketApiPaths { private static final String API_2 = "/api/2.0/"; diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/BitbucketVcsType.java b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/BitbucketVcsType.java new file mode 100644 index 0000000..82ae18e --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/BitbucketVcsType.java @@ -0,0 +1,28 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * Licensed 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.arcbees.vcs.bitbucket; + +import com.arcbees.vcs.VcsType; + +public class BitbucketVcsType implements VcsType { + private static final String BITBUCKET = "bitbucket"; + + @Override + public String getName() { + return BITBUCKET; + } +} diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/model/Branch.java b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketBranch.java similarity index 82% rename from bitbucket/src/main/java/com/arcbees/bitbucket/model/Branch.java rename to vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketBranch.java index a3faf24..5339b29 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/model/Branch.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketBranch.java @@ -14,15 +14,19 @@ * the License. */ -package com.arcbees.bitbucket.model; +package com.arcbees.vcs.bitbucket.model; -public class Branch { +import com.arcbees.vcs.model.Branch; + +public class BitbucketBranch implements Branch { private String name; + @Override public String getName() { return name; } + @Override public void setName(String name) { this.name = name; } diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/model/Comment.java b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketComment.java similarity index 63% rename from bitbucket/src/main/java/com/arcbees/bitbucket/model/Comment.java rename to vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketComment.java index 930d6ef..3aeef48 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/model/Comment.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketComment.java @@ -14,38 +14,22 @@ * the License. */ -package com.arcbees.bitbucket.model; +package com.arcbees.vcs.bitbucket.model; +import com.arcbees.vcs.model.Comment; import com.google.gson.annotations.SerializedName; -public class Comment { - @SerializedName("pull_request_id") - private Integer pullRequestId; +public class BitbucketComment implements Comment { @SerializedName("comment_id") private Long commentId; - private boolean deleted; - - public Integer getPullRequestId() { - return pullRequestId; - } - - public void setPullRequestId(Integer pullRequestId) { - this.pullRequestId = pullRequestId; - } + @Override public Long getCommentId() { return commentId; } + @Override public void setCommentId(Long commentId) { this.commentId = commentId; } - - public boolean isDeleted() { - return deleted; - } - - public void setDeleted(boolean deleted) { - this.deleted = deleted; - } } diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/model/Commit.java b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketCommit.java similarity index 77% rename from bitbucket/src/main/java/com/arcbees/bitbucket/model/Commit.java rename to vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketCommit.java index aecded6..6172c54 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/model/Commit.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketCommit.java @@ -14,25 +14,20 @@ * the License. */ -package com.arcbees.bitbucket.model; +package com.arcbees.vcs.bitbucket.model; -public class Commit { +import com.arcbees.vcs.model.Commit; + +public class BitbucketCommit implements Commit { private String hash; - private Links links; + @Override public String getHash() { return hash; } + @Override public void setHash(String hash) { this.hash = hash; } - - public Links getLinks() { - return links; - } - - public void setLinks(Links links) { - this.links = links; - } } diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/model/PullRequest.java b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketPullRequest.java similarity index 66% rename from bitbucket/src/main/java/com/arcbees/bitbucket/model/PullRequest.java rename to vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketPullRequest.java index cca2e50..a191fa2 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/model/PullRequest.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketPullRequest.java @@ -14,123 +14,103 @@ * the License. */ -package com.arcbees.bitbucket.model; +package com.arcbees.vcs.bitbucket.model; import java.util.Date; +import com.arcbees.vcs.model.PullRequest; +import com.arcbees.vcs.model.PullRequestTarget; import com.google.gson.annotations.SerializedName; -public class PullRequest { +public class BitbucketPullRequest implements PullRequest { private String status; private String description; - private Links links; private String title; private int id; @SerializedName("created_on") private Date createdOn; @SerializedName("updated_on") private Date updatedOn; - private User user; - @SerializedName("merge_commit") - private Commit mergeCommit; - @SerializedName("closed_by") - private User closedBy; - private PullRequestTarget source; - private PullRequestTarget destination; + private BitbucketPullRequestTarget source; + private BitbucketPullRequestTarget destination; + @Override public String getStatus() { return status; } + @Override public void setStatus(String status) { this.status = status; } + @Override public String getDescription() { return description; } + @Override public void setDescription(String description) { this.description = description; } - public Links getLinks() { - return links; - } - - public void setLinks(Links links) { - this.links = links; - } - + @Override public String getTitle() { return title; } + @Override public void setTitle(String title) { this.title = title; } + @Override public int getId() { return id; } + @Override public void setId(int id) { this.id = id; } + @Override public Date getCreatedOn() { return createdOn; } + @Override public void setCreatedOn(Date createdOn) { this.createdOn = createdOn; } + @Override public Date getUpdatedOn() { return updatedOn; } + @Override public void setUpdatedOn(Date updatedOn) { this.updatedOn = updatedOn; } - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - - public Commit getMergeCommit() { - return mergeCommit; - } - - public void setMergeCommit(Commit mergeCommit) { - this.mergeCommit = mergeCommit; - } - - public User getClosedBy() { - return closedBy; - } - - public void setClosedBy(User closedBy) { - this.closedBy = closedBy; - } - + @Override public PullRequestTarget getSource() { return source; } - public void setSource(PullRequestTarget source) { + @Override + public void setSource(BitbucketPullRequestTarget source) { this.source = source; } + @Override public PullRequestTarget getDestination() { return destination; } - public void setDestination(PullRequestTarget destination) { + @Override + public void setDestination(BitbucketPullRequestTarget destination) { this.destination = destination; } } diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/model/PullRequestTarget.java b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketPullRequestTarget.java similarity index 61% rename from bitbucket/src/main/java/com/arcbees/bitbucket/model/PullRequestTarget.java rename to vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketPullRequestTarget.java index f707098..52cc8a3 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/model/PullRequestTarget.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketPullRequestTarget.java @@ -14,34 +14,33 @@ * the License. */ -package com.arcbees.bitbucket.model; +package com.arcbees.vcs.bitbucket.model; -public class PullRequestTarget { - private Commit commit; - private Branch branch; - private Repository repository; +import com.arcbees.vcs.model.Branch; +import com.arcbees.vcs.model.Commit; +import com.arcbees.vcs.model.PullRequestTarget; +public class BitbucketPullRequestTarget implements PullRequestTarget { + private BitbucketCommit commit; + private BitbucketBranch branch; + + @Override public Commit getCommit() { return commit; } - public void setCommit(Commit commit) { + @Override + public void setCommit(BitbucketCommit commit) { this.commit = commit; } + @Override public Branch getBranch() { return branch; } - public void setBranch(Branch branch) { + @Override + public void setBranch(BitbucketBranch branch) { this.branch = branch; } - - public Repository getRepository() { - return repository; - } - - public void setRepository(Repository repository) { - this.repository = repository; - } } diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/model/Repository.java b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketPullRequests.java similarity index 54% rename from bitbucket/src/main/java/com/arcbees/bitbucket/model/Repository.java rename to vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketPullRequests.java index a3971bb..c07388b 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/model/Repository.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketPullRequests.java @@ -14,28 +14,25 @@ * the License. */ -package com.arcbees.bitbucket.model; +package com.arcbees.vcs.bitbucket.model; -import com.google.gson.annotations.SerializedName; - -public class Repository { - @SerializedName("full_name") - private String fullName; - private Links links; +import java.util.List; - public String getFullName() { - return fullName; - } +import com.arcbees.vcs.model.PullRequest; +import com.arcbees.vcs.model.PullRequests; +import com.google.gson.annotations.SerializedName; - public void setFullName(String fullName) { - this.fullName = fullName; - } +public class BitbucketPullRequests implements PullRequests { + @SerializedName("values") + private List pullRequests; - public Links getLinks() { - return links; + @Override + public List getPullRequests() { + return pullRequests; } - public void setLinks(Links links) { - this.links = links; + @Override + public void setPullRequests(List pullRequests) { + this.pullRequests = pullRequests; } } diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/model/Branch.java b/vcs-utils/src/main/java/com/arcbees/vcs/model/Branch.java new file mode 100644 index 0000000..18fe832 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/model/Branch.java @@ -0,0 +1,23 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * Licensed 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.arcbees.vcs.model; + +public interface Branch { + String getName(); + + void setName(String name); +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/model/Comment.java b/vcs-utils/src/main/java/com/arcbees/vcs/model/Comment.java new file mode 100644 index 0000000..dcddb17 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/model/Comment.java @@ -0,0 +1,23 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * Licensed 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.arcbees.vcs.model; + +public interface Comment { + Long getCommentId(); + + void setCommentId(Long commentId); +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/model/Commit.java b/vcs-utils/src/main/java/com/arcbees/vcs/model/Commit.java new file mode 100644 index 0000000..eeb34d7 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/model/Commit.java @@ -0,0 +1,23 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * Licensed 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.arcbees.vcs.model; + +public interface Commit { + String getHash(); + + void setHash(String hash); +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/model/PullRequest.java b/vcs-utils/src/main/java/com/arcbees/vcs/model/PullRequest.java new file mode 100644 index 0000000..963303a --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/model/PullRequest.java @@ -0,0 +1,53 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * Licensed 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.arcbees.vcs.model; + +import java.util.Date; + +public interface PullRequest { + String getStatus(); + + void setStatus(String status); + + String getDescription(); + + void setDescription(String description); + + String getTitle(); + + void setTitle(String title); + + int getId(); + + void setId(int id); + + Date getCreatedOn(); + + void setCreatedOn(Date createdOn); + + Date getUpdatedOn(); + + void setUpdatedOn(Date updatedOn); + + PullRequestTarget getSource(); + + void setSource(T source); + + PullRequestTarget getDestination(); + + void setDestination(T destination); +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/model/PullRequestTarget.java b/vcs-utils/src/main/java/com/arcbees/vcs/model/PullRequestTarget.java new file mode 100644 index 0000000..a2c64c2 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/model/PullRequestTarget.java @@ -0,0 +1,27 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * Licensed 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.arcbees.vcs.model; + +public interface PullRequestTarget { + Commit getCommit(); + + void setCommit(C commit); + + Branch getBranch(); + + void setBranch(B branch); +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/model/PullRequests.java b/vcs-utils/src/main/java/com/arcbees/vcs/model/PullRequests.java new file mode 100644 index 0000000..5455b8f --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/model/PullRequests.java @@ -0,0 +1,25 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * Licensed 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.arcbees.vcs.model; + +import java.util.List; + +public interface PullRequests { + List getPullRequests(); + + void setPullRequests(List pullRequests); +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/stash/StashApiFactoryImpl.java b/vcs-utils/src/main/java/com/arcbees/vcs/stash/StashApiFactoryImpl.java new file mode 100644 index 0000000..3446ba1 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/stash/StashApiFactoryImpl.java @@ -0,0 +1,49 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * This file is part of Stash TeamCity plugin. + * + * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, + * see http://www.gnu.org/licenses/. + */ + +package com.arcbees.vcs.stash; + +import com.arcbees.vcs.VcsApi; +import com.arcbees.vcs.VcsApiFactory; +import com.arcbees.vcs.VcsPropertiesHelper; +import com.arcbees.vcs.VcsType; +import com.arcbees.vcs.util.HttpClientWrapper; + +public class StashApiFactoryImpl implements VcsApiFactory { + private final HttpClientWrapper httpClient; + private final StashVcsType stashVcsType; + + public StashApiFactoryImpl(HttpClientWrapper httpClient, + StashVcsType stashVcsType) { + this.httpClient = httpClient; + this.stashVcsType = stashVcsType; + } + + @Override + public boolean handles(VcsType vcsType) { + return vcsType.equals(stashVcsType); + } + + @Override + public VcsApi create(VcsPropertiesHelper vcsPropertiesHelper) { + return new StashApiImpl(httpClient, new StashApiPaths(vcsPropertiesHelper.getServerUrl()), + vcsPropertiesHelper.getUserName(), + vcsPropertiesHelper.getPassword(), + vcsPropertiesHelper.getRepositoryOwner(), + vcsPropertiesHelper.getRepositoryName()); + } +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/stash/StashApiImpl.java b/vcs-utils/src/main/java/com/arcbees/vcs/stash/StashApiImpl.java new file mode 100644 index 0000000..2e4e70e --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/stash/StashApiImpl.java @@ -0,0 +1,152 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * This file is part of Stash TeamCity plugin. + * + * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, + * see http://www.gnu.org/licenses/. + */ + +package com.arcbees.vcs.stash; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.util.Date; + +import org.apache.http.HttpHeaders; +import org.apache.http.HttpResponse; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.entity.ContentType; +import org.apache.http.message.BasicHeader; +import org.apache.http.util.EntityUtils; + +import com.arcbees.vcs.AbstractVcsApi; +import com.arcbees.vcs.model.Comment; +import com.arcbees.vcs.model.PullRequest; +import com.arcbees.vcs.model.PullRequests; +import com.arcbees.vcs.stash.model.StashComment; +import com.arcbees.vcs.stash.model.StashPullRequests; +import com.arcbees.vcs.util.GsonDateTypeAdapter; +import com.arcbees.vcs.util.HttpClientWrapper; +import com.arcbees.vcs.util.UnexpectedHttpStatusException; +import com.google.common.base.Charsets; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +public class StashApiImpl extends AbstractVcsApi { + private final HttpClientWrapper httpClient; + private final Gson gson; + private final StashApiPaths apiPaths; + private final String repositoryOwner; + private final String repositoryName; + private final UsernamePasswordCredentials credentials; + + public StashApiImpl(HttpClientWrapper httpClient, + StashApiPaths apiPaths, + String userName, + String password, + String repositoryOwner, + String repositoryName) { + this.httpClient = httpClient; + this.apiPaths = apiPaths; + this.repositoryOwner = repositoryOwner; + this.repositoryName = repositoryName; + this.credentials = new UsernamePasswordCredentials(userName, password); + this.gson = new GsonBuilder().registerTypeAdapter(Date.class, new GsonDateTypeAdapter()).create(); + } + + @Override + public PullRequests getOpenedPullRequests() throws IOException { + String requestUrl = apiPaths.getOpenedPullRequests(repositoryOwner, repositoryName); + + HttpGet request = new HttpGet(requestUrl); + + return processResponse(httpClient, request, credentials, gson, StashPullRequests.class); + } + + @Override + public PullRequests getMergedPullRequests() throws IOException { + String requestUrl = apiPaths.getMergedPullRequests(repositoryOwner, repositoryName); + + HttpGet request = new HttpGet(requestUrl); + + return processResponse(httpClient, request, credentials, gson, StashPullRequests.class); + } + + @Override + public PullRequest getPullRequestForBranch(final String branchName) throws IOException { + PullRequest pullRequestForBranch = findPullRequestForBranch(branchName, getOpenedPullRequests()); + + if (pullRequestForBranch == null) { + pullRequestForBranch = findPullRequestForBranch(branchName, getMergedPullRequests()); + } + + return pullRequestForBranch; + } + + @Override + public void deleteComment(Integer pullRequestId, Long commentId) throws IOException { + StashComment oldComment = getComment(pullRequestId, commentId); + + if (oldComment != null) { + String requestUrl = apiPaths.pullRequestComment(repositoryOwner, repositoryName, pullRequestId, commentId) + + "?version=" + oldComment.getVersion(); + + HttpDelete request = new HttpDelete(requestUrl); + + includeAuthentication(request, credentials); + setDefaultHeaders(request); + + HttpResponse response = null; + try { + response = httpClient.execute(request); + if (response.getStatusLine().getStatusCode() != HttpURLConnection.HTTP_NO_CONTENT) { + throw new IOException("Failed to complete request to Stash. Status: " + response.getStatusLine()); + } + } finally { + if (response != null) { + EntityUtils.consumeQuietly(response.getEntity()); + } + } + } + } + + @Override + public Comment postComment(Integer pullRequestId, + String comment) throws IOException { + String requestUrl = apiPaths.addComment(repositoryOwner, repositoryName, pullRequestId); + + HttpPost request = new HttpPost(requestUrl); + request.setHeader(new BasicHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType())); + request.setEntity(new ByteArrayEntity(gson.toJson(new StashComment(comment)).getBytes(Charsets.UTF_8))); + + return processResponse(httpClient, request, credentials, gson, StashComment.class); + } + + private StashComment getComment(Integer pullRequestId, Long commentId) throws IOException { + String requestUrl = apiPaths.pullRequestComment(repositoryOwner, repositoryName, pullRequestId, commentId); + + HttpGet request = new HttpGet(requestUrl); + + includeAuthentication(request, credentials); + setDefaultHeaders(request); + + try { + return processResponse(httpClient, request, credentials, gson, StashComment.class); + } catch (UnexpectedHttpStatusException e) { + return null; + } + } +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/stash/StashApiPaths.java b/vcs-utils/src/main/java/com/arcbees/vcs/stash/StashApiPaths.java new file mode 100644 index 0000000..b580383 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/stash/StashApiPaths.java @@ -0,0 +1,74 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * This file is part of Stash TeamCity plugin. + * + * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, + * see http://www.gnu.org/licenses/. + */ + +package com.arcbees.vcs.stash; + +public class StashApiPaths { + private static final String API_1 = "/rest/api/1.0/projects/"; + private static final String REPOSITORIES = "repos/"; + private static final String PULLREQUESTS = "/pull-requests/"; + private static final String COMMENTS = "/comments"; + private static final String SLASH = "/"; + private static final String STATE_MERGED = "?state=MERGED"; + + private final String baseUrl; + + public StashApiPaths(String baseUrl) { + if (baseUrl.endsWith("/")) { + baseUrl = baseUrl.substring(0, baseUrl.length() - 1); + } + + this.baseUrl = baseUrl; + } + + public String getOpenedPullRequests(String repositoryOwner, + String repositoryName) { + return getPullRequests(repositoryOwner, repositoryName); + } + + public String getMergedPullRequests(String repositoryOwner, String repositoryName) { + return getPullRequests(repositoryOwner, repositoryName) + STATE_MERGED; + } + + public String getPullRequest(String repositoryOwner, + String repositoryName, + Integer pullRequestId) { + return baseUrl + API_1 + pathToPullRequest(repositoryOwner, repositoryName, pullRequestId); + } + + public String addComment(String repositoryOwner, + String repositoryName, + Integer pullRequestId) { + return baseUrl + API_1 + pathToPullRequest(repositoryOwner, repositoryName, pullRequestId) + COMMENTS; + } + + public String pullRequestComment(String repositoryOwner, + String repositoryName, + Integer pullRequestId, + Long commentId) { + return baseUrl + API_1 + pathToPullRequest(repositoryOwner, repositoryName, pullRequestId) + + COMMENTS + SLASH + commentId; + } + + private String getPullRequests(String repositoryOwner, String repositoryName) { + return baseUrl + API_1 + repositoryOwner + SLASH + REPOSITORIES + repositoryName + PULLREQUESTS; + } + + private String pathToPullRequest(String repositoryOwner, String repositoryName, Integer pullRequestId) { + return repositoryOwner + SLASH + REPOSITORIES + repositoryName + PULLREQUESTS + pullRequestId; + } +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/stash/StashVcsType.java b/vcs-utils/src/main/java/com/arcbees/vcs/stash/StashVcsType.java new file mode 100644 index 0000000..579276a --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/stash/StashVcsType.java @@ -0,0 +1,29 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * This file is part of Stash TeamCity plugin. + * + * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, + * see http://www.gnu.org/licenses/. + */ + +package com.arcbees.vcs.stash; + +import com.arcbees.vcs.VcsType; + +public class StashVcsType implements VcsType { + private static final String STASH = "stash"; + + @Override + public String getName() { + return STASH; + } +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashBranch.java b/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashBranch.java new file mode 100644 index 0000000..d78f8ed --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashBranch.java @@ -0,0 +1,41 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * This file is part of Stash TeamCity plugin. + * + * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, + * see http://www.gnu.org/licenses/. + */ + +package com.arcbees.vcs.stash.model; + +import com.arcbees.vcs.model.Branch; + +public class StashBranch implements Branch { + private String name; + + public StashBranch() { + } + + public StashBranch(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashComment.java b/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashComment.java new file mode 100644 index 0000000..dc06cb9 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashComment.java @@ -0,0 +1,59 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * This file is part of Stash TeamCity plugin. + * + * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, + * see http://www.gnu.org/licenses/. + */ + +package com.arcbees.vcs.stash.model; + +import com.arcbees.vcs.model.Comment; + +public class StashComment implements Comment { + private Long id; + private String text; + private String version; + + public StashComment() { + } + + public StashComment(String text) { + this.text = text; + } + + @Override + public Long getCommentId() { + return id; + } + + @Override + public void setCommentId(Long commentId) { + this.id = commentId; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashCommit.java b/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashCommit.java new file mode 100644 index 0000000..0a9608c --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashCommit.java @@ -0,0 +1,41 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * This file is part of Stash TeamCity plugin. + * + * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, + * see http://www.gnu.org/licenses/. + */ + +package com.arcbees.vcs.stash.model; + +import com.arcbees.vcs.model.Commit; + +public class StashCommit implements Commit { + private String hash; + + public StashCommit() { + } + + public StashCommit(String hash) { + this.hash = hash; + } + + @Override + public String getHash() { + return hash; + } + + @Override + public void setHash(String hash) { + this.hash = hash; + } +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashPullRequest.java b/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashPullRequest.java new file mode 100644 index 0000000..25eb4c1 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashPullRequest.java @@ -0,0 +1,114 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * This file is part of Stash TeamCity plugin. + * + * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, + * see http://www.gnu.org/licenses/. + */ + +package com.arcbees.vcs.stash.model; + +import java.util.Date; + +import com.arcbees.vcs.model.PullRequest; +import com.arcbees.vcs.model.PullRequestTarget; + +public class StashPullRequest implements PullRequest { + private String state; + private String description; + private String title; + private int id; + private Date createdDate; + private Date updatedDate; + private StashPullRequestTarget fromRef; + private StashPullRequestTarget toRef; + + @Override + public String getStatus() { + return state; + } + + @Override + public void setStatus(String status) { + this.state = status; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public void setDescription(String description) { + this.description = description; + } + + @Override + public String getTitle() { + return title; + } + + @Override + public void setTitle(String title) { + this.title = title; + } + + @Override + public int getId() { + return id; + } + + @Override + public void setId(int id) { + this.id = id; + } + + @Override + public Date getCreatedOn() { + return createdDate; + } + + @Override + public void setCreatedOn(Date createdOn) { + this.createdDate = createdOn; + } + + @Override + public Date getUpdatedOn() { + return updatedDate; + } + + @Override + public void setUpdatedOn(Date updatedOn) { + this.updatedDate = updatedOn; + } + + @Override + public PullRequestTarget getSource() { + return fromRef; + } + + @Override + public void setSource(StashPullRequestTarget source) { + this.fromRef = source; + } + + @Override + public PullRequestTarget getDestination() { + return toRef; + } + + @Override + public void setDestination(StashPullRequestTarget destination) { + this.toRef = destination; + } +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashPullRequestTarget.java b/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashPullRequestTarget.java new file mode 100644 index 0000000..f1a3d41 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashPullRequestTarget.java @@ -0,0 +1,55 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * This file is part of Stash TeamCity plugin. + * + * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, + * see http://www.gnu.org/licenses/. + */ + +package com.arcbees.vcs.stash.model; + +import com.arcbees.vcs.model.Branch; +import com.arcbees.vcs.model.Commit; +import com.arcbees.vcs.model.PullRequestTarget; + +public class StashPullRequestTarget implements PullRequestTarget { + private StashCommit commit; + private StashBranch branch; + private String latestChangeset; + private String displayId; + + @Override + public Commit getCommit() { + if (commit == null) { + setCommit(new StashCommit(latestChangeset)); + } + return commit; + } + + @Override + public void setCommit(StashCommit commit) { + this.commit = commit; + } + + @Override + public Branch getBranch() { + if (branch == null) { + setBranch(new StashBranch(displayId)); + } + return branch; + } + + @Override + public void setBranch(StashBranch branch) { + this.branch = branch; + } +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashPullRequests.java b/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashPullRequests.java new file mode 100644 index 0000000..95eea06 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashPullRequests.java @@ -0,0 +1,39 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * This file is part of Stash TeamCity plugin. + * + * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, + * see http://www.gnu.org/licenses/. + */ + +package com.arcbees.vcs.stash.model; + +import java.util.List; + +import com.arcbees.vcs.model.PullRequest; +import com.arcbees.vcs.model.PullRequests; +import com.google.gson.annotations.SerializedName; + +public class StashPullRequests implements PullRequests { + @SerializedName("values") + private List pullRequests; + + @Override + public List getPullRequests() { + return pullRequests; + } + + @Override + public void setPullRequests(List pullRequests) { + this.pullRequests = pullRequests; + } +} diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/util/GsonDateTypeAdapter.java b/vcs-utils/src/main/java/com/arcbees/vcs/util/GsonDateTypeAdapter.java similarity index 91% rename from bitbucket/src/main/java/com/arcbees/bitbucket/util/GsonDateTypeAdapter.java rename to vcs-utils/src/main/java/com/arcbees/vcs/util/GsonDateTypeAdapter.java index fade40d..63a6508 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/util/GsonDateTypeAdapter.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/util/GsonDateTypeAdapter.java @@ -14,7 +14,7 @@ * the License. */ -package com.arcbees.bitbucket.util; +package com.arcbees.vcs.util; import java.lang.reflect.Type; import java.text.DateFormat; @@ -45,7 +45,6 @@ public Date deserialize(JsonElement json, Type type, JsonDeserializationContext String value = json.getAsJsonPrimitive().getAsString(); Matcher matcher = DATE_TIME_LONG_FORMAT_PATTERN.matcher(value); - Exception lastError = null; for (DateFormat dateFormat : dateFormats) { try { if (matcher.matches()) { @@ -54,10 +53,13 @@ public Date deserialize(JsonElement json, Type type, JsonDeserializationContext return dateFormat.parse(value); } catch (ParseException e) { - lastError = e; } } - throw new JsonParseException(lastError); + try { + return new Date(json.getAsJsonPrimitive().getAsLong()); + } catch (NumberFormatException e) { + throw new JsonParseException(e); + } } } diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/api/impl/HttpClientWrapper.java b/vcs-utils/src/main/java/com/arcbees/vcs/util/HttpClientWrapper.java similarity index 95% rename from bitbucket/src/main/java/com/arcbees/bitbucket/api/impl/HttpClientWrapper.java rename to vcs-utils/src/main/java/com/arcbees/vcs/util/HttpClientWrapper.java index 6634a08..304dfc8 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/api/impl/HttpClientWrapper.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/util/HttpClientWrapper.java @@ -14,7 +14,7 @@ * the License. */ -package com.arcbees.bitbucket.api.impl; +package com.arcbees.vcs.util; import java.io.IOException; diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/api/impl/HttpClientWrapperImpl.java b/vcs-utils/src/main/java/com/arcbees/vcs/util/HttpClientWrapperImpl.java similarity index 96% rename from bitbucket/src/main/java/com/arcbees/bitbucket/api/impl/HttpClientWrapperImpl.java rename to vcs-utils/src/main/java/com/arcbees/vcs/util/HttpClientWrapperImpl.java index cf9b9dc..d5f79c5 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/api/impl/HttpClientWrapperImpl.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/util/HttpClientWrapperImpl.java @@ -14,11 +14,9 @@ * the License. */ -package com.arcbees.bitbucket.api.impl; +package com.arcbees.vcs.util; import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; diff --git a/bitbucket/src/main/java/com/arcbees/bitbucket/util/JsonCustomDataStorage.java b/vcs-utils/src/main/java/com/arcbees/vcs/util/JsonCustomDataStorage.java similarity index 85% rename from bitbucket/src/main/java/com/arcbees/bitbucket/util/JsonCustomDataStorage.java rename to vcs-utils/src/main/java/com/arcbees/vcs/util/JsonCustomDataStorage.java index 6ccd8bd..a26aa41 100644 --- a/bitbucket/src/main/java/com/arcbees/bitbucket/util/JsonCustomDataStorage.java +++ b/vcs-utils/src/main/java/com/arcbees/vcs/util/JsonCustomDataStorage.java @@ -14,9 +14,12 @@ * the License. */ -package com.arcbees.bitbucket.util; +package com.arcbees.vcs.util; +import com.arcbees.vcs.model.Comment; +import com.arcbees.vcs.model.PullRequest; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; @@ -34,7 +37,10 @@ public static JsonCustomDataStorage create(CustomDataStorage dataStorage, private final CustomDataStorage dataStorage; private final Class clazz; private final TypeToken typeToken; - private final Gson gson = new Gson(); + private final Gson gson = new GsonBuilder() + .registerTypeAdapter(PullRequest.class, new PolymorphicTypeAdapter()) + .registerTypeAdapter(Comment.class, new PolymorphicTypeAdapter()) + .create(); private JsonCustomDataStorage(CustomDataStorage dataStorage, Class clazz) { diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/util/PolymorphicTypeAdapter.java b/vcs-utils/src/main/java/com/arcbees/vcs/util/PolymorphicTypeAdapter.java new file mode 100644 index 0000000..adf3900 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/util/PolymorphicTypeAdapter.java @@ -0,0 +1,62 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * Licensed 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.arcbees.vcs.util; + +import java.lang.reflect.Type; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +public class PolymorphicTypeAdapter implements JsonSerializer, JsonDeserializer { + private static final String CLASSNAME = "@class"; + private static final String VALUE = "@value"; + + @Override + public T deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { + JsonObject jsonObject = json.getAsJsonObject(); + JsonPrimitive jsonPrimitive = (JsonPrimitive) jsonObject.get(CLASSNAME); + String className = jsonPrimitive.getAsString(); + + Class clazz; + try { + clazz = Class.forName(className); + } catch (ClassNotFoundException e) { + throw new JsonParseException(e.getMessage()); + } + + return context.deserialize(jsonObject.get(VALUE), clazz); + } + + @Override + public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) { + JsonObject retValue = new JsonObject(); + + String className = src.getClass().getCanonicalName(); + retValue.addProperty(CLASSNAME, className); + + JsonElement jsonElement = context.serialize(src); + retValue.add(VALUE, jsonElement); + + return retValue; + } +} diff --git a/vcs-utils/src/main/java/com/arcbees/vcs/util/UnexpectedHttpStatusException.java b/vcs-utils/src/main/java/com/arcbees/vcs/util/UnexpectedHttpStatusException.java new file mode 100644 index 0000000..1f5a719 --- /dev/null +++ b/vcs-utils/src/main/java/com/arcbees/vcs/util/UnexpectedHttpStatusException.java @@ -0,0 +1,32 @@ +/** + * Copyright 2014 ArcBees Inc. + * + * Licensed 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.arcbees.vcs.util; + +import java.io.IOException; + +public class UnexpectedHttpStatusException extends IOException { + private final int statusCode; + + public UnexpectedHttpStatusException(int statusCode, String message) { + super(message); + this.statusCode = statusCode; + } + + public int getStatusCode() { + return statusCode; + } +} diff --git a/vcs-utils/src/main/resources/META-INF/build-server-plugin-vcs-utils.xml b/vcs-utils/src/main/resources/META-INF/build-server-plugin-vcs-utils.xml new file mode 100644 index 0000000..0845307 --- /dev/null +++ b/vcs-utils/src/main/resources/META-INF/build-server-plugin-vcs-utils.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/vcs-utils/src/main/resources/buildServerResources/vcsSettings.jsp b/vcs-utils/src/main/resources/buildServerResources/vcsSettings.jsp new file mode 100644 index 0000000..a38f1c8 --- /dev/null +++ b/vcs-utils/src/main/resources/buildServerResources/vcsSettings.jsp @@ -0,0 +1,86 @@ +<%@ include file="/include.jsp" %> +<%@ include file="/include-internal.jsp" %> + + + + + + + Specify VCS repository name and credentials + + + VCS Type + + + Bitbucket + Stash + Github + + + + + Server URL: + + + + Server URL + + + + + User Name: + + + + VCS user name + + + + Password: + + + + VCS password + + + + + + Owner: + + + + VCS repository owner (user or organization) + + + + Repository: + + + + VCS repository name + + +