modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
| 46 -
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/discovery/DiscoveryAgentService.java
| 19
modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
| 3
modules/core/domain/src/main/java/org/rhq/core/domain/discovery/PlatformSyncInfo.java
| 73 +-
modules/core/domain/src/main/java/org/rhq/core/domain/discovery/ResourceSyncInfo.java
| 140 ++--
modules/core/domain/src/main/java/org/rhq/core/domain/discovery/SyncInfo.java
| 98 --
modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/AbstractIgnoreTypesInventoryManagerBaseTest.java
| 36 -
modules/core/plugin-container/src/main/java/org/rhq/core/pc/StandaloneContainer.java
| 3
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/RuntimeSynchronizer.java
| 2
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
| 338 ++++------
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/AbstractResourceUpgradeHandlingTest.java
| 4
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
| 50 -
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
| 20
modules/core/plugin-container/src/test/java/org/rhq/test/pc/PluginContainerTest.java
| 37 -
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java
| 28
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/configuration/LargeGroupPluginConfigurationTest.java
| 17
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/discovery/DiscoveryBossBeanTest.java
| 65 +
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java
| 18
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
| 87 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
| 7
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
| 5
21 files changed, 582 insertions(+), 514 deletions(-)
New commits:
commit 5ef600890aaedcc3a040f5496d18c3c808d73795
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Jan 3 16:50:39 2014 -0500
fix merge issue, this class somehow disappeared
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/install/remote/RemoteAccessInfo.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/install/remote/RemoteAccessInfo.java
new file mode 100644
index 0000000..b2ab566
--- /dev/null
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/install/remote/RemoteAccessInfo.java
@@ -0,0 +1,94 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program 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 version 2 of the License.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.core.domain.install.remote;
+
+import java.io.Serializable;
+
+/**
+ * @author Greg Hinkle
+ */
+public class RemoteAccessInfo implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String host;
+ private String user;
+ private String password;
+ private byte[] key;
+ private int port = 22;
+
+ public RemoteAccessInfo(String host, String user, byte[] key) {
+ this.host = host;
+ this.user = user;
+ this.key = key;
+ }
+
+ public RemoteAccessInfo(String host, String user, String password) {
+ this(host, 22, user, password);
+ }
+
+ public RemoteAccessInfo(String host, int port, String user, String password) {
+ this.host = host;
+ this.port = port;
+ this.user = user;
+ this.password = password;
+ }
+
+ public RemoteAccessInfo() {
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ public String getUser() {
+ return user;
+ }
+
+ public void setUser(String user) {
+ this.user = user;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public byte[] getKey() {
+ return key;
+ }
+
+ public void setKey(byte[] key) {
+ this.key = key;
+ }
+}
commit d0ab1fc5e0163804c1db9179f598e4b8d791e56b
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Jan 3 16:05:16 2014 -0500
Some tweaks to test code
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index 2bcb7aa..2cca059 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -421,10 +421,6 @@ public class FakeServerInventory {
return platform == null ? null :
PlatformSyncInfo.buildPlatformSyncInfo(platform);
}
- private Collection<ResourceSyncInfo> getResourceSyncInfo(Resource resource) {
- return resource == null ? null : convert(resource);
- }
-
private static Collection<ResourceSyncInfo> convert(Resource root) {
Set<ResourceSyncInfo> result = new HashSet<ResourceSyncInfo>();
convertInternal(root, result);
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/test/pc/PluginContainerTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/test/pc/PluginContainerTest.java
index c9528a0..5beb7a5 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/test/pc/PluginContainerTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/test/pc/PluginContainerTest.java
@@ -60,7 +60,7 @@ import org.rhq.test.JMockTest;
* <p>
* This class is used to declaratively setup a plugin container a test wants
* to use using the {@link PluginContainerSetup} annotation on a test method or class.
- *
+ *
* @author Lukas Krejci
*/
public class PluginContainerTest extends JMockTest {
@@ -96,9 +96,9 @@ public class PluginContainerTest extends JMockTest {
* provided by JMock.
* <p>
* This method together with {@link #setServerSideFake(String, Object)} provides a
generic
- * "storage" for tests to share these objects and is only provided as a
convenience to
+ * "storage" for tests to share these objects and is only provided as a
convenience to
* the test writers. There's nothing that would manadate using it.
- *
+ *
* @param name
* @return
*/
@@ -114,7 +114,7 @@ public class PluginContainerTest extends JMockTest {
}
/**
- * Returns the {@link PluginContainerConfiguration} as configured using
+ * Returns the {@link PluginContainerConfiguration} as configured using
* the {@link PluginContainerSetup} annotation on the current test (or null
* if no such thing is configured).
* @return
@@ -202,7 +202,7 @@ public class PluginContainerTest extends JMockTest {
* <p>
* This is not done automatically to support sharing the plugin container among
* multiple tests to simulate upgrades, etc.
- *
+ *
* @throws IOException
*/
public static void clearStorageOfCurrentPluginContainer() throws IOException {
@@ -219,9 +219,9 @@ public class PluginContainerTest extends JMockTest {
/**
* This method clears the storage of all tests made. This is useful in {@link
AfterSuite}
- * method to clean up after all the tests (annotated with {@link
PluginContainerSetup})
+ * method to clean up after all the tests (annotated with {@link
PluginContainerSetup})
* that have been run.
- *
+ *
* @throws IOException
*/
public synchronized static void clearStorage() throws IOException {
@@ -238,9 +238,9 @@ public class PluginContainerTest extends JMockTest {
* this method is provided to automatically clean up after all the plugin container
tests that ran
* in the test suite.
* <p>
- * If you use PluginContainerTest as a listener, you have to call {@link
#clearStorage()} method
+ * If you use PluginContainerTest as a listener, you have to call {@link
#clearStorage()} method
* on your own.
- *
+ *
* @throws IOException
*/
@AfterSuite
@@ -249,12 +249,12 @@ public class PluginContainerTest extends JMockTest {
}
/**
- * This method returns the {@link PluginContainerConfiguration} that will be used in
- * the current test as was configured by the PluginContainerSetup annotation.
+ * This method returns the {@link PluginContainerConfiguration} that will be used in
+ * the current test as was configured by the PluginContainerSetup annotation.
* <p>
- * If your test class inherits from PluginContainerTest, you can override this method
+ * If your test class inherits from PluginContainerTest, you can override this
method
* to provide custom configuration.
- *
+ *
* @param testObject the object of the current test
* @param testMethod the test method currently being executed on the test object
* @return
@@ -293,7 +293,7 @@ public class PluginContainerTest extends JMockTest {
}
/**
- * This method is called after the test to tear down resources associated with the
+ * This method is called after the test to tear down resources associated with the
* current plugin container configuration.
*/
protected void tearDownPluginContainerConfiguration() {
@@ -371,9 +371,16 @@ public class PluginContainerTest extends JMockTest {
}
}
+ // Note that on WINDOWS this does not always/usually work and therefore test
failures
+ // tend to happen. For unknown reasons windows/jvm keeps a lock on the plugin jar
and it
+ // fails to delete, thus allowing for multiple versions of the plugin in the same
path. I've
+ // added a system out to make it more clear in the log. There was no obvious
workaround.
private void deletePlugins(File deployDirectory) throws IOException {
if (deployDirectory.exists()) {
- FileUtil.purge(deployDirectory, false);
+ FileUtil.purge(deployDirectory, true);
+ }
+ if (deployDirectory.exists()) {
+ throw new IllegalStateException("Failed to clean up plugins in [" +
deployDirectory.getPath() + "]");
}
}
commit 5a919182bd6a2fe23ff0e920b7047b40f76c2edc
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Jan 2 11:12:18 2014 -0500
i'll assume this was a mistake to import a JUnit annotation, and it should have
been testng
diff --git
a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/script/ModulesDirectoryScriptSourceProviderTest.java
b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/script/ModulesDirectoryScriptSourceProviderTest.java
index 4060d07..8227e38 100644
---
a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/script/ModulesDirectoryScriptSourceProviderTest.java
+++
b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/script/ModulesDirectoryScriptSourceProviderTest.java
@@ -28,8 +28,8 @@ import java.io.PrintWriter;
import java.net.URI;
import java.net.URISyntaxException;
-import org.junit.BeforeClass;
import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
commit 348b20e0dd42e0cb4ad381f6589f7518d8c40567
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Jan 2 10:50:02 2014 -0500
BZ 994250 - finish the merging/peer review for patches submitted so that rhqctl
returns proper exit codes. Note that this completes the merge of the two submitted patches
- see prior two commits to this one. This third commit fixes some problems with the
original patches: 1. Some scripts/files are not found in bin/internal of the distro, but
rather are in bin/ - so we need to avoid using getBinDir() in those cases 2. Fix the code
to conform to code conventions - DEATH TO TABS! 3. Remove a constant that got resurrected
(ControlCommand.RHQ_STORAGE_BASEDIR_PROP is no longer needed) 4. A couple other minor
things
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
index 5db80a1..a13a598 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
@@ -60,7 +60,6 @@ public abstract class ControlCommand {
public static final String SERVER_OPTION = "server";
public static final String STORAGE_OPTION = "storage";
public static final String AGENT_OPTION = "agent";
- public static final String RHQ_STORAGE_BASEDIR_PROP =
"rhq.storage.basedir";
public static final String RHQ_AGENT_BASEDIR_PROP = "rhq.agent.basedir";
protected static final String STORAGE_BASEDIR_NAME = "rhq-storage";
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
index 28a37de..88b085f 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
@@ -135,7 +135,7 @@ public class RHQControl {
} catch (Throwable t) {
log.warn("Failed to clean up after the failed installation attempt.
"
+ "You may have to clean up some things before attempting to
install again", t);
- rValue = EXIT_CODE_OPERATION_FAILED;
+ rValue = EXIT_CODE_OPERATION_FAILED;
}
}
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
index 1b3d47b..ed2b2f8 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
@@ -88,14 +88,14 @@ public abstract class AbstractInstall extends ControlCommand {
executor.setStreamHandler(new PumpStreamHandler());
org.apache.commons.exec.CommandLine commandLine;
- int rValue = RHQControl.EXIT_CODE_OK;
+ int rValue = RHQControl.EXIT_CODE_OK;
if (replaceExistingService) {
- commandLine = getCommandLine(batFile, "stop");
- rValue = Math.max(rValue, executor.execute(commandLine));
+ commandLine = getCommandLine(batFile, "stop");
+ rValue = Math.max(rValue, executor.execute(commandLine));
- commandLine = getCommandLine(batFile, "remove");
- rValue = Math.max(rValue, executor.execute(commandLine));
+ commandLine = getCommandLine(batFile, "remove");
+ rValue = Math.max(rValue, executor.execute(commandLine));
}
commandLine = getCommandLine(batFile, "install");
@@ -277,7 +277,7 @@ public abstract class AbstractInstall extends ControlCommand {
return RHQControl.EXIT_CODE_OK;
}
- int rValue = 0;
+ int rValue = 0;
try {
File agentBinDir = new File(agentBasedir, "bin");
@@ -317,7 +317,7 @@ public abstract class AbstractInstall extends ControlCommand {
throw e;
}
- return rValue;
+ return rValue;
}
protected int startAgent(final File agentBasedir) throws Exception {
@@ -366,7 +366,7 @@ public abstract class AbstractInstall extends ControlCommand {
Executor executor = new DefaultExecutor();
executor.setWorkingDirectory(agentBinDir);
executor.setStreamHandler(new PumpStreamHandler());
- org.apache.commons.exec.CommandLine commandLine =
getCommandLine("rhq-agent-wrapper", "stop");
+ org.apache.commons.exec.CommandLine commandLine;
int rValue = 0;
@@ -635,7 +635,7 @@ public abstract class AbstractInstall extends ControlCommand {
clearAgentPreferences();
int rValue = installAgent(agentBasedir);
configureAgent(agentBasedir, commandLine);
- return rValue;
+ return rValue;
}
private int installAgent(final File agentBasedir) throws IOException {
@@ -667,7 +667,7 @@ public abstract class AbstractInstall extends ControlCommand {
int exitValue = executor.execute(commandLine);
log.info("The agent installer finished running with exit value " +
exitValue);
- return exitValue;
+ return exitValue;
} catch (IOException e) {
log.error("An error occurred while running the agent installer: " +
e.getMessage());
throw e;
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
index 5d540a1..e2ef3a8 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
@@ -138,7 +138,7 @@ public class Start extends ControlCommand {
executor.setStreamHandler(new PumpStreamHandler());
org.apache.commons.exec.CommandLine commandLine;
- int rValue;
+ int rValue;
// Cassandra looks for JAVA_HOME or then defaults to PATH. We want it to use the
Java
// defined for RHQ, so make sure JAVA_HOME is set, and set to the RHQ Java for
the executor
@@ -167,7 +167,7 @@ public class Start extends ControlCommand {
// For now we are duplicating logic in the status command. This code will be
// replaced when we implement a rhq-storage.sh script.
if (isStorageRunning()) {
- String pid = getStoragePid();
+ String pid = getStoragePid();
System.out.println("RHQ storage node (pid " + pid + ") is
running");
rValue = RHQControl.EXIT_CODE_OK;
} else {
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
index a3920e0..7ef66b4 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
@@ -144,7 +144,7 @@ public class Stop extends AbstractInstall {
rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
}
} else {
- if(isStorageRunning()) {
+ if (isStorageRunning()) {
String pid = getStoragePid();
System.out.println("Stopping RHQ storage node...");
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
index cc3d8c2..e80edd9 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
@@ -186,7 +186,7 @@ public class Upgrade extends AbstractInstall {
return exitValue;
}
- // If any failures occur during upgrade, we know we need to reset
rhq-server.properties.
+ // If any failures occur during upgrade, we know we need to reset
rhq-server.properties.
final FileReverter serverPropFileReverter = new
FileReverter(getServerPropertiesFile());
addUndoTask(new ControlCommand.UndoTask("Reverting server properties
file") {
public void performUndoWork() throws Exception {
@@ -229,7 +229,7 @@ public class Upgrade extends AbstractInstall {
}
} catch (Throwable t) {
log.warn("Unable to stop services: " + t.getMessage());
- rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
+ rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
}
}
@@ -262,7 +262,7 @@ public class Upgrade extends AbstractInstall {
}
Executor executor = new DefaultExecutor();
- executor.setWorkingDirectory(getBinDir());
+ executor.setWorkingDirectory(new File(getBaseDir(), "bin")); //
data migrator script is not in bin/internal
executor.setStreamHandler(new PumpStreamHandler());
int exitValue = executor.execute(commandLine);
@@ -546,7 +546,7 @@ public class Upgrade extends AbstractInstall {
}
// now merge the old settings in with the default properties from the new server
install
- String newServerPropsFilePath = new File(getBinDir(),
"rhq-server.properties").getAbsolutePath();
+ String newServerPropsFilePath = new File(getBaseDir(),
"bin/rhq-server.properties").getAbsolutePath();
PropertiesFileUpdate newServerPropsFile = new
PropertiesFileUpdate(newServerPropsFilePath);
newServerPropsFile.update(oldServerProps);
commit 250b302c53dfb020cdf61ef82162f9836ed32bfc
Author: burmanm <yak(a)iki.fi>
Date: Tue Aug 6 17:52:38 2013 +0200
Fix return codes of the rhqctl command, rebased to the 4.10 master.
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
index a13a598..5db80a1 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
@@ -60,6 +60,7 @@ public abstract class ControlCommand {
public static final String SERVER_OPTION = "server";
public static final String STORAGE_OPTION = "storage";
public static final String AGENT_OPTION = "agent";
+ public static final String RHQ_STORAGE_BASEDIR_PROP =
"rhq.storage.basedir";
public static final String RHQ_AGENT_BASEDIR_PROP = "rhq.agent.basedir";
protected static final String STORAGE_BASEDIR_NAME = "rhq-storage";
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
index 88b085f..28a37de 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
@@ -135,7 +135,7 @@ public class RHQControl {
} catch (Throwable t) {
log.warn("Failed to clean up after the failed installation attempt.
"
+ "You may have to clean up some things before attempting to
install again", t);
- rValue = EXIT_CODE_OPERATION_FAILED;
+ rValue = EXIT_CODE_OPERATION_FAILED;
}
}
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
index ed2b2f8..1b3d47b 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
@@ -88,14 +88,14 @@ public abstract class AbstractInstall extends ControlCommand {
executor.setStreamHandler(new PumpStreamHandler());
org.apache.commons.exec.CommandLine commandLine;
- int rValue = RHQControl.EXIT_CODE_OK;
+ int rValue = RHQControl.EXIT_CODE_OK;
if (replaceExistingService) {
- commandLine = getCommandLine(batFile, "stop");
- rValue = Math.max(rValue, executor.execute(commandLine));
+ commandLine = getCommandLine(batFile, "stop");
+ rValue = Math.max(rValue, executor.execute(commandLine));
- commandLine = getCommandLine(batFile, "remove");
- rValue = Math.max(rValue, executor.execute(commandLine));
+ commandLine = getCommandLine(batFile, "remove");
+ rValue = Math.max(rValue, executor.execute(commandLine));
}
commandLine = getCommandLine(batFile, "install");
@@ -277,7 +277,7 @@ public abstract class AbstractInstall extends ControlCommand {
return RHQControl.EXIT_CODE_OK;
}
- int rValue = 0;
+ int rValue = 0;
try {
File agentBinDir = new File(agentBasedir, "bin");
@@ -317,7 +317,7 @@ public abstract class AbstractInstall extends ControlCommand {
throw e;
}
- return rValue;
+ return rValue;
}
protected int startAgent(final File agentBasedir) throws Exception {
@@ -366,7 +366,7 @@ public abstract class AbstractInstall extends ControlCommand {
Executor executor = new DefaultExecutor();
executor.setWorkingDirectory(agentBinDir);
executor.setStreamHandler(new PumpStreamHandler());
- org.apache.commons.exec.CommandLine commandLine;
+ org.apache.commons.exec.CommandLine commandLine =
getCommandLine("rhq-agent-wrapper", "stop");
int rValue = 0;
@@ -635,7 +635,7 @@ public abstract class AbstractInstall extends ControlCommand {
clearAgentPreferences();
int rValue = installAgent(agentBasedir);
configureAgent(agentBasedir, commandLine);
- return rValue;
+ return rValue;
}
private int installAgent(final File agentBasedir) throws IOException {
@@ -667,7 +667,7 @@ public abstract class AbstractInstall extends ControlCommand {
int exitValue = executor.execute(commandLine);
log.info("The agent installer finished running with exit value " +
exitValue);
- return exitValue;
+ return exitValue;
} catch (IOException e) {
log.error("An error occurred while running the agent installer: " +
e.getMessage());
throw e;
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
index e2ef3a8..5d540a1 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
@@ -138,7 +138,7 @@ public class Start extends ControlCommand {
executor.setStreamHandler(new PumpStreamHandler());
org.apache.commons.exec.CommandLine commandLine;
- int rValue;
+ int rValue;
// Cassandra looks for JAVA_HOME or then defaults to PATH. We want it to use the
Java
// defined for RHQ, so make sure JAVA_HOME is set, and set to the RHQ Java for
the executor
@@ -167,7 +167,7 @@ public class Start extends ControlCommand {
// For now we are duplicating logic in the status command. This code will be
// replaced when we implement a rhq-storage.sh script.
if (isStorageRunning()) {
- String pid = getStoragePid();
+ String pid = getStoragePid();
System.out.println("RHQ storage node (pid " + pid + ") is
running");
rValue = RHQControl.EXIT_CODE_OK;
} else {
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
index 7ef66b4..a3920e0 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
@@ -144,7 +144,7 @@ public class Stop extends AbstractInstall {
rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
}
} else {
- if (isStorageRunning()) {
+ if(isStorageRunning()) {
String pid = getStoragePid();
System.out.println("Stopping RHQ storage node...");
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
index e80edd9..cc3d8c2 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
@@ -186,7 +186,7 @@ public class Upgrade extends AbstractInstall {
return exitValue;
}
- // If any failures occur during upgrade, we know we need to reset
rhq-server.properties.
+ // If any failures occur during upgrade, we know we need to reset
rhq-server.properties.
final FileReverter serverPropFileReverter = new
FileReverter(getServerPropertiesFile());
addUndoTask(new ControlCommand.UndoTask("Reverting server properties
file") {
public void performUndoWork() throws Exception {
@@ -229,7 +229,7 @@ public class Upgrade extends AbstractInstall {
}
} catch (Throwable t) {
log.warn("Unable to stop services: " + t.getMessage());
- rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
+ rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
}
}
@@ -262,7 +262,7 @@ public class Upgrade extends AbstractInstall {
}
Executor executor = new DefaultExecutor();
- executor.setWorkingDirectory(new File(getBaseDir(), "bin")); //
data migrator script is not in bin/internal
+ executor.setWorkingDirectory(getBinDir());
executor.setStreamHandler(new PumpStreamHandler());
int exitValue = executor.execute(commandLine);
@@ -546,7 +546,7 @@ public class Upgrade extends AbstractInstall {
}
// now merge the old settings in with the default properties from the new server
install
- String newServerPropsFilePath = new File(getBaseDir(),
"bin/rhq-server.properties").getAbsolutePath();
+ String newServerPropsFilePath = new File(getBinDir(),
"rhq-server.properties").getAbsolutePath();
PropertiesFileUpdate newServerPropsFile = new
PropertiesFileUpdate(newServerPropsFilePath);
newServerPropsFile.update(oldServerProps);
commit 0a6f9edeb14c03c5c0f1c9312bd0d939ba097c2c
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Tue Dec 17 21:35:47 2013 +0100
Bug 968361 - Improve database plugin design to support connection pooling
This changeset introduces a new API for database plugins and deprecates the previous
one. Compatibility with the previous API will be maintained until next major version of
RHQ.
The 'rhq-database-plugin' was based on
org.rhq.plugins.database.DatabaseComponent interface which encouraged plugin authors to
share a single JDBC connection across database components. This was wrong for various
reasons (connection leaks, concurrent JDBC calls... etc).
The new API introduces three important classes:
* org.rhq.plugins.database.PooledConnectionProvider
* org.rhq.plugins.database.BasePooledConnectionProvider
* org.rhq.plugins.database.ConnectionPoolingSupport
BasePooledConnectionProvider is a base implementation of a PooledConnectionProvider.
Plugin authors should create a concrete implementation of BasePooledConnectionProvider
which overrides the #getDriverClass() method. This is important if a database plugin
embeds a JDBC driver: the database-specific driver class must be loaded by the child
plugin classloader.
ConnectionPoolingSupport helps to manage the compatibility with the old API. It's
a contract that all new database resource components should obey to. It declares the
following methods:
* #supportsConnectionPooling()
* #getPooledConnectionProvider()
Results of calls to #supportsConnectionPooling() #getPooledConnectionProvider() must
be consistent. In practice, a top level server database component should be able to create
a PooledConnectionProvider instance, and child servers and services should indicate they
support connection pooling only if their parent component does.
The 'rhq-database-plugin' embeds the BoneCP library (JDBC connection pooling)
and its dependencies (Google's Guava). Child plugins will have all the classes
accessible as soon as they have this node in their plugin descriptor:
===
<depends plugin="Database" useClasses="true"/>
===
This changeset includes the necessary changes to support connection pooling in the
Oracle, Postgres and MySQL plugins.
Thanks to Elias Ross for contributing the original patch from which this changeset is
derived.
diff --git
a/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
b/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
deleted file mode 100644
index 6c81332..0000000
---
a/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
- * All rights reserved.
- *
- * This program 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 version 2 of the License.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-package org.rhq.plugins.mysql;
-
-import java.sql.Connection;
-import java.sql.Driver;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.util.HashMap;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * A class to manage the connections to MySQL
- * This class keeps a cache of connections to MySQL and reuses them on demand
- * We assume single threaded access to the Connection in the agent
- * this will need to be reworked if that assumption is not correct
- * @author Steve Millidge (C2B2 Consulting Limited)
- */
-class MySqlConnectionManager {
-
- private HashMap<MySqlConnectionInfo, Connection> connections;
- private static MySqlConnectionManager singleton;
- private Log logger = LogFactory.getLog(MySqlConnectionManager.class);
-
- private MySqlConnectionManager() {
- connections = new HashMap<MySqlConnectionInfo,Connection>();
- }
-
- static MySqlConnectionManager getConnectionManager() {
- if (singleton == null) {
- singleton = new MySqlConnectionManager();
- }
- return singleton;
- }
-
- public void shutdown() {
- Driver driver = null;
- for (Connection conn : connections.values()) {
- try {
- if (driver == null) {
- String driverName = conn.getMetaData().getDriverName();
- driver = DriverManager.getDriver(driverName);
- }
- conn.close();
- }catch(SQLException e) { logger.info("Problem closing connection on
Shutdown ignoring...");}
- }
- // deregister driver as well
- if (driver != null) {
- try {
- DriverManager.deregisterDriver(driver);
- } catch (SQLException ex) {
- logger.warn("Unable to deregister MySQL Driver on shutdown");
- }
- }
- }
-
- void closeConnection(MySqlConnectionInfo info) {
- Connection conn = connections.get(info);
- if (conn != null) {
- try {
- if (logger.isDebugEnabled()) {
- logger.debug("Closing Connection to " + info.buildURL());
- }
- conn.close();
- } catch (SQLException e) {
- logger.warn("Problem closing connection to " + info.buildURL()
+ " on close");
- }
- }
- connections.remove(info);
- }
-
- Connection getConnection (MySqlConnectionInfo info) throws SQLException {
- try {
- Class.forName("com.mysql.jdbc.Driver");
- } catch (Exception ex) {
- logger.error("Unable to find com.mysql.jdbc.Driver");
- }
-
- Connection conn = connections.get(info);
- String url = info.buildURL();
- if (conn == null) {
- if (logger.isInfoEnabled()) {
- logger.info("Attemping connection to " + url);
- }
- conn = DriverManager.getConnection(url,info.getUser(), info.getPassword());
- if (logger.isInfoEnabled()) {
- logger.info("Successfully connected to " + url);
- }
- connections.put(info, conn);
- } else {
- if (logger.isDebugEnabled()) {
- logger.debug("Reusing existing connection to " + url);
- }
- }
-
- // check the validity of the connection
- if (!conn.isValid(0)) {
- // attempt a single reconnect here and now
- conn.close();
- conn = DriverManager.getConnection(url,info.getUser(), info.getPassword());
- connections.put(info, conn);
- logger.info("Refreshed a connection to " + url);
- }
- return conn;
- }
-
-}
commit 08c7491931efe151b6cd798a429821d57b33cec9
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Mon Dec 23 14:50:55 2013 +0100
Plugin validation for mysql plugin was failing because the Class.forName() statement
was invoked from the constructor of the component. I moved this code to the method that
actually opens the connection. This is the same strategy we use with our postgres plugin.
diff --git
a/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
b/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
new file mode 100644
index 0000000..6c81332
--- /dev/null
+++
b/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
@@ -0,0 +1,125 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program 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 version 2 of the License.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.plugins.mysql;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.HashMap;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * A class to manage the connections to MySQL
+ * This class keeps a cache of connections to MySQL and reuses them on demand
+ * We assume single threaded access to the Connection in the agent
+ * this will need to be reworked if that assumption is not correct
+ * @author Steve Millidge (C2B2 Consulting Limited)
+ */
+class MySqlConnectionManager {
+
+ private HashMap<MySqlConnectionInfo, Connection> connections;
+ private static MySqlConnectionManager singleton;
+ private Log logger = LogFactory.getLog(MySqlConnectionManager.class);
+
+ private MySqlConnectionManager() {
+ connections = new HashMap<MySqlConnectionInfo,Connection>();
+ }
+
+ static MySqlConnectionManager getConnectionManager() {
+ if (singleton == null) {
+ singleton = new MySqlConnectionManager();
+ }
+ return singleton;
+ }
+
+ public void shutdown() {
+ Driver driver = null;
+ for (Connection conn : connections.values()) {
+ try {
+ if (driver == null) {
+ String driverName = conn.getMetaData().getDriverName();
+ driver = DriverManager.getDriver(driverName);
+ }
+ conn.close();
+ }catch(SQLException e) { logger.info("Problem closing connection on
Shutdown ignoring...");}
+ }
+ // deregister driver as well
+ if (driver != null) {
+ try {
+ DriverManager.deregisterDriver(driver);
+ } catch (SQLException ex) {
+ logger.warn("Unable to deregister MySQL Driver on shutdown");
+ }
+ }
+ }
+
+ void closeConnection(MySqlConnectionInfo info) {
+ Connection conn = connections.get(info);
+ if (conn != null) {
+ try {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Closing Connection to " + info.buildURL());
+ }
+ conn.close();
+ } catch (SQLException e) {
+ logger.warn("Problem closing connection to " + info.buildURL()
+ " on close");
+ }
+ }
+ connections.remove(info);
+ }
+
+ Connection getConnection (MySqlConnectionInfo info) throws SQLException {
+ try {
+ Class.forName("com.mysql.jdbc.Driver");
+ } catch (Exception ex) {
+ logger.error("Unable to find com.mysql.jdbc.Driver");
+ }
+
+ Connection conn = connections.get(info);
+ String url = info.buildURL();
+ if (conn == null) {
+ if (logger.isInfoEnabled()) {
+ logger.info("Attemping connection to " + url);
+ }
+ conn = DriverManager.getConnection(url,info.getUser(), info.getPassword());
+ if (logger.isInfoEnabled()) {
+ logger.info("Successfully connected to " + url);
+ }
+ connections.put(info, conn);
+ } else {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Reusing existing connection to " + url);
+ }
+ }
+
+ // check the validity of the connection
+ if (!conn.isValid(0)) {
+ // attempt a single reconnect here and now
+ conn.close();
+ conn = DriverManager.getConnection(url,info.getUser(), info.getPassword());
+ connections.put(info, conn);
+ logger.info("Refreshed a connection to " + url);
+ }
+ return conn;
+ }
+
+}
commit e7efdb0be2b07af94576bf50388b5dee4084f164
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Dec 13 17:39:57 2013 +0100
[BZ 1042892] Don't use ${} notation for shell variables in CLI scripts.
As of BZ 959603, the files are subject to maven resource filtering and
so it can happen that the build server passes a variable to the build
process that clashes with the variable name defined in the script.
(Yes, this actually happened on our Jenkins server that passed
"-DCLASSPATH=" to the maven process for some reason, which resulted in
wonderful corruption of the rhq-cli.sh script).
diff --git a/modules/enterprise/remoting/cli/src/etc/rhq-cli-env.sh
b/modules/enterprise/remoting/cli/src/etc/rhq-cli-env.sh
index 112ec66..80f24c5 100755
--- a/modules/enterprise/remoting/cli/src/etc/rhq-cli-env.sh
+++ b/modules/enterprise/remoting/cli/src/etc/rhq-cli-env.sh
@@ -3,6 +3,14 @@
#===========================================================================
#
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# IMPORTANT: Avoid enclosing shell variables in braces using the ${XXX}
+# notation. This file is subject to maven resource variable expansion
+# during the build and so it can happen that the build environment
+# could corrupt this file by expanding variables that clash with
+# the names defined herein.
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
# RHQ_CLI_DEBUG - If this is defined, the script will emit debug
# messages. It will also enable debug
# messages to be emitted from the cli itself.
@@ -41,7 +49,7 @@
# to the CLI's defaults, then you will want to
# use RHQ_CLI_ADDITIONAL_JAVA_OPTS instead.
#
-#RHQ_CLI_JAVA_OPTS="-Xms64m -Xmx128m -Djava.net.preferIPv4Stack=true
-Drhq.scripting.modules.root-dir=${RHQ_CLI_MODULES_DIR}"
+#RHQ_CLI_JAVA_OPTS="-Xms64m -Xmx128m -Djava.net.preferIPv4Stack=true
-Drhq.scripting.modules.root-dir=$RHQ_CLI_MODULES_DIR"
# RHQ_CLI_JAVA_ENDORSED_DIRS - Java VM command line option to set the
# endorsed dirs for the CLI's VM. If this
diff --git a/modules/enterprise/remoting/cli/src/etc/rhq-cli.sh
b/modules/enterprise/remoting/cli/src/etc/rhq-cli.sh
index 8399b50..b0980e6 100644
--- a/modules/enterprise/remoting/cli/src/etc/rhq-cli.sh
+++ b/modules/enterprise/remoting/cli/src/etc/rhq-cli.sh
@@ -11,6 +11,14 @@
# set via rhq-client-env.sh, which is sourced by this script.
# =============================================================================
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# IMPORTANT: Avoid enclosing shell variables in braces using the ${XXX}
+# notation. This file is subject to maven resource variable expansion
+# during the build and so it can happen that the build environment
+# could corrupt this file by expanding variables that clash with
+# the names defined herein.
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
# ----------------------------------------------------------------------
# Subroutine that simply dumps a message iff debug mode is enabled
# ----------------------------------------------------------------------
@@ -42,16 +50,17 @@ esac
_DOLLARZERO=`readlink "$0" 2>/dev/null || echo "$0"`
RHQ_CLI_BIN_DIR_PATH=`dirname "$_DOLLARZERO"`
-if [ -f "${RHQ_CLI_BIN_DIR_PATH}/rhq-cli-env.sh" ]; then
- debug_msg "Loading environment script:
${RHQ_CLI_BIN_DIR_PATH}/rhq-cli-env.sh"
- . "${RHQ_CLI_BIN_DIR_PATH}/rhq-cli-env.sh" $*
+if [ -f "$RHQ_CLI_BIN_DIR_PATH/rhq-cli-env.sh" ]; then
+ debug_msg "Loading environment script:
$RHQ_CLI_BIN_DIR_PATH/rhq-cli-env.sh"
+ . "$RHQ_CLI_BIN_DIR_PATH/rhq-cli-env.sh" $*
else
- debug_msg "No environment script found at:
${RHQ_CLI_BIN_DIR_PATH}/rhq-cli-env.sh"
+ debug_msg "No environment script found at:
$RHQ_CLI_BIN_DIR_PATH/rhq-cli-env.sh"
fi
# this variable is set during the build and defines the desired default behavior for
directory changing
# we do want to change the dir in RHQ, but possibly don't want to do that in JBoss ON
for backwards compatibility
# reasons.
+# (yes, this USES ${} in the source (not in the distribution) because we seed the default
value from the build)
RHQ_CLI_CHANGE_DIR_ON_START_DEFAULT=${rhq.cli.change-dir-on-start-default}
if [ -z "$RHQ_CLI_CHANGE_DIR_ON_START" ]; then
RHQ_CLI_CHANGE_DIR_ON_START="$RHQ_CLI_CHANGE_DIR_ON_START_DEFAULT"
@@ -61,24 +70,24 @@ fi
# Previous versions always changed directory.
if [ -n "$RHQ_CLI_CHANGE_DIR_ON_START" -a
"$RHQ_CLI_CHANGE_DIR_ON_START" != "false" ]; then
if [ -z "$RHQ_CLI_HOME" ]; then
- cd "${RHQ_CLI_BIN_DIR_PATH}/.."
+ cd "$RHQ_CLI_BIN_DIR_PATH/.."
else
- cd "${RHQ_CLI_HOME}" || {
- echo "Cannot go to the RHQ_CLI_HOME directory: ${RHQ_CLI_HOME}"
+ cd "$RHQ_CLI_HOME" || {
+ echo "Cannot go to the RHQ_CLI_HOME directory: $RHQ_CLI_HOME"
exit 1
}
fi
RHQ_CLI_HOME=`pwd`
else
if [ -z "$RHQ_CLI_HOME" ]; then
- RHQ_CLI_HOME="${RHQ_CLI_BIN_DIR_PATH}/.."
+ RHQ_CLI_HOME="$RHQ_CLI_BIN_DIR_PATH/.."
fi
#get an absolute path
RHQ_CLI_HOME=`readlink -f "$RHQ_CLI_HOME"`
if [ ! -d "$RHQ_CLI_HOME" ]; then
- echo "RHQ_CLI_HOME detected or defined as [${RHQ_CLI_HOME}] doesn't seem
to exist or is not a directory"
+ echo "RHQ_CLI_HOME detected or defined as [$RHQ_CLI_HOME] doesn't seem
to exist or is not a directory"
exit 1
fi
fi
@@ -90,7 +99,7 @@ debug_msg "RHQ_CLI_HOME: $RHQ_CLI_HOME"
# sample modules.
# ----------------------------------------------------------------------
if [ -z "$RHQ_CLI_MODULES_DIR" ]; then
- RHQ_CLI_MODULES_DIR="${RHQ_CLI_HOME}/samples/modules"
+ RHQ_CLI_MODULES_DIR="$RHQ_CLI_HOME/samples/modules"
fi
# ----------------------------------------------------------------------
@@ -110,7 +119,7 @@ fi
if [ -z "$RHQ_CLI_JAVA_EXE_FILE_PATH" ]; then
if [ -z "$RHQ_CLI_JAVA_HOME" ]; then
- RHQ_CLI_JAVA_HOME="${RHQ_CLI_HOME}/jre"
+ RHQ_CLI_JAVA_HOME="$RHQ_CLI_HOME/jre"
if [ -d "$RHQ_CLI_JAVA_HOME" ]; then
debug_msg "Using the embedded JRE"
else
@@ -119,7 +128,7 @@ if [ -z "$RHQ_CLI_JAVA_EXE_FILE_PATH" ]; then
fi
fi
debug_msg "RHQ_CLI_JAVA_HOME: $RHQ_CLI_JAVA_HOME"
- RHQ_CLI_JAVA_EXE_FILE_PATH=${RHQ_CLI_JAVA_HOME}/bin/java
+ RHQ_CLI_JAVA_EXE_FILE_PATH="$RHQ_CLI_JAVA_HOME/bin/java"
fi
debug_msg "RHQ_CLI_JAVA_EXE_FILE_PATH: $RHQ_CLI_JAVA_EXE_FILE_PATH"
@@ -133,14 +142,14 @@ fi
# Prepare the classpath (take into account possible spaces in dir names)
# ----------------------------------------------------------------------
-CLASSPATH="${RHQ_CLI_HOME}/conf"
-_JAR_FILES=`cd "${RHQ_CLI_HOME}/lib";ls -1 *.jar`
+CLASSPATH="$RHQ_CLI_HOME/conf"
+_JAR_FILES=`cd "$RHQ_CLI_HOME/lib";ls -1 *.jar`
for _JAR in $_JAR_FILES ; do
- _JAR="${RHQ_CLI_HOME}/lib/${_JAR}"
+ _JAR="$RHQ_CLI_HOME/lib/$_JAR"
if [ -z "$CLASSPATH" ]; then
- CLASSPATH="${_JAR}"
+ CLASSPATH="$_JAR"
else
- CLASSPATH="${CLASSPATH}:${_JAR}"
+ CLASSPATH="$CLASSPATH:$_JAR"
fi
debug_msg "CLASSPATH entry: $_JAR"
done
@@ -151,7 +160,7 @@ debug_msg "CLASSPATH entry: $_JAR"
# ----------------------------------------------------------------------
if [ -z "$RHQ_CLI_JAVA_OPTS" ]; then
- RHQ_CLI_JAVA_OPTS="-Xms64m -Xmx128m -Djava.net.preferIPv4Stack=true
-Drhq.scripting.modules.root-dir=${RHQ_CLI_MODULES_DIR}"
+ RHQ_CLI_JAVA_OPTS="-Xms64m -Xmx128m -Djava.net.preferIPv4Stack=true
-Drhq.scripting.modules.root-dir=$RHQ_CLI_MODULES_DIR"
fi
debug_msg "RHQ_CLI_JAVA_OPTS: $RHQ_CLI_JAVA_OPTS"
@@ -159,7 +168,7 @@ if [ "$RHQ_CLI_JAVA_ENDORSED_DIRS" = "none" ];
then
debug_msg "Not explicitly setting java.endorsed.dirs"
else
if [ -z "$RHQ_CLI_JAVA_ENDORSED_DIRS" ]; then
- RHQ_CLI_JAVA_ENDORSED_DIRS="${RHQ_CLI_HOME}/lib/endorsed"
+ RHQ_CLI_JAVA_ENDORSED_DIRS="$RHQ_CLI_HOME/lib/endorsed"
fi
# convert the path if on Windows
@@ -167,14 +176,14 @@ else
RHQ_CLI_JAVA_ENDORSED_DIRS=`cygpath --windows --path
"$RHQ_CLI_JAVA_ENDORSED_DIRS"`
fi
debug_msg "RHQ_CLI_JAVA_ENDORSED_DIRS: $RHQ_CLI_JAVA_ENDORSED_DIRS"
-
_JAVA_ENDORSED_DIRS_OPT="-Djava.endorsed.dirs=\"${RHQ_CLI_JAVA_ENDORSED_DIRS}\""
+
_JAVA_ENDORSED_DIRS_OPT="-Djava.endorsed.dirs=\"$RHQ_CLI_JAVA_ENDORSED_DIRS\""
fi
if [ "$RHQ_CLI_JAVA_LIBRARY_PATH" = "none" ]; then
debug_msg "Not explicitly setting java.library.path"
else
if [ -z "$RHQ_CLI_JAVA_LIBRARY_PATH" ]; then
- RHQ_CLI_JAVA_LIBRARY_PATH="${RHQ_CLI_HOME}/lib"
+ RHQ_CLI_JAVA_LIBRARY_PATH="$RHQ_CLI_HOME/lib"
fi
# convert the path if on Windows
@@ -182,7 +191,7 @@ else
RHQ_CLI_JAVA_LIBRARY_PATH=`cygpath --windows --path
"$RHQ_CLI_JAVA_LIBRARY_PATH"`
fi
debug_msg "RHQ_CLI_JAVA_LIBRARY_PATH: $RHQ_CLI_JAVA_LIBRARY_PATH"
-
_JAVA_LIBRARY_PATH_OPT="-Djava.library.path=\"${RHQ_CLI_JAVA_LIBRARY_PATH}\""
+
_JAVA_LIBRARY_PATH_OPT="-Djava.library.path=\"$RHQ_CLI_JAVA_LIBRARY_PATH\""
fi
debug_msg "RHQ_CLI_ADDITIONAL_JAVA_OPTS: $RHQ_CLI_ADDITIONAL_JAVA_OPTS"
@@ -201,8 +210,8 @@ if [ -n "$RHQ_CLI_DEBUG" ]; then
fi
# create the logs directory
-if [ ! -d "${RHQ_CLI_HOME}/logs" ]; then
- mkdir "${RHQ_CLI_HOME}/logs"
+if [ ! -d "$RHQ_CLI_HOME/logs" ]; then
+ mkdir "$RHQ_CLI_HOME/logs"
fi
# convert some of the paths if we are on Windows
@@ -220,15 +229,15 @@ fi
debug_msg "Executing the CLI with this command line:"
exit_code=0
if [ -z "$RHQ_CLI_CMDLINE_OPTS" ]; then
- debug_msg "${RHQ_CLI_JAVA_EXE_FILE_PATH} ${_JAVA_ENDORSED_DIRS_OPT}
${_JAVA_LIBRARY_PATH_OPT} ${RHQ_CLI_JAVA_OPTS} ${RHQ_CLI_ADDITIONAL_JAVA_OPTS}
${_LOG_CONFIG} -cp ${CLASSPATH} org.rhq.enterprise.client.ClientMain $@"
- "${RHQ_CLI_JAVA_EXE_FILE_PATH}" ${_JAVA_ENDORSED_DIRS_OPT}
${_JAVA_LIBRARY_PATH_OPT} ${RHQ_CLI_JAVA_OPTS} ${RHQ_CLI_ADDITIONAL_JAVA_OPTS}
${_LOG_CONFIG} -cp "${CLASSPATH}" org.rhq.enterprise.client.ClientMain
"$@"
+ debug_msg "$RHQ_CLI_JAVA_EXE_FILE_PATH $_JAVA_ENDORSED_DIRS_OPT
$_JAVA_LIBRARY_PATH_OPT $RHQ_CLI_JAVA_OPTS $RHQ_CLI_ADDITIONAL_JAVA_OPTS $_LOG_CONFIG -cp
$CLASSPATH org.rhq.enterprise.client.ClientMain $@"
+ "$RHQ_CLI_JAVA_EXE_FILE_PATH" $_JAVA_ENDORSED_DIRS_OPT
$_JAVA_LIBRARY_PATH_OPT $RHQ_CLI_JAVA_OPTS $RHQ_CLI_ADDITIONAL_JAVA_OPTS $_LOG_CONFIG -cp
"$CLASSPATH" org.rhq.enterprise.client.ClientMain "$@"
exit_code=$?
else
- debug_msg "${RHQ_CLI_JAVA_EXE_FILE_PATH} ${_JAVA_ENDORSED_DIRS_OPT}
${_JAVA_LIBRARY_PATH_OPT} ${RHQ_CLI_JAVA_OPTS} ${RHQ_CLI_ADDITIONAL_JAVA_OPTS}
${_LOG_CONFIG} -cp ${CLASSPATH} org.rhq.enterprise.client.ClientMain
${RHQ_CLI_CMDLINE_OPTS}"
- "${RHQ_CLI_JAVA_EXE_FILE_PATH}" ${_JAVA_ENDORSED_DIRS_OPT}
${_JAVA_LIBRARY_PATH_OPT} ${RHQ_CLI_JAVA_OPTS} ${RHQ_CLI_ADDITIONAL_JAVA_OPTS}
${_LOG_CONFIG} -cp "${CLASSPATH}" org.rhq.enterprise.client.ClientMain
${RHQ_CLI_CMDLINE_OPTS}
+ debug_msg "$RHQ_CLI_JAVA_EXE_FILE_PATH $_JAVA_ENDORSED_DIRS_OPT
$_JAVA_LIBRARY_PATH_OPT $RHQ_CLI_JAVA_OPTS $RHQ_CLI_ADDITIONAL_JAVA_OPTS $_LOG_CONFIG -cp
$CLASSPATH org.rhq.enterprise.client.ClientMain $RHQ_CLI_CMDLINE_OPTS"
+ "$RHQ_CLI_JAVA_EXE_FILE_PATH" $_JAVA_ENDORSED_DIRS_OPT
$_JAVA_LIBRARY_PATH_OPT $RHQ_CLI_JAVA_OPTS $RHQ_CLI_ADDITIONAL_JAVA_OPTS $_LOG_CONFIG -cp
"$CLASSPATH" org.rhq.enterprise.client.ClientMain $RHQ_CLI_CMDLINE_OPTS
exit_code=$?
fi
debug_msg "$0 done."
-exit ${exit_code}
+exit $exit_code
commit c215cd1fcf8f3676928c3a0d12de0174691c25f0
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Dec 12 22:43:55 2013 +0100
Better testability in the ModulesDirectoryScriptSourceProvider.
Also changed the default module path from "./samples/modules" to
"./modules". This should be safe with the fix for BZ 959603 which
causes the CLI to always pass the system property to load the modules
from. The new default path is less coupled with the FS layout of the CLI
distribution.
diff --git
a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/script/ModulesDirectoryScriptSourceProviderTest.java
b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/script/ModulesDirectoryScriptSourceProviderTest.java
index 8227e38..4060d07 100644
---
a/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/script/ModulesDirectoryScriptSourceProviderTest.java
+++
b/modules/enterprise/remoting/cli/src/test/java/org/rhq/enterprise/client/script/ModulesDirectoryScriptSourceProviderTest.java
@@ -28,8 +28,8 @@ import java.io.PrintWriter;
import java.net.URI;
import java.net.URISyntaxException;
+import org.junit.BeforeClass;
import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
commit cade5bd5f33aa7b8e8aafcaa883b0eaa053b8878
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Dec 12 23:10:14 2013 +0100
[BZ 959603] - Don't change CWD on CLI startup.
Since the very beginning of CLI, RHQ always changed the CWD to
$RHQ_CLI_HOME when starting up, which is rather strange and
non-standard.
To keep the backwards compatibility, the behavior can be toggled on
or off.
The default behavior can be changed in the build by setting the
rhq.cli.change-dir-on-start-default
property. In RHQ, this defaults to "false", causing RHQ to NOT change
directories when starting up the CLI anymore.
Further, the behavior can be toggled by the user by setting the
RHQ_CLI_CHANGE_DIR_ON_START environment variable to "true" (or any
other value but "false" actually) or "false" explicitly.
Additionally, a new environment variable called "RHQ_CLI_MODULES_DIR"
was added. This was necessary to not break the loading of the
provided CommonJS modules available in the
$RHQ_CLI_HOME/samples/modules directory if the CLI was started from
another directory.
By adding the new RHQ_CLI_MODULES_DIR, which is initialized to the
correct value if not provided externally, we correctly load the
sample modules with the additional benefit of easier change of the
modules location for the user (previously this was only possible
through
RHQ_CLI_ADDITIONAL_JAVA_OPTS="-Drhq.scripting.modules.root-dir=..."
, while now one only needs RHQ_CLI_MODULES_DIR=...).
diff --git a/modules/enterprise/remoting/cli/src/etc/rhq-cli-env.sh
b/modules/enterprise/remoting/cli/src/etc/rhq-cli-env.sh
index 80f24c5..112ec66 100755
--- a/modules/enterprise/remoting/cli/src/etc/rhq-cli-env.sh
+++ b/modules/enterprise/remoting/cli/src/etc/rhq-cli-env.sh
@@ -3,14 +3,6 @@
#===========================================================================
#
-# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-# IMPORTANT: Avoid enclosing shell variables in braces using the ${XXX}
-# notation. This file is subject to maven resource variable expansion
-# during the build and so it can happen that the build environment
-# could corrupt this file by expanding variables that clash with
-# the names defined herein.
-# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
# RHQ_CLI_DEBUG - If this is defined, the script will emit debug
# messages. It will also enable debug
# messages to be emitted from the cli itself.
@@ -49,7 +41,7 @@
# to the CLI's defaults, then you will want to
# use RHQ_CLI_ADDITIONAL_JAVA_OPTS instead.
#
-#RHQ_CLI_JAVA_OPTS="-Xms64m -Xmx128m -Djava.net.preferIPv4Stack=true
-Drhq.scripting.modules.root-dir=$RHQ_CLI_MODULES_DIR"
+#RHQ_CLI_JAVA_OPTS="-Xms64m -Xmx128m -Djava.net.preferIPv4Stack=true
-Drhq.scripting.modules.root-dir=${RHQ_CLI_MODULES_DIR}"
# RHQ_CLI_JAVA_ENDORSED_DIRS - Java VM command line option to set the
# endorsed dirs for the CLI's VM. If this
diff --git a/modules/enterprise/remoting/cli/src/etc/rhq-cli.sh
b/modules/enterprise/remoting/cli/src/etc/rhq-cli.sh
index b0980e6..8399b50 100644
--- a/modules/enterprise/remoting/cli/src/etc/rhq-cli.sh
+++ b/modules/enterprise/remoting/cli/src/etc/rhq-cli.sh
@@ -11,14 +11,6 @@
# set via rhq-client-env.sh, which is sourced by this script.
# =============================================================================
-# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-# IMPORTANT: Avoid enclosing shell variables in braces using the ${XXX}
-# notation. This file is subject to maven resource variable expansion
-# during the build and so it can happen that the build environment
-# could corrupt this file by expanding variables that clash with
-# the names defined herein.
-# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
# ----------------------------------------------------------------------
# Subroutine that simply dumps a message iff debug mode is enabled
# ----------------------------------------------------------------------
@@ -50,17 +42,16 @@ esac
_DOLLARZERO=`readlink "$0" 2>/dev/null || echo "$0"`
RHQ_CLI_BIN_DIR_PATH=`dirname "$_DOLLARZERO"`
-if [ -f "$RHQ_CLI_BIN_DIR_PATH/rhq-cli-env.sh" ]; then
- debug_msg "Loading environment script:
$RHQ_CLI_BIN_DIR_PATH/rhq-cli-env.sh"
- . "$RHQ_CLI_BIN_DIR_PATH/rhq-cli-env.sh" $*
+if [ -f "${RHQ_CLI_BIN_DIR_PATH}/rhq-cli-env.sh" ]; then
+ debug_msg "Loading environment script:
${RHQ_CLI_BIN_DIR_PATH}/rhq-cli-env.sh"
+ . "${RHQ_CLI_BIN_DIR_PATH}/rhq-cli-env.sh" $*
else
- debug_msg "No environment script found at:
$RHQ_CLI_BIN_DIR_PATH/rhq-cli-env.sh"
+ debug_msg "No environment script found at:
${RHQ_CLI_BIN_DIR_PATH}/rhq-cli-env.sh"
fi
# this variable is set during the build and defines the desired default behavior for
directory changing
# we do want to change the dir in RHQ, but possibly don't want to do that in JBoss ON
for backwards compatibility
# reasons.
-# (yes, this USES ${} in the source (not in the distribution) because we seed the default
value from the build)
RHQ_CLI_CHANGE_DIR_ON_START_DEFAULT=${rhq.cli.change-dir-on-start-default}
if [ -z "$RHQ_CLI_CHANGE_DIR_ON_START" ]; then
RHQ_CLI_CHANGE_DIR_ON_START="$RHQ_CLI_CHANGE_DIR_ON_START_DEFAULT"
@@ -70,24 +61,24 @@ fi
# Previous versions always changed directory.
if [ -n "$RHQ_CLI_CHANGE_DIR_ON_START" -a
"$RHQ_CLI_CHANGE_DIR_ON_START" != "false" ]; then
if [ -z "$RHQ_CLI_HOME" ]; then
- cd "$RHQ_CLI_BIN_DIR_PATH/.."
+ cd "${RHQ_CLI_BIN_DIR_PATH}/.."
else
- cd "$RHQ_CLI_HOME" || {
- echo "Cannot go to the RHQ_CLI_HOME directory: $RHQ_CLI_HOME"
+ cd "${RHQ_CLI_HOME}" || {
+ echo "Cannot go to the RHQ_CLI_HOME directory: ${RHQ_CLI_HOME}"
exit 1
}
fi
RHQ_CLI_HOME=`pwd`
else
if [ -z "$RHQ_CLI_HOME" ]; then
- RHQ_CLI_HOME="$RHQ_CLI_BIN_DIR_PATH/.."
+ RHQ_CLI_HOME="${RHQ_CLI_BIN_DIR_PATH}/.."
fi
#get an absolute path
RHQ_CLI_HOME=`readlink -f "$RHQ_CLI_HOME"`
if [ ! -d "$RHQ_CLI_HOME" ]; then
- echo "RHQ_CLI_HOME detected or defined as [$RHQ_CLI_HOME] doesn't seem
to exist or is not a directory"
+ echo "RHQ_CLI_HOME detected or defined as [${RHQ_CLI_HOME}] doesn't seem
to exist or is not a directory"
exit 1
fi
fi
@@ -99,7 +90,7 @@ debug_msg "RHQ_CLI_HOME: $RHQ_CLI_HOME"
# sample modules.
# ----------------------------------------------------------------------
if [ -z "$RHQ_CLI_MODULES_DIR" ]; then
- RHQ_CLI_MODULES_DIR="$RHQ_CLI_HOME/samples/modules"
+ RHQ_CLI_MODULES_DIR="${RHQ_CLI_HOME}/samples/modules"
fi
# ----------------------------------------------------------------------
@@ -119,7 +110,7 @@ fi
if [ -z "$RHQ_CLI_JAVA_EXE_FILE_PATH" ]; then
if [ -z "$RHQ_CLI_JAVA_HOME" ]; then
- RHQ_CLI_JAVA_HOME="$RHQ_CLI_HOME/jre"
+ RHQ_CLI_JAVA_HOME="${RHQ_CLI_HOME}/jre"
if [ -d "$RHQ_CLI_JAVA_HOME" ]; then
debug_msg "Using the embedded JRE"
else
@@ -128,7 +119,7 @@ if [ -z "$RHQ_CLI_JAVA_EXE_FILE_PATH" ]; then
fi
fi
debug_msg "RHQ_CLI_JAVA_HOME: $RHQ_CLI_JAVA_HOME"
- RHQ_CLI_JAVA_EXE_FILE_PATH="$RHQ_CLI_JAVA_HOME/bin/java"
+ RHQ_CLI_JAVA_EXE_FILE_PATH=${RHQ_CLI_JAVA_HOME}/bin/java
fi
debug_msg "RHQ_CLI_JAVA_EXE_FILE_PATH: $RHQ_CLI_JAVA_EXE_FILE_PATH"
@@ -142,14 +133,14 @@ fi
# Prepare the classpath (take into account possible spaces in dir names)
# ----------------------------------------------------------------------
-CLASSPATH="$RHQ_CLI_HOME/conf"
-_JAR_FILES=`cd "$RHQ_CLI_HOME/lib";ls -1 *.jar`
+CLASSPATH="${RHQ_CLI_HOME}/conf"
+_JAR_FILES=`cd "${RHQ_CLI_HOME}/lib";ls -1 *.jar`
for _JAR in $_JAR_FILES ; do
- _JAR="$RHQ_CLI_HOME/lib/$_JAR"
+ _JAR="${RHQ_CLI_HOME}/lib/${_JAR}"
if [ -z "$CLASSPATH" ]; then
- CLASSPATH="$_JAR"
+ CLASSPATH="${_JAR}"
else
- CLASSPATH="$CLASSPATH:$_JAR"
+ CLASSPATH="${CLASSPATH}:${_JAR}"
fi
debug_msg "CLASSPATH entry: $_JAR"
done
@@ -160,7 +151,7 @@ debug_msg "CLASSPATH entry: $_JAR"
# ----------------------------------------------------------------------
if [ -z "$RHQ_CLI_JAVA_OPTS" ]; then
- RHQ_CLI_JAVA_OPTS="-Xms64m -Xmx128m -Djava.net.preferIPv4Stack=true
-Drhq.scripting.modules.root-dir=$RHQ_CLI_MODULES_DIR"
+ RHQ_CLI_JAVA_OPTS="-Xms64m -Xmx128m -Djava.net.preferIPv4Stack=true
-Drhq.scripting.modules.root-dir=${RHQ_CLI_MODULES_DIR}"
fi
debug_msg "RHQ_CLI_JAVA_OPTS: $RHQ_CLI_JAVA_OPTS"
@@ -168,7 +159,7 @@ if [ "$RHQ_CLI_JAVA_ENDORSED_DIRS" = "none" ];
then
debug_msg "Not explicitly setting java.endorsed.dirs"
else
if [ -z "$RHQ_CLI_JAVA_ENDORSED_DIRS" ]; then
- RHQ_CLI_JAVA_ENDORSED_DIRS="$RHQ_CLI_HOME/lib/endorsed"
+ RHQ_CLI_JAVA_ENDORSED_DIRS="${RHQ_CLI_HOME}/lib/endorsed"
fi
# convert the path if on Windows
@@ -176,14 +167,14 @@ else
RHQ_CLI_JAVA_ENDORSED_DIRS=`cygpath --windows --path
"$RHQ_CLI_JAVA_ENDORSED_DIRS"`
fi
debug_msg "RHQ_CLI_JAVA_ENDORSED_DIRS: $RHQ_CLI_JAVA_ENDORSED_DIRS"
-
_JAVA_ENDORSED_DIRS_OPT="-Djava.endorsed.dirs=\"$RHQ_CLI_JAVA_ENDORSED_DIRS\""
+
_JAVA_ENDORSED_DIRS_OPT="-Djava.endorsed.dirs=\"${RHQ_CLI_JAVA_ENDORSED_DIRS}\""
fi
if [ "$RHQ_CLI_JAVA_LIBRARY_PATH" = "none" ]; then
debug_msg "Not explicitly setting java.library.path"
else
if [ -z "$RHQ_CLI_JAVA_LIBRARY_PATH" ]; then
- RHQ_CLI_JAVA_LIBRARY_PATH="$RHQ_CLI_HOME/lib"
+ RHQ_CLI_JAVA_LIBRARY_PATH="${RHQ_CLI_HOME}/lib"
fi
# convert the path if on Windows
@@ -191,7 +182,7 @@ else
RHQ_CLI_JAVA_LIBRARY_PATH=`cygpath --windows --path
"$RHQ_CLI_JAVA_LIBRARY_PATH"`
fi
debug_msg "RHQ_CLI_JAVA_LIBRARY_PATH: $RHQ_CLI_JAVA_LIBRARY_PATH"
-
_JAVA_LIBRARY_PATH_OPT="-Djava.library.path=\"$RHQ_CLI_JAVA_LIBRARY_PATH\""
+
_JAVA_LIBRARY_PATH_OPT="-Djava.library.path=\"${RHQ_CLI_JAVA_LIBRARY_PATH}\""
fi
debug_msg "RHQ_CLI_ADDITIONAL_JAVA_OPTS: $RHQ_CLI_ADDITIONAL_JAVA_OPTS"
@@ -210,8 +201,8 @@ if [ -n "$RHQ_CLI_DEBUG" ]; then
fi
# create the logs directory
-if [ ! -d "$RHQ_CLI_HOME/logs" ]; then
- mkdir "$RHQ_CLI_HOME/logs"
+if [ ! -d "${RHQ_CLI_HOME}/logs" ]; then
+ mkdir "${RHQ_CLI_HOME}/logs"
fi
# convert some of the paths if we are on Windows
@@ -229,15 +220,15 @@ fi
debug_msg "Executing the CLI with this command line:"
exit_code=0
if [ -z "$RHQ_CLI_CMDLINE_OPTS" ]; then
- debug_msg "$RHQ_CLI_JAVA_EXE_FILE_PATH $_JAVA_ENDORSED_DIRS_OPT
$_JAVA_LIBRARY_PATH_OPT $RHQ_CLI_JAVA_OPTS $RHQ_CLI_ADDITIONAL_JAVA_OPTS $_LOG_CONFIG -cp
$CLASSPATH org.rhq.enterprise.client.ClientMain $@"
- "$RHQ_CLI_JAVA_EXE_FILE_PATH" $_JAVA_ENDORSED_DIRS_OPT
$_JAVA_LIBRARY_PATH_OPT $RHQ_CLI_JAVA_OPTS $RHQ_CLI_ADDITIONAL_JAVA_OPTS $_LOG_CONFIG -cp
"$CLASSPATH" org.rhq.enterprise.client.ClientMain "$@"
+ debug_msg "${RHQ_CLI_JAVA_EXE_FILE_PATH} ${_JAVA_ENDORSED_DIRS_OPT}
${_JAVA_LIBRARY_PATH_OPT} ${RHQ_CLI_JAVA_OPTS} ${RHQ_CLI_ADDITIONAL_JAVA_OPTS}
${_LOG_CONFIG} -cp ${CLASSPATH} org.rhq.enterprise.client.ClientMain $@"
+ "${RHQ_CLI_JAVA_EXE_FILE_PATH}" ${_JAVA_ENDORSED_DIRS_OPT}
${_JAVA_LIBRARY_PATH_OPT} ${RHQ_CLI_JAVA_OPTS} ${RHQ_CLI_ADDITIONAL_JAVA_OPTS}
${_LOG_CONFIG} -cp "${CLASSPATH}" org.rhq.enterprise.client.ClientMain
"$@"
exit_code=$?
else
- debug_msg "$RHQ_CLI_JAVA_EXE_FILE_PATH $_JAVA_ENDORSED_DIRS_OPT
$_JAVA_LIBRARY_PATH_OPT $RHQ_CLI_JAVA_OPTS $RHQ_CLI_ADDITIONAL_JAVA_OPTS $_LOG_CONFIG -cp
$CLASSPATH org.rhq.enterprise.client.ClientMain $RHQ_CLI_CMDLINE_OPTS"
- "$RHQ_CLI_JAVA_EXE_FILE_PATH" $_JAVA_ENDORSED_DIRS_OPT
$_JAVA_LIBRARY_PATH_OPT $RHQ_CLI_JAVA_OPTS $RHQ_CLI_ADDITIONAL_JAVA_OPTS $_LOG_CONFIG -cp
"$CLASSPATH" org.rhq.enterprise.client.ClientMain $RHQ_CLI_CMDLINE_OPTS
+ debug_msg "${RHQ_CLI_JAVA_EXE_FILE_PATH} ${_JAVA_ENDORSED_DIRS_OPT}
${_JAVA_LIBRARY_PATH_OPT} ${RHQ_CLI_JAVA_OPTS} ${RHQ_CLI_ADDITIONAL_JAVA_OPTS}
${_LOG_CONFIG} -cp ${CLASSPATH} org.rhq.enterprise.client.ClientMain
${RHQ_CLI_CMDLINE_OPTS}"
+ "${RHQ_CLI_JAVA_EXE_FILE_PATH}" ${_JAVA_ENDORSED_DIRS_OPT}
${_JAVA_LIBRARY_PATH_OPT} ${RHQ_CLI_JAVA_OPTS} ${RHQ_CLI_ADDITIONAL_JAVA_OPTS}
${_LOG_CONFIG} -cp "${CLASSPATH}" org.rhq.enterprise.client.ClientMain
${RHQ_CLI_CMDLINE_OPTS}
exit_code=$?
fi
debug_msg "$0 done."
-exit $exit_code
+exit ${exit_code}
commit d7f38193b70683744ee13d7238d2d5b7f75b82db
Author: John Sanda <jsanda(a)redhat.com>
Date: Thu Dec 12 10:14:12 2013 -0500
calculate bloom filters
diff --git
a/modules/enterprise/remoting/cli/src/main/samples/modules/rhq.storage.sizing.js
b/modules/enterprise/remoting/cli/src/main/samples/modules/rhq.storage.sizing.js
index 77c22fd..d185f56 100644
--- a/modules/enterprise/remoting/cli/src/main/samples/modules/rhq.storage.sizing.js
+++ b/modules/enterprise/remoting/cli/src/main/samples/modules/rhq.storage.sizing.js
@@ -24,8 +24,113 @@
var time = new Time();
+ function BloomFilter(keys) {
+ function BloomSpecification(k, bucketsPerElement) {
+ this.K = k;
+ this.bucketsPerElement = bucketsPerElement;
+ }
+
+ // This is taken directly from BloomCalculations.java
+ this.probs = [
+ [1.0], // dummy row representing 0 buckets per element
+ [1.0, 1.0], // dummy row representing 1 buckets per element
+ [1.0, 0.393, 0.400],
+ [1.0, 0.283, 0.237, 0.253],
+ [1.0, 0.221, 0.155, 0.147, 0.160],
+ [1.0, 0.181, 0.109, 0.092, 0.092, 0.101], // 5
+ [1.0, 0.154, 0.0804, 0.0609, 0.0561, 0.0578, 0.0638],
+ [1.0, 0.133, 0.0618, 0.0423, 0.0359, 0.0347, 0.0364],
+ [1.0, 0.118, 0.0489, 0.0306, 0.024, 0.0217, 0.0216, 0.0229],
+ [1.0, 0.105, 0.0397, 0.0228, 0.0166, 0.0141, 0.0133, 0.0135, 0.0145],
+ [1.0, 0.0952, 0.0329, 0.0174, 0.0118, 0.00943, 0.00844, 0.00819, 0.00846], //
10
+ [1.0, 0.0869, 0.0276, 0.0136, 0.00864, 0.0065, 0.00552, 0.00513, 0.00509],
+ [1.0, 0.08, 0.0236, 0.0108, 0.00646, 0.00459, 0.00371, 0.00329, 0.00314],
+ [1.0, 0.074, 0.0203, 0.00875, 0.00492, 0.00332, 0.00255, 0.00217, 0.00199,
0.00194],
+ [1.0, 0.0689, 0.0177, 0.00718, 0.00381, 0.00244, 0.00179, 0.00146, 0.00129,
0.00121, 0.0012],
+ [1.0, 0.0645, 0.0156, 0.00596, 0.003, 0.00183, 0.00128, 0.001, 0.000852,
0.000775, 0.000744], // 15
+ [1.0, 0.0606, 0.0138, 0.005, 0.00239, 0.00139, 0.000935, 0.000702, 0.000574,
0.000505, 0.00047, 0.000459],
+ [1.0, 0.0571, 0.0123, 0.00423, 0.00193, 0.00107, 0.000692, 0.000499, 0.000394,
0.000335, 0.000302, 0.000287, 0.000284],
+ [1.0, 0.054, 0.0111, 0.00362, 0.00158, 0.000839, 0.000519, 0.00036, 0.000275,
0.000226, 0.000198, 0.000183, 0.000176],
+ [1.0, 0.0513, 0.00998, 0.00312, 0.0013, 0.000663, 0.000394, 0.000264, 0.000194,
0.000155, 0.000132, 0.000118, 0.000111, 0.000109],
+ [1.0, 0.0488, 0.00906, 0.0027, 0.00108, 0.00053, 0.000303, 0.000196, 0.00014,
0.000108, 8.89e-05, 7.77e-05, 7.12e-05, 6.79e-05, 6.71e-05] // 20
+ ]; // the first column is a dummy column representing K=0.
+
+ var self = this;
+ var excess = 20;
+ var bitset_excess = 20;
+ var minBuckets = 2;
+ var minK = 1;
+ var optKPerBuckets = [];
+ var maxFalsePosProb = 0.01;
+
+
+ for (i = 0; i < this.probs.length; i++) {
+ var min = java.lang.Double.MAX_VALUE;
+ var prob = this.probs[i];
+ for (j = 0; j < prob.length; j++) {
+ if (prob[j] < min) {
+ min = prob[j];
+ optKPerBuckets[i] = Math.max(minK, j);
+ }
+ }
+ }
+
+ var bucketsPerElement = maxBucketsPerElement(keys);
+ var spec = computeBloomSpec(bucketsPerElement, maxFalsePosProb);
+ var numBits = (keys * spec.bucketsPerElement) + bitset_excess;
+ var wordCount = bits2words(numBits);
+
+ if (wordCount > java.lang.Integer.MAX_VALUE) {
+ throw "Bloom filter size is > 16GB, reduce the
bloom_filter_fp_chance";
+ }
+
+ var bytes = wordCount * 8;
+ this.size = bytes + 8;
+
+ function maxBucketsPerElement(numElements) {
+ numElements = Math.max(1, numElements);
+ var v = (java.lang.Long.MAX_VALUE - excess) / keys;
+ if (v < 1) {
+ throw "Cannot compute probabilities for " + numElements + "
elements.";
+ }
+ return Math.min(self.probs.length - 1, v);
+ }
+
+ // This is taken from BloomCalculations.java
+ function computeBloomSpec(maxBucketsPerElement, maxFalsePosProb) {
+ var maxK = self.probs[maxBucketsPerElement].length - 1;
+
+ // Handle the trivial cases
+ if(maxFalsePosProb >= self.probs[minBuckets][minK]) {
+ return new BloomSpecification(2, optKPerBuckets[2]);
+ }
+ if (maxFalsePosProb < self.probs[maxBucketsPerElement][maxK]) {
+ throw "Unable to satisfy " + maxFalsePosProb + " with " +
maxBucketsPerElement + " buckets per element";
+ }
+
+ // First find the minimal required number of buckets:
+ var bucketsPerElement = 2;
+ var K = optKPerBuckets[2];
+ while(self.probs[bucketsPerElement][K] > maxFalsePosProb){
+ bucketsPerElement++;
+ K = optKPerBuckets[bucketsPerElement];
+ }
+ // Now that the number of buckets is sufficient, see if we can relax K
+ // without losing too much precision.
+ while(self.probs[bucketsPerElement][K - 1] <= maxFalsePosProb) {
+ K--;
+ }
+ println('K = ' + K + ', bucketsPerElement = ' +
bucketsPerElement);
+ return new BloomSpecification(K, bucketsPerElement);
+ }
+
+ function bits2words(numBits) {
+ return (((numBits-1)>>>6)+1);
+ }
+ }
+
/**
- * Encapsulates sizing data for a set of rows, having the samae number of columns and
+ * Encapsulates sizing data for a set of rows, having the same number of columns and
* each column being the same size.
*/
function RowInfo() {
@@ -124,6 +229,7 @@
schedules) {
var table = new Table(name);
table.data = calculateData(schedules, columnSize, rowKeySize, duration);
+ table.bloomFilter = new BloomFilter(5).size;
util.foreach(table.data.rows, function(interval) {
var rowInfo = table.data.rows[interval];
@@ -216,8 +322,8 @@
var rowKeyValueSize = 4;
var columnNameSize = 8;
- return calculateMetricsTableSize('raw_metrics', columnSize, rowKeySize,
rowKeyValueSize, columnNameSize, time.week,
- schedules);
+ return calculateMetricsTableSize('raw_metrics', columnSize, rowKeySize,
rowKeyValueSize, columnNameSize,
+ time.week, schedules);
};
/**
@@ -261,4 +367,9 @@
exports.sizeOf24HourMetrics = function(schedules) {
return calculateAggregatesTableSize('twenty_four_hour_metrics', time.day *
365, schedules);
};
+
+ // exposed for testing
+ exports.bloomFilter = function(keys) {
+ return new BloomFilter(keys).size;
+ }
})();
\ No newline at end of file
commit 2d3db381399b7dae1328e63be912ad8cc976b624
Author: John Sanda <jsanda(a)redhat.com>
Date: Wed Dec 11 17:03:35 2013 -0500
adding some usage docs
diff --git
a/modules/enterprise/remoting/cli/src/main/samples/modules/rhq.storage.sizing.js
b/modules/enterprise/remoting/cli/src/main/samples/modules/rhq.storage.sizing.js
index 77e78b7..77c22fd 100644
--- a/modules/enterprise/remoting/cli/src/main/samples/modules/rhq.storage.sizing.js
+++ b/modules/enterprise/remoting/cli/src/main/samples/modules/rhq.storage.sizing.js
@@ -5,6 +5,11 @@
* installs, some input, in terms of the numbers and types of resources, will have to be
provided in order to generate
* the estimates. Right now the module has functionality for generating the sizes of the
data and partition index files
* for the metrics tables (which does not include the metrics_index table).
+ *
+ * current usage (from CLI shell):
+ *
+ * $ storage = require('modules:/rhq.storage.sizing.js');
+ * $ results = storage.sizeOfRawMetrics({30000: 5, 60000: 5});
*/
(function() {
var util = require('modules:/util');
commit 059d79cb7dc66b343785a620f3e4dc11d0f654b5
Author: John Sanda <jsanda(a)redhat.com>
Date: Wed Dec 11 16:59:10 2013 -0500
initial commit for storage sizing CLI script
diff --git
a/modules/enterprise/remoting/cli/src/main/samples/modules/rhq.storage.sizing.js
b/modules/enterprise/remoting/cli/src/main/samples/modules/rhq.storage.sizing.js
index d185f56..77e78b7 100644
--- a/modules/enterprise/remoting/cli/src/main/samples/modules/rhq.storage.sizing.js
+++ b/modules/enterprise/remoting/cli/src/main/samples/modules/rhq.storage.sizing.js
@@ -5,11 +5,6 @@
* installs, some input, in terms of the numbers and types of resources, will have to be
provided in order to generate
* the estimates. Right now the module has functionality for generating the sizes of the
data and partition index files
* for the metrics tables (which does not include the metrics_index table).
- *
- * current usage (from CLI shell):
- *
- * $ storage = require('modules:/rhq.storage.sizing.js');
- * $ results = storage.sizeOfRawMetrics({30000: 5, 60000: 5});
*/
(function() {
var util = require('modules:/util');
@@ -24,113 +19,8 @@
var time = new Time();
- function BloomFilter(keys) {
- function BloomSpecification(k, bucketsPerElement) {
- this.K = k;
- this.bucketsPerElement = bucketsPerElement;
- }
-
- // This is taken directly from BloomCalculations.java
- this.probs = [
- [1.0], // dummy row representing 0 buckets per element
- [1.0, 1.0], // dummy row representing 1 buckets per element
- [1.0, 0.393, 0.400],
- [1.0, 0.283, 0.237, 0.253],
- [1.0, 0.221, 0.155, 0.147, 0.160],
- [1.0, 0.181, 0.109, 0.092, 0.092, 0.101], // 5
- [1.0, 0.154, 0.0804, 0.0609, 0.0561, 0.0578, 0.0638],
- [1.0, 0.133, 0.0618, 0.0423, 0.0359, 0.0347, 0.0364],
- [1.0, 0.118, 0.0489, 0.0306, 0.024, 0.0217, 0.0216, 0.0229],
- [1.0, 0.105, 0.0397, 0.0228, 0.0166, 0.0141, 0.0133, 0.0135, 0.0145],
- [1.0, 0.0952, 0.0329, 0.0174, 0.0118, 0.00943, 0.00844, 0.00819, 0.00846], //
10
- [1.0, 0.0869, 0.0276, 0.0136, 0.00864, 0.0065, 0.00552, 0.00513, 0.00509],
- [1.0, 0.08, 0.0236, 0.0108, 0.00646, 0.00459, 0.00371, 0.00329, 0.00314],
- [1.0, 0.074, 0.0203, 0.00875, 0.00492, 0.00332, 0.00255, 0.00217, 0.00199,
0.00194],
- [1.0, 0.0689, 0.0177, 0.00718, 0.00381, 0.00244, 0.00179, 0.00146, 0.00129,
0.00121, 0.0012],
- [1.0, 0.0645, 0.0156, 0.00596, 0.003, 0.00183, 0.00128, 0.001, 0.000852,
0.000775, 0.000744], // 15
- [1.0, 0.0606, 0.0138, 0.005, 0.00239, 0.00139, 0.000935, 0.000702, 0.000574,
0.000505, 0.00047, 0.000459],
- [1.0, 0.0571, 0.0123, 0.00423, 0.00193, 0.00107, 0.000692, 0.000499, 0.000394,
0.000335, 0.000302, 0.000287, 0.000284],
- [1.0, 0.054, 0.0111, 0.00362, 0.00158, 0.000839, 0.000519, 0.00036, 0.000275,
0.000226, 0.000198, 0.000183, 0.000176],
- [1.0, 0.0513, 0.00998, 0.00312, 0.0013, 0.000663, 0.000394, 0.000264, 0.000194,
0.000155, 0.000132, 0.000118, 0.000111, 0.000109],
- [1.0, 0.0488, 0.00906, 0.0027, 0.00108, 0.00053, 0.000303, 0.000196, 0.00014,
0.000108, 8.89e-05, 7.77e-05, 7.12e-05, 6.79e-05, 6.71e-05] // 20
- ]; // the first column is a dummy column representing K=0.
-
- var self = this;
- var excess = 20;
- var bitset_excess = 20;
- var minBuckets = 2;
- var minK = 1;
- var optKPerBuckets = [];
- var maxFalsePosProb = 0.01;
-
-
- for (i = 0; i < this.probs.length; i++) {
- var min = java.lang.Double.MAX_VALUE;
- var prob = this.probs[i];
- for (j = 0; j < prob.length; j++) {
- if (prob[j] < min) {
- min = prob[j];
- optKPerBuckets[i] = Math.max(minK, j);
- }
- }
- }
-
- var bucketsPerElement = maxBucketsPerElement(keys);
- var spec = computeBloomSpec(bucketsPerElement, maxFalsePosProb);
- var numBits = (keys * spec.bucketsPerElement) + bitset_excess;
- var wordCount = bits2words(numBits);
-
- if (wordCount > java.lang.Integer.MAX_VALUE) {
- throw "Bloom filter size is > 16GB, reduce the
bloom_filter_fp_chance";
- }
-
- var bytes = wordCount * 8;
- this.size = bytes + 8;
-
- function maxBucketsPerElement(numElements) {
- numElements = Math.max(1, numElements);
- var v = (java.lang.Long.MAX_VALUE - excess) / keys;
- if (v < 1) {
- throw "Cannot compute probabilities for " + numElements + "
elements.";
- }
- return Math.min(self.probs.length - 1, v);
- }
-
- // This is taken from BloomCalculations.java
- function computeBloomSpec(maxBucketsPerElement, maxFalsePosProb) {
- var maxK = self.probs[maxBucketsPerElement].length - 1;
-
- // Handle the trivial cases
- if(maxFalsePosProb >= self.probs[minBuckets][minK]) {
- return new BloomSpecification(2, optKPerBuckets[2]);
- }
- if (maxFalsePosProb < self.probs[maxBucketsPerElement][maxK]) {
- throw "Unable to satisfy " + maxFalsePosProb + " with " +
maxBucketsPerElement + " buckets per element";
- }
-
- // First find the minimal required number of buckets:
- var bucketsPerElement = 2;
- var K = optKPerBuckets[2];
- while(self.probs[bucketsPerElement][K] > maxFalsePosProb){
- bucketsPerElement++;
- K = optKPerBuckets[bucketsPerElement];
- }
- // Now that the number of buckets is sufficient, see if we can relax K
- // without losing too much precision.
- while(self.probs[bucketsPerElement][K - 1] <= maxFalsePosProb) {
- K--;
- }
- println('K = ' + K + ', bucketsPerElement = ' +
bucketsPerElement);
- return new BloomSpecification(K, bucketsPerElement);
- }
-
- function bits2words(numBits) {
- return (((numBits-1)>>>6)+1);
- }
- }
-
/**
- * Encapsulates sizing data for a set of rows, having the same number of columns and
+ * Encapsulates sizing data for a set of rows, having the samae number of columns and
* each column being the same size.
*/
function RowInfo() {
@@ -229,7 +119,6 @@
schedules) {
var table = new Table(name);
table.data = calculateData(schedules, columnSize, rowKeySize, duration);
- table.bloomFilter = new BloomFilter(5).size;
util.foreach(table.data.rows, function(interval) {
var rowInfo = table.data.rows[interval];
@@ -322,8 +211,8 @@
var rowKeyValueSize = 4;
var columnNameSize = 8;
- return calculateMetricsTableSize('raw_metrics', columnSize, rowKeySize,
rowKeyValueSize, columnNameSize,
- time.week, schedules);
+ return calculateMetricsTableSize('raw_metrics', columnSize, rowKeySize,
rowKeyValueSize, columnNameSize, time.week,
+ schedules);
};
/**
@@ -367,9 +256,4 @@
exports.sizeOf24HourMetrics = function(schedules) {
return calculateAggregatesTableSize('twenty_four_hour_metrics', time.day *
365, schedules);
};
-
- // exposed for testing
- exports.bloomFilter = function(keys) {
- return new BloomFilter(keys).size;
- }
})();
\ No newline at end of file
commit d7e1db17c8ab375a5369bf704891124bab449555
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Jan 2 10:50:02 2014 -0500
BZ 994250 - finish the merging/peer review for patches submitted so that rhqctl
returns proper exit codes. Note that this completes the merge of the two submitted patches
- see prior two commits to this one. This third commit fixes some problems with the
original patches: 1. Some scripts/files are not found in bin/internal of the distro, but
rather are in bin/ - so we need to avoid using getBinDir() in those cases 2. Fix the code
to conform to code conventions - DEATH TO TABS! 3. Remove a constant that got resurrected
(ControlCommand.RHQ_STORAGE_BASEDIR_PROP is no longer needed) 4. A couple other minor
things
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
index 5db80a1..a13a598 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
@@ -60,7 +60,6 @@ public abstract class ControlCommand {
public static final String SERVER_OPTION = "server";
public static final String STORAGE_OPTION = "storage";
public static final String AGENT_OPTION = "agent";
- public static final String RHQ_STORAGE_BASEDIR_PROP =
"rhq.storage.basedir";
public static final String RHQ_AGENT_BASEDIR_PROP = "rhq.agent.basedir";
protected static final String STORAGE_BASEDIR_NAME = "rhq-storage";
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
index 28a37de..88b085f 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
@@ -135,7 +135,7 @@ public class RHQControl {
} catch (Throwable t) {
log.warn("Failed to clean up after the failed installation attempt.
"
+ "You may have to clean up some things before attempting to
install again", t);
- rValue = EXIT_CODE_OPERATION_FAILED;
+ rValue = EXIT_CODE_OPERATION_FAILED;
}
}
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
index 1b3d47b..ed2b2f8 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
@@ -88,14 +88,14 @@ public abstract class AbstractInstall extends ControlCommand {
executor.setStreamHandler(new PumpStreamHandler());
org.apache.commons.exec.CommandLine commandLine;
- int rValue = RHQControl.EXIT_CODE_OK;
+ int rValue = RHQControl.EXIT_CODE_OK;
if (replaceExistingService) {
- commandLine = getCommandLine(batFile, "stop");
- rValue = Math.max(rValue, executor.execute(commandLine));
+ commandLine = getCommandLine(batFile, "stop");
+ rValue = Math.max(rValue, executor.execute(commandLine));
- commandLine = getCommandLine(batFile, "remove");
- rValue = Math.max(rValue, executor.execute(commandLine));
+ commandLine = getCommandLine(batFile, "remove");
+ rValue = Math.max(rValue, executor.execute(commandLine));
}
commandLine = getCommandLine(batFile, "install");
@@ -277,7 +277,7 @@ public abstract class AbstractInstall extends ControlCommand {
return RHQControl.EXIT_CODE_OK;
}
- int rValue = 0;
+ int rValue = 0;
try {
File agentBinDir = new File(agentBasedir, "bin");
@@ -317,7 +317,7 @@ public abstract class AbstractInstall extends ControlCommand {
throw e;
}
- return rValue;
+ return rValue;
}
protected int startAgent(final File agentBasedir) throws Exception {
@@ -366,7 +366,7 @@ public abstract class AbstractInstall extends ControlCommand {
Executor executor = new DefaultExecutor();
executor.setWorkingDirectory(agentBinDir);
executor.setStreamHandler(new PumpStreamHandler());
- org.apache.commons.exec.CommandLine commandLine =
getCommandLine("rhq-agent-wrapper", "stop");
+ org.apache.commons.exec.CommandLine commandLine;
int rValue = 0;
@@ -635,7 +635,7 @@ public abstract class AbstractInstall extends ControlCommand {
clearAgentPreferences();
int rValue = installAgent(agentBasedir);
configureAgent(agentBasedir, commandLine);
- return rValue;
+ return rValue;
}
private int installAgent(final File agentBasedir) throws IOException {
@@ -667,7 +667,7 @@ public abstract class AbstractInstall extends ControlCommand {
int exitValue = executor.execute(commandLine);
log.info("The agent installer finished running with exit value " +
exitValue);
- return exitValue;
+ return exitValue;
} catch (IOException e) {
log.error("An error occurred while running the agent installer: " +
e.getMessage());
throw e;
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
index 5d540a1..e2ef3a8 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
@@ -138,7 +138,7 @@ public class Start extends ControlCommand {
executor.setStreamHandler(new PumpStreamHandler());
org.apache.commons.exec.CommandLine commandLine;
- int rValue;
+ int rValue;
// Cassandra looks for JAVA_HOME or then defaults to PATH. We want it to use the
Java
// defined for RHQ, so make sure JAVA_HOME is set, and set to the RHQ Java for
the executor
@@ -167,7 +167,7 @@ public class Start extends ControlCommand {
// For now we are duplicating logic in the status command. This code will be
// replaced when we implement a rhq-storage.sh script.
if (isStorageRunning()) {
- String pid = getStoragePid();
+ String pid = getStoragePid();
System.out.println("RHQ storage node (pid " + pid + ") is
running");
rValue = RHQControl.EXIT_CODE_OK;
} else {
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
index a3920e0..7ef66b4 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
@@ -144,7 +144,7 @@ public class Stop extends AbstractInstall {
rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
}
} else {
- if(isStorageRunning()) {
+ if (isStorageRunning()) {
String pid = getStoragePid();
System.out.println("Stopping RHQ storage node...");
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
index cc3d8c2..e80edd9 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
@@ -186,7 +186,7 @@ public class Upgrade extends AbstractInstall {
return exitValue;
}
- // If any failures occur during upgrade, we know we need to reset
rhq-server.properties.
+ // If any failures occur during upgrade, we know we need to reset
rhq-server.properties.
final FileReverter serverPropFileReverter = new
FileReverter(getServerPropertiesFile());
addUndoTask(new ControlCommand.UndoTask("Reverting server properties
file") {
public void performUndoWork() throws Exception {
@@ -229,7 +229,7 @@ public class Upgrade extends AbstractInstall {
}
} catch (Throwable t) {
log.warn("Unable to stop services: " + t.getMessage());
- rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
+ rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
}
}
@@ -262,7 +262,7 @@ public class Upgrade extends AbstractInstall {
}
Executor executor = new DefaultExecutor();
- executor.setWorkingDirectory(getBinDir());
+ executor.setWorkingDirectory(new File(getBaseDir(), "bin")); //
data migrator script is not in bin/internal
executor.setStreamHandler(new PumpStreamHandler());
int exitValue = executor.execute(commandLine);
@@ -546,7 +546,7 @@ public class Upgrade extends AbstractInstall {
}
// now merge the old settings in with the default properties from the new server
install
- String newServerPropsFilePath = new File(getBinDir(),
"rhq-server.properties").getAbsolutePath();
+ String newServerPropsFilePath = new File(getBaseDir(),
"bin/rhq-server.properties").getAbsolutePath();
PropertiesFileUpdate newServerPropsFile = new
PropertiesFileUpdate(newServerPropsFilePath);
newServerPropsFile.update(oldServerProps);
commit 005a2ac4e16f1ea57db5172cd7c2f2fda2bde30e
Author: burmanm <yak(a)iki.fi>
Date: Tue Aug 6 17:52:38 2013 +0200
Fix return codes of the rhqctl command, rebased to the 4.10 master.
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
index a13a598..5db80a1 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
@@ -60,6 +60,7 @@ public abstract class ControlCommand {
public static final String SERVER_OPTION = "server";
public static final String STORAGE_OPTION = "storage";
public static final String AGENT_OPTION = "agent";
+ public static final String RHQ_STORAGE_BASEDIR_PROP =
"rhq.storage.basedir";
public static final String RHQ_AGENT_BASEDIR_PROP = "rhq.agent.basedir";
protected static final String STORAGE_BASEDIR_NAME = "rhq-storage";
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
index 88b085f..28a37de 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
@@ -135,7 +135,7 @@ public class RHQControl {
} catch (Throwable t) {
log.warn("Failed to clean up after the failed installation attempt.
"
+ "You may have to clean up some things before attempting to
install again", t);
- rValue = EXIT_CODE_OPERATION_FAILED;
+ rValue = EXIT_CODE_OPERATION_FAILED;
}
}
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
index ed2b2f8..1b3d47b 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
@@ -88,14 +88,14 @@ public abstract class AbstractInstall extends ControlCommand {
executor.setStreamHandler(new PumpStreamHandler());
org.apache.commons.exec.CommandLine commandLine;
- int rValue = RHQControl.EXIT_CODE_OK;
+ int rValue = RHQControl.EXIT_CODE_OK;
if (replaceExistingService) {
- commandLine = getCommandLine(batFile, "stop");
- rValue = Math.max(rValue, executor.execute(commandLine));
+ commandLine = getCommandLine(batFile, "stop");
+ rValue = Math.max(rValue, executor.execute(commandLine));
- commandLine = getCommandLine(batFile, "remove");
- rValue = Math.max(rValue, executor.execute(commandLine));
+ commandLine = getCommandLine(batFile, "remove");
+ rValue = Math.max(rValue, executor.execute(commandLine));
}
commandLine = getCommandLine(batFile, "install");
@@ -277,7 +277,7 @@ public abstract class AbstractInstall extends ControlCommand {
return RHQControl.EXIT_CODE_OK;
}
- int rValue = 0;
+ int rValue = 0;
try {
File agentBinDir = new File(agentBasedir, "bin");
@@ -317,7 +317,7 @@ public abstract class AbstractInstall extends ControlCommand {
throw e;
}
- return rValue;
+ return rValue;
}
protected int startAgent(final File agentBasedir) throws Exception {
@@ -366,7 +366,7 @@ public abstract class AbstractInstall extends ControlCommand {
Executor executor = new DefaultExecutor();
executor.setWorkingDirectory(agentBinDir);
executor.setStreamHandler(new PumpStreamHandler());
- org.apache.commons.exec.CommandLine commandLine;
+ org.apache.commons.exec.CommandLine commandLine =
getCommandLine("rhq-agent-wrapper", "stop");
int rValue = 0;
@@ -635,7 +635,7 @@ public abstract class AbstractInstall extends ControlCommand {
clearAgentPreferences();
int rValue = installAgent(agentBasedir);
configureAgent(agentBasedir, commandLine);
- return rValue;
+ return rValue;
}
private int installAgent(final File agentBasedir) throws IOException {
@@ -667,7 +667,7 @@ public abstract class AbstractInstall extends ControlCommand {
int exitValue = executor.execute(commandLine);
log.info("The agent installer finished running with exit value " +
exitValue);
- return exitValue;
+ return exitValue;
} catch (IOException e) {
log.error("An error occurred while running the agent installer: " +
e.getMessage());
throw e;
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
index e2ef3a8..5d540a1 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
@@ -138,7 +138,7 @@ public class Start extends ControlCommand {
executor.setStreamHandler(new PumpStreamHandler());
org.apache.commons.exec.CommandLine commandLine;
- int rValue;
+ int rValue;
// Cassandra looks for JAVA_HOME or then defaults to PATH. We want it to use the
Java
// defined for RHQ, so make sure JAVA_HOME is set, and set to the RHQ Java for
the executor
@@ -167,7 +167,7 @@ public class Start extends ControlCommand {
// For now we are duplicating logic in the status command. This code will be
// replaced when we implement a rhq-storage.sh script.
if (isStorageRunning()) {
- String pid = getStoragePid();
+ String pid = getStoragePid();
System.out.println("RHQ storage node (pid " + pid + ") is
running");
rValue = RHQControl.EXIT_CODE_OK;
} else {
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
index 7ef66b4..a3920e0 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
@@ -144,7 +144,7 @@ public class Stop extends AbstractInstall {
rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
}
} else {
- if (isStorageRunning()) {
+ if(isStorageRunning()) {
String pid = getStoragePid();
System.out.println("Stopping RHQ storage node...");
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
index e80edd9..cc3d8c2 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
@@ -186,7 +186,7 @@ public class Upgrade extends AbstractInstall {
return exitValue;
}
- // If any failures occur during upgrade, we know we need to reset
rhq-server.properties.
+ // If any failures occur during upgrade, we know we need to reset
rhq-server.properties.
final FileReverter serverPropFileReverter = new
FileReverter(getServerPropertiesFile());
addUndoTask(new ControlCommand.UndoTask("Reverting server properties
file") {
public void performUndoWork() throws Exception {
@@ -229,7 +229,7 @@ public class Upgrade extends AbstractInstall {
}
} catch (Throwable t) {
log.warn("Unable to stop services: " + t.getMessage());
- rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
+ rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
}
}
@@ -262,7 +262,7 @@ public class Upgrade extends AbstractInstall {
}
Executor executor = new DefaultExecutor();
- executor.setWorkingDirectory(new File(getBaseDir(), "bin")); //
data migrator script is not in bin/internal
+ executor.setWorkingDirectory(getBinDir());
executor.setStreamHandler(new PumpStreamHandler());
int exitValue = executor.execute(commandLine);
@@ -546,7 +546,7 @@ public class Upgrade extends AbstractInstall {
}
// now merge the old settings in with the default properties from the new server
install
- String newServerPropsFilePath = new File(getBaseDir(),
"bin/rhq-server.properties").getAbsolutePath();
+ String newServerPropsFilePath = new File(getBinDir(),
"rhq-server.properties").getAbsolutePath();
PropertiesFileUpdate newServerPropsFile = new
PropertiesFileUpdate(newServerPropsFilePath);
newServerPropsFile.update(oldServerProps);
commit 964dfe9331a111394acea159433635fb2378ddce
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Tue Dec 17 21:35:47 2013 +0100
Bug 968361 - Improve database plugin design to support connection pooling
This changeset introduces a new API for database plugins and deprecates the previous
one. Compatibility with the previous API will be maintained until next major version of
RHQ.
The 'rhq-database-plugin' was based on
org.rhq.plugins.database.DatabaseComponent interface which encouraged plugin authors to
share a single JDBC connection across database components. This was wrong for various
reasons (connection leaks, concurrent JDBC calls... etc).
The new API introduces three important classes:
* org.rhq.plugins.database.PooledConnectionProvider
* org.rhq.plugins.database.BasePooledConnectionProvider
* org.rhq.plugins.database.ConnectionPoolingSupport
BasePooledConnectionProvider is a base implementation of a PooledConnectionProvider.
Plugin authors should create a concrete implementation of BasePooledConnectionProvider
which overrides the #getDriverClass() method. This is important if a database plugin
embeds a JDBC driver: the database-specific driver class must be loaded by the child
plugin classloader.
ConnectionPoolingSupport helps to manage the compatibility with the old API. It's
a contract that all new database resource components should obey to. It declares the
following methods:
* #supportsConnectionPooling()
* #getPooledConnectionProvider()
Results of calls to #supportsConnectionPooling() #getPooledConnectionProvider() must
be consistent. In practice, a top level server database component should be able to create
a PooledConnectionProvider instance, and child servers and services should indicate they
support connection pooling only if their parent component does.
The 'rhq-database-plugin' embeds the BoneCP library (JDBC connection pooling)
and its dependencies (Google's Guava). Child plugins will have all the classes
accessible as soon as they have this node in their plugin descriptor:
===
<depends plugin="Database" useClasses="true"/>
===
This changeset includes the necessary changes to support connection pooling in the
Oracle, Postgres and MySQL plugins.
Thanks to Elias Ross for contributing the original patch from which this changeset is
derived.
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/install/remote/RemoteAccessInfo.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/install/remote/RemoteAccessInfo.java
deleted file mode 100644
index b2ab566..0000000
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/install/remote/RemoteAccessInfo.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
- * All rights reserved.
- *
- * This program 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 version 2 of the License.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.rhq.core.domain.install.remote;
-
-import java.io.Serializable;
-
-/**
- * @author Greg Hinkle
- */
-public class RemoteAccessInfo implements Serializable {
- private static final long serialVersionUID = 1L;
-
- private String host;
- private String user;
- private String password;
- private byte[] key;
- private int port = 22;
-
- public RemoteAccessInfo(String host, String user, byte[] key) {
- this.host = host;
- this.user = user;
- this.key = key;
- }
-
- public RemoteAccessInfo(String host, String user, String password) {
- this(host, 22, user, password);
- }
-
- public RemoteAccessInfo(String host, int port, String user, String password) {
- this.host = host;
- this.port = port;
- this.user = user;
- this.password = password;
- }
-
- public RemoteAccessInfo() {
- }
-
- public String getHost() {
- return host;
- }
-
- public void setHost(String host) {
- this.host = host;
- }
-
- public int getPort() {
- return port;
- }
-
- public void setPort(int port) {
- this.port = port;
- }
-
- public String getUser() {
- return user;
- }
-
- public void setUser(String user) {
- this.user = user;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- public byte[] getKey() {
- return key;
- }
-
- public void setKey(byte[] key) {
- this.key = key;
- }
-}
diff --git
a/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
b/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
deleted file mode 100644
index 6c81332..0000000
---
a/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
- * All rights reserved.
- *
- * This program 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 version 2 of the License.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-package org.rhq.plugins.mysql;
-
-import java.sql.Connection;
-import java.sql.Driver;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.util.HashMap;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * A class to manage the connections to MySQL
- * This class keeps a cache of connections to MySQL and reuses them on demand
- * We assume single threaded access to the Connection in the agent
- * this will need to be reworked if that assumption is not correct
- * @author Steve Millidge (C2B2 Consulting Limited)
- */
-class MySqlConnectionManager {
-
- private HashMap<MySqlConnectionInfo, Connection> connections;
- private static MySqlConnectionManager singleton;
- private Log logger = LogFactory.getLog(MySqlConnectionManager.class);
-
- private MySqlConnectionManager() {
- connections = new HashMap<MySqlConnectionInfo,Connection>();
- }
-
- static MySqlConnectionManager getConnectionManager() {
- if (singleton == null) {
- singleton = new MySqlConnectionManager();
- }
- return singleton;
- }
-
- public void shutdown() {
- Driver driver = null;
- for (Connection conn : connections.values()) {
- try {
- if (driver == null) {
- String driverName = conn.getMetaData().getDriverName();
- driver = DriverManager.getDriver(driverName);
- }
- conn.close();
- }catch(SQLException e) { logger.info("Problem closing connection on
Shutdown ignoring...");}
- }
- // deregister driver as well
- if (driver != null) {
- try {
- DriverManager.deregisterDriver(driver);
- } catch (SQLException ex) {
- logger.warn("Unable to deregister MySQL Driver on shutdown");
- }
- }
- }
-
- void closeConnection(MySqlConnectionInfo info) {
- Connection conn = connections.get(info);
- if (conn != null) {
- try {
- if (logger.isDebugEnabled()) {
- logger.debug("Closing Connection to " + info.buildURL());
- }
- conn.close();
- } catch (SQLException e) {
- logger.warn("Problem closing connection to " + info.buildURL()
+ " on close");
- }
- }
- connections.remove(info);
- }
-
- Connection getConnection (MySqlConnectionInfo info) throws SQLException {
- try {
- Class.forName("com.mysql.jdbc.Driver");
- } catch (Exception ex) {
- logger.error("Unable to find com.mysql.jdbc.Driver");
- }
-
- Connection conn = connections.get(info);
- String url = info.buildURL();
- if (conn == null) {
- if (logger.isInfoEnabled()) {
- logger.info("Attemping connection to " + url);
- }
- conn = DriverManager.getConnection(url,info.getUser(), info.getPassword());
- if (logger.isInfoEnabled()) {
- logger.info("Successfully connected to " + url);
- }
- connections.put(info, conn);
- } else {
- if (logger.isDebugEnabled()) {
- logger.debug("Reusing existing connection to " + url);
- }
- }
-
- // check the validity of the connection
- if (!conn.isValid(0)) {
- // attempt a single reconnect here and now
- conn.close();
- conn = DriverManager.getConnection(url,info.getUser(), info.getPassword());
- connections.put(info, conn);
- logger.info("Refreshed a connection to " + url);
- }
- return conn;
- }
-
-}
commit 3e115204a92a25e133016df93afb444d78cd933a
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Mon Dec 23 14:50:55 2013 +0100
Plugin validation for mysql plugin was failing because the Class.forName() statement
was invoked from the constructor of the component. I moved this code to the method that
actually opens the connection. This is the same strategy we use with our postgres plugin.
diff --git
a/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
b/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
new file mode 100644
index 0000000..6c81332
--- /dev/null
+++
b/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
@@ -0,0 +1,125 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program 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 version 2 of the License.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.plugins.mysql;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.HashMap;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * A class to manage the connections to MySQL
+ * This class keeps a cache of connections to MySQL and reuses them on demand
+ * We assume single threaded access to the Connection in the agent
+ * this will need to be reworked if that assumption is not correct
+ * @author Steve Millidge (C2B2 Consulting Limited)
+ */
+class MySqlConnectionManager {
+
+ private HashMap<MySqlConnectionInfo, Connection> connections;
+ private static MySqlConnectionManager singleton;
+ private Log logger = LogFactory.getLog(MySqlConnectionManager.class);
+
+ private MySqlConnectionManager() {
+ connections = new HashMap<MySqlConnectionInfo,Connection>();
+ }
+
+ static MySqlConnectionManager getConnectionManager() {
+ if (singleton == null) {
+ singleton = new MySqlConnectionManager();
+ }
+ return singleton;
+ }
+
+ public void shutdown() {
+ Driver driver = null;
+ for (Connection conn : connections.values()) {
+ try {
+ if (driver == null) {
+ String driverName = conn.getMetaData().getDriverName();
+ driver = DriverManager.getDriver(driverName);
+ }
+ conn.close();
+ }catch(SQLException e) { logger.info("Problem closing connection on
Shutdown ignoring...");}
+ }
+ // deregister driver as well
+ if (driver != null) {
+ try {
+ DriverManager.deregisterDriver(driver);
+ } catch (SQLException ex) {
+ logger.warn("Unable to deregister MySQL Driver on shutdown");
+ }
+ }
+ }
+
+ void closeConnection(MySqlConnectionInfo info) {
+ Connection conn = connections.get(info);
+ if (conn != null) {
+ try {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Closing Connection to " + info.buildURL());
+ }
+ conn.close();
+ } catch (SQLException e) {
+ logger.warn("Problem closing connection to " + info.buildURL()
+ " on close");
+ }
+ }
+ connections.remove(info);
+ }
+
+ Connection getConnection (MySqlConnectionInfo info) throws SQLException {
+ try {
+ Class.forName("com.mysql.jdbc.Driver");
+ } catch (Exception ex) {
+ logger.error("Unable to find com.mysql.jdbc.Driver");
+ }
+
+ Connection conn = connections.get(info);
+ String url = info.buildURL();
+ if (conn == null) {
+ if (logger.isInfoEnabled()) {
+ logger.info("Attemping connection to " + url);
+ }
+ conn = DriverManager.getConnection(url,info.getUser(), info.getPassword());
+ if (logger.isInfoEnabled()) {
+ logger.info("Successfully connected to " + url);
+ }
+ connections.put(info, conn);
+ } else {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Reusing existing connection to " + url);
+ }
+ }
+
+ // check the validity of the connection
+ if (!conn.isValid(0)) {
+ // attempt a single reconnect here and now
+ conn.close();
+ conn = DriverManager.getConnection(url,info.getUser(), info.getPassword());
+ connections.put(info, conn);
+ logger.info("Refreshed a connection to " + url);
+ }
+ return conn;
+ }
+
+}
commit bd89436f6e6b5db574a32ffd6636e13e1d702d54
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Dec 19 14:03:24 2013 -0500
Add a little more logging to get a better start/end of a sync.
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index 24dcb44..6bdbede 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1228,10 +1228,12 @@ public class InventoryManager extends AgentService implements
ContainerService,
Collection<ResourceSyncInfo> syncInfos = platformSyncInfo.getServices();
syncInfos.add(platformResourceSyncInfo);
- log.info("Sync Starting: Platform [" +
platformSyncInfo.getPlatform().getId() + "] and top level services.");
+ log.info("Sync Starting: Platform [" +
platformSyncInfo.getPlatform().getId() + "]");
+
+ log.info("Sync Starting: Platform Top level services [" +
platformSyncInfo.getPlatform().getId() + "]");
hadSyncedResources = syncResources(platformResourceSyncInfo.getId(), syncInfos)
|| hadSyncedResources;
- log.info("Sync Complete: Platform [" +
platformSyncInfo.getPlatform().getId() + "]. Local inventory changed: ["
- + hadSyncedResources + "]");
+ log.info("Sync Complete: Platform Top level services [" +
platformSyncInfo.getPlatform().getId()
+ + "] Local inventory changed: [" + hadSyncedResources +
"]");
syncInfos = null; // release to GC
@@ -1257,6 +1259,8 @@ public class InventoryManager extends AgentService implements
ContainerService,
purgeObsoleteResources(allServerSideUuids);
+ log.info("Sync Complete: Platform [" +
platformSyncInfo.getPlatform().getId() + "].");
+
// If we synced any Resources, one or more Resource components were probably
started, request a
// full avail report to make sure their availabilities are determined on the next
avail run (typically
// < 30s away). A full avail report will ensure an initial avail check is
performed for a resource.
@@ -1271,6 +1275,9 @@ public class InventoryManager extends AgentService implements
ContainerService,
// time the upgrade kicks in..
if (hadSyncedResources && !isResourceUpgradeActive()) {
+ log.info("Sync changes detected, requesting full availability report and
service discovery: Platform ["
+ + platformSyncInfo.getPlatform().getId() + "]");
+
// TODO: If someday this is undesirable for scalability reasons, we could
probably instead call
// requestAvailabilityCheck on each unknown or modified resource.
requestFullAvailabilityReport();
commit ad9e7671b663f622cee1dac8e3e0113fe838743f
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Dec 18 09:28:48 2013 -0500
[1023451] [perf] Large retained heap during inventory report merge (causing OOMs)
Note - this is related work, not necessarily a solution to this problem.
This commit builds on the "chunking" work introduced earlier. This work
replaces the tree structure, previously used to pass sync info between
agent and server, with flat collections. This allows us to replace the
costly Hibernate-based tree building approach with more comprehensive queries
that reduce the number of DB round trips dramatically.
Notes:
- This commit fixed an issue with the previous work regarding the handling
of top level services.
- The ResourceSyncInfo class is now even lighter weight, parent-child info is
removed.
- PlatformSyncInfo is now a POJO.
- The handling of unknown resources (agent side) changed significantly
because it had depended on the previous tree structure.
- mocks again had to be updated
diff --git
a/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
b/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
index 74a0acc..60f61c1 100644
---
a/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
+++
b/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
@@ -19,7 +19,6 @@
package org.rhq.test.arquillian;
-import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -248,10 +247,10 @@ public class FakeServerInventory {
};
}
- public synchronized Answer<ResourceSyncInfo> getResourceSyncInfo() {
- return new Answer<ResourceSyncInfo>() {
+ public synchronized Answer<Collection<ResourceSyncInfo>>
getResourceSyncInfo() {
+ return new Answer<Collection<ResourceSyncInfo>>() {
@Override
- public ResourceSyncInfo answer(InvocationOnMock invocation) throws Throwable
{
+ public Collection<ResourceSyncInfo> answer(InvocationOnMock invocation)
throws Throwable {
synchronized (FakeServerInventory.this) {
Integer resourceId = (Integer) invocation.getArguments()[0];
@@ -622,37 +621,29 @@ public class FakeServerInventory {
return platform == null ? null :
PlatformSyncInfo.buildPlatformSyncInfo(platform);
}
- private ResourceSyncInfo getResourceSyncInfo(Resource resource) {
+ private Collection<ResourceSyncInfo> getResourceSyncInfo(Resource resource) {
return resource == null ? null : convert(resource);
}
- private static ResourceSyncInfo convert(Resource root) {
- return convertInternal(root, true, new HashMap<String,
ResourceSyncInfo>());
+ private static Collection<ResourceSyncInfo> convert(Resource root) {
+ Set<ResourceSyncInfo> result = new HashSet<ResourceSyncInfo>();
+ convertInternal(root, result);
+ return result;
}
- private static ResourceSyncInfo convertInternal(Resource root, boolean
isTopLevelServer,
- Map<String, ResourceSyncInfo> intermediateResults) {
+ private static void convertInternal(Resource root, Collection<ResourceSyncInfo>
result) {
- ResourceSyncInfo ret = intermediateResults.get(root.getUuid());
+ ResourceSyncInfo rootSyncInfo = ResourceSyncInfo.buildResourceSyncInfo(root);
- if (ret != null) {
- return ret;
+ if (result.contains(rootSyncInfo)) {
+ return;
}
try {
- ret = ResourceSyncInfo.buildResourceSyncInfo(root);
- intermediateResults.put(root.getUuid(), ret);
+ result.add(rootSyncInfo);
- Integer parentId = root.getParentResource() == null ? null :
root.getParentResource().getId();
- getPrivateField(ResourceSyncInfo.class, "parentId").set(ret,
parentId);
-
- Set<ResourceSyncInfo> children = new
LinkedHashSet<ResourceSyncInfo>();
for (Resource child : root.getChildResources()) {
- ResourceSyncInfo syncChild = convertInternal(child, false,
intermediateResults);
-
- children.add(syncChild);
+ convertInternal(child, result);
}
- getPrivateField(ResourceSyncInfo.class, "childSyncInfos").set(ret,
children);
- return ret;
} catch (Exception e) {
throw new IllegalStateException("Failed to convert resource " +
root
@@ -660,15 +651,6 @@ public class FakeServerInventory {
}
}
- private static Field getPrivateField(Class<?> clazz, String fieldName) throws
NoSuchFieldException {
- Field field = clazz.getDeclaredField(fieldName);
- if (!field.isAccessible()) {
- field.setAccessible(true);
- }
-
- return field;
- }
-
private void throwIfFailing() {
if (failing) {
throw new RuntimeException("Fake server inventory is in the failing
mode.");
diff --git
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/discovery/DiscoveryAgentService.java
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/discovery/DiscoveryAgentService.java
index e3313f0..4c2a821 100644
---
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/discovery/DiscoveryAgentService.java
+++
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/discovery/DiscoveryAgentService.java
@@ -22,6 +22,8 @@
*/
package org.rhq.core.clientapi.agent.discovery;
+import java.util.Collection;
+
import org.jetbrains.annotations.NotNull;
import org.rhq.core.clientapi.agent.PluginContainerException;
@@ -29,8 +31,8 @@ import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.discovery.AvailabilityReport;
import org.rhq.core.domain.discovery.MergeResourceResponse;
+import org.rhq.core.domain.discovery.PlatformSyncInfo;
import org.rhq.core.domain.discovery.ResourceSyncInfo;
-import org.rhq.core.domain.measurement.Availability;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceError;
@@ -56,11 +58,20 @@ public interface DiscoveryAgentService {
throws InvalidPluginConfigurationClientException, PluginContainerException;
/**
- * Called to inform the agent of a status change for the resource represented by
syncInfo. The agent processes the syncInfo for the resource and initiates a status update
for its sub-tree.
+ * Called by the server when requesting a full platform sync. The provided info will
guide the subsequent
+ * agent-initiated sync.
+ *
+ * @param syncInfo for the platform to be synchronized with the server.
+ */
+ void synchronizePlatform(PlatformSyncInfo syncInfo);
+
+ /**
+ * Called by the server to update the agent with changed for specified top level
server. The agent will
+ * synchronize its inventory for the server and its subtree given the provided
information.
*
- * @param syncInfo for the root of the tree to be updated.
+ * @param syncInfo for the top level server to be synchronized with the server.
*/
- void synchronizeInventory(ResourceSyncInfo syncInfo);
+ void synchronizeServer(int resourceId, Collection<ResourceSyncInfo>
toplevelServerSyncInfo);
/**
* Access to the current inventory managed by the plugin container.
diff --git
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
index df2a286..4280305 100644
---
a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
+++
b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/discovery/DiscoveryServerService.java
@@ -22,6 +22,7 @@
*/
package org.rhq.core.clientapi.server.discovery;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -73,7 +74,7 @@ public interface DiscoveryServerService {
@LimitedConcurrency(CONCURRENCY_LIMIT_INVENTORY_REPORT)
@Timeout(0L)
// should be something like 1000L * 60 * 30 but until we can be assured we never take
longer, disable timeout
- ResourceSyncInfo getResourceSyncInfo(int resourceId);
+ Collection<ResourceSyncInfo> getResourceSyncInfo(int resourceId);
/**
* Merges a new availability report from the agent into the server. This updates the
availability statuses of known
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/PlatformSyncInfo.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/PlatformSyncInfo.java
index 951f542..3d989f3 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/PlatformSyncInfo.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/PlatformSyncInfo.java
@@ -23,52 +23,69 @@
package org.rhq.core.domain.discovery;
import java.io.Serializable;
-import java.util.Collection;
-import java.util.Collections;
+import java.util.HashSet;
import java.util.Set;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.OneToMany;
-import javax.persistence.Table;
-
-import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceCategory;
/**
- * @author Ian Springer
+ * This immutable POJO returns the information necessary for the agent to perform a
complete sync with the server
+ * inventory. It does not provide *all* of the sync info, only the platform and its top
level *service* hierarchy. It
+ * expects the agent to call back to the server for each of the platform's top level
servers and therefore provides
+ * only the top level server Ids.
+ *
* @author Jay Shaughnessy
*/
-@Entity
-@Table(name = "RHQ_RESOURCE")
-public class PlatformSyncInfo extends SyncInfo implements Serializable {
+public class PlatformSyncInfo implements Serializable {
private static final long serialVersionUID = 1L;
- @OneToMany(mappedBy = "parentResource", fetch = FetchType.EAGER)
- private Set<Resource> topLevelServers;
+ private ResourceSyncInfo platform;
+ private Set<ResourceSyncInfo> services;
+ private Set<Integer> topLevelServerIds;
+
+ public PlatformSyncInfo(ResourceSyncInfo platform, Set<ResourceSyncInfo>
services, Set<Integer> topLevelServerIds) {
+ super();
+ this.platform = platform;
+ this.services = services;
+ this.topLevelServerIds = topLevelServerIds;
+ }
+
+ /**
+ * @return just the platform sync info
+ */
+ public ResourceSyncInfo getPlatform() {
+ return platform;
+ }
- // JPA requires public or protected no-param constructor; Externalizable requires
public no-param constructor.
- public PlatformSyncInfo() {
+ /**
+ * @return the sync info for the platform hierarchy excluding the platform itself and
the top level servers
+ */
+ public Set<ResourceSyncInfo> getServices() {
+ return services;
}
- public Collection<Resource> getTopLevelServers() {
- return topLevelServers;
+ /**
+ * @return just the type level server ids, so that the agent can call back for sync
info on each top level server
+ */
+ public Set<Integer> getTopLevelServerIds() {
+ return topLevelServerIds;
}
// for testing
public static PlatformSyncInfo buildPlatformSyncInfo(Resource platform) {
- Set<Resource> toplevelServers = platform.getChildResources();
+ Set<Integer> toplevelServerIds = new HashSet<Integer>();
+ for (Resource r : platform.getChildResources()) {
+ if (r.getResourceType().getCategory().equals(ResourceCategory.SERVER)) {
+ toplevelServerIds.add(r.getId());
+ }
+ }
- PlatformSyncInfo syncInfo = new PlatformSyncInfo(platform.getId(),
platform.getUuid(), platform.getMtime(),
- platform.getInventoryStatus(), (null == toplevelServers ?
Collections.EMPTY_SET : toplevelServers));
+ ResourceSyncInfo resSyncInfo = ResourceSyncInfo.buildResourceSyncInfo(platform);
- return syncInfo;
- }
+ PlatformSyncInfo syncInfo = new PlatformSyncInfo(resSyncInfo, new
HashSet<ResourceSyncInfo>(1),
+ toplevelServerIds);
- // for testing
- private PlatformSyncInfo(int id, String uuid, long mtime, InventoryStatus istatus,
Set<Resource> children) {
- super(id, uuid, mtime, istatus);
- this.topLevelServers = children;
+ return syncInfo;
}
-
}
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/ResourceSyncInfo.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/ResourceSyncInfo.java
index e9cb222..b1fb366 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/ResourceSyncInfo.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/ResourceSyncInfo.java
@@ -23,85 +23,131 @@
package org.rhq.core.domain.discovery;
import java.io.Serializable;
-import java.util.Collection;
-import java.util.HashSet;
import javax.persistence.Column;
import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.OneToMany;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
import javax.persistence.Table;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
/**
- * Sync info for any non-platform resource.
+ * Sync info for a resource. This is a lightweight "Resource" entity that
contains only the information required
+ * to perform Inventory Sync between the Agent and Server.
*
- * @author Ian Springer
* @author Jay Shaughnessy
*/
@Entity
+@NamedQueries({
+ @NamedQuery(name = ResourceSyncInfo.QUERY_SERVICE_CHILDREN, query = "" //
+ + "SELECT r " //
+ + " FROM ResourceSyncInfo r " //
+ + " WHERE r.id IN ( SELECT rr.id FROM Resource rr WHERE rr.parentResource.id
IN ( :parentIds )) " //
+ + ""),
+ @NamedQuery(name = ResourceSyncInfo.QUERY_TOP_LEVEL_SERVER, query = "" //
+ + "SELECT rsi " //
+ + " FROM ResourceSyncInfo rsi " //
+ + " WHERE rsi.id = :resourceId " //
+ + " OR rsi.id IN (SELECT rr.id FROM Resource rr WHERE
rr.parentResource.id = :resourceId) "
+ + " OR rsi.id IN (SELECT rr.id FROM Resource rr WHERE
rr.parentResource.parentResource.id = :resourceId) "
+ + " OR rsi.id IN (SELECT rr.id FROM Resource rr WHERE
rr.parentResource.parentResource.parentResource.id = :resourceId) "
+ + " OR rsi.id IN (SELECT rr.id FROM Resource rr WHERE
rr.parentResource.parentResource.parentResource.parentResource.id = :resourceId) "
+ + " OR rsi.id IN (SELECT rr.id FROM Resource rr WHERE
rr.parentResource.parentResource.parentResource.parentResource.parentResource.id =
:resourceId) "
+ + " ") })
@Table(name = "RHQ_RESOURCE")
-public class ResourceSyncInfo extends SyncInfo implements Serializable {
+public class ResourceSyncInfo implements Serializable {
private static final long serialVersionUID = 1L;
- @Column(name = "PARENT_RESOURCE_ID")
- private Integer parentId;
-
- @OneToMany(mappedBy = "parentId", fetch = FetchType.EAGER)
- private Collection<ResourceSyncInfo> childSyncInfos;
+ /** Sync info for platform service children (for building up hierarchy that excludes
the top level servers */
+ public static final String QUERY_SERVICE_CHILDREN =
"ResourceSyncInfo.platformServiceChildren";
+ /** Sync info rooted at the specified top level server and including all of it's
hierarchy (up to 5 levels below
+ * the top level server. note that we support up to 6 levels below platform but we
are starting one level down) */
+ public static final String QUERY_TOP_LEVEL_SERVER =
"ResourceSyncInfo.topLevelServer";
+
+ /**
+ * Server-assigned id
+ */
+ @Column(name = "ID", nullable = false)
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private int id;
+
+ /**
+ * Agent-assigned uuid
+ */
+ @Column(name = "UUID")
+ private String uuid;
+
+ /**
+ * Last modified time
+ */
+ @Column(name = "MTIME")
+ private long mtime;
+
+ @Column(name = "INVENTORY_STATUS")
+ @Enumerated(EnumType.STRING)
+ private InventoryStatus inventoryStatus;
// JPA requires public or protected no-param constructor; Externalizable requires
public no-param constructor.
public ResourceSyncInfo() {
}
- public Collection<ResourceSyncInfo> getChildSyncInfos() {
- return childSyncInfos;
+ public int getId() {
+ return id;
}
- // for testing
- public static ResourceSyncInfo buildResourceSyncInfo(Resource resource) {
- Collection<ResourceSyncInfo> children;
-
- if (resource.getChildResources() != null) {
- children = new
HashSet<ResourceSyncInfo>(resource.getChildResources().size());
- for (Resource child : resource.getChildResources()) {
- children.add(buildResourceSyncInfo(child));
- }
- } else {
- children = new HashSet<ResourceSyncInfo>(0);
- }
-
- return buildResourceSyncInfo(resource, children);
+ public String getUuid() {
+ return uuid;
}
- // for testing
- public static ResourceSyncInfo buildResourceSyncInfo(Resource resource,
Collection<ResourceSyncInfo> children) {
-
- ResourceSyncInfo syncInfo = new ResourceSyncInfo(resource.getId(),
resource.getUuid(), resource.getMtime(),
- resource.getInventoryStatus(), children);
-
- return syncInfo;
+ public long getMtime() {
+ return mtime;
}
-
- public static ResourceSyncInfo buildResourceSyncInfo(SyncInfo syncInfo) {
-
- return buildResourceSyncInfo(syncInfo, ((Collection<ResourceSyncInfo>)
null));
+ public InventoryStatus getInventoryStatus() {
+ return inventoryStatus;
}
- public static ResourceSyncInfo buildResourceSyncInfo(SyncInfo syncInfo,
Collection<ResourceSyncInfo> children) {
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
+ return result;
+ }
- ResourceSyncInfo resourceSyncInfo = new ResourceSyncInfo(syncInfo.getId(),
syncInfo.getUuid(),
- syncInfo.getMtime(), syncInfo.getInventoryStatus(), children);
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ResourceSyncInfo other = (ResourceSyncInfo) obj;
+ if (uuid == null) {
+ if (other.uuid != null)
+ return false;
+ } else if (!uuid.equals(other.uuid))
+ return false;
+ return true;
+ }
- return resourceSyncInfo;
+ protected ResourceSyncInfo(int id, String uuid, long mtime, InventoryStatus istatus)
{
+ this.id = id;
+ this.uuid = uuid;
+ this.mtime = mtime;
+ this.inventoryStatus = istatus;
}
- private ResourceSyncInfo(int id, String uuid, long mtime, InventoryStatus istatus,
- Collection<ResourceSyncInfo> children) {
- super(id, uuid, mtime, istatus);
- this.childSyncInfos = children;
+ static public ResourceSyncInfo buildResourceSyncInfo(Resource res) {
+ return new ResourceSyncInfo(res.getId(), res.getUuid(), res.getMtime(),
res.getInventoryStatus());
}
}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/SyncInfo.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/SyncInfo.java
deleted file mode 100644
index 370d84f..0000000
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/SyncInfo.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2013 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * This program 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 and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.rhq.core.domain.discovery;
-
-import java.io.Serializable;
-
-import javax.persistence.Column;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.MappedSuperclass;
-
-import org.rhq.core.domain.resource.InventoryStatus;
-
-/**
- * This is the abstract base class for SyncInfo, which may be for a platform or a [top
level server] resource.
- *
- * @author Ian Springer
- * @author Jay Shaughnessy
- */
-@MappedSuperclass
-public abstract class SyncInfo implements Serializable {
- private static final long serialVersionUID = 1L;
-
- /**
- * Server-assigned id
- */
- @Column(name = "ID", nullable = false)
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private int id;
-
- /**
- * Agent-assigned uuid
- */
- @Column(name = "UUID")
- private String uuid;
-
- /**
- * Last modified time
- */
- @Column(name = "MTIME")
- private long mtime;
-
- @Column(name = "INVENTORY_STATUS")
- @Enumerated(EnumType.STRING)
- private InventoryStatus inventoryStatus;
-
- // JPA requires public or protected no-param constructor; Externalizable requires
public no-param constructor.
- public SyncInfo() {
- }
-
- public int getId() {
- return id;
- }
-
- public String getUuid() {
- return uuid;
- }
-
- public long getMtime() {
- return mtime;
- }
-
- public InventoryStatus getInventoryStatus() {
- return inventoryStatus;
- }
-
- protected SyncInfo(int id, String uuid, long mtime, InventoryStatus istatus) {
- this.id = id;
- this.uuid = uuid;
- this.mtime = mtime;
- this.inventoryStatus = istatus;
- }
-
-}
diff --git
a/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/AbstractIgnoreTypesInventoryManagerBaseTest.java
b/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/AbstractIgnoreTypesInventoryManagerBaseTest.java
index 4591dfc..cb799de 100644
---
a/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/AbstractIgnoreTypesInventoryManagerBaseTest.java
+++
b/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/AbstractIgnoreTypesInventoryManagerBaseTest.java
@@ -22,8 +22,10 @@ import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when;
import java.io.File;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -217,17 +219,43 @@ public abstract class AbstractIgnoreTypesInventoryManagerBaseTest
extends Arquil
return;
}
- protected Answer<ResourceSyncInfo> getResourceSyncInfo() {
- return new Answer<ResourceSyncInfo>() {
+ protected Answer<Collection<ResourceSyncInfo>> getResourceSyncInfo() {
+ return new Answer<Collection<ResourceSyncInfo>>() {
@Override
- public ResourceSyncInfo answer(InvocationOnMock invocation) throws Throwable
{
+ public Collection<ResourceSyncInfo> answer(InvocationOnMock invocation)
throws Throwable {
Integer resourceId = (Integer) invocation.getArguments()[0];
- ResourceSyncInfo result =
ResourceSyncInfo.buildResourceSyncInfo(simulatedInventory.get(resourceId));
+ Collection<ResourceSyncInfo> result =
convert(simulatedInventory.get(resourceId));
return result;
}
};
}
+ private static Collection<ResourceSyncInfo> convert(Resource root) {
+ Set<ResourceSyncInfo> result = new HashSet<ResourceSyncInfo>();
+ convertInternal(root, result);
+ return result;
+ }
+
+ private static void convertInternal(Resource root, Collection<ResourceSyncInfo>
result) {
+
+ ResourceSyncInfo rootSyncInfo = ResourceSyncInfo.buildResourceSyncInfo(root);
+
+ if (result.contains(rootSyncInfo)) {
+ return;
+ }
+ try {
+ result.add(rootSyncInfo);
+
+ for (Resource child : root.getChildResources()) {
+ convertInternal(child, result);
+ }
+
+ } catch (Exception e) {
+ throw new IllegalStateException("Failed to convert resource " +
root
+ + " to a ResourceSyncInfo. This should not happen.", e);
+ }
+ }
+
protected void validateFullInventory() {
System.out.println("Validating full inventory...");
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/StandaloneContainer.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/StandaloneContainer.java
index 33cf21a..849541d 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/StandaloneContainer.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/StandaloneContainer.java
@@ -25,6 +25,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
@@ -903,7 +904,7 @@ public class StandaloneContainer {
}
@Override
- public ResourceSyncInfo getResourceSyncInfo(int resourceId) {
+ public Collection<ResourceSyncInfo> getResourceSyncInfo(int resourceId) {
return null;
}
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/RuntimeSynchronizer.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/RuntimeSynchronizer.java
index 679db62..1708072 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/RuntimeSynchronizer.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/RuntimeSynchronizer.java
@@ -45,7 +45,7 @@ import org.rhq.core.pc.drift.ScheduleQueue;
* <br/><br/>
* Note that inventory sync happens regularly after the plugin container is initialized.
* Discovery scans are performed at fixed intervals. The results of a discovery scan are
- * reported to the server, and the server sends back {@link
org.rhq.core.domain.discovery.ResourceSyncInfo resource sync info}
+ * reported to the server, and the server sends back {@link
org.rhq.core.domain.discovery.OldResourceSyncInfo resource sync info}
* which is then used to sync with the local inventory.
*/
class RuntimeSynchronizer implements DriftSynchronizer {
diff --git
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index b809f6f..24dcb44 100644
---
a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++
b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -228,6 +228,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
/**
* @see ContainerService#initialize()
*/
+ @Override
public void initialize() {
inventoryLock.writeLock().lock();
@@ -290,6 +291,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
/**
* @see ContainerService#shutdown()
*/
+ @Override
public void shutdown() {
PluginContainer pluginContainer = PluginContainer.getInstance();
pluginContainer.shutdownExecutorService(this.inventoryThreadPoolExecutor, true);
@@ -626,10 +628,12 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
}
+ @Override
public void setConfiguration(PluginContainerConfiguration configuration) {
this.configuration = configuration;
}
+ @Override
public void updatePluginConfiguration(int resourceId, Configuration
newPluginConfiguration)
throws InvalidPluginConfigurationClientException, PluginContainerException {
ResourceContainer container = getResourceContainer(resourceId);
@@ -673,11 +677,13 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
}
+ @Override
@NotNull
public InventoryReport executeServerScanImmediately() {
return submit(serverScanExecutor);
}
+ @Override
@NotNull
public InventoryReport executeServiceScanImmediately() {
return submit(serviceScanExecutor);
@@ -689,6 +695,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
return submit(discoveryExecutor);
}
+ @Override
public void executeServiceScanDeferred() {
inventoryThreadPoolExecutor.submit((Callable<InventoryReport>)
this.serviceScanExecutor);
}
@@ -705,6 +712,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
* @param changedOnlyReport
* @return The report, for inspection
*/
+ @Override
public AvailabilityReport executeAvailabilityScanImmediately(boolean
changedOnlyReport) {
return executeAvailabilityScanImmediately(changedOnlyReport, false);
}
@@ -745,6 +753,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
}
+ @Override
@NotNull
public AvailabilityReport getCurrentAvailability(Resource resource, boolean
changesOnly) {
try {
@@ -790,6 +799,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
configuration.getServerServices().getDiscoveryServerService().setResourceEnablement(resourceId,
setEnabled);
}
+ @Override
public MergeResourceResponse manuallyAddResource(ResourceType resourceType, int
parentResourceId,
Configuration pluginConfiguration, int ownerSubjectId) throws
InvalidPluginConfigurationClientException,
PluginContainerException {
@@ -1202,36 +1212,45 @@ public class InventoryManager extends AgentService implements
ContainerService,
/**
* Performs a full platform sync so that resources passed in are reflected in the
agent's inventory.
*
- * @param platformSyncInfo sync info on the platform and references to the top level
servers
+ * @param platformSyncInfo sync info on the platform and references to the top level
servers. not null.
*/
private void syncPlatform(PlatformSyncInfo platformSyncInfo) {
final Set<String> allServerSideUuids = new HashSet<String>();
boolean hadSyncedResources = false;
+ ResourceSyncInfo platformResourceSyncInfo = platformSyncInfo.getPlatform();
- // always sync the platform because it does not get included in the top level
server sync
- allServerSideUuids.add(platformSyncInfo.getUuid());
- ResourceSyncInfo platformResourceSyncInfo =
ResourceSyncInfo.buildResourceSyncInfo(platformSyncInfo);
- log.info("Sync Starting: Platform [" + platformResourceSyncInfo.getId()
+ "]");
- hadSyncedResources = syncResource(platformResourceSyncInfo) ||
hadSyncedResources;
- log.info("Sync Complete: Platform [" + platformResourceSyncInfo.getId()
+ "]. Local inventory changed: ["
+ // sync the platform because it does not get included in the top level server
sync
+ allServerSideUuids.add(platformResourceSyncInfo.getUuid());
+ // sync the top level service hierarchy
+ addAllUuids(platformSyncInfo.getServices(), allServerSideUuids);
+
+ // Add the platform sync info to the service hierarchy in order to process in one
batch
+ Collection<ResourceSyncInfo> syncInfos = platformSyncInfo.getServices();
+ syncInfos.add(platformResourceSyncInfo);
+
+ log.info("Sync Starting: Platform [" +
platformSyncInfo.getPlatform().getId() + "] and top level services.");
+ hadSyncedResources = syncResources(platformResourceSyncInfo.getId(), syncInfos)
|| hadSyncedResources;
+ log.info("Sync Complete: Platform [" +
platformSyncInfo.getPlatform().getId() + "]. Local inventory changed: ["
+ hadSyncedResources + "]");
+ syncInfos = null; // release to GC
+
// then sync the top level servers by calling back to the server for the sync
info for each. We
// do this one at a time to avoid forcing the whole inventory into active memory
at one time during the sync.
- Collection<Resource> topLevelServers =
platformSyncInfo.getTopLevelServers();
- if (null != topLevelServers) {
+ Collection<Integer> topLevelServerIds =
platformSyncInfo.getTopLevelServerIds();
+ if (null != topLevelServerIds) {
DiscoveryServerService service =
configuration.getServerServices().getDiscoveryServerService();
- for (Resource topLevelServer : topLevelServers) {
- ResourceSyncInfo topLevelServerSyncInfo =
service.getResourceSyncInfo(topLevelServer.getId());
- if (null != topLevelServerSyncInfo) {
- //topLevelServerSyncInfo =
ResourceSyncInfo.buildResourceSyncInfo(platformSyncInfo,
- // topLevelServerSyncInfo);
- getAllUuids(topLevelServerSyncInfo, allServerSideUuids);
- log.info("Sync Starting: Top Level Server [" +
topLevelServerSyncInfo.getId() + "]");
- hadSyncedResources = syncResource(topLevelServerSyncInfo) ||
hadSyncedResources;
- log.info("Sync Complete: Top Level Server [" +
topLevelServerSyncInfo.getId()
- + "] Local inventory changed: [" + hadSyncedResources +
"]");
+ for (Integer topLevelServerId : topLevelServerIds) {
+ syncInfos = service.getResourceSyncInfo(topLevelServerId);
+ if (null != syncInfos) {
+ addAllUuids(syncInfos, allServerSideUuids);
+ log.info("Sync Starting: Top Level Server [" +
topLevelServerId + "]");
+ hadSyncedResources = syncResources(topLevelServerId, syncInfos) ||
hadSyncedResources;
+ log.info("Sync Complete: Top Level Server [" +
topLevelServerId + "] Local inventory changed: ["
+ + hadSyncedResources + "]");
+
+ syncInfos = null; // release to GC
}
}
}
@@ -1261,13 +1280,9 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
}
- private void getAllUuids(ResourceSyncInfo syncInfo, Set<String>
allServerSideUuids) {
- allServerSideUuids.add(syncInfo.getUuid());
-
- if (null != syncInfo.getChildSyncInfos()) {
- for (ResourceSyncInfo child : syncInfo.getChildSyncInfos()) {
- getAllUuids(child, allServerSideUuids);
- }
+ private void addAllUuids(Collection<ResourceSyncInfo> syncInfos,
Set<String> allServerSideUuids) {
+ for (ResourceSyncInfo syncInfo : syncInfos) {
+ allServerSideUuids.add(syncInfo.getUuid());
}
}
@@ -1278,7 +1293,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
* @param syncInfo the resources' sync data
* @return true if any resources needed synchronization, false otherwise
*/
- private boolean syncResource(ResourceSyncInfo syncInfo) {
+ private boolean syncResources(int rootResourceId, Collection<ResourceSyncInfo>
syncInfos) {
boolean result = false;
final long startTime = System.currentTimeMillis();
final Set<Resource> syncedResources = new LinkedHashSet<Resource>();
@@ -1292,7 +1307,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
try {
log.debug("Processing Server sync info...");
- processSyncInfo(syncInfo, syncedResources, unknownResourceSyncInfos,
modifiedResourceIds,
+ processSyncInfo(syncInfos, syncedResources, unknownResourceSyncInfos,
modifiedResourceIds,
deletedResourceIds, newlyCommittedResources, ignoredResources);
if (log.isDebugEnabled()) {
@@ -1318,7 +1333,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
result = !(syncedResources.isEmpty() &&
unknownResourceSyncInfos.isEmpty() && modifiedResourceIds.isEmpty());
} catch (Throwable t) {
- log.warn("Failed to synchronize local inventory with Server inventory
for Resource [" + syncInfo.getId()
+ log.warn("Failed to synchronize local inventory with Server inventory
for Resource [" + rootResourceId
+ "] and its descendants: " + t.getMessage());
// convert to runtime exception so as not to change the api
throw new RuntimeException(t);
@@ -1327,13 +1342,19 @@ public class InventoryManager extends AgentService implements
ContainerService,
return result;
}
- public void synchronizeInventory(ResourceSyncInfo resourceSyncInfo) {
- log.info("Synchronizing local inventory with Server inventory for Resource
[" + resourceSyncInfo.getId()
- + "] and its descendants...");
+ @Override
+ public void synchronizePlatform(PlatformSyncInfo syncInfo) {
+ syncPlatform(syncInfo);
+ performServiceScan(syncInfo.getPlatform().getId()); // NOTE: This will block (the
initial scan blocks).
+ // TODO: (jshaughn) should we also request a full avail scan?
+ }
- // Get the latest resource data rooted at the given id.
- syncResource(resourceSyncInfo); // this method assumes we only get a single
resource and its children (BZ 887411)
- performServiceScan(resourceSyncInfo.getId()); // NOTE: This will block (the
initial scan blocks).
+ @Override
+ public void synchronizeServer(int resourceId, Collection<ResourceSyncInfo>
topLevelServerSyncInfo) {
+ log.info("Synchronizing local inventory with Server inventory for Resource
[" + resourceId
+ + "] and its descendants...");
+ syncResources(resourceId, topLevelServerSyncInfo);
+ performServiceScan(resourceId); // NOTE: This will block (the initial scan
blocks).
// TODO: (jshaughn) should we also request a full avail scan?
}
@@ -1397,6 +1418,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
return resourceContainer.getResourceComponent();
}
+ @Override
public void uninventoryResource(int resourceId) {
ResourceContainer resourceContainer = getResourceContainer(resourceId);
if (resourceContainer == null) {
@@ -1542,6 +1564,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
return parentContainerResource.getChildResources();
}
+ @Override
public Resource getPlatform() {
return platform;
}
@@ -2541,6 +2564,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
return mgr;
}
+ @Override
public void requestFullAvailabilityReport() {
if (null != availabilityExecutor) {
availabilityExecutor.sendFullReportNextTime();
@@ -2684,10 +2708,12 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
}
+ @Override
public void enableServiceScans(int serverResourceId, Configuration config) {
throw new UnsupportedOperationException("not implemented yet"); //
TODO: Implement this method.
}
+ @Override
public void disableServiceScans(int serverResourceId) {
throw new UnsupportedOperationException("not implemented yet"); //
TODO: Implement this method.
}
@@ -2905,84 +2931,79 @@ public class InventoryManager extends AgentService implements
ContainerService,
return versionUpdated;
}
- private void processSyncInfo(ResourceSyncInfo syncInfo, Set<Resource>
syncedResources,
+ private void processSyncInfo(Collection<ResourceSyncInfo> syncInfos,
Set<Resource> syncedResources,
Set<ResourceSyncInfo> unknownResourceSyncInfos, Set<Integer>
modifiedResourceIds,
Set<Integer> deletedResourceIds, Set<Resource>
newlyCommittedResources, Set<Resource> ignoredResources) {
- if (InventoryStatus.DELETED == syncInfo.getInventoryStatus()) {
- // A previously deleted resource still being reported by the server. Support
for this option can
- // be removed if the server is ever modified to not report deleted resources.
It is happening currently
- // because deleted resources are kept to support resource history. The
deleted resources are rightfully not
- // in the PC inventory, and so must be handled separately, and not as unknown
resources.
- deletedResourceIds.add(syncInfo.getId());
- } else {
- ResourceContainer container = getResourceContainer(syncInfo.getUuid());
- if (container == null) {
- // Either a manually added Resource or just something we haven't
discovered.
- // If this unknown resource is to be ignored, then don't bother to do
anything.
- if (InventoryStatus.IGNORED != syncInfo.getInventoryStatus()) {
- unknownResourceSyncInfos.add(syncInfo);
- log.info("Got unknown resource: " + syncInfo.getId());
- } else {
- log.info("Got an unknown but ignored resource - ignoring it:
" + syncInfo.getId());
- }
+ for (ResourceSyncInfo syncInfo : syncInfos) {
+ if (InventoryStatus.DELETED == syncInfo.getInventoryStatus()) {
+ // A previously deleted resource still being reported by the server.
Support for this option can
+ // be removed if the server is ever modified to not report deleted
resources. It is happening currently
+ // because deleted resources are kept to support resource history. The
deleted resources are rightfully not
+ // in the PC inventory, and so must be handled separately, and not as
unknown resources.
+ deletedResourceIds.add(syncInfo.getId());
} else {
- Resource resource = container.getResource();
- // Ensure the Resource classloader is initialized on the Resource
container.
- initResourceContainer(resource);
-
- if (log.isDebugEnabled()) {
- log.debug("Local Resource: id=" + resource.getId() +
", status=" + resource.getInventoryStatus()
- + ", mtime=" + resource.getMtime());
- log.debug("Sync Resource: " + syncInfo.getId() + ",
status=" + syncInfo.getInventoryStatus()
- + ", mtime=" + syncInfo.getMtime());
- }
-
- final boolean ignoreResource = (InventoryStatus.IGNORED ==
syncInfo.getInventoryStatus());
- final boolean ignoreResourceType =
this.pluginManager.getMetadataManager()
- .isDisabledOrIgnoredResourceType(resource.getResourceType());
- if (ignoreResource || ignoreResourceType) {
- // a resource or its type has been tagged to be ignored - we need to
remove it from our inventory
- ignoredResources.add(resource);
+ ResourceContainer container = getResourceContainer(syncInfo.getUuid());
+ if (container == null) {
+ // Either a manually added Resource or just something we haven't
discovered.
+ // If this unknown resource is to be ignored, then don't bother
to do anything.
+ if (InventoryStatus.IGNORED != syncInfo.getInventoryStatus()) {
+ unknownResourceSyncInfos.add(syncInfo);
+ log.info("Got unknown resource: " + syncInfo.getId());
+ } else {
+ log.info("Got an unknown but ignored resource - ignoring it:
" + syncInfo.getId());
+ }
} else {
- if (resource.getInventoryStatus() != InventoryStatus.COMMITTED
- && syncInfo.getInventoryStatus() ==
InventoryStatus.COMMITTED) {
- newlyCommittedResources.add(resource);
+ Resource resource = container.getResource();
+ // Ensure the Resource classloader is initialized on the Resource
container.
+ initResourceContainer(resource);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Local Resource: id=" + resource.getId() +
", status="
+ + resource.getInventoryStatus() + ", mtime=" +
resource.getMtime());
+ log.debug("Sync Resource: " + syncInfo.getId() +
", status=" + syncInfo.getInventoryStatus()
+ + ", mtime=" + syncInfo.getMtime());
}
- if (resource.getId() == 0) {
- // This must be a Resource we just reported to the server. Just
update its id, mtime, and status.
- resource.setId(syncInfo.getId());
- resource.setMtime(syncInfo.getMtime());
- resource.setInventoryStatus(syncInfo.getInventoryStatus());
- refreshResourceComponentState(container, true);
- syncedResources.add(resource);
+ final boolean ignoreResource = (InventoryStatus.IGNORED ==
syncInfo.getInventoryStatus());
+ final boolean ignoreResourceType =
this.pluginManager.getMetadataManager()
+ .isDisabledOrIgnoredResourceType(resource.getResourceType());
+ if (ignoreResource || ignoreResourceType) {
+ // a resource or its type has been tagged to be ignored - we need
to remove it from our inventory
+ ignoredResources.add(resource);
} else {
- // It's a resource that was already synced at least once.
- if (resource.getId() != syncInfo.getId()) {
- // This really should never happen, but check for it just to
be bulletproof.
- log.error("PC Resource id (" + resource.getId() +
") does not match Server Resource id ("
- + syncInfo.getId() + ") for Resource with uuid
" + resource.getUuid() + ": " + resource);
- modifiedResourceIds.add(syncInfo.getId());
+ if (resource.getInventoryStatus() != InventoryStatus.COMMITTED
+ && syncInfo.getInventoryStatus() ==
InventoryStatus.COMMITTED) {
+ newlyCommittedResources.add(resource);
}
- // See if it's been modified on the Server since the last
time we synced.
- else if (resource.getMtime() < syncInfo.getMtime()) {
- modifiedResourceIds.add(resource.getId());
+
+ if (resource.getId() == 0) {
+ // This must be a Resource we just reported to the server.
Just update its id, mtime, and status.
+ resource.setId(syncInfo.getId());
+ resource.setMtime(syncInfo.getMtime());
+ resource.setInventoryStatus(syncInfo.getInventoryStatus());
+ refreshResourceComponentState(container, true);
+ syncedResources.add(resource);
} else {
- // Only try to start up the component if the Resource has
*not* been modified on the Server.
- // Otherwise, hold off until we've synced the Resource
with the Server.
- refreshResourceComponentState(container, false);
+ // It's a resource that was already synced at least
once.
+ if (resource.getId() != syncInfo.getId()) {
+ // This really should never happen, but check for it just
to be bulletproof.
+ log.error("PC Resource id (" +
resource.getId()
+ + ") does not match Server Resource id (" +
syncInfo.getId()
+ + ") for Resource with uuid " +
resource.getUuid() + ": " + resource);
+ modifiedResourceIds.add(syncInfo.getId());
+ }
+ // See if it's been modified on the Server since the last
time we synced.
+ else if (resource.getMtime() < syncInfo.getMtime()) {
+ modifiedResourceIds.add(resource.getId());
+ } else {
+ // Only try to start up the component if the Resource has
*not* been modified on the Server.
+ // Otherwise, hold off until we've synced the
Resource with the Server.
+ refreshResourceComponentState(container, false);
+ }
}
}
}
-
- // Recurse...
- if (null != syncInfo.getChildSyncInfos()) {
- for (ResourceSyncInfo childSyncInfo : syncInfo.getChildSyncInfos())
{
- processSyncInfo(childSyncInfo, syncedResources,
unknownResourceSyncInfos, modifiedResourceIds,
- deletedResourceIds, newlyCommittedResources,
ignoredResources);
- }
- }
}
}
}
@@ -3037,46 +3058,20 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
private Set<Resource> getResourcesFromSyncInfos(Set<ResourceSyncInfo>
syncInfos) {
-
- final StopWatch stopWatch = new StopWatch();
- final int syncInfosSize = syncInfos.size();
- final Set<Resource> result = new HashSet<Resource>(syncInfosSize);
-
- for (ResourceSyncInfo syncInfo : syncInfos) {
- Resource resource = getResourceFromSyncInfo(syncInfo);
- result.add(resource);
- }
-
- if (log.isDebugEnabled()) {
- log.debug("Time to build resource tree from [" + syncInfosSize +
"] sync infos=" + stopWatch.getElapsed());
- }
-
- return result;
- }
-
- private Resource getResourceFromSyncInfo(ResourceSyncInfo syncInfo) {
- final boolean isDebugEnabled = log.isDebugEnabled();
- final StopWatch stopWatch = new StopWatch();
- String marker = null;
-
/////
- // First we need to do a breadth first traversal of the sync info tree and build
a list of all resource IDs.
-
- if (isDebugEnabled) {
- marker = "a. Breadth-first retrieval of sync info tree";
- stopWatch.markTimeBegin(marker);
- }
-
- List<Integer> resourceIdList = treeToBreadthFirstList(syncInfo);
- int fullResourceTreeSize = resourceIdList.size();
- if (isDebugEnabled) {
- stopWatch.markTimeEnd(marker);
+ // First we need to get a list of the unknown resource ids
+ List<Integer> resourceIdList = new
ArrayList<Integer>(syncInfos.size());
+ for (ResourceSyncInfo syncInfo : syncInfos) {
+ resourceIdList.add(syncInfo.getId());
}
/////
// Now we need to loop over batches of the resource ID list - asking the server
for their resource representations.
// When we get the resources from the server, we put them in our resourceMap,
keyed on ID.
+ final boolean isDebugEnabled = log.isDebugEnabled();
+ final StopWatch stopWatch = new StopWatch();
+ String marker = null;
Map<Integer, Resource> resourceMap = new HashMap<Integer,
Resource>(resourceIdList.size());
int batchNumber = 0;
while (!resourceIdList.isEmpty()) {
@@ -3091,7 +3086,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
// This usage of .clear() will remove the processed resources from the
backing list.
String markerPrefix = null;
if (isDebugEnabled) {
- markerPrefix = String.format("b. Batch [%03d] (%d): ",
batchNumber, fullResourceTreeSize);
+ markerPrefix = String.format("a. Batch [%03d] (%d): ",
batchNumber, syncInfos.size());
marker = String.format("%sGet resource ID sublist - %d of %d
remaining", markerPrefix, end, size);
stopWatch.markTimeBegin(marker);
}
@@ -3136,61 +3131,39 @@ public class InventoryManager extends AgentService implements
ContainerService,
}
}
- if (fullResourceTreeSize != resourceMap.size()) {
- log.warn("Expected [" + fullResourceTreeSize + "] but found
[" + resourceMap.size()
+ if (syncInfos.size() != resourceMap.size()) {
+ log.warn("Expected [" + syncInfos.size() + "] but found
[" + resourceMap.size()
+ "] resources when fetching from server");
}
/////
// We now have all the resources associated with all sync infos in a map.
- // We need to build the full resource tree using the sync info as the blueprint
for how to order the resources in a tree.
+ // We need to build the full resource tree using the resource parent info as the
blueprint for how to
+ // link the resources in the tree.
if (isDebugEnabled) {
- marker = "c. Build the full resource tree";
+ marker = "b. Build the resource hierarchies";
stopWatch.markTimeBegin(marker);
}
- Resource result = syncInfoTreeToResourceTree(syncInfo, resourceMap);
- resourceMap.clear();
-
- if (isDebugEnabled) {
- stopWatch.markTimeEnd(marker);
-
- log.debug("Full resource tree built from sync info - performance: "
+ stopWatch);
- }
-
- return result;
- }
-
- private Resource syncInfoTreeToResourceTree(ResourceSyncInfo syncInfo,
Map<Integer, Resource> resourceMap) {
- Resource result = resourceMap.get(syncInfo.getId());
-
- if (null == result || null == syncInfo.getChildSyncInfos()) {
- return result;
- }
-
- for (ResourceSyncInfo child : syncInfo.getChildSyncInfos()) {
- Resource childResource = syncInfoTreeToResourceTree(child, resourceMap);
- if (null != childResource) {
- result.addChildResource(childResource);
+ // The root resources to be merged (i.e. the resources whose parents are not in
the map)
+ Set<Resource> result = new HashSet<Resource>();
+ for (Resource resource : resourceMap.values()) {
+ if (null == resource.getParentResource()) {
+ result.add(resource); // the platform, make sure we have this
+ continue;
+ }
+ Resource parent = resourceMap.get(resource.getParentResource().getId());
+ if (null != parent) {
+ parent.addChildResource(resource);
+ } else {
+ result.add(resource);
}
}
- return result;
- }
-
- private List<Integer> treeToBreadthFirstList(ResourceSyncInfo syncInfo) {
- List<Integer> result = new ArrayList<Integer>();
+ if (isDebugEnabled) {
+ stopWatch.markTimeEnd(marker);
- LinkedList<ResourceSyncInfo> queue = new
LinkedList<ResourceSyncInfo>();
- queue.add(syncInfo);
- while (!queue.isEmpty()) {
- ResourceSyncInfo node = queue.remove();
- result.add(node.getId());
- if (null != node.getChildSyncInfos()) {
- for (ResourceSyncInfo child : node.getChildSyncInfos()) {
- queue.add(child);
- }
- }
+ log.debug("Resource trees built from map - performance: " +
stopWatch);
}
return result;
@@ -3500,6 +3473,7 @@ public class InventoryManager extends AgentService implements
ContainerService,
*/
class ResourceGotActivatedListener implements InventoryEventListener {
+ @Override
public void resourceActivated(Resource resource) {
if (resource != null && resource.getId() > 0) {
if (log.isDebugEnabled()) {
@@ -3514,14 +3488,17 @@ public class InventoryManager extends AgentService implements
ContainerService,
removeInventoryEventListener(this);
}
+ @Override
public void resourceDeactivated(Resource resource) {
// nothing to do
}
+ @Override
public void resourcesAdded(Set<Resource> resources) {
// nothing to do
}
+ @Override
public void resourcesRemoved(Set<Resource> resources) {
// nothing to do
}
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/AbstractResourceUpgradeHandlingTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/AbstractResourceUpgradeHandlingTest.java
index cfa6fa7..e9a3c05 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/AbstractResourceUpgradeHandlingTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/AbstractResourceUpgradeHandlingTest.java
@@ -56,6 +56,10 @@ public abstract class AbstractResourceUpgradeHandlingTest extends
ResourceUpgrad
expectations.with(Expectations.any(InventoryReport.class)));
expectations.will(inventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ expectations.allowing(ss.getDiscoveryServerService()).getResourceSyncInfo(
+ expectations.with(Expectations.any(Integer.class)));
+ expectations.will(inventory.getResourceSyncInfo());
+
expectations.allowing(ss.getDiscoveryServerService()).upgradeResources(
expectations.with(Expectations.any(Set.class)));
expectations.will(inventory.upgradeResources());
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index 5a18d65..2bcb7aa 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -19,7 +19,6 @@
package org.rhq.core.pc.upgrade;
-import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -132,12 +131,12 @@ public class FakeServerInventory {
throwIfFailing();
Integer resourceId = (Integer) invocation.getParameter(0);
-
- for (Resource c : platform.getChildResources()) {
- if (c.getId() == resourceId) {
- return getResourceSyncInfo(c);
+ for (Resource r : resourceStore.values()) {
+ if (resourceId.equals(r.getId())) {
+ return convert(r);
}
}
+
return null;
}
}
@@ -422,37 +421,29 @@ public class FakeServerInventory {
return platform == null ? null :
PlatformSyncInfo.buildPlatformSyncInfo(platform);
}
- private ResourceSyncInfo getResourceSyncInfo(Resource resource) {
+ private Collection<ResourceSyncInfo> getResourceSyncInfo(Resource resource) {
return resource == null ? null : convert(resource);
}
- private static ResourceSyncInfo convert(Resource root) {
- return convertInternal(root, true, new HashMap<String,
ResourceSyncInfo>());
+ private static Collection<ResourceSyncInfo> convert(Resource root) {
+ Set<ResourceSyncInfo> result = new HashSet<ResourceSyncInfo>();
+ convertInternal(root, result);
+ return result;
}
- private static ResourceSyncInfo convertInternal(Resource root, boolean
isTopLevelServer,
- Map<String, ResourceSyncInfo> intermediateResults) {
+ private static void convertInternal(Resource root, Collection<ResourceSyncInfo>
result) {
- ResourceSyncInfo ret = intermediateResults.get(root.getUuid());
+ ResourceSyncInfo rootSyncInfo = ResourceSyncInfo.buildResourceSyncInfo(root);
- if (ret != null) {
- return ret;
+ if (result.contains(rootSyncInfo)) {
+ return;
}
try {
- ret = ResourceSyncInfo.buildResourceSyncInfo(root);
- intermediateResults.put(root.getUuid(), ret);
-
- Integer parentId = root.getParentResource() == null ? null :
root.getParentResource().getId();
- getPrivateField(ResourceSyncInfo.class, "parentId").set(ret,
parentId);
+ result.add(rootSyncInfo);
- Set<ResourceSyncInfo> children = new
LinkedHashSet<ResourceSyncInfo>();
for (Resource child : root.getChildResources()) {
- ResourceSyncInfo syncChild = convertInternal(child, false,
intermediateResults);
-
- children.add(syncChild);
+ convertInternal(child, result);
}
- getPrivateField(ResourceSyncInfo.class, "childSyncInfos").set(ret,
children);
- return ret;
} catch (Exception e) {
throw new IllegalStateException("Failed to convert resource " +
root
@@ -460,15 +451,6 @@ public class FakeServerInventory {
}
}
- private static Field getPrivateField(Class<?> clazz, String fieldName) throws
NoSuchFieldException {
- Field field = clazz.getDeclaredField(fieldName);
- if (!field.isAccessible()) {
- field.setAccessible(true);
- }
-
- return field;
- }
-
private static Resource findResource(Resource root, Resource template,
Comparator<Resource> comparator) {
if (root == null)
return null;
diff --git
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
index 176f0a4..5572adf 100644
---
a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
+++
b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java
@@ -42,7 +42,7 @@ import org.rhq.test.pc.PluginContainerSetup;
import org.rhq.test.pc.PluginContainerTest;
/**
- *
+ *
*
* @author Lukas Krejci
*/
@@ -91,6 +91,9 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
allowing(ss.getDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
will(inv.mergeInventoryReport(InventoryStatus.COMMITTED));
+
allowing(ss.getDiscoveryServerService()).getResourceSyncInfo(with(any(Integer.class)));
+ will(inv.getResourceSyncInfo());
+
oneOf(ss.getDiscoveryServerService()).upgradeResources(with(any(Set.class)));
will(inv.upgradeResources());
}
@@ -159,6 +162,9 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
allowing(ss.getDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
will(inv.mergeInventoryReport(InventoryStatus.COMMITTED));
+
allowing(ss.getDiscoveryServerService()).getResourceSyncInfo(with(any(Integer.class)));
+ will(inv.getResourceSyncInfo());
+
never(ss.getDiscoveryServerService()).upgradeResources(with(any(Set.class)));
}
});
@@ -208,6 +214,9 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
allowing(ss.getDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
will(inv.mergeInventoryReport(InventoryStatus.COMMITTED));
+
allowing(ss.getDiscoveryServerService()).getResourceSyncInfo(with(any(Integer.class)));
+ will(inv.getResourceSyncInfo());
+
never(ss.getDiscoveryServerService()).upgradeResources(with(any(Set.class)));
}
});
@@ -258,6 +267,9 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
allowing(ss.getDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
will(inv.mergeInventoryReport(InventoryStatus.COMMITTED));
+
allowing(ss.getDiscoveryServerService()).getResourceSyncInfo(with(any(Integer.class)));
+ will(inv.getResourceSyncInfo());
+
oneOf(ss.getDiscoveryServerService()).upgradeResources(with(any(Set.class)));
will(inv.upgradeResources());
}
@@ -297,6 +309,9 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
allowing(ss.getDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
will(inv.mergeInventoryReport(requiredInventoryStatus));
+
+
allowing(ss.getDiscoveryServerService()).getResourceSyncInfo(with(any(Integer.class)));
+ will(inv.getResourceSyncInfo());
}
});
@@ -334,6 +349,9 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
allowing(ss.getDiscoveryServerService()).mergeInventoryReport(with(any(InventoryReport.class)));
will(serverInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+
allowing(ss.getDiscoveryServerService()).getResourceSyncInfo(with(any(Integer.class)));
+ will(serverInventory.getResourceSyncInfo());
+
oneOf(ss.getDiscoveryServerService()).upgradeResources(with(any(Set.class)));
will(serverInventory.upgradeResources());
}
diff --git
a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java
b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java
index 35fa7f1..4de1380 100644
---
a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java
+++
b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBeanTest.java
@@ -20,6 +20,7 @@ package org.rhq.enterprise.server.configuration;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -35,7 +36,6 @@ import org.rhq.core.clientapi.agent.discovery.DiscoveryAgentService;
import org.rhq.core.clientapi.agent.discovery.InvalidPluginConfigurationClientException;
import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
-import org.rhq.core.communications.command.annotation.Asynchronous;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
@@ -50,8 +50,8 @@ import
org.rhq.core.domain.configuration.group.GroupPluginConfigurationUpdate;
import org.rhq.core.domain.criteria.ResourceConfigurationUpdateCriteria;
import org.rhq.core.domain.discovery.AvailabilityReport;
import org.rhq.core.domain.discovery.MergeResourceResponse;
+import org.rhq.core.domain.discovery.PlatformSyncInfo;
import org.rhq.core.domain.discovery.ResourceSyncInfo;
-import org.rhq.core.domain.measurement.Availability;
import org.rhq.core.domain.resource.Agent;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
@@ -227,7 +227,7 @@ public class ConfigurationManagerBeanTest extends AbstractEJB3Test {
inProgress =
configurationManager.isResourceConfigurationUpdateInProgress(overlord, resourceId);
if (inProgress) {
- // history2 should be history1 since the update is not complete
+ // history2 should be history1 since the update is not complete
assert history2 != null;
assert history2.getId() == history1.getId();
myprop = history2.getConfiguration().getSimple("myboolean");
@@ -235,7 +235,7 @@ public class ConfigurationManagerBeanTest extends AbstractEJB3Test {
assert "true".equals(myprop.getStringValue());
myprop = history2.getConfiguration().getSimple("mysleep"); //
this wasn't in the first config
assert myprop == null;
- // record that this test case ran, we expect it will if the agent delay
is there
+ // record that this test case ran, we expect it will if the agent delay
is there
inProgressTested = true;
} else {
// update is complete, history 2 should be different
@@ -284,7 +284,7 @@ public class ConfigurationManagerBeanTest extends AbstractEJB3Test {
assert "true".equals(myprop.getStringValue());
// now update to config2 - the "agent" will sleep for a bit before it
completes
- // so we will have an INPROGRESS configuration for a few seconds before it goes
to SUCCESS
+ // so we will have an INPROGRESS configuration for a few seconds before it goes
to SUCCESS
configurationManager.updateResourceConfiguration(overlord, resourceId,
configuration2);
// now update to config3 - this should fail as you can't update while there
is one in progress
@@ -306,7 +306,7 @@ public class ConfigurationManagerBeanTest extends AbstractEJB3Test {
inProgress =
configurationManager.isResourceConfigurationUpdateInProgress(overlord, resourceId);
if (inProgress) {
- // history2 should be history1 since the update is not complete
+ // history2 should be history1 since the update is not complete
assert history2 != null;
assert history2.getId() == history1.getId();
myprop =
history2.getConfiguration().getSimple("myboolean");
@@ -314,7 +314,7 @@ public class ConfigurationManagerBeanTest extends AbstractEJB3Test {
assert "true".equals(myprop.getStringValue());
myprop = history2.getConfiguration().getSimple("mysleep");
// this wasn't in the first config
assert myprop == null;
- // record that this test case ran, we expect it will if the agent
delay is there
+ // record that this test case ran, we expect it will if the agent
delay is there
inProgressTested = true;
} else {
// update is complete, history 2 should be different
@@ -741,7 +741,7 @@ public class ConfigurationManagerBeanTest extends AbstractEJB3Test {
}
/** Exercise the ConfigurationManagerBean getOptionsForConfigurationDefinition.
- *
+ *
* @throws Exception
*/
@Test(enabled = ENABLE_TESTS)
@@ -1219,10 +1219,6 @@ public class ConfigurationManagerBeanTest extends AbstractEJB3Test
{
public void uninventoryResource(int resourceId) {
}
- @Asynchronous(guaranteedDelivery = true)
- public void synchronizeInventory(ResourceSyncInfo syncInfo) {
- }
-
public Configuration validate(Configuration configuration, int resourceId,
boolean isStructured)
throws PluginContainerException {
return null;
@@ -1232,5 +1228,13 @@ public class ConfigurationManagerBeanTest extends AbstractEJB3Test
{
public void requestFullAvailabilityReport() {
return;
}
+
+ @Override
+ public void synchronizePlatform(PlatformSyncInfo syncInfo) {
+ }
+
+ @Override
+ public void synchronizeServer(int resourceId, Collection<ResourceSyncInfo>
toplevelServerSyncInfo) {
+ }
}
}
diff --git
a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/configuration/LargeGroupPluginConfigurationTest.java
b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/configuration/LargeGroupPluginConfigurationTest.java
index 13343d8..b5e0dba 100644
---
a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/configuration/LargeGroupPluginConfigurationTest.java
+++
b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/configuration/LargeGroupPluginConfigurationTest.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.server.configuration;
+import java.util.Collection;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -34,8 +35,8 @@ import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
import org.rhq.core.domain.discovery.AvailabilityReport;
import org.rhq.core.domain.discovery.MergeResourceResponse;
+import org.rhq.core.domain.discovery.PlatformSyncInfo;
import org.rhq.core.domain.discovery.ResourceSyncInfo;
-import org.rhq.core.domain.measurement.Availability;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.enterprise.server.authz.PermissionException;
@@ -112,7 +113,7 @@ public class LargeGroupPluginConfigurationTest extends
LargeGroupTestBase {
int groupUpdateId =
configurationManager.scheduleGroupPluginConfigurationUpdate(env.normalSubject,
env.compatibleGroup.getId(), existingMap);
- // group plugin configuration update has been kicked off, wait for the mock
agents to each complete their update
+ // group plugin configuration update has been kicked off, wait for the mock
agents to each complete their update
System.out.print("Waiting for mock agents");
assert latch.await(5, TimeUnit.MINUTES) : "agents should not have taken this
long";
System.out.println(" Mock agents are done.");
@@ -222,10 +223,6 @@ public class LargeGroupPluginConfigurationTest extends
LargeGroupTestBase {
}
@Override
- public void synchronizeInventory(ResourceSyncInfo syncInfo) {
- }
-
- @Override
public void uninventoryResource(int resourceId) {
}
@@ -241,5 +238,13 @@ public class LargeGroupPluginConfigurationTest extends
LargeGroupTestBase {
public void requestFullAvailabilityReport() {
return;
}
+
+ @Override
+ public void synchronizePlatform(PlatformSyncInfo syncInfo) {
+ }
+
+ @Override
+ public void synchronizeServer(int resourceId, Collection<ResourceSyncInfo>
toplevelServerSyncInfo) {
+ }
}
}
diff --git
a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/discovery/DiscoveryBossBeanTest.java
b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/discovery/DiscoveryBossBeanTest.java
index 9cf9f98..eb3cf20 100644
---
a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/discovery/DiscoveryBossBeanTest.java
+++
b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/discovery/DiscoveryBossBeanTest.java
@@ -205,10 +205,12 @@ public class DiscoveryBossBeanTest extends AbstractEJB3Test {
assert results != null;
assert results.getIgnoredResourceTypes() == null : "nothing should have been
ignored in this test";
assertNotNull(results.getPlatformSyncInfo());
- ResourceSyncInfo syncInfo =
discoveryBoss.getResourceSyncInfo(results.getPlatformSyncInfo().getId());
- assert syncInfo != null;
+ Collection<ResourceSyncInfo> syncInfos =
discoveryBoss.getResourceSyncInfo(results.getPlatformSyncInfo()
+ .getPlatform().getId());
+ assert syncInfos != null;
+ assert !syncInfos.isEmpty();
- platform.setId(syncInfo.getId());
+ platform.setId(results.getPlatformSyncInfo().getPlatform().getId());
// Now submit the server and its children as an update report
inventoryReport = new InventoryReport(agent);
@@ -251,16 +253,19 @@ public class DiscoveryBossBeanTest extends AbstractEJB3Test {
assert results != null;
assert results.getIgnoredResourceTypes() == null : "nothing should have been
ignored in this test";
assertNotNull(results.getPlatformSyncInfo());
- ResourceSyncInfo syncInfo =
discoveryBoss.getResourceSyncInfo(results.getPlatformSyncInfo().getId());
- assert syncInfo != null;
+ assertNotNull(results.getPlatformSyncInfo().getTopLevelServerIds());
+ assertTrue(!results.getPlatformSyncInfo().getTopLevelServerIds().isEmpty());
+ Integer resourceId =
results.getPlatformSyncInfo().getTopLevelServerIds().iterator().next();
+ Collection<ResourceSyncInfo> syncInfos =
discoveryBoss.getResourceSyncInfo(resourceId);
+ assert syncInfos != null;
+ assert !syncInfos.isEmpty();
- ResourceSyncInfo serverSyncInfo =
syncInfo.getChildSyncInfos().iterator().next();
Resource resource1 =
discoveryBoss.manuallyAddResource(subjectManager.getOverlord(), serviceType2.getId(),
- serverSyncInfo.getId(), new Configuration());
+ resourceId, new Configuration());
try {
Resource resource2 =
discoveryBoss.manuallyAddResource(subjectManager.getOverlord(), serviceType2.getId(),
- serverSyncInfo.getId(), new Configuration());
+ resourceId, new Configuration());
fail("Manually adding a singleton that already existed succeeded: "
+ resource2);
} catch (EJBException e) {
assertEquals(String.valueOf(e.getCause()), RuntimeException.class,
e.getCause().getClass());
@@ -295,15 +300,15 @@ public class DiscoveryBossBeanTest extends AbstractEJB3Test {
assert platformSyncInfo != null;
// Check merge result
- assertEquals(InventoryStatus.NEW, platformSyncInfo.getInventoryStatus());
- assertEquals(platform.getChildResources().size(),
platformSyncInfo.getTopLevelServers().size());
+ assertEquals(InventoryStatus.NEW,
platformSyncInfo.getPlatform().getInventoryStatus());
+ assertEquals(platform.getChildResources().size(),
platformSyncInfo.getTopLevelServerIds().size());
// Collect the resource ids generated for the platform and the servers
- int platformId = platformSyncInfo.getId();
+ int platformId = platformSyncInfo.getPlatform().getId();
List<Integer> serverIds = new LinkedList<Integer>();
- for (Resource serverSyncInfo : platformSyncInfo.getTopLevelServers()) {
- serverIds.add(serverSyncInfo.getId());
+ for (Integer serverId : platformSyncInfo.getTopLevelServerIds()) {
+ serverIds.add(serverId);
}
int[] arrayOfServerIds = ArrayUtils.unwrapCollection(serverIds);
@@ -368,8 +373,8 @@ public class DiscoveryBossBeanTest extends AbstractEJB3Test {
assert mergeResults.getIgnoredResourceTypes().contains(new
ResourceTypeFlyweight(serverType));
// Check merge result - make sure we should not see any children under the
platform (it should have been ignored)
- assertEquals(InventoryStatus.NEW, platformSyncInfo.getInventoryStatus());
- assertEquals(platformSyncInfo.getTopLevelServers().size(), 0);
+ assertEquals(InventoryStatus.NEW,
platformSyncInfo.getPlatform().getInventoryStatus());
+ assertEquals(platformSyncInfo.getTopLevelServerIds().size(), 0);
}
@Test(groups = "integration.ejb3")
@@ -428,10 +433,10 @@ public class DiscoveryBossBeanTest extends AbstractEJB3Test {
assert platformSyncInfo != null;
// Collect the resource ids generated for the platform and the servers
- int platformId = platformSyncInfo.getId();
+ int platformId = platformSyncInfo.getPlatform().getId();
List<Integer> serverIds = new LinkedList<Integer>();
- for (Resource serverSyncInfo : platformSyncInfo.getTopLevelServers()) {
- serverIds.add(serverSyncInfo.getId());
+ for (Integer serverId : platformSyncInfo.getTopLevelServerIds()) {
+ serverIds.add(serverId);
}
int[] arrayOfServerIds = ArrayUtils.unwrapCollection(serverIds);
@@ -469,8 +474,8 @@ public class DiscoveryBossBeanTest extends AbstractEJB3Test {
assertEquals(mergeResults.getIgnoredResourceTypes().size(), 1);
assert mergeResults.getIgnoredResourceTypes().contains(new
ResourceTypeFlyweight(serverType));
- assertEquals(InventoryStatus.COMMITTED, platformSyncInfo.getInventoryStatus());
// notice platform is committed now
- assertEquals(platformSyncInfo.getTopLevelServers().size(), 0); // notice there
are no server children now
+ assertEquals(InventoryStatus.COMMITTED,
platformSyncInfo.getPlatform().getInventoryStatus()); // notice platform is committed now
+ assertEquals(platformSyncInfo.getTopLevelServerIds().size(), 0); // notice there
are no server children now
}
@Test(groups = "integration.ejb3")
@@ -501,11 +506,11 @@ public class DiscoveryBossBeanTest extends AbstractEJB3Test {
assert platformSyncInfo != null;
// Check merge result
- assertEquals(InventoryStatus.COMMITTED, platformSyncInfo.getInventoryStatus());
- assertEquals(storagePlatform.getChildResources().size(),
platformSyncInfo.getTopLevelServers().size());
+ assertEquals(InventoryStatus.COMMITTED,
platformSyncInfo.getPlatform().getInventoryStatus());
+ assertEquals(storagePlatform.getChildResources().size(),
platformSyncInfo.getTopLevelServerIds().size());
storageNode = resourceManager.getResourceById(subjectManager.getOverlord(),
platformSyncInfo
- .getTopLevelServers().iterator().next().getId());
+ .getTopLevelServerIds().iterator().next());
assertNotNull(storageNode);
assertEquals(InventoryStatus.COMMITTED, storageNode.getInventoryStatus());
}
@@ -533,8 +538,7 @@ public class DiscoveryBossBeanTest extends AbstractEJB3Test {
// Then simulate a create resource request
final String userSuppliedResourceName = prefix("User Supplied Resource
Name");
final String newResourceKey = prefix("Created Resource Key");
- Resource serverSyncInfo =
firstDiscoverySyncInfo.getTopLevelServers().iterator().next();
- final int serverResourceId = serverSyncInfo.getId();
+ final int serverResourceId =
firstDiscoverySyncInfo.getTopLevelServerIds().iterator().next();
executeInTransaction(false, new TransactionCallback() {
@Override
@@ -568,10 +572,13 @@ public class DiscoveryBossBeanTest extends AbstractEJB3Test {
// Check that the resource ends with the user supplied name in inventory
- ResourceSyncInfo topLevelServerSyncInfo =
discoveryBoss.getResourceSyncInfo(secondDiscoverySyncInfo
- .getTopLevelServers().iterator().next().getId());
- ResourceSyncInfo service1SyncInfo =
topLevelServerSyncInfo.getChildSyncInfos().iterator().next();
- Resource service1Resource = getEntityManager().find(Resource.class,
service1SyncInfo.getId());
+ Integer toplevelServerId =
secondDiscoverySyncInfo.getTopLevelServerIds().iterator().next();
+ Collection<ResourceSyncInfo> topLevelServerSyncInfo =
discoveryBoss.getResourceSyncInfo(toplevelServerId);
+ assert topLevelServerSyncInfo.size() == 2;
+ Iterator<ResourceSyncInfo> iter = topLevelServerSyncInfo.iterator();
+ Integer childId = iter.next().getId();
+ childId = childId.equals(toplevelServerId) ? iter.next().getId() : childId;
+ Resource service1Resource = getEntityManager().find(Resource.class, childId);
assertEquals(userSuppliedResourceName, service1Resource.getName());
}
diff --git
a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java
b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java
index 0c3a86e..93e2220 100644
---
a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java
+++
b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/TestAgentClient.java
@@ -19,6 +19,7 @@
package org.rhq.enterprise.server.test;
import java.io.InputStream;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -53,17 +54,16 @@ import org.rhq.core.clientapi.server.content.DeletePackagesRequest;
import org.rhq.core.clientapi.server.content.DeployPackagesRequest;
import org.rhq.core.clientapi.server.content.RetrievePackageBitsRequest;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
-import org.rhq.core.communications.command.annotation.Asynchronous;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.content.transfer.DeployPackageStep;
import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
import org.rhq.core.domain.discovery.AvailabilityReport;
import org.rhq.core.domain.discovery.MergeResourceResponse;
+import org.rhq.core.domain.discovery.PlatformSyncInfo;
import org.rhq.core.domain.discovery.ResourceSyncInfo;
import org.rhq.core.domain.drift.DriftDefinition;
import org.rhq.core.domain.drift.DriftFile;
import org.rhq.core.domain.drift.DriftSnapshot;
-import org.rhq.core.domain.measurement.Availability;
import org.rhq.core.domain.measurement.MeasurementData;
import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
import org.rhq.core.domain.measurement.ResourceMeasurementScheduleRequest;
@@ -333,12 +333,6 @@ public class TestAgentClient implements AgentClient,
BundleAgentService, DriftAg
throws InvalidPluginConfigurationClientException, PluginContainerException {
}
- @Asynchronous(guaranteedDelivery = true)
- @Override
- public void synchronizeInventory(ResourceSyncInfo syncInfo) {
- return;
- }
-
@Override
public void createResource(CreateResourceRequest request) throws
PluginContainerException {
}
@@ -421,4 +415,12 @@ public class TestAgentClient implements AgentClient,
BundleAgentService, DriftAg
public void requestFullAvailabilityReport() {
return;
}
+
+ @Override
+ public void synchronizePlatform(PlatformSyncInfo syncInfo) {
+ }
+
+ @Override
+ public void synchronizeServer(int resourceId, Collection<ResourceSyncInfo>
toplevelServerSyncInfo) {
+ }
}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 71e2e3f..656abd2 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -24,6 +24,7 @@ import static org.rhq.core.util.StringUtil.isBlank;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
@@ -271,14 +272,78 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
return null;
}
- PlatformSyncInfo result = entityManager.find(PlatformSyncInfo.class,
platform.getId());
+ Set<Resource> toplevelServices = new HashSet<Resource>();
+ Set<Integer> topLevelServerIds = new HashSet<Integer>();
+
+ for (Resource platformChild : platform.getChildResources()) {
+ switch (platformChild.getResourceType().getCategory()) {
+ case SERVER:
+ topLevelServerIds.add(platformChild.getId());
+ break;
+ case SERVICE:
+ toplevelServices.add(platformChild);
+ break;
+ default:
+ break;
+ }
+ }
+
+ ResourceSyncInfo platformSyncInfo =
ResourceSyncInfo.buildResourceSyncInfo(platform);
+ Set<ResourceSyncInfo> topLevelServiceSyncInfo =
getToplevelServiceSyncInfo(toplevelServices);
+ PlatformSyncInfo result = new PlatformSyncInfo(platformSyncInfo,
topLevelServiceSyncInfo, topLevelServerIds);
+
return result;
}
+ /**
+ * At the time of writing (4.10) platform top level services don't have children
so this will be quick, but
+ * write it to handle any future children. In general this will still be a
relatively small number of resources.
+ *
+ * @param topLevelServices
+ * @return The top level service hierarchy sync info
+ */
+ private Set<ResourceSyncInfo> getToplevelServiceSyncInfo(Set<Resource>
topLevelServices) {
+ Set<ResourceSyncInfo> result = new
HashSet<ResourceSyncInfo>(topLevelServices.size());
+ Set<Integer> topLevelServiceIds = new HashSet<Integer>();
+
+ for (Resource topLevelService : topLevelServices) {
+ result.add(ResourceSyncInfo.buildResourceSyncInfo(topLevelService));
+ topLevelServiceIds.add(topLevelService.getId());
+ }
+
+ getToplevelServiceSyncInfoHierarchy(topLevelServiceIds, result);
+
+ return result;
+ }
+
+ private void getToplevelServiceSyncInfoHierarchy(Set<Integer> parentIds,
Set<ResourceSyncInfo> result) {
+ if (parentIds.isEmpty()) {
+ return;
+ }
+
+ Query q =
entityManager.createNamedQuery(ResourceSyncInfo.QUERY_SERVICE_CHILDREN);
+ q.setParameter("parentIds", parentIds);
+ List<ResourceSyncInfo> childSyncInfos = q.getResultList();
+
+ if (!childSyncInfos.isEmpty()) {
+ result.addAll(childSyncInfos);
+
+ Set<Integer> childIds = new
HashSet<Integer>(childSyncInfos.size());
+ for (ResourceSyncInfo childSyncInfo : childSyncInfos) {
+ childIds.add(childSyncInfo.getId());
+ }
+ getToplevelServiceSyncInfoHierarchy(childIds, result);
+ }
+ }
+
@Override
- public ResourceSyncInfo getResourceSyncInfo(int resourceId) {
- // [PERF] this is expensive, it let's hibernate grab the whole hierarchy via
eager fetch of children.
- ResourceSyncInfo result = entityManager.find(ResourceSyncInfo.class,
resourceId);
+ public Collection<ResourceSyncInfo> getResourceSyncInfo(int resourceId) {
+ // [PERF] this is an expensive query that can return a large collection. But
it's faster than the old way of
+ // letting hibernate grab the whole hierarchy via eager fetch of children...
+ Query q =
entityManager.createNamedQuery(ResourceSyncInfo.QUERY_TOP_LEVEL_SERVER);
+ q.setParameter("resourceId", resourceId);
+
+ Collection<ResourceSyncInfo> result = q.getResultList();
return result;
}
@@ -360,7 +425,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
servers = attachedServers;
// Update and persist the actual inventory statuses
- // This is done is a separate transaction to stop failures in the agent from
rolling back the transaction
+ // This is done in a separate transaction to stop failures in the agent from
rolling back the transaction
discoveryBoss.updateInventoryStatusInNewTransaction(user, platforms, servers,
status);
scheduleAgentInventoryOperationJob(platforms, servers);
@@ -422,7 +487,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
}
/**
- * Synchronize the agents inventory status for platforms, and then the servers,
+ * Synchronize the agent's inventory status for platforms, and then the servers,
* omitting servers under synced platforms since they will have been handled
* already. On status change request an agent sync on the affected resources.
* The agent will sync status and determine what other sync work needs to be
@@ -438,8 +503,9 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
AgentClient agentClient = agentManager.getAgentClient(platform.getAgent());
if (agentClient != null) {
try {
- syncInfo = entityManager.find(ResourceSyncInfo.class,
platform.getId());
-
agentClient.getDiscoveryAgentService().synchronizeInventory(syncInfo);
+ //syncInfo = entityManager.find(ResourceSyncInfo.class,
platform.getId());
+ PlatformSyncInfo platformSyncInfo =
getPlatformSyncInfo(platform.getAgent());
+
agentClient.getDiscoveryAgentService().synchronizePlatform(platformSyncInfo);
} catch (Exception e) {
LOG.warn("Could not perform commit synchronization with agent
for platform [" + platform.getName()
+ "]", e);
@@ -455,8 +521,9 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
AgentClient agentClient =
agentManager.getAgentClient(server.getAgent());
if (agentClient != null) {
try {
- syncInfo = entityManager.find(ResourceSyncInfo.class,
server.getId());
-
agentClient.getDiscoveryAgentService().synchronizeInventory(syncInfo);
+ //syncInfo = entityManager.find(ResourceSyncInfo.class,
server.getId());
+ Collection<ResourceSyncInfo> syncInfos =
getResourceSyncInfo(server.getId());
+
agentClient.getDiscoveryAgentService().synchronizeServer(server.getId(), syncInfos);
} catch (Exception e) {
LOG.warn("Could not perform commit synchronization with
agent for server [" + server.getName()
+ "]", e);
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
index 7ed9445..85b55f0 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossLocal.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.server.discovery;
+import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
@@ -87,9 +88,11 @@ public interface DiscoveryBossLocal extends DiscoveryBossRemote {
/**
* @param resourceid the root resourceId on which we want to sync
- * @return null if resource not found, otherwise the entire tree rooted at the
specified resource
+ * @return null if resource not found, otherwise the entire tree rooted at the
specified resource, as an
+ * unordered collection. Although not strictly a Set (to save on computation) this
collection should not
+ * contain duplicates.
*/
- ResourceSyncInfo getResourceSyncInfo(int resourceId);
+ Collection<ResourceSyncInfo> getResourceSyncInfo(int resourceId);
/**
* Returns a map of platforms (the keys) and their servers (the values) that are in
the auto-discovery queue but not
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
index 533948b..8fd2cf2 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryServerServiceImpl.java
@@ -19,6 +19,7 @@
package org.rhq.enterprise.server.discovery;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -121,10 +122,10 @@ public class DiscoveryServerServiceImpl implements
DiscoveryServerService {
}
@Override
- public ResourceSyncInfo getResourceSyncInfo(int resourceId) {
+ public Collection<ResourceSyncInfo> getResourceSyncInfo(int resourceId) {
long start = System.currentTimeMillis();
DiscoveryBossLocal discoveryBoss = LookupUtil.getDiscoveryBoss();
- ResourceSyncInfo results;
+ Collection<ResourceSyncInfo> results;
results = discoveryBoss.getResourceSyncInfo(resourceId);
commit e8b4257d03e566107be564cfa5f71db594589afc
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Jan 2 10:50:02 2014 -0500
BZ 994250 - finish the merging/peer review for patches submitted so that rhqctl
returns proper exit codes. Note that this completes the merge of the two submitted patches
- see prior two commits to this one. This third commit fixes some problems with the
original patches: 1. Some scripts/files are not found in bin/internal of the distro, but
rather are in bin/ - so we need to avoid using getBinDir() in those cases 2. Fix the code
to conform to code conventions - DEATH TO TABS! 3. Remove a constant that got resurrected
(ControlCommand.RHQ_STORAGE_BASEDIR_PROP is no longer needed) 4. A couple other minor
things
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
index 5db80a1..a13a598 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
@@ -60,7 +60,6 @@ public abstract class ControlCommand {
public static final String SERVER_OPTION = "server";
public static final String STORAGE_OPTION = "storage";
public static final String AGENT_OPTION = "agent";
- public static final String RHQ_STORAGE_BASEDIR_PROP =
"rhq.storage.basedir";
public static final String RHQ_AGENT_BASEDIR_PROP = "rhq.agent.basedir";
protected static final String STORAGE_BASEDIR_NAME = "rhq-storage";
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
index 28a37de..88b085f 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
@@ -135,7 +135,7 @@ public class RHQControl {
} catch (Throwable t) {
log.warn("Failed to clean up after the failed installation attempt.
"
+ "You may have to clean up some things before attempting to
install again", t);
- rValue = EXIT_CODE_OPERATION_FAILED;
+ rValue = EXIT_CODE_OPERATION_FAILED;
}
}
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
index 1b3d47b..ed2b2f8 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
@@ -88,14 +88,14 @@ public abstract class AbstractInstall extends ControlCommand {
executor.setStreamHandler(new PumpStreamHandler());
org.apache.commons.exec.CommandLine commandLine;
- int rValue = RHQControl.EXIT_CODE_OK;
+ int rValue = RHQControl.EXIT_CODE_OK;
if (replaceExistingService) {
- commandLine = getCommandLine(batFile, "stop");
- rValue = Math.max(rValue, executor.execute(commandLine));
+ commandLine = getCommandLine(batFile, "stop");
+ rValue = Math.max(rValue, executor.execute(commandLine));
- commandLine = getCommandLine(batFile, "remove");
- rValue = Math.max(rValue, executor.execute(commandLine));
+ commandLine = getCommandLine(batFile, "remove");
+ rValue = Math.max(rValue, executor.execute(commandLine));
}
commandLine = getCommandLine(batFile, "install");
@@ -277,7 +277,7 @@ public abstract class AbstractInstall extends ControlCommand {
return RHQControl.EXIT_CODE_OK;
}
- int rValue = 0;
+ int rValue = 0;
try {
File agentBinDir = new File(agentBasedir, "bin");
@@ -317,7 +317,7 @@ public abstract class AbstractInstall extends ControlCommand {
throw e;
}
- return rValue;
+ return rValue;
}
protected int startAgent(final File agentBasedir) throws Exception {
@@ -366,7 +366,7 @@ public abstract class AbstractInstall extends ControlCommand {
Executor executor = new DefaultExecutor();
executor.setWorkingDirectory(agentBinDir);
executor.setStreamHandler(new PumpStreamHandler());
- org.apache.commons.exec.CommandLine commandLine =
getCommandLine("rhq-agent-wrapper", "stop");
+ org.apache.commons.exec.CommandLine commandLine;
int rValue = 0;
@@ -635,7 +635,7 @@ public abstract class AbstractInstall extends ControlCommand {
clearAgentPreferences();
int rValue = installAgent(agentBasedir);
configureAgent(agentBasedir, commandLine);
- return rValue;
+ return rValue;
}
private int installAgent(final File agentBasedir) throws IOException {
@@ -667,7 +667,7 @@ public abstract class AbstractInstall extends ControlCommand {
int exitValue = executor.execute(commandLine);
log.info("The agent installer finished running with exit value " +
exitValue);
- return exitValue;
+ return exitValue;
} catch (IOException e) {
log.error("An error occurred while running the agent installer: " +
e.getMessage());
throw e;
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
index 5d540a1..e2ef3a8 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
@@ -138,7 +138,7 @@ public class Start extends ControlCommand {
executor.setStreamHandler(new PumpStreamHandler());
org.apache.commons.exec.CommandLine commandLine;
- int rValue;
+ int rValue;
// Cassandra looks for JAVA_HOME or then defaults to PATH. We want it to use the
Java
// defined for RHQ, so make sure JAVA_HOME is set, and set to the RHQ Java for
the executor
@@ -167,7 +167,7 @@ public class Start extends ControlCommand {
// For now we are duplicating logic in the status command. This code will be
// replaced when we implement a rhq-storage.sh script.
if (isStorageRunning()) {
- String pid = getStoragePid();
+ String pid = getStoragePid();
System.out.println("RHQ storage node (pid " + pid + ") is
running");
rValue = RHQControl.EXIT_CODE_OK;
} else {
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
index a3920e0..7ef66b4 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
@@ -144,7 +144,7 @@ public class Stop extends AbstractInstall {
rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
}
} else {
- if(isStorageRunning()) {
+ if (isStorageRunning()) {
String pid = getStoragePid();
System.out.println("Stopping RHQ storage node...");
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
index cc3d8c2..e80edd9 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
@@ -186,7 +186,7 @@ public class Upgrade extends AbstractInstall {
return exitValue;
}
- // If any failures occur during upgrade, we know we need to reset
rhq-server.properties.
+ // If any failures occur during upgrade, we know we need to reset
rhq-server.properties.
final FileReverter serverPropFileReverter = new
FileReverter(getServerPropertiesFile());
addUndoTask(new ControlCommand.UndoTask("Reverting server properties
file") {
public void performUndoWork() throws Exception {
@@ -229,7 +229,7 @@ public class Upgrade extends AbstractInstall {
}
} catch (Throwable t) {
log.warn("Unable to stop services: " + t.getMessage());
- rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
+ rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
}
}
@@ -262,7 +262,7 @@ public class Upgrade extends AbstractInstall {
}
Executor executor = new DefaultExecutor();
- executor.setWorkingDirectory(getBinDir());
+ executor.setWorkingDirectory(new File(getBaseDir(), "bin")); //
data migrator script is not in bin/internal
executor.setStreamHandler(new PumpStreamHandler());
int exitValue = executor.execute(commandLine);
@@ -546,7 +546,7 @@ public class Upgrade extends AbstractInstall {
}
// now merge the old settings in with the default properties from the new server
install
- String newServerPropsFilePath = new File(getBinDir(),
"rhq-server.properties").getAbsolutePath();
+ String newServerPropsFilePath = new File(getBaseDir(),
"bin/rhq-server.properties").getAbsolutePath();
PropertiesFileUpdate newServerPropsFile = new
PropertiesFileUpdate(newServerPropsFilePath);
newServerPropsFile.update(oldServerProps);
commit 7f9d9c21135cd1d210438f48b7df0737709b5dfe
Author: burmanm <yak(a)iki.fi>
Date: Tue Aug 6 17:52:38 2013 +0200
Fix return codes of the rhqctl command, rebased to the 4.10 master.
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
index a13a598..5db80a1 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/ControlCommand.java
@@ -60,6 +60,7 @@ public abstract class ControlCommand {
public static final String SERVER_OPTION = "server";
public static final String STORAGE_OPTION = "storage";
public static final String AGENT_OPTION = "agent";
+ public static final String RHQ_STORAGE_BASEDIR_PROP =
"rhq.storage.basedir";
public static final String RHQ_AGENT_BASEDIR_PROP = "rhq.agent.basedir";
protected static final String STORAGE_BASEDIR_NAME = "rhq-storage";
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
index 88b085f..28a37de 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/RHQControl.java
@@ -135,7 +135,7 @@ public class RHQControl {
} catch (Throwable t) {
log.warn("Failed to clean up after the failed installation attempt.
"
+ "You may have to clean up some things before attempting to
install again", t);
- rValue = EXIT_CODE_OPERATION_FAILED;
+ rValue = EXIT_CODE_OPERATION_FAILED;
}
}
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
index ed2b2f8..1b3d47b 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/AbstractInstall.java
@@ -88,14 +88,14 @@ public abstract class AbstractInstall extends ControlCommand {
executor.setStreamHandler(new PumpStreamHandler());
org.apache.commons.exec.CommandLine commandLine;
- int rValue = RHQControl.EXIT_CODE_OK;
+ int rValue = RHQControl.EXIT_CODE_OK;
if (replaceExistingService) {
- commandLine = getCommandLine(batFile, "stop");
- rValue = Math.max(rValue, executor.execute(commandLine));
+ commandLine = getCommandLine(batFile, "stop");
+ rValue = Math.max(rValue, executor.execute(commandLine));
- commandLine = getCommandLine(batFile, "remove");
- rValue = Math.max(rValue, executor.execute(commandLine));
+ commandLine = getCommandLine(batFile, "remove");
+ rValue = Math.max(rValue, executor.execute(commandLine));
}
commandLine = getCommandLine(batFile, "install");
@@ -277,7 +277,7 @@ public abstract class AbstractInstall extends ControlCommand {
return RHQControl.EXIT_CODE_OK;
}
- int rValue = 0;
+ int rValue = 0;
try {
File agentBinDir = new File(agentBasedir, "bin");
@@ -317,7 +317,7 @@ public abstract class AbstractInstall extends ControlCommand {
throw e;
}
- return rValue;
+ return rValue;
}
protected int startAgent(final File agentBasedir) throws Exception {
@@ -366,7 +366,7 @@ public abstract class AbstractInstall extends ControlCommand {
Executor executor = new DefaultExecutor();
executor.setWorkingDirectory(agentBinDir);
executor.setStreamHandler(new PumpStreamHandler());
- org.apache.commons.exec.CommandLine commandLine;
+ org.apache.commons.exec.CommandLine commandLine =
getCommandLine("rhq-agent-wrapper", "stop");
int rValue = 0;
@@ -635,7 +635,7 @@ public abstract class AbstractInstall extends ControlCommand {
clearAgentPreferences();
int rValue = installAgent(agentBasedir);
configureAgent(agentBasedir, commandLine);
- return rValue;
+ return rValue;
}
private int installAgent(final File agentBasedir) throws IOException {
@@ -667,7 +667,7 @@ public abstract class AbstractInstall extends ControlCommand {
int exitValue = executor.execute(commandLine);
log.info("The agent installer finished running with exit value " +
exitValue);
- return exitValue;
+ return exitValue;
} catch (IOException e) {
log.error("An error occurred while running the agent installer: " +
e.getMessage());
throw e;
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
index e2ef3a8..5d540a1 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Start.java
@@ -138,7 +138,7 @@ public class Start extends ControlCommand {
executor.setStreamHandler(new PumpStreamHandler());
org.apache.commons.exec.CommandLine commandLine;
- int rValue;
+ int rValue;
// Cassandra looks for JAVA_HOME or then defaults to PATH. We want it to use the
Java
// defined for RHQ, so make sure JAVA_HOME is set, and set to the RHQ Java for
the executor
@@ -167,7 +167,7 @@ public class Start extends ControlCommand {
// For now we are duplicating logic in the status command. This code will be
// replaced when we implement a rhq-storage.sh script.
if (isStorageRunning()) {
- String pid = getStoragePid();
+ String pid = getStoragePid();
System.out.println("RHQ storage node (pid " + pid + ") is
running");
rValue = RHQControl.EXIT_CODE_OK;
} else {
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
index 7ef66b4..a3920e0 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Stop.java
@@ -144,7 +144,7 @@ public class Stop extends AbstractInstall {
rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
}
} else {
- if (isStorageRunning()) {
+ if(isStorageRunning()) {
String pid = getStoragePid();
System.out.println("Stopping RHQ storage node...");
diff --git
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
index e80edd9..cc3d8c2 100644
---
a/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
+++
b/modules/enterprise/server/server-control/src/main/java/org/rhq/server/control/command/Upgrade.java
@@ -186,7 +186,7 @@ public class Upgrade extends AbstractInstall {
return exitValue;
}
- // If any failures occur during upgrade, we know we need to reset
rhq-server.properties.
+ // If any failures occur during upgrade, we know we need to reset
rhq-server.properties.
final FileReverter serverPropFileReverter = new
FileReverter(getServerPropertiesFile());
addUndoTask(new ControlCommand.UndoTask("Reverting server properties
file") {
public void performUndoWork() throws Exception {
@@ -229,7 +229,7 @@ public class Upgrade extends AbstractInstall {
}
} catch (Throwable t) {
log.warn("Unable to stop services: " + t.getMessage());
- rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
+ rValue = RHQControl.EXIT_CODE_OPERATION_FAILED;
}
}
@@ -262,7 +262,7 @@ public class Upgrade extends AbstractInstall {
}
Executor executor = new DefaultExecutor();
- executor.setWorkingDirectory(new File(getBaseDir(), "bin")); //
data migrator script is not in bin/internal
+ executor.setWorkingDirectory(getBinDir());
executor.setStreamHandler(new PumpStreamHandler());
int exitValue = executor.execute(commandLine);
@@ -546,7 +546,7 @@ public class Upgrade extends AbstractInstall {
}
// now merge the old settings in with the default properties from the new server
install
- String newServerPropsFilePath = new File(getBaseDir(),
"bin/rhq-server.properties").getAbsolutePath();
+ String newServerPropsFilePath = new File(getBinDir(),
"rhq-server.properties").getAbsolutePath();
PropertiesFileUpdate newServerPropsFile = new
PropertiesFileUpdate(newServerPropsFilePath);
newServerPropsFile.update(oldServerProps);
commit 1eb8c728c0c1939115fe90bd1c91fbf5ecf0a036
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Tue Dec 17 21:35:47 2013 +0100
Bug 968361 - Improve database plugin design to support connection pooling
This changeset introduces a new API for database plugins and deprecates the previous
one. Compatibility with the previous API will be maintained until next major version of
RHQ.
The 'rhq-database-plugin' was based on
org.rhq.plugins.database.DatabaseComponent interface which encouraged plugin authors to
share a single JDBC connection across database components. This was wrong for various
reasons (connection leaks, concurrent JDBC calls... etc).
The new API introduces three important classes:
* org.rhq.plugins.database.PooledConnectionProvider
* org.rhq.plugins.database.BasePooledConnectionProvider
* org.rhq.plugins.database.ConnectionPoolingSupport
BasePooledConnectionProvider is a base implementation of a PooledConnectionProvider.
Plugin authors should create a concrete implementation of BasePooledConnectionProvider
which overrides the #getDriverClass() method. This is important if a database plugin
embeds a JDBC driver: the database-specific driver class must be loaded by the child
plugin classloader.
ConnectionPoolingSupport helps to manage the compatibility with the old API. It's
a contract that all new database resource components should obey to. It declares the
following methods:
* #supportsConnectionPooling()
* #getPooledConnectionProvider()
Results of calls to #supportsConnectionPooling() #getPooledConnectionProvider() must
be consistent. In practice, a top level server database component should be able to create
a PooledConnectionProvider instance, and child servers and services should indicate they
support connection pooling only if their parent component does.
The 'rhq-database-plugin' embeds the BoneCP library (JDBC connection pooling)
and its dependencies (Google's Guava). Child plugins will have all the classes
accessible as soon as they have this node in their plugin descriptor:
===
<depends plugin="Database" useClasses="true"/>
===
This changeset includes the necessary changes to support connection pooling in the
Oracle, Postgres and MySQL plugins.
Thanks to Elias Ross for contributing the original patch from which this changeset is
derived.
diff --git
a/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
b/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
deleted file mode 100644
index 6c81332..0000000
---
a/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
- * All rights reserved.
- *
- * This program 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 version 2 of the License.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-package org.rhq.plugins.mysql;
-
-import java.sql.Connection;
-import java.sql.Driver;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.util.HashMap;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * A class to manage the connections to MySQL
- * This class keeps a cache of connections to MySQL and reuses them on demand
- * We assume single threaded access to the Connection in the agent
- * this will need to be reworked if that assumption is not correct
- * @author Steve Millidge (C2B2 Consulting Limited)
- */
-class MySqlConnectionManager {
-
- private HashMap<MySqlConnectionInfo, Connection> connections;
- private static MySqlConnectionManager singleton;
- private Log logger = LogFactory.getLog(MySqlConnectionManager.class);
-
- private MySqlConnectionManager() {
- connections = new HashMap<MySqlConnectionInfo,Connection>();
- }
-
- static MySqlConnectionManager getConnectionManager() {
- if (singleton == null) {
- singleton = new MySqlConnectionManager();
- }
- return singleton;
- }
-
- public void shutdown() {
- Driver driver = null;
- for (Connection conn : connections.values()) {
- try {
- if (driver == null) {
- String driverName = conn.getMetaData().getDriverName();
- driver = DriverManager.getDriver(driverName);
- }
- conn.close();
- }catch(SQLException e) { logger.info("Problem closing connection on
Shutdown ignoring...");}
- }
- // deregister driver as well
- if (driver != null) {
- try {
- DriverManager.deregisterDriver(driver);
- } catch (SQLException ex) {
- logger.warn("Unable to deregister MySQL Driver on shutdown");
- }
- }
- }
-
- void closeConnection(MySqlConnectionInfo info) {
- Connection conn = connections.get(info);
- if (conn != null) {
- try {
- if (logger.isDebugEnabled()) {
- logger.debug("Closing Connection to " + info.buildURL());
- }
- conn.close();
- } catch (SQLException e) {
- logger.warn("Problem closing connection to " + info.buildURL()
+ " on close");
- }
- }
- connections.remove(info);
- }
-
- Connection getConnection (MySqlConnectionInfo info) throws SQLException {
- try {
- Class.forName("com.mysql.jdbc.Driver");
- } catch (Exception ex) {
- logger.error("Unable to find com.mysql.jdbc.Driver");
- }
-
- Connection conn = connections.get(info);
- String url = info.buildURL();
- if (conn == null) {
- if (logger.isInfoEnabled()) {
- logger.info("Attemping connection to " + url);
- }
- conn = DriverManager.getConnection(url,info.getUser(), info.getPassword());
- if (logger.isInfoEnabled()) {
- logger.info("Successfully connected to " + url);
- }
- connections.put(info, conn);
- } else {
- if (logger.isDebugEnabled()) {
- logger.debug("Reusing existing connection to " + url);
- }
- }
-
- // check the validity of the connection
- if (!conn.isValid(0)) {
- // attempt a single reconnect here and now
- conn.close();
- conn = DriverManager.getConnection(url,info.getUser(), info.getPassword());
- connections.put(info, conn);
- logger.info("Refreshed a connection to " + url);
- }
- return conn;
- }
-
-}
commit ec1dee4e898b0383c09df083c0d8cb999aa70e85
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Mon Dec 23 14:50:55 2013 +0100
Plugin validation for mysql plugin was failing because the Class.forName() statement
was invoked from the constructor of the component. I moved this code to the method that
actually opens the connection. This is the same strategy we use with our postgres plugin.
diff --git
a/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
b/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
new file mode 100644
index 0000000..6c81332
--- /dev/null
+++
b/modules/plugins/mysql/src/main/java/org/rhq/plugins/mysql/MySqlConnectionManager.java
@@ -0,0 +1,125 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2008 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program 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 version 2 of the License.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.plugins.mysql;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.HashMap;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * A class to manage the connections to MySQL
+ * This class keeps a cache of connections to MySQL and reuses them on demand
+ * We assume single threaded access to the Connection in the agent
+ * this will need to be reworked if that assumption is not correct
+ * @author Steve Millidge (C2B2 Consulting Limited)
+ */
+class MySqlConnectionManager {
+
+ private HashMap<MySqlConnectionInfo, Connection> connections;
+ private static MySqlConnectionManager singleton;
+ private Log logger = LogFactory.getLog(MySqlConnectionManager.class);
+
+ private MySqlConnectionManager() {
+ connections = new HashMap<MySqlConnectionInfo,Connection>();
+ }
+
+ static MySqlConnectionManager getConnectionManager() {
+ if (singleton == null) {
+ singleton = new MySqlConnectionManager();
+ }
+ return singleton;
+ }
+
+ public void shutdown() {
+ Driver driver = null;
+ for (Connection conn : connections.values()) {
+ try {
+ if (driver == null) {
+ String driverName = conn.getMetaData().getDriverName();
+ driver = DriverManager.getDriver(driverName);
+ }
+ conn.close();
+ }catch(SQLException e) { logger.info("Problem closing connection on
Shutdown ignoring...");}
+ }
+ // deregister driver as well
+ if (driver != null) {
+ try {
+ DriverManager.deregisterDriver(driver);
+ } catch (SQLException ex) {
+ logger.warn("Unable to deregister MySQL Driver on shutdown");
+ }
+ }
+ }
+
+ void closeConnection(MySqlConnectionInfo info) {
+ Connection conn = connections.get(info);
+ if (conn != null) {
+ try {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Closing Connection to " + info.buildURL());
+ }
+ conn.close();
+ } catch (SQLException e) {
+ logger.warn("Problem closing connection to " + info.buildURL()
+ " on close");
+ }
+ }
+ connections.remove(info);
+ }
+
+ Connection getConnection (MySqlConnectionInfo info) throws SQLException {
+ try {
+ Class.forName("com.mysql.jdbc.Driver");
+ } catch (Exception ex) {
+ logger.error("Unable to find com.mysql.jdbc.Driver");
+ }
+
+ Connection conn = connections.get(info);
+ String url = info.buildURL();
+ if (conn == null) {
+ if (logger.isInfoEnabled()) {
+ logger.info("Attemping connection to " + url);
+ }
+ conn = DriverManager.getConnection(url,info.getUser(), info.getPassword());
+ if (logger.isInfoEnabled()) {
+ logger.info("Successfully connected to " + url);
+ }
+ connections.put(info, conn);
+ } else {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Reusing existing connection to " + url);
+ }
+ }
+
+ // check the validity of the connection
+ if (!conn.isValid(0)) {
+ // attempt a single reconnect here and now
+ conn.close();
+ conn = DriverManager.getConnection(url,info.getUser(), info.getPassword());
+ connections.put(info, conn);
+ logger.info("Refreshed a connection to " + url);
+ }
+ return conn;
+ }
+
+}