Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[JENKINS-40098] Bundle naming strategy should be able to specify an i…
…nstance type Introduced a change enabling both overriding through using a sysprop, or by implementing a new Extension Point. The approach with Extension Points should enable more dynamic needs, when the sysprop one will be immediately usable by anyone without having to develop an extension. Note: if found, the extension is preferred over the sysprop.
- Loading branch information
Showing
3 changed files
with
153 additions
and
0 deletions.
There are no files selected for viewing
78 changes: 78 additions & 0 deletions
78
src/main/java/com/cloudbees/jenkins/support/BundleNameInstanceTypeProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package com.cloudbees.jenkins.support; | ||
|
||
import com.cloudbees.jenkins.support.api.SupportProvider; | ||
import com.google.common.annotations.VisibleForTesting; | ||
import hudson.ExtensionList; | ||
import hudson.ExtensionPoint; | ||
|
||
import javax.annotation.Nonnull; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
/** | ||
* <p>Extension point allowing to customize the support bundle naming strategy.</p> | ||
* <p> | ||
* It will work the following way: | ||
* </p> | ||
* <ol> | ||
* <li>If an implementation of {@link BundleNameInstanceTypeProvider} is found, it will be used.<br> | ||
* <strong>WARNING: </strong>if many are found, then a warning will be issued, and the first extension found will | ||
* be used.</li> | ||
* <li>If not, then it will check for the presence of the {@link #SUPPORT_BUNDLE_NAMING_INSTANCE_SPEC_PROPERTY} | ||
* system property, and will use its value if provided.</li> | ||
* <li>If not, then will fallback to the original behaviour, which is simply an empty String</li> | ||
* </ol> | ||
* | ||
* @see SupportProvider#getName() for prefixing. | ||
*/ | ||
public abstract class BundleNameInstanceTypeProvider implements ExtensionPoint { | ||
|
||
@VisibleForTesting | ||
static final String SUPPORT_BUNDLE_NAMING_INSTANCE_SPEC_PROPERTY = SupportPlugin.class.getName() + ".instanceType"; | ||
|
||
private static final Logger LOGGER = Logger.getLogger(BundleNameInstanceTypeProvider.class.getName()); | ||
|
||
private static final BundleNameInstanceTypeProvider DEFAULT_STRATEGY = new BundleNameInstanceTypeProvider() { | ||
|
||
@Override | ||
public String getInstanceType() { | ||
return System.getProperty(SUPPORT_BUNDLE_NAMING_INSTANCE_SPEC_PROPERTY, ""); | ||
} | ||
}; | ||
|
||
/* package */ | ||
@Nonnull | ||
static BundleNameInstanceTypeProvider getInstance() { | ||
final ExtensionList<BundleNameInstanceTypeProvider> all = ExtensionList.lookup(BundleNameInstanceTypeProvider.class); | ||
final int extensionCount = all.size(); | ||
if (extensionCount < 1) { | ||
LOGGER.fine("No alternative strategy provided for support bundle prefixing."); | ||
return DEFAULT_STRATEGY; | ||
} | ||
|
||
if (all.size() > 1) { | ||
if (LOGGER.isLoggable(Level.WARNING)) { | ||
LOGGER.warning("{0} implementations found for support bundle prefix naming strategy. " + | ||
"Can be only 0 or 1. Choosing the first found."); | ||
for (BundleNameInstanceTypeProvider bundlePrefixProvider : all) { | ||
LOGGER.log(Level.WARNING, "class '{0}' found", bundlePrefixProvider.getClass().getName()); | ||
} | ||
} | ||
} | ||
return all.get(0); | ||
} | ||
|
||
/** | ||
* Returns the <strong>non-null</strong> instance type to be used for generated support bundle names. | ||
* Aims to provide informational data about the generated bundles. | ||
* | ||
* <p> | ||
* <p><b>Will be used for file name generation, so avoid funky characters. | ||
* Please stay in <code>[a-zA-Z-_]</code></b>. Also consider the file name length, you probably want to be defensive | ||
* and not return crazily long strings. Something below 20 characters or so might sound reasonable.</p> | ||
* | ||
* @return the instance type specification to be used for generated support bundles. | ||
*/ | ||
@Nonnull | ||
public abstract String getInstanceType(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
src/test/java/com/cloudbees/jenkins/support/BundleNamePrefixTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package com.cloudbees.jenkins.support; | ||
|
||
import org.junit.Rule; | ||
import org.junit.Test; | ||
import org.jvnet.hudson.test.JenkinsRule; | ||
import org.jvnet.hudson.test.TestExtension; | ||
|
||
import javax.annotation.Nonnull; | ||
import java.text.SimpleDateFormat; | ||
import java.util.Date; | ||
|
||
import static org.hamcrest.core.StringStartsWith.startsWith; | ||
import static org.junit.Assert.assertThat; | ||
|
||
public class BundleNamePrefixTest { | ||
|
||
private static final String CURRENT_YEAR = new SimpleDateFormat("YYYY").format(new Date()); | ||
|
||
@Rule | ||
public JenkinsRule rule = new JenkinsRule(); | ||
|
||
@Test | ||
public void checkOriginalBehaviour() throws Exception { | ||
assertThat(SupportPlugin.getBundleFileName(), startsWith("support_" + CURRENT_YEAR)); | ||
} | ||
|
||
@Test | ||
public void checkWithOneProvider() throws Exception { | ||
assertThat(SupportPlugin.getBundleFileName(), startsWith("support_pouet_" + CURRENT_YEAR)); | ||
} | ||
|
||
@Test | ||
public void tooManyProviders() throws Exception { | ||
assertThat(SupportPlugin.getBundleFileName(), startsWith("support_Zis_" + CURRENT_YEAR)); | ||
} | ||
|
||
@Test | ||
public void withSysProp() throws Exception { | ||
System.setProperty(BundleNameInstanceTypeProvider.SUPPORT_BUNDLE_NAMING_INSTANCE_SPEC_PROPERTY, "paf"); | ||
assertThat(SupportPlugin.getBundleFileName(), startsWith("support_paf_" + CURRENT_YEAR)); | ||
System.getProperties().remove(BundleNameInstanceTypeProvider.SUPPORT_BUNDLE_NAMING_INSTANCE_SPEC_PROPERTY); | ||
} | ||
|
||
@TestExtension("checkWithOneProvider") | ||
public static class TestProvider extends BundleNameInstanceTypeProvider { | ||
|
||
@Nonnull | ||
@Override | ||
public String getInstanceType() { | ||
return "pouet"; | ||
} | ||
} | ||
|
||
@TestExtension("tooManyProviders") | ||
public static class SpuriousProvider1 extends BundleNameInstanceTypeProvider { | ||
@Nonnull | ||
@Override | ||
public String getInstanceType() { | ||
return "Zis"; | ||
} | ||
} | ||
|
||
@TestExtension("tooManyProviders") | ||
public static class SpuriousProvider2 extends BundleNameInstanceTypeProvider { | ||
@Nonnull | ||
@Override | ||
public String getInstanceType() { | ||
return "Zat"; | ||
} | ||
} | ||
} |