From 7109e20fb9cd73f595257c657b0bee3f0bb5da91 Mon Sep 17 00:00:00 2001 From: Peter Palaga Date: Fri, 31 Oct 2014 23:08:56 +0100 Subject: [PATCH] BZ1140043 InvalidPluginConfigurationException in agent log - product type is [Portal], was Portal Platform --- .../rhq/plugins/PortalDiscoveryCallback.java | 18 +-- .../gatein/rhq/plugins/VersionComparator.java | 139 ++++++++++++++++++ .../plugins/PortalDiscoveryCallbackTest.java | 43 +++++- .../rhq/plugins/VersionComparatorTest.java | 60 ++++++++ 4 files changed, 241 insertions(+), 19 deletions(-) create mode 100644 src/main/java/org/gatein/rhq/plugins/VersionComparator.java create mode 100644 src/test/java/org/gatein/rhq/plugins/VersionComparatorTest.java diff --git a/src/main/java/org/gatein/rhq/plugins/PortalDiscoveryCallback.java b/src/main/java/org/gatein/rhq/plugins/PortalDiscoveryCallback.java index 753a29b..9c33bbb 100644 --- a/src/main/java/org/gatein/rhq/plugins/PortalDiscoveryCallback.java +++ b/src/main/java/org/gatein/rhq/plugins/PortalDiscoveryCallback.java @@ -5,9 +5,6 @@ import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; import org.rhq.core.pluginapi.inventory.ResourceDiscoveryCallback; -import java.util.HashMap; -import java.util.Map; - /** * @author Nick Scavelli */ @@ -18,6 +15,7 @@ public class PortalDiscoveryCallback implements ResourceDiscoveryCallback private static final String CONFIG_PRODUCT_NAME = "expectedRuntimeProductName"; private static final String PRODUCT_NAME = "Portal"; + private static final String VERSION_RENAMED_TO_JBOSS_Portal = "6.1.1.GA"; @Override public DiscoveryCallbackResults discoveredResources(DiscoveredResourceDetails discoveredResourceDetails) throws Exception @@ -32,18 +30,7 @@ public DiscoveryCallbackResults discoveredResources(DiscoveredResourceDetails di String version = discoveredResourceDetails.getResourceVersion(); String name = discoveredResourceDetails.getResourceName(); - // small hack: we check if the version is higher than 6.1.1, as the logic is the same for all known subsequent versions - // first, we discard everything after the last dot, as it's usually the release-level string (GA, ER1, ER2, CR1...) - // then, we get only the numeric chars, and the resulting should be a string with length of 3 - String cleanedVersion = version.substring(0, version.lastIndexOf(".")).replaceAll("[^\\d]", ""); - if (null == cleanedVersion || cleanedVersion.length() > 3) - { - throw new IllegalArgumentException("Couldn't reliably determine the Portal version for '" + version + "'"); - } - - int versionAsInteger = Integer.parseInt(cleanedVersion); - if (versionAsInteger >= 611) - { + if (VersionComparator.instance().compare(VERSION_RENAMED_TO_JBOSS_Portal, version) <= 0) { if (trace) { String before = discoveredResourceDetails.getPluginConfiguration().getSimpleValue(CONFIG_PRODUCT_NAME); @@ -52,7 +39,6 @@ public DiscoveryCallbackResults discoveredResources(DiscoveredResourceDetails di discoveredResourceDetails.getPluginConfiguration().setSimpleValue(CONFIG_PRODUCT_NAME, PRODUCT_NAME); result = DiscoveryCallbackResults.PROCESSED; } - return result; } diff --git a/src/main/java/org/gatein/rhq/plugins/VersionComparator.java b/src/main/java/org/gatein/rhq/plugins/VersionComparator.java new file mode 100644 index 0000000..1918d6d --- /dev/null +++ b/src/main/java/org/gatein/rhq/plugins/VersionComparator.java @@ -0,0 +1,139 @@ +package org.gatein.rhq.plugins; + +import java.util.Comparator; + +/** + * Comparator for software versions like {@code "6.2"}, {@code "6.2.0"}, {@code "6.2.0.GA"}, etc. + * + * @author Peter Palaga + */ +public class VersionComparator implements Comparator +{ + /** + * A stream of version string parts. + */ + static class VersionTokenizer + { + private int position = 0; + private final int length; + private final String source; + private int counter = 0; + private final int numericComponentsCount; + + public VersionTokenizer(String source, int numericComponentsCount) + { + super(); + this.source = source; + this.numericComponentsCount = numericComponentsCount; + this.length = source.length(); + } + + /** + * @return next version part delimited either by period or end of input + */ + private String next() + { + if (position >= length) + { + return null; + } + int end = source.indexOf(DELIMITER, position); + int start = position; + if (end >= 0) + { + position = end + 1; + } else + { + position = length; + end = length; + } + return source.substring(start, end); + } + + /** + * @return next {@code int} version part delimited either by period or end of input + * @throws NumberFormatException if the current part cannot be parset as {@code int} + * @throws IllegalArgumentException if some of the parts is parsed into a negative integer + */ + public int nextInt() + { + if (counter >= numericComponentsCount) + { + throw new IllegalStateException(this.getClass().getSimpleName() + + ".nextInt() cannot be invoked more than " + + numericComponentsCount + " times."); + } + counter++; + String token = next(); + if (token == null) + { + return DEFAULT_NUMERIC_COMPONENT; + } + int result = Integer.valueOf(token); + if (result < 0) + { + throw new IllegalArgumentException("Version string '" + source + + "' contains negative component " + result); + } + return result; + } + + /** + * @return the rest of the input from the current position to the input end + */ + public String rest() + { + if (position >= length) + { + return DEFAULT_QUALIFIER; + } + int start = position; + position = length; + return source.substring(start); + } + + } + + /** + * @return the singleton instance of {@link VersionComparator} + */ + public static VersionComparator instance() + { + return INSTANCE; + } + + /** The singleton. */ + private static final VersionComparator INSTANCE = new VersionComparator(); + + /** The period character - the delimiter of version parts. */ + public static final int DELIMITER = '.'; + + /** Literal {@code "GA"} returned if there is no qualifier in the input. */ + public static final String DEFAULT_QUALIFIER = "GA"; + + /** Literal {@code 0} returned if the input is missing minor or micro version part. */ + public static final int DEFAULT_NUMERIC_COMPONENT = 0; + + /** {@code 3} - the number of numeric parts in a version string. */ + public static final int MAJOR_MINOR_MICRO = 3; + + /** For thrown exceptions, see {@link VersionTokenizer#nextInt()}. + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + @Override + public int compare(String version1, String version2) + { + VersionTokenizer t1 = new VersionTokenizer(version1, MAJOR_MINOR_MICRO); + VersionTokenizer t2 = new VersionTokenizer(version2, MAJOR_MINOR_MICRO); + for (int i = 0; i < MAJOR_MINOR_MICRO; i++) + { + int compare = Integer.compare(t1.nextInt(), t2.nextInt()); + if (compare != 0) + { + return compare; + } + } + return t1.rest().compareTo(t2.rest()); + } + +} diff --git a/src/test/java/org/gatein/rhq/plugins/PortalDiscoveryCallbackTest.java b/src/test/java/org/gatein/rhq/plugins/PortalDiscoveryCallbackTest.java index 64ec007..1ecffc2 100644 --- a/src/test/java/org/gatein/rhq/plugins/PortalDiscoveryCallbackTest.java +++ b/src/test/java/org/gatein/rhq/plugins/PortalDiscoveryCallbackTest.java @@ -33,6 +33,20 @@ public void testVersionIs611() throws Exception Configuration configuration = new Configuration(); ResourceType type = new ResourceType(); + DiscoveredResourceDetails details = new DiscoveredResourceDetails(type, "bogus", "JPP Something", "6.1.1", "", configuration, null); + ResourceDiscoveryCallback.DiscoveryCallbackResults results = new PortalDiscoveryCallback().discoveredResources(details); + + assertEquals(ResourceDiscoveryCallback.DiscoveryCallbackResults.PROCESSED, results); + assertEquals("Portal", details.getPluginConfiguration().getSimpleValue("expectedRuntimeProductName")); + } + + + @Test + public void testVersionIs611GA() throws Exception + { + Configuration configuration = new Configuration(); + ResourceType type = new ResourceType(); + DiscoveredResourceDetails details = new DiscoveredResourceDetails(type, "bogus", "JPP Something", "6.1.1.GA", "", configuration, null); ResourceDiscoveryCallback.DiscoveryCallbackResults results = new PortalDiscoveryCallback().discoveredResources(details); @@ -41,7 +55,7 @@ public void testVersionIs611() throws Exception } @Test - public void testVersionHigherThan611() throws Exception + public void test620ER3HigherThan611() throws Exception { Configuration configuration = new Configuration(); ResourceType type = new ResourceType(); @@ -53,13 +67,36 @@ public void testVersionHigherThan611() throws Exception assertEquals("Portal", details.getPluginConfiguration().getSimpleValue("expectedRuntimeProductName")); } + @Test + public void test620HigherThan611() throws Exception + { + Configuration configuration = new Configuration(); + ResourceType type = new ResourceType(); + + DiscoveredResourceDetails details = new DiscoveredResourceDetails(type, "bogus", "JPP Something", "6.2.0", "", configuration, null); + ResourceDiscoveryCallback.DiscoveryCallbackResults results = new PortalDiscoveryCallback().discoveredResources(details); + + assertEquals(ResourceDiscoveryCallback.DiscoveryCallbackResults.PROCESSED, results); + assertEquals("Portal", details.getPluginConfiguration().getSimpleValue("expectedRuntimeProductName")); + } + @Test(expected = IllegalArgumentException.class) - public void testFailOnUnknownVersion() throws Exception + public void testFailOnMalformedVersion() throws Exception + { + Configuration configuration = new Configuration(); + ResourceType type = new ResourceType(); + + DiscoveredResourceDetails details = new DiscoveredResourceDetails(type, "bogus", "JPP Something", "6.-2.0.ER3", "", configuration, null); + new PortalDiscoveryCallback().discoveredResources(details); + } + + @Test(expected = NumberFormatException.class) + public void testFailOnMalformedVersion2() throws Exception { Configuration configuration = new Configuration(); ResourceType type = new ResourceType(); - DiscoveredResourceDetails details = new DiscoveredResourceDetails(type, "bogus", "JPP Something", "6.22.0.ER3", "", configuration, null); + DiscoveredResourceDetails details = new DiscoveredResourceDetails(type, "bogus", "JPP Something", "6.1.GA", "", configuration, null); new PortalDiscoveryCallback().discoveredResources(details); } diff --git a/src/test/java/org/gatein/rhq/plugins/VersionComparatorTest.java b/src/test/java/org/gatein/rhq/plugins/VersionComparatorTest.java new file mode 100644 index 0000000..abdf780 --- /dev/null +++ b/src/test/java/org/gatein/rhq/plugins/VersionComparatorTest.java @@ -0,0 +1,60 @@ +package org.gatein.rhq.plugins; + +import org.junit.Assert; +import org.junit.Test; + +public class VersionComparatorTest +{ + @Test + public void test() + { + ensureNFE("6.2.GA"); + + test("1", "1.0", 0); + test("1", "1.0.0", 0); + test("1", "1.0.0.GA", 0); + + test("1", "2", -1); + test("9", "11", -1); + test("1.0.0.DR1", "1.0.0.DR2", -1); + test("1.0.0.DR10", "1.0.0.ER2", -1); + + ensureNFE("1.GA"); + ensureNFE("1.0.GA"); + ensureNFE("1-GA"); + + ensureIAE("-1"); + ensureIAE("1.-1"); + ensureIAE("1.1.-1"); + + } + + private void ensureNFE(String v) + { + try + { + VersionComparator.instance().compare(v, v); + Assert.fail("NumberFormatException expected"); + } catch (NumberFormatException expected) + { + } + } + + private void ensureIAE(String v) + { + try + { + VersionComparator.instance().compare(v, v); + Assert.fail("IllegalArgumentException expected"); + } catch (IllegalArgumentException expected) + { + } + } + + private static void test(String v1, String v2, int expected) + { + Assert.assertEquals("'"+ v1 + "' ? '"+ v2 +"'", expected, VersionComparator.instance().compare(v1, v2)); + Assert.assertEquals("'"+ v2 + "' ? '"+ v1 +"'", -expected, VersionComparator.instance().compare(v2, v1)); + } + +}