Skip to content

Commit

Permalink
Add global config for hook url override (#164)
Browse files Browse the repository at this point in the history
* Add global config vor hook url override

* Remove load()

Co-authored-by: Christian Del Monte <[email protected]>
  • Loading branch information
Christian Del Monte and Christian Del Monte authored Feb 10, 2021
1 parent 45a064e commit 10f0757
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 28 deletions.
11 changes: 11 additions & 0 deletions .groovylintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "recommended",
"groovyLint.format.enable": true,
"rules": {
"formatting.Indentation": {
"spacesPerIndentLevel": 2,
"severity": "info"
},
"UnnecessaryReturnKeyword": "error"
}
}
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@
<version>2.11</version>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.11</version>
</dependency>
</dependencies>

<url>https://github.com/jenkinsci/bitbucket-push-and-pull-request-plugin</url>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,24 @@
import javax.servlet.http.HttpServletResponse;
import hudson.Extension;
import hudson.security.csrf.CrumbExclusion;
import io.jenkins.plugins.bitbucketpushandpullrequest.config.BitBucketPPRPluginConfig;


@Extension
public class BitBucketPPRCrumbExclusion extends CrumbExclusion {


private static final BitBucketPPRPluginConfig globalConfig = BitBucketPPRPluginConfig.getInstance();

public String getHookPath() {
return globalConfig.isHookUrlSet() ? globalConfig.getHookUrl() :HOOK_URL;
}

@Override
public boolean process(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws IOException, ServletException {

String path = request.getPathInfo();
if (path != null && (path.equals("/" + HOOK_URL) || path.equals("/" + HOOK_URL + "/"))) {
if (path != null && (path.equals("/" + getHookPath()) || path.equals("/" + getHookPath() + "/"))) {

chain.doFilter(request, response);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@
import java.util.logging.Logger;
import javax.naming.OperationNotSupportedException;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import org.apache.commons.io.IOUtils;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import com.google.gson.Gson;
import hudson.Extension;
import hudson.model.UnprotectedRootAction;
import io.jenkins.plugins.bitbucketpushandpullrequest.config.BitBucketPPRPluginConfig;
import io.jenkins.plugins.bitbucketpushandpullrequest.model.BitBucketPPRHookEvent;
import io.jenkins.plugins.bitbucketpushandpullrequest.model.BitBucketPPRPayload;
import io.jenkins.plugins.bitbucketpushandpullrequest.model.BitBucketPPRPayloadFactory;
Expand All @@ -54,7 +55,8 @@
public class BitBucketPPRHookReceiver implements UnprotectedRootAction {

private static final Logger logger = Logger.getLogger(BitBucketPPRHookReceiver.class.getName());

private static final BitBucketPPRPluginConfig globalConfig = BitBucketPPRPluginConfig.getInstance();

@Override
public String getIconFileName() {
return null;
Expand All @@ -67,7 +69,7 @@ public String getDisplayName() {

@Override
public String getUrlName() {
return HOOK_URL;
return globalConfig.isHookUrlSet() ? globalConfig.getHookUrl() :HOOK_URL;
}

public void doIndex(StaplerRequest request, StaplerResponse response) throws IOException {
Expand All @@ -78,7 +80,7 @@ public void doIndex(StaplerRequest request, StaplerResponse response) throws IOE
return;
}

if (request.getRequestURI().contains("/" + HOOK_URL + "/")) {
if (request.getRequestURI().contains("/" + getUrlName() + "/")) {
logger.finest("Received input stream over Bitbucket hook notification:" + inputStream);

inputStream = decodeInputStream(inputStream, request.getContentType());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ public class BitBucketPPRTrigger extends Trigger<Job<?, ?>> {
private static final Logger logger = Logger.getLogger(BitBucketPPRTrigger.class.getName());
private List<BitBucketPPRTriggerFilter> triggers;

public static final boolean ALLOW_HOOKURL_OVERRIDE = true;

{
System.setErr(BitBucketPPRUtils.createLoggingProxyForErrors(System.err));
}
Expand All @@ -90,10 +92,10 @@ public Object readResolve() throws ObjectStreamException {

// TODO: is this he place for that? And why only for push?
if (triggers == null) {
BitBucketPPRRepositoryPushActionFilter repositoryPushActionFilter = new BitBucketPPRRepositoryPushActionFilter(
false, false, spec);
BitBucketPPRRepositoryTriggerFilter repositoryTriggerFilter = new BitBucketPPRRepositoryTriggerFilter(
repositoryPushActionFilter);
BitBucketPPRRepositoryPushActionFilter repositoryPushActionFilter =
new BitBucketPPRRepositoryPushActionFilter(false, false, spec);
BitBucketPPRRepositoryTriggerFilter repositoryTriggerFilter =
new BitBucketPPRRepositoryTriggerFilter(repositoryPushActionFilter);
triggers = new ArrayList<>();
triggers.add(repositoryTriggerFilter);
}
Expand All @@ -110,63 +112,68 @@ public Object readResolve() throws ObjectStreamException {
*/
public void onPost(BitBucketPPRHookEvent bitbucketEvent, BitBucketPPRAction bitbucketAction, SCM scmTrigger,
BitBucketPPRObservable observable) throws Exception {
logger.log(Level.INFO, "Called onPost with " + bitbucketAction.toString());
logger.log(Level.FINEST, "Called onPost Method for action " + bitbucketAction.toString());

BitBucketPPRFilterMatcher filterMatcher = new BitBucketPPRFilterMatcher();
List<BitBucketPPRTriggerFilter> matchingFilters = filterMatcher.getMatchingFilters(bitbucketEvent, triggers);

if (matchingFilters != null && !matchingFilters.isEmpty()) {
logger.log(Level.INFO, "matchingFilters is not null AND is not empty {0} ", matchingFilters);
logger.finest("Following triggers are configured:");
for (BitBucketPPRTriggerFilter matchingFilter : matchingFilters) {
logger.finest(matchingFilter.getClass().getName());
}

BitBucketPPRPollingRunnable bitbucketPollingRunnable = new BitBucketPPRPollingRunnable(job, getLogFile(),
new BitBucketPPRPollResultListener() {
BitBucketPPRPollingRunnable bitbucketPollingRunnable =
new BitBucketPPRPollingRunnable(job, getLogFile(), new BitBucketPPRPollResultListener() {
@Override
public void onPollSuccess(PollingResult pollingResult) {

logger.log(Level.INFO, "Called onPollSuccess with polling result {0}", pollingResult);
logger.log(Level.INFO, "Polled BB PPR. The result of the polling is {0}", pollingResult.change.name());
for (BitBucketPPRTriggerFilter filter : matchingFilters) {
BitBucketPPRTriggerCause cause;
try {
cause = filter.getCause(getLogFile(), bitbucketAction, bitbucketEvent);

logger.log(Level.INFO, () -> "On Poll Success, get cause: " + cause.toString());
logger.info("The polling of the BB PPR job was successful for the cause: " + cause.toString());

if (shouldScheduleJob(filter, pollingResult, bitbucketAction)) {
scheduleJob(cause, bitbucketAction, scmTrigger, observable, filter);
return;
}
} catch (Throwable e) {
logger.log(Level.INFO, "Something went wrong in the on Poll Success " + e.getMessage());
logger
.warning("During the polling process of a BB PPR job an exception was thrown: " + e.getMessage());
e.printStackTrace();
}
}
}

@Override
public void onPollError(Throwable e) {
logger.log(Level.INFO, "Called onPollError: " + e.getMessage());
logger.log(Level.FINEST, "Called onPollError: " + e.getMessage());
e.printStackTrace();
}
});

try {
getDescriptor().queue.execute(bitbucketPollingRunnable);
} catch (Throwable e) {
logger.log(Level.INFO, "No matching filters {0}", e.getMessage());
logger.warning("Error: cannot add the BB PPR polling runnable to the Jenkins' SequentialExecutionQueue queue:"
+ e.getMessage());
e.printStackTrace();
}

} else {
logger.log(Level.INFO, "No matching filters");
logger.info("Triggers are not configured.");
}
}

private boolean shouldScheduleJob(BitBucketPPRTriggerFilter filter, PollingResult pollingResult,
BitBucketPPRAction bitbucketAction) {
logger.log(Level.INFO,
logger.log(Level.FINEST,
"Should schedule job: {0} and (polling result has changes: {1} or trigger also if there aren't changes: {2})",
new Object[] { filter.shouldScheduleJob(bitbucketAction), pollingResult.hasChanges(),
filter.shouldTriggerAlsoIfNothingChanged() });
new Object[] {filter.shouldScheduleJob(bitbucketAction), pollingResult.hasChanges(),
filter.shouldTriggerAlsoIfNothingChanged()});

return filter.shouldScheduleJob(bitbucketAction)
&& (pollingResult.hasChanges() || filter.shouldTriggerAlsoIfNothingChanged());
Expand Down Expand Up @@ -254,7 +261,7 @@ public File getLogFile() throws JobNotStartedException, IOException {
File file = new File(job.getRootDir(), "bitbucket-polling.log");
if (file.createNewFile()) {
logger.log(Level.FINE, "Created new file {0} for logging in the directory {1}.",
new Object[] { "bitbucket-polling.log", job.getRootDir() });
new Object[] {"bitbucket-polling.log", job.getRootDir()});
}

return file;
Expand All @@ -270,8 +277,7 @@ public List<BitBucketPPRTriggerFilter> getTriggers() {
}

/**
* Action object for {@link BitBucketPPRProject}. Used to display the polling
* log.
* Action object for {@link BitBucketPPRProject}. Used to display the polling log.
*/
public class BitBucketPPRWebHookPollingAction implements hudson.model.Action {
public Job<?, ?> getOwner() {
Expand Down Expand Up @@ -309,8 +315,8 @@ public void writeLogTo(XMLOutput out) throws Exception {
@Symbol("bitBucketTrigger")
@Extension
public static class DescriptorImpl extends TriggerDescriptor {
private final SequentialExecutionQueue queue = new SequentialExecutionQueue(
Jenkins.MasterComputer.threadPoolForRemoting);
private final SequentialExecutionQueue queue =
new SequentialExecutionQueue(Jenkins.MasterComputer.threadPoolForRemoting);

@Override
public boolean isApplicable(Item item) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package io.jenkins.plugins.bitbucketpushandpullrequest.config;

import static org.apache.commons.lang3.StringUtils.isEmpty;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Logger;
import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.StaplerRequest;
import hudson.Extension;
import hudson.ExtensionList;
import jenkins.model.GlobalConfiguration;
import net.sf.json.JSONObject;

@Extension
public class BitBucketPPRPluginConfig extends GlobalConfiguration {
private static final Logger logger = Logger.getLogger(BitBucketPPRPluginConfig.class.getName());
public static final String BITBUCKET_PPR_PLUGIN_CONFIGURATION_ID = "bitbucket-ppr-plugin-configuration";

@SuppressWarnings("unused")
public String hookUrl;

public BitBucketPPRPluginConfig() {
logger.fine("Read bitbucket push and pull request plugin global configuration.");
load();
}

public static BitBucketPPRPluginConfig getInstance() {
return ExtensionList.lookupSingleton(BitBucketPPRPluginConfig.class);
}

@DataBoundSetter
public void setHookUrl(String hookUrl) {
if (isEmpty(hookUrl)) {
this.hookUrl = "";
} else {
this.hookUrl = hookUrl;
}
save();
}

public boolean isHookUrlSet() {
return ! isEmpty(hookUrl);
}

public String getHookUrl() {
return hookUrl;
}

@Override
public String getDisplayName() {
return "Bitbucket Push and Pull Request";
}

@Override
public boolean configure(StaplerRequest req, JSONObject formData) throws FormException {
req.bindJSON(this, formData);
save();
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout"
xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<f:section title="${%BitBucket Push and Pull Request}">
<f:entry title="Hook URL" field="hookUrlTitle">
<f:textbox field="hookUrl" />
</f:entry>
</f:section>
</j:jelly>

0 comments on commit 10f0757

Please sign in to comment.