[rhq] modules/enterprise
by Jiri Kremser
modules/enterprise/gui/agentupdate-war/pom.xml | 153 +++++
modules/enterprise/gui/agentupdate-war/src/main/java/org/rhq/enterprise/gui/agentupdate/AgentUpdateServlet.java | 273 +++++++++
modules/enterprise/gui/agentupdate-war/src/main/webapp/index.html | 5
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/DownloadsView.java | 6
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SystemGWTServiceImpl.java | 10
modules/enterprise/gui/downloads-war/pom.xml | 153 +++++
modules/enterprise/gui/downloads-war/src/main/java/org/rhq/enterprise/gui/download/DownloadServlet.java | 295 ++++++++++
modules/enterprise/gui/pom.xml | 3
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/agentupdate/AgentUpdateServlet.java | 271 ---------
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/client/RemoteClientServlet.java | 196 ------
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/download/DownloadServlet.java | 293 ---------
modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/web.xml | 48 -
modules/enterprise/gui/remote-client-war/pom.xml | 153 +++++
modules/enterprise/gui/remote-client-war/src/main/java/org/rhq/enterprise/gui/client/RemoteClientServlet.java | 196 ++++++
modules/enterprise/gui/remote-client-war/src/main/webapp/index.html | 5
modules/enterprise/server/ear/pom.xml | 43 +
16 files changed, 1285 insertions(+), 818 deletions(-)
New commits:
commit a91848332427bcf365fccece1dcc6805009e68ad
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Tue Oct 1 00:58:38 2013 +0200
[BZ 1013489] - It is not possible to download an agent from RHQ server (HTTP Status 404) - Introducing three new simple wars for handling the "/agentupdate/{download|version}", "/client/{download|version}" and "/downloads/*". Besides fixing this bug, this commit should help to remove portal war in the future.
diff --git a/modules/enterprise/gui/agentupdate-war/pom.xml b/modules/enterprise/gui/agentupdate-war/pom.xml
new file mode 100644
index 0000000..a6a9182
--- /dev/null
+++ b/modules/enterprise/gui/agentupdate-war/pom.xml
@@ -0,0 +1,153 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-parent</artifactId>
+ <version>4.10.0-SNAPSHOT</version>
+ <relativePath>../../../../pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-agentupdate-war</artifactId>
+ <packaging>war</packaging>
+ <name>RHQ Enterprise Agent Update War</name>
+ <description>the RHQ Enterprise Agent Update webapp</description>
+
+ <dependencies>
+ <!-- Internal Deps -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-domain</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope> <!-- by rhq.ear (as ejb-jar) -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope> <!-- by rhq.ear (as ejb-jar) -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-util</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope> <!-- by rhq.ear -->
+ </dependency>
+
+ <!-- Import the Servlet API, we use provided scope as the API is included in JBoss AS 7 -->
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope> <!-- by JBossAS -->
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <!-- Set the name of the war, used as the context root when the app
+ is deployed -->
+ <finalName>rhq-agentupdate</finalName>
+ <plugins>
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <failOnMissingWebXml>false</failOnMissingWebXml>
+ <archive>
+ <manifest>
+ <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ </manifest>
+ <manifestEntries>
+ <Build-Number>${buildNumber}</Build-Number>
+ </manifestEntries>
+ </archive>
+ <webResources>
+ <resource>
+ <filtering>false</filtering>
+ <directory>${basedir}/src/main/webapp</directory>
+ </resource>
+ </webResources>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <profiles>
+ <profile>
+ <id>dev</id>
+
+ <properties>
+ <rhq.rootDir>../../../..</rhq.rootDir>
+ <rhq.containerDir>${rhq.rootDir}/${rhq.devContainerServerPath}</rhq.containerDir>
+ <rhq.deploymentName>${project.build.finalName}.war</rhq.deploymentName>
+ <rhq.deploymentDir>${rhq.containerDir}/${rhq.earDeployDir}/${rhq.deploymentName}</rhq.deploymentDir>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>deploy-classes</id>
+ <phase>compile</phase>
+ <configuration>
+ <target>
+ <property name="classes.dir" location="${rhq.deploymentDir}/WEB-INF/classes" />
+ <echo>*** Copying updated files from target/classes to ${classes.dir}...</echo>
+ <copy todir="${classes.dir}" verbose="${rhq.verbose}">
+ <fileset dir="target/classes" />
+ </copy>
+ <property name="deployment.dir" location="${rhq.deploymentDir}" />
+ <echo>*** Copying updated files from src${file.separator}main${file.separator}webapp${file.separator} to ${deployment.dir}${file.separator}...</echo>
+ <copy todir="${deployment.dir}" verbose="${rhq.verbose}">
+ <fileset dir="${basedir}/src/main/webapp" />
+ </copy>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>deploy</id>
+ <phase>package</phase>
+ <configuration>
+ <target>
+ <property name="deployment.dir" location="${rhq.deploymentDir}" />
+ <echo>*** Copying updated files from target${file.separator}${project.build.finalName}${file.separator} to ${deployment.dir}${file.separator}...</echo>
+ <copy todir="${deployment.dir}" verbose="${rhq.verbose}">
+ <fileset dir="${basedir}/target/${project.build.finalName}" />
+ </copy>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>undeploy</id>
+ <phase>clean</phase>
+ <configuration>
+ <target>
+ <property name="deployment.dir" location="${rhq.deploymentDir}" />
+ <echo>*** Deleting ${deployment.dir}${file.separator}...</echo>
+ <delete dir="${deployment.dir}" />
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/modules/enterprise/gui/agentupdate-war/src/main/java/org/rhq/enterprise/gui/agentupdate/AgentUpdateServlet.java b/modules/enterprise/gui/agentupdate-war/src/main/java/org/rhq/enterprise/gui/agentupdate/AgentUpdateServlet.java
new file mode 100644
index 0000000..a35a9c6
--- /dev/null
+++ b/modules/enterprise/gui/agentupdate-war/src/main/java/org/rhq/enterprise/gui/agentupdate/AgentUpdateServlet.java
@@ -0,0 +1,273 @@
+/*
+ * 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.enterprise.gui.agentupdate;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.cloud.Server.OperationMode;
+import org.rhq.core.domain.common.composite.SystemSetting;
+import org.rhq.core.domain.common.composite.SystemSettings;
+import org.rhq.core.util.exception.ThrowableUtil;
+import org.rhq.core.util.stream.StreamUtil;
+import org.rhq.enterprise.server.core.AgentManagerLocal;
+import org.rhq.enterprise.server.util.LookupUtil;
+
+/**
+ * Serves the agent update binary that is stored in the RHQ Server's download area.
+ * This servlet also provides version information regarding the version of the agent
+ * this servlet serves up as well as versions of agents the RHQ Server supports.
+ */
+@WebServlet(urlPatterns = {"/download", "/version"}, loadOnStartup = 1)
+public class AgentUpdateServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ // the system property that defines how many concurrent downloads we will allow
+ private static String SYSPROP_AGENT_DOWNLOADS_LIMIT = "rhq.server.agent-downloads-limit";
+
+ // if the system property is not set or invalid, this is the default limit for number of concurrent downloads
+ private static int DEFAULT_AGENT_DOWNLOADS_LIMIT = 45;
+
+ // the error code that will be returned if the server has been configured to disable agent updates
+ private static final int ERROR_CODE_AGENT_UPDATE_DISABLED = HttpServletResponse.SC_FORBIDDEN;
+
+ // the error code that will be returned if the server has too many agents downloading the agent update binary
+ private static final int ERROR_CODE_TOO_MANY_DOWNLOADS = HttpServletResponse.SC_SERVICE_UNAVAILABLE;
+
+ private AtomicInteger numActiveDownloads = null;
+
+ private Log log = LogFactory.getLog(this.getClass());
+
+ private AgentManagerLocal agentManager = null;
+
+ private boolean initialized = false;
+
+ @Override
+ public void init() throws ServletException {
+ log.info("Starting the RHQ agent update servlet");
+ numActiveDownloads = new AtomicInteger(0);
+ }
+
+ private synchronized void loadAgentUpdateBinaryInfo() throws ServletException {
+ if (!initialized) {
+ log.info("RHQ agent update servlet is looking up binary file information...");
+
+ // make sure we have a agent update binary file; log its location
+ try {
+ log.info("Agent Update Binary File: " + getAgentUpdateBinaryFile());
+ } catch (Throwable t) {
+ log.error("Missing agent update binary file - agents will not be able to update", t);
+ }
+
+ // make sure we create a version file if we have to by getting the version file now
+ try {
+ File versionFile = getAgentUpdateVersionFile();
+
+ // log the version info - this also makes sure we can read it back in
+ log.debug(versionFile + ": " + new String(StreamUtil.slurp(new FileInputStream(versionFile))));
+
+ } catch (Throwable t) {
+ log.error("Cannot determine the agent version information - agents will not be able to update.", t);
+ }
+
+ initialized = true;
+ }
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+
+ // lazily initialize the servlet - we do this because when we started deploying on AS7, our servlets
+ // init() method was being called before the agent SLSB is ready. So we don't init() this at startup,
+ // rather, we now init this servlet the first time someone requests the agent update binary file.
+ loadAgentUpdateBinaryInfo();
+
+ // seeing odd browser caching issues, even though we set Last-Modified. so force no caching for now
+ disableBrowserCache(resp);
+
+ String servletPath = req.getServletPath();
+ if (servletPath != null) {
+ if (isServerAcceptingRequests()) {
+ if (servletPath.endsWith("version")) {
+ getVersion(req, resp);
+ } else if (servletPath.endsWith("download")) {
+ try {
+ numActiveDownloads.incrementAndGet();
+ getDownload(req, resp);
+ } finally {
+ numActiveDownloads.decrementAndGet();
+ }
+ } else {
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid servlet path [" + servletPath
+ + "] - please contact administrator");
+ }
+ } else {
+ sendErrorServerNotAcceptingRequests(resp);
+ }
+ } else {
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid servlet path - please contact administrator");
+ }
+
+ return;
+ }
+
+ private void getDownload(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ int limit = getDownloadLimit();
+ if (limit <= 0) {
+ sendErrorAgentUpdateDisabled(resp);
+ return;
+ } else if (limit < numActiveDownloads.get()) {
+ sendErrorTooManyDownloads(resp);
+ return;
+ }
+
+ try {
+ File agentJar = getAgentUpdateBinaryFile();
+ resp.setContentType("application/octet-stream");
+ resp.setHeader("Content-Disposition", "attachment; filename=" + agentJar.getName());
+ resp.setContentLength((int) agentJar.length());
+ resp.setDateHeader("Last-Modified", agentJar.lastModified());
+
+ FileInputStream agentJarStream = new FileInputStream(agentJar);
+ try {
+ StreamUtil.copy(agentJarStream, resp.getOutputStream(), false);
+ } finally {
+ agentJarStream.close();
+ }
+ } catch (Throwable t) {
+ String clientAddr = getClientAddress(req);
+ log.error("Failed to stream agent jar to remote client [" + clientAddr + "]: "
+ + ThrowableUtil.getAllMessages(t));
+ disableBrowserCache(resp);
+ resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to stream agent jar");
+ }
+
+ return;
+ }
+
+ private void getVersion(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ try {
+ File versionFile = getAgentUpdateVersionFile();
+ resp.setContentType("text/plain");
+ resp.setDateHeader("Last-Modified", versionFile.lastModified());
+
+ FileInputStream stream = new FileInputStream(versionFile);
+ byte[] versionData = StreamUtil.slurp(stream);
+ resp.getOutputStream().write(versionData);
+ } catch (Throwable t) {
+ String clientAddr = getClientAddress(req);
+ log.error("Failed to stream version info to remote client [" + clientAddr + "]: "
+ + ThrowableUtil.getAllMessages(t));
+ disableBrowserCache(resp);
+ resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to stream version info");
+ }
+
+ return;
+ }
+
+ private int getDownloadLimit() {
+ // if the server cloud was configured to disallow updates, return 0
+ SystemSettings systemConfig = LookupUtil.getSystemManager().getSystemSettings(
+ LookupUtil.getSubjectManager().getOverlord());
+ if (!Boolean.parseBoolean(systemConfig.get(SystemSetting.AGENT_AUTO_UPDATE_ENABLED))) {
+ return 0;
+ }
+
+ String limitStr = System.getProperty(SYSPROP_AGENT_DOWNLOADS_LIMIT);
+ int limit;
+ try {
+ limit = Integer.parseInt(limitStr);
+ } catch (Exception e) {
+ limit = DEFAULT_AGENT_DOWNLOADS_LIMIT;
+ log.warn("Agent downloads limit system property [" + SYSPROP_AGENT_DOWNLOADS_LIMIT
+ + "] is either not set or invalid [" + limitStr + "] - limit will be [" + limit + "].");
+ }
+
+ return limit;
+ }
+
+ private void disableBrowserCache(HttpServletResponse resp) {
+ resp.setHeader("Cache-Control", "no-cache, no-store");
+ resp.setHeader("Expires", "-1");
+ resp.setHeader("Pragma", "no-cache");
+ }
+
+ private void sendErrorServerNotAcceptingRequests(HttpServletResponse resp) throws IOException {
+ disableBrowserCache(resp);
+ resp.sendError(ERROR_CODE_AGENT_UPDATE_DISABLED, "Server Is Down For Maintenance");
+ }
+
+ private void sendErrorAgentUpdateDisabled(HttpServletResponse resp) throws IOException {
+ disableBrowserCache(resp);
+ resp.sendError(ERROR_CODE_AGENT_UPDATE_DISABLED, "Agent Updates Has Been Disabled");
+ }
+
+ private void sendErrorTooManyDownloads(HttpServletResponse resp) throws IOException {
+ disableBrowserCache(resp);
+ resp.setHeader("Retry-After", "30");
+ resp.sendError(ERROR_CODE_TOO_MANY_DOWNLOADS, "Maximum limit exceeded - download agent later");
+ }
+
+ private File getAgentUpdateVersionFile() throws Exception {
+ return getAgentManager().getAgentUpdateVersionFile();
+ }
+
+ private File getAgentUpdateBinaryFile() throws Exception {
+ return getAgentManager().getAgentUpdateBinaryFile();
+ }
+
+ private AgentManagerLocal getAgentManager() {
+ if (this.agentManager == null) {
+ this.agentManager = LookupUtil.getAgentManager();
+ }
+ return this.agentManager;
+ }
+
+ private boolean isServerAcceptingRequests() {
+ try {
+ OperationMode mode = LookupUtil.getServerManager().getServer().getOperationMode();
+ return mode == OperationMode.NORMAL;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ private String getClientAddress(HttpServletRequest request) {
+ String ip = request.getHeader("X-Forwarded-For");
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = String.format("%s (%s)", request.getRemoteHost(), request.getRemoteAddr());
+ }
+ }
+ return ip;
+ }
+}
diff --git a/modules/enterprise/gui/agentupdate-war/src/main/webapp/index.html b/modules/enterprise/gui/agentupdate-war/src/main/webapp/index.html
new file mode 100644
index 0000000..5d7a115
--- /dev/null
+++ b/modules/enterprise/gui/agentupdate-war/src/main/webapp/index.html
@@ -0,0 +1,5 @@
+<html>
+ <head>
+ <meta http-equiv="Refresh" content="0; URL=version">
+ </head>
+</html>
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/DownloadsView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/DownloadsView.java
index 5f3b9b6..ed966c2 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/DownloadsView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/DownloadsView.java
@@ -53,8 +53,6 @@ public class DownloadsView extends EnhancedVLayout {
public static final String VIEW_PATH = AdministrationView.VIEW_ID + "/"
+ AdministrationView.SECTION_CONFIGURATION_VIEW_ID + "/" + VIEW_ID;
- private static final String PORTAL_WAR_CONTEXT = "/portal";
-
private final SystemGWTServiceAsync systemManager = GWTServiceLookup.getSystemService();
private SectionStack sectionStack;
@@ -145,7 +143,7 @@ public class DownloadsView extends EnhancedVLayout {
StaticTextItem linkItem = new StaticTextItem("agentLink");
linkItem.setTitle(MSG.common_label_link());
- linkItem.setValue("<a href=\"" + PORTAL_WAR_CONTEXT + "/agentupdate/download\">"
+ linkItem.setValue("<a href=\"/agentupdate/download\">"
+ MSG.view_admin_downloads_agent_link_value(version, build) + "</a>");
SpacerItem spacerItem = new SpacerItem("agentSpacer");
@@ -196,7 +194,7 @@ public class DownloadsView extends EnhancedVLayout {
StaticTextItem linkItem = new StaticTextItem("cliLink");
linkItem.setTitle(MSG.common_label_link());
- linkItem.setValue("<a href=\"" + PORTAL_WAR_CONTEXT + "/client/download\">"
+ linkItem.setValue("<a href=\"/client/download\">"
+ MSG.view_admin_downloads_cli_link_value(version, build) + "</a>");
SpacerItem spacerItem = new SpacerItem("clientSpacer");
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SystemGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SystemGWTServiceImpl.java
index 9792b5f..6c458e3 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SystemGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SystemGWTServiceImpl.java
@@ -48,8 +48,6 @@ public class SystemGWTServiceImpl extends AbstractGWTServiceImpl implements Syst
private static final long serialVersionUID = 1L;
- private static final String PORTAL_WAR_CONTEXT = "/portal";
-
private SystemManagerLocal systemManager = LookupUtil.getSystemManager();
private AgentManagerLocal agentManager = LookupUtil.getAgentManager();
private RemoteClientManagerLocal remoteClientManager = LookupUtil.getRemoteClientManager();
@@ -138,7 +136,7 @@ public class SystemGWTServiceImpl extends AbstractGWTServiceImpl implements Syst
HashMap<String, String> map = new HashMap<String, String>(files.size());
for (File file : files) {
// key is the filename, value is the relative URL to download the file from the server
- map.put(file.getName(), PORTAL_WAR_CONTEXT + "/downloads/connectors/" + file.getName());
+ map.put(file.getName(), "/downloads/connectors/" + file.getName());
}
return map;
} catch (Throwable t) {
@@ -158,7 +156,7 @@ public class SystemGWTServiceImpl extends AbstractGWTServiceImpl implements Syst
HashMap<String, String> ret = new HashMap<String, String>(files.size());
for (File file : files) {
- ret.put(file.getName(), PORTAL_WAR_CONTEXT + "/downloads/cli-alert-scripts/" + file.getName());
+ ret.put(file.getName(), "/downloads/cli-alert-scripts/" + file.getName());
}
return ret;
}
@@ -178,7 +176,7 @@ public class SystemGWTServiceImpl extends AbstractGWTServiceImpl implements Syst
HashMap<String, String> ret = new HashMap<String, String>(files.size());
for (File file : files) {
- ret.put(file.getName(), PORTAL_WAR_CONTEXT + "/downloads/script-modules/" + file.getName());
+ ret.put(file.getName(), "/downloads/script-modules/" + file.getName());
}
return ret;
}
@@ -207,7 +205,7 @@ public class SystemGWTServiceImpl extends AbstractGWTServiceImpl implements Syst
}
File file = files.get(0);
HashMap<String, String> ret = new HashMap<String, String>(1);
- ret.put(file.getName(), PORTAL_WAR_CONTEXT + "/downloads/bundle-deployer/" + file.getName());
+ ret.put(file.getName(), "/downloads/bundle-deployer/" + file.getName());
return ret;
} catch (Throwable t) {
throw getExceptionToThrowToClient(t);
diff --git a/modules/enterprise/gui/downloads-war/pom.xml b/modules/enterprise/gui/downloads-war/pom.xml
new file mode 100644
index 0000000..9d694cb
--- /dev/null
+++ b/modules/enterprise/gui/downloads-war/pom.xml
@@ -0,0 +1,153 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-parent</artifactId>
+ <version>4.10.0-SNAPSHOT</version>
+ <relativePath>../../../../pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-downloads-war</artifactId>
+ <packaging>war</packaging>
+ <name>RHQ Enterprise Downloads War</name>
+ <description>the RHQ Enterprise Downloads webapp</description>
+
+ <dependencies>
+ <!-- Internal Deps -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-domain</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope> <!-- by rhq.ear (as ejb-jar) -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope> <!-- by rhq.ear (as ejb-jar) -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-util</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope> <!-- by rhq.ear -->
+ </dependency>
+
+ <!-- Import the Servlet API, we use provided scope as the API is included in JBoss AS 7 -->
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope> <!-- by JBossAS -->
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <!-- Set the name of the war, used as the context root when the app
+ is deployed -->
+ <finalName>rhq-downloads</finalName>
+ <plugins>
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <failOnMissingWebXml>false</failOnMissingWebXml>
+ <archive>
+ <manifest>
+ <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ </manifest>
+ <manifestEntries>
+ <Build-Number>${buildNumber}</Build-Number>
+ </manifestEntries>
+ </archive>
+ <webResources>
+ <resource>
+ <filtering>false</filtering>
+ <directory>${basedir}/src/main/webapp</directory>
+ </resource>
+ </webResources>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <profiles>
+ <profile>
+ <id>dev</id>
+
+ <properties>
+ <rhq.rootDir>../../../..</rhq.rootDir>
+ <rhq.containerDir>${rhq.rootDir}/${rhq.devContainerServerPath}</rhq.containerDir>
+ <rhq.deploymentName>${project.build.finalName}.war</rhq.deploymentName>
+ <rhq.deploymentDir>${rhq.containerDir}/${rhq.earDeployDir}/${rhq.deploymentName}</rhq.deploymentDir>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>deploy-classes</id>
+ <phase>compile</phase>
+ <configuration>
+ <target>
+ <property name="classes.dir" location="${rhq.deploymentDir}/WEB-INF/classes" />
+ <echo>*** Copying updated files from target/classes to ${classes.dir}...</echo>
+ <copy todir="${classes.dir}" verbose="${rhq.verbose}">
+ <fileset dir="target/classes" />
+ </copy>
+ <property name="deployment.dir" location="${rhq.deploymentDir}" />
+ <echo>*** Copying updated files from src${file.separator}main${file.separator}webapp${file.separator} to ${deployment.dir}${file.separator}...</echo>
+ <copy todir="${deployment.dir}" verbose="${rhq.verbose}">
+ <fileset dir="${basedir}/src/main/webapp" />
+ </copy>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>deploy</id>
+ <phase>package</phase>
+ <configuration>
+ <target>
+ <property name="deployment.dir" location="${rhq.deploymentDir}" />
+ <echo>*** Copying updated files from target${file.separator}${project.build.finalName}${file.separator} to ${deployment.dir}${file.separator}...</echo>
+ <copy todir="${deployment.dir}" verbose="${rhq.verbose}">
+ <fileset dir="${basedir}/target/${project.build.finalName}" />
+ </copy>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>undeploy</id>
+ <phase>clean</phase>
+ <configuration>
+ <target>
+ <property name="deployment.dir" location="${rhq.deploymentDir}" />
+ <echo>*** Deleting ${deployment.dir}${file.separator}...</echo>
+ <delete dir="${deployment.dir}" />
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/modules/enterprise/gui/downloads-war/src/main/java/org/rhq/enterprise/gui/download/DownloadServlet.java b/modules/enterprise/gui/downloads-war/src/main/java/org/rhq/enterprise/gui/download/DownloadServlet.java
new file mode 100644
index 0000000..a6b6818
--- /dev/null
+++ b/modules/enterprise/gui/downloads-war/src/main/java/org/rhq/enterprise/gui/download/DownloadServlet.java
@@ -0,0 +1,295 @@
+/*
+ * 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.enterprise.gui.download;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.cloud.Server.OperationMode;
+import org.rhq.core.util.stream.StreamUtil;
+import org.rhq.enterprise.server.util.LookupUtil;
+
+/**
+ * Serves the static content found in rhq-downloads.
+ */
+@WebServlet(urlPatterns = {"/*"}, loadOnStartup = 1)
+public class DownloadServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ // the system property that disables/enables file listing - default is to show the listing
+ private static String SYSPROP_SHOW_DOWNLOADS_LISTING = "rhq.server.show-downloads-listing";
+
+ private static int numActiveDownloads = 0;
+ private static boolean showDownloadsListing;
+
+ private Log log = LogFactory.getLog(this.getClass());
+
+ @Override
+ public void init() throws ServletException {
+ log.info("Starting the RHQ download servlet...");
+
+ String propValue = System.getProperty(SYSPROP_SHOW_DOWNLOADS_LISTING, "true");
+ showDownloadsListing = Boolean.parseBoolean(propValue);
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+
+ // seeing odd browser caching issues, even though we set Last-Modified. so force no caching for now
+ disableBrowserCache(resp);
+
+ if (isServerAcceptingRequests()) {
+ String requestedDirectory = getRequestedDirectory(req);
+ if (requestedDirectory == null) {
+ numActiveDownloads++;
+ download(req, resp);
+ numActiveDownloads--;
+ } else {
+ if (showDownloadsListing) {
+ outputFileList(requestedDirectory, req, resp);
+ } else {
+ disableBrowserCache(resp);
+ resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Listing disabled");
+ }
+ }
+ } else {
+ sendErrorServerNotAcceptingRequests(resp);
+ }
+ return;
+ }
+
+ /**
+ * Returns the relative path of the requested directory but only if it exists in
+ * one of the root directories. If the requested path is a file or the directory
+ * doesn't exist under a root directory, null is returned.
+ *
+ * @param req
+ * @return relative path of the directory being requested
+ * @throws ServletException
+ */
+ private String getRequestedDirectory(HttpServletRequest req) throws ServletException {
+
+ String pathInfo = req.getPathInfo();
+
+ File[] rootDownloadsDirs;
+ try {
+ rootDownloadsDirs = getRootDownloadsDirs();
+ } catch (Throwable t) {
+ throw new ServletException(t);
+ }
+
+ if (pathInfo == null || pathInfo.equals("") || pathInfo.equals("/")) {
+ return "";
+ }
+
+ for (File rootDownloadsDir : rootDownloadsDirs) {
+ File downloadDir = new File(rootDownloadsDir, pathInfo);
+ if (downloadDir.isDirectory()) {
+ return pathInfo;
+ }
+ }
+
+ // either the path does not exist or its a file, not a directory
+ return null;
+ }
+
+ private void download(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ try {
+ if (isForbiddenPath(req.getPathInfo(), resp)) {
+ return;
+ }
+
+ // look for the file in one of the root download directories
+ File fileToDownload = null;
+ File[] downloadDirs = getRootDownloadsDirs();
+ for (File downloadDir : downloadDirs) {
+ File file = new File(downloadDir, req.getPathInfo());
+ if (file.exists()) {
+ fileToDownload = file;
+ break;
+ }
+ }
+
+ if (fileToDownload == null) {
+ disableBrowserCache(resp);
+ resp.sendError(HttpServletResponse.SC_NOT_FOUND, "File does not exist: " + req.getPathInfo());
+ return;
+ }
+
+ resp.setContentType(getMimeType(fileToDownload));
+ resp.setHeader("Content-Disposition", "attachment; filename=" + fileToDownload.getName());
+ resp.setContentLength((int) fileToDownload.length());
+ resp.setDateHeader("Last-Modified", fileToDownload.lastModified());
+
+ FileInputStream stream = new FileInputStream(fileToDownload);
+ try {
+ StreamUtil.copy(stream, resp.getOutputStream(), false);
+ } finally {
+ stream.close();
+ }
+ } catch (Throwable t) {
+ log.error("Failed to stream download content.", t);
+ disableBrowserCache(resp);
+ resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to download content");
+ }
+
+ return;
+ }
+
+ private String getMimeType(File file) {
+ String mimeType = null;
+
+ try {
+ mimeType = getServletContext().getMimeType(file.getName());
+ } catch (Throwable t) {
+ // i'm paranoid, no idea if this will ever happen, but its not fatal so keep going
+ log.warn("Failed to get mime type for [" + file + "].", t);
+ }
+
+ if (mimeType == null) {
+ mimeType = "application/octet-stream";
+ }
+ return mimeType;
+ }
+
+ private void outputFileList(String requestedDirectory, HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException {
+
+ try {
+ if (!isForbiddenPath(requestedDirectory, resp)) {
+ File requestedDirectoryRelativePath = new File(requestedDirectory);
+ String dirName = requestedDirectoryRelativePath.getName();
+ disableBrowserCache(resp);
+ resp.setContentType("text/html");
+ PrintWriter writer = resp.getWriter();
+ writer.println(String.format("<html><head><title>Available Downloads: %s</title></head>", dirName));
+ writer.println("<body><h1>Available Downloads</h1>");
+ writer.println(String.format("<font size=\"+2\"><b><pre>%s</pre></b></font>", dirName));
+ List<File> files = getDownloadFiles(requestedDirectory);
+ if (files.size() > 0) {
+ String pathInfo = req.getPathInfo();
+ if (!pathInfo.endsWith("/")) {
+ pathInfo += "/";
+ }
+ writer.println("<ul>");
+ for (File file : files) {
+ writer.println("<li><a href=\"" + req.getContextPath() + req.getServletPath() + pathInfo + file.getName() + "\">"
+ + file.getName() + "</a></li>");
+ }
+ writer.println("</ul>");
+ } else {
+ writer.println("<h4>NONE</h4>");
+ }
+ writer.println("</body></html>");
+ }
+ } catch (Exception e) {
+ throw new ServletException("Cannot get downloads listing", e);
+ }
+ }
+
+ private boolean isForbiddenPath(String requestedPath, HttpServletResponse resp) throws IOException {
+ boolean forbidden = true; // assume it is forbidden
+ if (requestedPath.toString().contains("rhq-agent")) {
+ resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Use /agentupdate/download to obtain the agent");
+ } else if (requestedPath.toString().contains("rhq-client")) {
+ resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Use /client/download to obtain the client");
+ } else {
+ forbidden = false;
+ }
+ return forbidden;
+ }
+
+ private void sendErrorServerNotAcceptingRequests(HttpServletResponse resp) throws IOException {
+ disableBrowserCache(resp);
+ resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Server Is Down For Maintenance");
+ }
+
+ private void disableBrowserCache(HttpServletResponse resp) {
+ resp.setHeader("Cache-Control", "no-cache, no-store");
+ resp.setHeader("Expires", "-1");
+ resp.setHeader("Pragma", "no-cache");
+ }
+
+ private List<File> getDownloadFiles(String requestedDirectory) throws Exception {
+ // its possible if more than one root dir has the file, we'll get duplicates.
+ // this should never happen, so ignore this edge case.
+ List<File> returnFiles = new ArrayList<File>();
+ File[] rootDownloadDirs = getRootDownloadsDirs();
+ for (File rootDownloadDir : rootDownloadDirs) {
+ File dir = new File(rootDownloadDir, requestedDirectory);
+ File[] filesArray = dir.listFiles();
+ // this is simple - we only serve up files located in the requested directory - no content from subdirectories
+ if (filesArray != null) {
+ for (File file : filesArray) {
+ if (file.isFile()) {
+ returnFiles.add(file);
+ }
+ }
+ }
+ }
+
+ return returnFiles;
+ }
+
+ /**
+ * There are two locations for downloads - the static content under the EAR's rhq-downloads
+ * and dynamic content in the data directory.
+ *
+ * @return the two root locations
+ *
+ * @throws Exception
+ */
+ private File[] getRootDownloadsDirs() throws Exception {
+ File earDir = LookupUtil.getCoreServer().getEarDeploymentDir();
+ File downloadDir = new File(earDir, "rhq-downloads");
+ if (!downloadDir.exists()) {
+ throw new FileNotFoundException("Missing downloads directory at [" + downloadDir + "]");
+ }
+
+ File dataDir = LookupUtil.getCoreServer().getJBossServerDataDir();
+ File dataDownloadDir = new File(dataDir, "rhq-downloads");
+
+ return new File[] { dataDownloadDir, downloadDir }; // put the data dir first, I think that should take precedence
+ }
+
+ private boolean isServerAcceptingRequests() {
+ try {
+ OperationMode mode = LookupUtil.getServerManager().getServer().getOperationMode();
+ return mode == OperationMode.NORMAL;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+}
diff --git a/modules/enterprise/gui/pom.xml b/modules/enterprise/gui/pom.xml
index 648d913..31f5d8c 100644
--- a/modules/enterprise/gui/pom.xml
+++ b/modules/enterprise/gui/pom.xml
@@ -28,6 +28,9 @@
</activation>
<modules>
<module>portal-war</module>
+ <module>remote-client-war</module>
+ <module>agentupdate-war</module>
+ <module>downloads-war</module>
<module>content_http-war</module>
<module>coregui</module>
<module>rest-war</module>
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/agentupdate/AgentUpdateServlet.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/agentupdate/AgentUpdateServlet.java
deleted file mode 100644
index d115187..0000000
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/agentupdate/AgentUpdateServlet.java
+++ /dev/null
@@ -1,271 +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.enterprise.gui.agentupdate;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.rhq.core.domain.cloud.Server.OperationMode;
-import org.rhq.core.domain.common.composite.SystemSetting;
-import org.rhq.core.domain.common.composite.SystemSettings;
-import org.rhq.core.util.exception.ThrowableUtil;
-import org.rhq.core.util.stream.StreamUtil;
-import org.rhq.enterprise.server.core.AgentManagerLocal;
-import org.rhq.enterprise.server.util.LookupUtil;
-
-/**
- * Serves the agent update binary that is stored in the RHQ Server's download area.
- * This servlet also provides version information regarding the version of the agent
- * this servlet serves up as well as versions of agents the RHQ Server supports.
- */
-public class AgentUpdateServlet extends HttpServlet {
-
- private static final long serialVersionUID = 1L;
-
- // the system property that defines how many concurrent downloads we will allow
- private static String SYSPROP_AGENT_DOWNLOADS_LIMIT = "rhq.server.agent-downloads-limit";
-
- // if the system property is not set or invalid, this is the default limit for number of concurrent downloads
- private static int DEFAULT_AGENT_DOWNLOADS_LIMIT = 45;
-
- // the error code that will be returned if the server has been configured to disable agent updates
- private static final int ERROR_CODE_AGENT_UPDATE_DISABLED = HttpServletResponse.SC_FORBIDDEN;
-
- // the error code that will be returned if the server has too many agents downloading the agent update binary
- private static final int ERROR_CODE_TOO_MANY_DOWNLOADS = HttpServletResponse.SC_SERVICE_UNAVAILABLE;
-
- private AtomicInteger numActiveDownloads = null;
-
- private Log log = LogFactory.getLog(this.getClass());
-
- private AgentManagerLocal agentManager = null;
-
- private boolean initialized = false;
-
- @Override
- public void init() throws ServletException {
- log.info("Starting the RHQ agent update servlet");
- numActiveDownloads = new AtomicInteger(0);
- }
-
- private synchronized void loadAgentUpdateBinaryInfo() throws ServletException {
- if (!initialized) {
- log.info("RHQ agent update servlet is looking up binary file information...");
-
- // make sure we have a agent update binary file; log its location
- try {
- log.info("Agent Update Binary File: " + getAgentUpdateBinaryFile());
- } catch (Throwable t) {
- log.error("Missing agent update binary file - agents will not be able to update", t);
- }
-
- // make sure we create a version file if we have to by getting the version file now
- try {
- File versionFile = getAgentUpdateVersionFile();
-
- // log the version info - this also makes sure we can read it back in
- log.debug(versionFile + ": " + new String(StreamUtil.slurp(new FileInputStream(versionFile))));
-
- } catch (Throwable t) {
- log.error("Cannot determine the agent version information - agents will not be able to update.", t);
- }
-
- initialized = true;
- }
- }
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-
- // lazily initialize the servlet - we do this because when we started deploying on AS7, our servlets
- // init() method was being called before the agent SLSB is ready. So we don't init() this at startup,
- // rather, we now init this servlet the first time someone requests the agent update binary file.
- loadAgentUpdateBinaryInfo();
-
- // seeing odd browser caching issues, even though we set Last-Modified. so force no caching for now
- disableBrowserCache(resp);
-
- String servletPath = req.getServletPath();
- if (servletPath != null) {
- if (isServerAcceptingRequests()) {
- if (servletPath.endsWith("version")) {
- getVersion(req, resp);
- } else if (servletPath.endsWith("download")) {
- try {
- numActiveDownloads.incrementAndGet();
- getDownload(req, resp);
- } finally {
- numActiveDownloads.decrementAndGet();
- }
- } else {
- resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid servlet path [" + servletPath
- + "] - please contact administrator");
- }
- } else {
- sendErrorServerNotAcceptingRequests(resp);
- }
- } else {
- resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid servlet path - please contact administrator");
- }
-
- return;
- }
-
- private void getDownload(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- int limit = getDownloadLimit();
- if (limit <= 0) {
- sendErrorAgentUpdateDisabled(resp);
- return;
- } else if (limit < numActiveDownloads.get()) {
- sendErrorTooManyDownloads(resp);
- return;
- }
-
- try {
- File agentJar = getAgentUpdateBinaryFile();
- resp.setContentType("application/octet-stream");
- resp.setHeader("Content-Disposition", "attachment; filename=" + agentJar.getName());
- resp.setContentLength((int) agentJar.length());
- resp.setDateHeader("Last-Modified", agentJar.lastModified());
-
- FileInputStream agentJarStream = new FileInputStream(agentJar);
- try {
- StreamUtil.copy(agentJarStream, resp.getOutputStream(), false);
- } finally {
- agentJarStream.close();
- }
- } catch (Throwable t) {
- String clientAddr = getClientAddress(req);
- log.error("Failed to stream agent jar to remote client [" + clientAddr + "]: "
- + ThrowableUtil.getAllMessages(t));
- disableBrowserCache(resp);
- resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to stream agent jar");
- }
-
- return;
- }
-
- private void getVersion(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- try {
- File versionFile = getAgentUpdateVersionFile();
- resp.setContentType("text/plain");
- resp.setDateHeader("Last-Modified", versionFile.lastModified());
-
- FileInputStream stream = new FileInputStream(versionFile);
- byte[] versionData = StreamUtil.slurp(stream);
- resp.getOutputStream().write(versionData);
- } catch (Throwable t) {
- String clientAddr = getClientAddress(req);
- log.error("Failed to stream version info to remote client [" + clientAddr + "]: "
- + ThrowableUtil.getAllMessages(t));
- disableBrowserCache(resp);
- resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to stream version info");
- }
-
- return;
- }
-
- private int getDownloadLimit() {
- // if the server cloud was configured to disallow updates, return 0
- SystemSettings systemConfig = LookupUtil.getSystemManager().getSystemSettings(
- LookupUtil.getSubjectManager().getOverlord());
- if (!Boolean.parseBoolean(systemConfig.get(SystemSetting.AGENT_AUTO_UPDATE_ENABLED))) {
- return 0;
- }
-
- String limitStr = System.getProperty(SYSPROP_AGENT_DOWNLOADS_LIMIT);
- int limit;
- try {
- limit = Integer.parseInt(limitStr);
- } catch (Exception e) {
- limit = DEFAULT_AGENT_DOWNLOADS_LIMIT;
- log.warn("Agent downloads limit system property [" + SYSPROP_AGENT_DOWNLOADS_LIMIT
- + "] is either not set or invalid [" + limitStr + "] - limit will be [" + limit + "].");
- }
-
- return limit;
- }
-
- private void disableBrowserCache(HttpServletResponse resp) {
- resp.setHeader("Cache-Control", "no-cache, no-store");
- resp.setHeader("Expires", "-1");
- resp.setHeader("Pragma", "no-cache");
- }
-
- private void sendErrorServerNotAcceptingRequests(HttpServletResponse resp) throws IOException {
- disableBrowserCache(resp);
- resp.sendError(ERROR_CODE_AGENT_UPDATE_DISABLED, "Server Is Down For Maintenance");
- }
-
- private void sendErrorAgentUpdateDisabled(HttpServletResponse resp) throws IOException {
- disableBrowserCache(resp);
- resp.sendError(ERROR_CODE_AGENT_UPDATE_DISABLED, "Agent Updates Has Been Disabled");
- }
-
- private void sendErrorTooManyDownloads(HttpServletResponse resp) throws IOException {
- disableBrowserCache(resp);
- resp.setHeader("Retry-After", "30");
- resp.sendError(ERROR_CODE_TOO_MANY_DOWNLOADS, "Maximum limit exceeded - download agent later");
- }
-
- private File getAgentUpdateVersionFile() throws Exception {
- return getAgentManager().getAgentUpdateVersionFile();
- }
-
- private File getAgentUpdateBinaryFile() throws Exception {
- return getAgentManager().getAgentUpdateBinaryFile();
- }
-
- private AgentManagerLocal getAgentManager() {
- if (this.agentManager == null) {
- this.agentManager = LookupUtil.getAgentManager();
- }
- return this.agentManager;
- }
-
- private boolean isServerAcceptingRequests() {
- try {
- OperationMode mode = LookupUtil.getServerManager().getServer().getOperationMode();
- return mode == OperationMode.NORMAL;
- } catch (Exception e) {
- return false;
- }
- }
-
- private String getClientAddress(HttpServletRequest request) {
- String ip = request.getHeader("X-Forwarded-For");
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
- ip = request.getHeader("HTTP_X_FORWARDED_FOR");
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
- ip = String.format("%s (%s)", request.getRemoteHost(), request.getRemoteAddr());
- }
- }
- return ip;
- }
-}
\ No newline at end of file
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/client/RemoteClientServlet.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/client/RemoteClientServlet.java
deleted file mode 100644
index 9127927..0000000
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/client/RemoteClientServlet.java
+++ /dev/null
@@ -1,196 +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.enterprise.gui.client;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.rhq.core.domain.cloud.Server.OperationMode;
-import org.rhq.core.util.stream.StreamUtil;
-import org.rhq.enterprise.server.util.LookupUtil;
-
-/**
- * Serves the remote client binary that is stored in the RHQ Server's download area.
- * This servlet also provides version information regarding the version of the remote
- * client this servlet serves up.
- */
-public class RemoteClientServlet extends HttpServlet {
-
- private static final long serialVersionUID = 1L;
-
- // the system property that defines how many concurrent downloads we will allow
- private static String SYSPROP_CLIENT_DOWNLOADS_LIMIT = "rhq.server.client-downloads-limit";
-
- // if the system property is not set or invalid, this is the default limit for number of concurrent downloads
- // There is no reason this be heavily downloaded.
- private static int DEFAULT_CLIENT_DOWNLOADS_LIMIT = 5;
-
- // the error code that will be returned if the server has been configured to disable client updates
- private static final int ERROR_CODE_CLIENT_UPDATE_DISABLED = HttpServletResponse.SC_FORBIDDEN;
-
- // the error code that will be returned if the server has too many clients downloading the binary
- private static final int ERROR_CODE_TOO_MANY_DOWNLOADS = HttpServletResponse.SC_SERVICE_UNAVAILABLE;
-
- private static int numActiveDownloads = 0;
-
- private Log log = LogFactory.getLog(this.getClass());
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- // seeing odd browser caching issues, even though we set Last-Modified. so force no caching for now
- disableBrowserCache(resp);
-
- String servletPath = req.getServletPath();
- if (servletPath != null) {
- if (isServerAcceptingRequests()) {
- if (servletPath.endsWith("version")) {
- getVersion(req, resp);
- } else if (servletPath.endsWith("download")) {
- try {
- numActiveDownloads++;
- getDownload(req, resp);
- } finally {
- numActiveDownloads--;
- }
- } else {
- resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid servlet path [" + servletPath
- + "] - please contact administrator");
- }
- } else {
- sendErrorServerNotAcceptingRequests(resp);
- }
- } else {
- resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid servlet path - please contact administrator");
- }
-
- return;
- }
-
- private void getDownload(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- int limit = getDownloadLimit();
- if (limit <= 0) {
- sendErrorDownloadDisabled(resp);
- return;
- } else if (limit < numActiveDownloads) {
- sendErrorTooManyDownloads(resp);
- return;
- }
-
- try {
- File zip = LookupUtil.getRemoteClientManager().getRemoteClientBinaryFile();
- if (!zip.exists()) {
- disableBrowserCache(resp);
- resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Remote Client binary does not exist: "
- + zip.getName());
- return;
- }
-
- resp.setContentType("application/octet-stream");
- resp.setHeader("Content-Disposition", "attachment; filename=" + zip.getName());
- resp.setContentLength((int) zip.length());
- resp.setDateHeader("Last-Modified", zip.lastModified());
-
- FileInputStream zipStream = new FileInputStream(zip);
- try {
- StreamUtil.copy(zipStream, resp.getOutputStream(), false);
- } finally {
- zipStream.close();
- }
- } catch (Throwable t) {
- log.error("Failed to stream remote client zip.", t);
- disableBrowserCache(resp);
- resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to stream remote client zip");
- }
-
- return;
- }
-
- private void getVersion(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- try {
- File versionFile = LookupUtil.getRemoteClientManager().getRemoteClientVersionFile();
- resp.setContentType("text/plain");
- resp.setDateHeader("Last-Modified", versionFile.lastModified());
-
- FileInputStream stream = new FileInputStream(versionFile);
- byte[] versionData = StreamUtil.slurp(stream);
- resp.getOutputStream().write(versionData);
- } catch (Throwable t) {
- log.error("Failed to stream version info.", t);
- disableBrowserCache(resp);
- resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to stream version info");
- }
-
- return;
- }
-
- private int getDownloadLimit() {
- String limitStr = System.getProperty(SYSPROP_CLIENT_DOWNLOADS_LIMIT);
- int limit;
- try {
- limit = Integer.parseInt(limitStr);
- } catch (Exception e) {
- limit = DEFAULT_CLIENT_DOWNLOADS_LIMIT;
- log.warn("Remote Client downloads limit system property [" + SYSPROP_CLIENT_DOWNLOADS_LIMIT
- + "] is either not set or invalid [" + limitStr + "] - limit will be [" + limit + "].");
- }
-
- return limit;
- }
-
- private void disableBrowserCache(HttpServletResponse resp) {
- resp.setHeader("Cache-Control", "no-cache, no-store");
- resp.setHeader("Expires", "-1");
- resp.setHeader("Pragma", "no-cache");
- }
-
- private void sendErrorServerNotAcceptingRequests(HttpServletResponse resp) throws IOException {
- disableBrowserCache(resp);
- resp.sendError(ERROR_CODE_CLIENT_UPDATE_DISABLED, "Server Is Down For Maintenance");
- }
-
- private void sendErrorDownloadDisabled(HttpServletResponse resp) throws IOException {
- disableBrowserCache(resp);
- resp.sendError(ERROR_CODE_CLIENT_UPDATE_DISABLED, "Client Download Has Been Disabled");
- }
-
- private void sendErrorTooManyDownloads(HttpServletResponse resp) throws IOException {
- disableBrowserCache(resp);
- resp.setHeader("Retry-After", "30");
- resp.sendError(ERROR_CODE_TOO_MANY_DOWNLOADS, "Maximum limit exceeded - download client later");
- }
-
- private boolean isServerAcceptingRequests() {
- try {
- OperationMode mode = LookupUtil.getServerManager().getServer().getOperationMode();
- return mode == OperationMode.NORMAL;
- } catch (Exception e) {
- return false;
- }
- }
-
-}
\ No newline at end of file
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/download/DownloadServlet.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/download/DownloadServlet.java
deleted file mode 100644
index 59369a7..0000000
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/download/DownloadServlet.java
+++ /dev/null
@@ -1,293 +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.enterprise.gui.download;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.rhq.core.domain.cloud.Server.OperationMode;
-import org.rhq.core.util.stream.StreamUtil;
-import org.rhq.enterprise.server.util.LookupUtil;
-
-/**
- * Serves the static content found in rhq-downloads.
- */
-public class DownloadServlet extends HttpServlet {
-
- private static final long serialVersionUID = 1L;
-
- // the system property that disables/enables file listing - default is to show the listing
- private static String SYSPROP_SHOW_DOWNLOADS_LISTING = "rhq.server.show-downloads-listing";
-
- private static int numActiveDownloads = 0;
- private static boolean showDownloadsListing;
-
- private Log log = LogFactory.getLog(this.getClass());
-
- @Override
- public void init() throws ServletException {
- log.info("Starting the RHQ download servlet...");
-
- String propValue = System.getProperty(SYSPROP_SHOW_DOWNLOADS_LISTING, "true");
- showDownloadsListing = Boolean.parseBoolean(propValue);
- }
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-
- // seeing odd browser caching issues, even though we set Last-Modified. so force no caching for now
- disableBrowserCache(resp);
-
- if (isServerAcceptingRequests()) {
- String requestedDirectory = getRequestedDirectory(req);
- if (requestedDirectory == null) {
- numActiveDownloads++;
- download(req, resp);
- numActiveDownloads--;
- } else {
- if (showDownloadsListing) {
- outputFileList(requestedDirectory, req, resp);
- } else {
- disableBrowserCache(resp);
- resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Listing disabled");
- }
- }
- } else {
- sendErrorServerNotAcceptingRequests(resp);
- }
- return;
- }
-
- /**
- * Returns the relative path of the requested directory but only if it exists in
- * one of the root directories. If the requested path is a file or the directory
- * doesn't exist under a root directory, null is returned.
- *
- * @param req
- * @return relative path of the directory being requested
- * @throws ServletException
- */
- private String getRequestedDirectory(HttpServletRequest req) throws ServletException {
-
- String pathInfo = req.getPathInfo();
-
- File[] rootDownloadsDirs;
- try {
- rootDownloadsDirs = getRootDownloadsDirs();
- } catch (Throwable t) {
- throw new ServletException(t);
- }
-
- if (pathInfo == null || pathInfo.equals("") || pathInfo.equals("/")) {
- return "";
- }
-
- for (File rootDownloadsDir : rootDownloadsDirs) {
- File downloadDir = new File(rootDownloadsDir, pathInfo);
- if (downloadDir.isDirectory()) {
- return pathInfo;
- }
- }
-
- // either the path does not exist or its a file, not a directory
- return null;
- }
-
- private void download(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- try {
- if (isForbiddenPath(req.getPathInfo(), resp)) {
- return;
- }
-
- // look for the file in one of the root download directories
- File fileToDownload = null;
- File[] downloadDirs = getRootDownloadsDirs();
- for (File downloadDir : downloadDirs) {
- File file = new File(downloadDir, req.getPathInfo());
- if (file.exists()) {
- fileToDownload = file;
- break;
- }
- }
-
- if (fileToDownload == null) {
- disableBrowserCache(resp);
- resp.sendError(HttpServletResponse.SC_NOT_FOUND, "File does not exist: " + req.getPathInfo());
- return;
- }
-
- resp.setContentType(getMimeType(fileToDownload));
- resp.setHeader("Content-Disposition", "attachment; filename=" + fileToDownload.getName());
- resp.setContentLength((int) fileToDownload.length());
- resp.setDateHeader("Last-Modified", fileToDownload.lastModified());
-
- FileInputStream stream = new FileInputStream(fileToDownload);
- try {
- StreamUtil.copy(stream, resp.getOutputStream(), false);
- } finally {
- stream.close();
- }
- } catch (Throwable t) {
- log.error("Failed to stream download content.", t);
- disableBrowserCache(resp);
- resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to download content");
- }
-
- return;
- }
-
- private String getMimeType(File file) {
- String mimeType = null;
-
- try {
- mimeType = getServletContext().getMimeType(file.getName());
- } catch (Throwable t) {
- // i'm paranoid, no idea if this will ever happen, but its not fatal so keep going
- log.warn("Failed to get mime type for [" + file + "].", t);
- }
-
- if (mimeType == null) {
- mimeType = "application/octet-stream";
- }
- return mimeType;
- }
-
- private void outputFileList(String requestedDirectory, HttpServletRequest req, HttpServletResponse resp)
- throws ServletException {
-
- try {
- if (!isForbiddenPath(requestedDirectory, resp)) {
- File requestedDirectoryRelativePath = new File(requestedDirectory);
- String dirName = requestedDirectoryRelativePath.getName();
- disableBrowserCache(resp);
- resp.setContentType("text/html");
- PrintWriter writer = resp.getWriter();
- writer.println(String.format("<html><head><title>Available Downloads: %s</title></head>", dirName));
- writer.println("<body><h1>Available Downloads</h1>");
- writer.println(String.format("<font size=\"+2\"><b><pre>%s</pre></b></font>", dirName));
- List<File> files = getDownloadFiles(requestedDirectory);
- if (files.size() > 0) {
- String pathInfo = req.getPathInfo();
- if (!pathInfo.endsWith("/")) {
- pathInfo += "/";
- }
- writer.println("<ul>");
- for (File file : files) {
- writer.println("<li><a href=\"" + req.getServletPath() + pathInfo + file.getName() + "\">"
- + file.getName() + "</a></li>");
- }
- writer.println("</ul>");
- } else {
- writer.println("<h4>NONE</h4>");
- }
- writer.println("</body></html>");
- }
- } catch (Exception e) {
- throw new ServletException("Cannot get downloads listing", e);
- }
- }
-
- private boolean isForbiddenPath(String requestedPath, HttpServletResponse resp) throws IOException {
- boolean forbidden = true; // assume it is forbidden
- if (requestedPath.toString().contains("rhq-agent")) {
- resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Use /agentupdate/download to obtain the agent");
- } else if (requestedPath.toString().contains("rhq-client")) {
- resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Use /client/download to obtain the client");
- } else {
- forbidden = false;
- }
- return forbidden;
- }
-
- private void sendErrorServerNotAcceptingRequests(HttpServletResponse resp) throws IOException {
- disableBrowserCache(resp);
- resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Server Is Down For Maintenance");
- }
-
- private void disableBrowserCache(HttpServletResponse resp) {
- resp.setHeader("Cache-Control", "no-cache, no-store");
- resp.setHeader("Expires", "-1");
- resp.setHeader("Pragma", "no-cache");
- }
-
- private List<File> getDownloadFiles(String requestedDirectory) throws Exception {
- // its possible if more than one root dir has the file, we'll get duplicates.
- // this should never happen, so ignore this edge case.
- List<File> returnFiles = new ArrayList<File>();
- File[] rootDownloadDirs = getRootDownloadsDirs();
- for (File rootDownloadDir : rootDownloadDirs) {
- File dir = new File(rootDownloadDir, requestedDirectory);
- File[] filesArray = dir.listFiles();
- // this is simple - we only serve up files located in the requested directory - no content from subdirectories
- if (filesArray != null) {
- for (File file : filesArray) {
- if (file.isFile()) {
- returnFiles.add(file);
- }
- }
- }
- }
-
- return returnFiles;
- }
-
- /**
- * There are two locations for downloads - the static content under the EAR's rhq-downloads
- * and dynamic content in the data directory.
- *
- * @return the two root locations
- *
- * @throws Exception
- */
- private File[] getRootDownloadsDirs() throws Exception {
- File earDir = LookupUtil.getCoreServer().getEarDeploymentDir();
- File downloadDir = new File(earDir, "rhq-downloads");
- if (!downloadDir.exists()) {
- throw new FileNotFoundException("Missing downloads directory at [" + downloadDir + "]");
- }
-
- File dataDir = LookupUtil.getCoreServer().getJBossServerDataDir();
- File dataDownloadDir = new File(dataDir, "rhq-downloads");
-
- return new File[] { dataDownloadDir, downloadDir }; // put the data dir first, I think that should take precedence
- }
-
- private boolean isServerAcceptingRequests() {
- try {
- OperationMode mode = LookupUtil.getServerManager().getServer().getOperationMode();
- return mode == OperationMode.NORMAL;
- } catch (Exception e) {
- return false;
- }
- }
-
-}
\ No newline at end of file
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/web.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/web.xml
index f623679..5aa727d 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/web.xml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/web.xml
@@ -314,26 +314,6 @@
<load-on-startup>1</load-on-startup>
</servlet>
- <!-- Servlet that serves the agent update binaries and version information -->
- <servlet>
- <servlet-name>AgentUpdateServlet</servlet-name>
- <servlet-class>org.rhq.enterprise.gui.agentupdate.AgentUpdateServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
-
- <!-- Servlet that serves the content from rhq-downloads -->
- <servlet>
- <servlet-name>DownloadServlet</servlet-name>
- <servlet-class>org.rhq.enterprise.gui.download.DownloadServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
-
- <servlet>
- <servlet-name>RemoteClientServlet</servlet-name>
- <servlet-class>org.rhq.enterprise.gui.client.RemoteClientServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
-
<!-- standalone servlets used by the JSPs -->
<!-- Struts ActionServlet configuration (with debugging) -->
@@ -363,40 +343,12 @@
<load-on-startup>2</load-on-startup>
</servlet>
- <!-- The endpoints to the agent update servlet -->
- <servlet-mapping>
- <servlet-name>AgentUpdateServlet</servlet-name>
- <url-pattern>/agentupdate/version</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>AgentUpdateServlet</servlet-name>
- <url-pattern>/agentupdate/download</url-pattern>
- </servlet-mapping>
-
- <!-- The endpoints to the remote client servlet -->
- <servlet-mapping>
- <servlet-name>RemoteClientServlet</servlet-name>
- <url-pattern>/client/version</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>RemoteClientServlet</servlet-name>
- <url-pattern>/client/download</url-pattern>
- </servlet-mapping>
-
<!-- TODO what is this for? -->
<servlet-mapping>
<servlet-name>sessionAccess</servlet-name>
<url-pattern>/sessionAccess</url-pattern>
</servlet-mapping>
- <!-- The download servlet; this URI /downloads will effectively look like its pointing to rhq-downloads -->
- <servlet-mapping>
- <servlet-name>DownloadServlet</servlet-name>
- <url-pattern>/downloads/*</url-pattern>
- </servlet-mapping>
-
-
-
<!-- mappings for Struts ActionServlet -->
<servlet-mapping>
<servlet-name>action</servlet-name>
diff --git a/modules/enterprise/gui/remote-client-war/pom.xml b/modules/enterprise/gui/remote-client-war/pom.xml
new file mode 100644
index 0000000..92ec018
--- /dev/null
+++ b/modules/enterprise/gui/remote-client-war/pom.xml
@@ -0,0 +1,153 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-parent</artifactId>
+ <version>4.10.0-SNAPSHOT</version>
+ <relativePath>../../../../pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-remote-client-war</artifactId>
+ <packaging>war</packaging>
+ <name>RHQ Enterprise Remote Client War</name>
+ <description>the RHQ Enterprise Remote Client webapp</description>
+
+ <dependencies>
+ <!-- Internal Deps -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-domain</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope> <!-- by rhq.ear (as ejb-jar) -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope> <!-- by rhq.ear (as ejb-jar) -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-util</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope> <!-- by rhq.ear -->
+ </dependency>
+
+ <!-- Import the Servlet API, we use provided scope as the API is included in JBoss AS 7 -->
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope> <!-- by JBossAS -->
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <!-- Set the name of the war, used as the context root when the app
+ is deployed -->
+ <finalName>rhq-client</finalName>
+ <plugins>
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <failOnMissingWebXml>false</failOnMissingWebXml>
+ <archive>
+ <manifest>
+ <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ </manifest>
+ <manifestEntries>
+ <Build-Number>${buildNumber}</Build-Number>
+ </manifestEntries>
+ </archive>
+ <webResources>
+ <resource>
+ <filtering>false</filtering>
+ <directory>${basedir}/src/main/webapp</directory>
+ </resource>
+ </webResources>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <profiles>
+ <profile>
+ <id>dev</id>
+
+ <properties>
+ <rhq.rootDir>../../../..</rhq.rootDir>
+ <rhq.containerDir>${rhq.rootDir}/${rhq.devContainerServerPath}</rhq.containerDir>
+ <rhq.deploymentName>${project.build.finalName}.war</rhq.deploymentName>
+ <rhq.deploymentDir>${rhq.containerDir}/${rhq.earDeployDir}/${rhq.deploymentName}</rhq.deploymentDir>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>deploy-classes</id>
+ <phase>compile</phase>
+ <configuration>
+ <target>
+ <property name="classes.dir" location="${rhq.deploymentDir}/WEB-INF/classes" />
+ <echo>*** Copying updated files from target/classes to ${classes.dir}...</echo>
+ <copy todir="${classes.dir}" verbose="${rhq.verbose}">
+ <fileset dir="target/classes" />
+ </copy>
+ <property name="deployment.dir" location="${rhq.deploymentDir}" />
+ <echo>*** Copying updated files from src${file.separator}main${file.separator}webapp${file.separator} to ${deployment.dir}${file.separator}...</echo>
+ <copy todir="${deployment.dir}" verbose="${rhq.verbose}">
+ <fileset dir="${basedir}/src/main/webapp" />
+ </copy>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>deploy</id>
+ <phase>package</phase>
+ <configuration>
+ <target>
+ <property name="deployment.dir" location="${rhq.deploymentDir}" />
+ <echo>*** Copying updated files from target${file.separator}${project.build.finalName}${file.separator} to ${deployment.dir}${file.separator}...</echo>
+ <copy todir="${deployment.dir}" verbose="${rhq.verbose}">
+ <fileset dir="${basedir}/target/${project.build.finalName}" />
+ </copy>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>undeploy</id>
+ <phase>clean</phase>
+ <configuration>
+ <target>
+ <property name="deployment.dir" location="${rhq.deploymentDir}" />
+ <echo>*** Deleting ${deployment.dir}${file.separator}...</echo>
+ <delete dir="${deployment.dir}" />
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/modules/enterprise/gui/remote-client-war/src/main/java/org/rhq/enterprise/gui/client/RemoteClientServlet.java b/modules/enterprise/gui/remote-client-war/src/main/java/org/rhq/enterprise/gui/client/RemoteClientServlet.java
new file mode 100644
index 0000000..234fc58
--- /dev/null
+++ b/modules/enterprise/gui/remote-client-war/src/main/java/org/rhq/enterprise/gui/client/RemoteClientServlet.java
@@ -0,0 +1,196 @@
+/*
+ * 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.enterprise.gui.client;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.rhq.core.domain.cloud.Server.OperationMode;
+import org.rhq.core.util.stream.StreamUtil;
+import org.rhq.enterprise.server.util.LookupUtil;
+
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+/**
+ * Serves the remote client binary that is stored in the RHQ Server's download area.
+ * This servlet also provides version information regarding the version of the remote
+ * client this servlet serves up.
+ */
+@WebServlet(urlPatterns = {"/download", "/version"}, loadOnStartup = 1)
+public class RemoteClientServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ // the system property that defines how many concurrent downloads we will allow
+ private static String SYSPROP_CLIENT_DOWNLOADS_LIMIT = "rhq.server.client-downloads-limit";
+
+ // if the system property is not set or invalid, this is the default limit for number of concurrent downloads
+ // There is no reason this be heavily downloaded.
+ private static int DEFAULT_CLIENT_DOWNLOADS_LIMIT = 5;
+
+ // the error code that will be returned if the server has been configured to disable client updates
+ private static final int ERROR_CODE_CLIENT_UPDATE_DISABLED = HttpServletResponse.SC_FORBIDDEN;
+
+ // the error code that will be returned if the server has too many clients downloading the binary
+ private static final int ERROR_CODE_TOO_MANY_DOWNLOADS = HttpServletResponse.SC_SERVICE_UNAVAILABLE;
+
+ private static int numActiveDownloads = 0;
+
+ private Log log = LogFactory.getLog(this.getClass());
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ // seeing odd browser caching issues, even though we set Last-Modified. so force no caching for now
+ disableBrowserCache(resp);
+
+ String servletPath = req.getServletPath();
+ if (servletPath != null) {
+ if (isServerAcceptingRequests()) {
+ if (servletPath.endsWith("version")) {
+ getVersion(req, resp);
+ } else if (servletPath.endsWith("download")) {
+ try {
+ numActiveDownloads++;
+ getDownload(req, resp);
+ } finally {
+ numActiveDownloads--;
+ }
+ } else {
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid servlet path [" + servletPath
+ + "] - please contact administrator");
+ }
+ } else {
+ sendErrorServerNotAcceptingRequests(resp);
+ }
+ } else {
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid servlet path - please contact administrator");
+ }
+
+ return;
+ }
+
+ private void getDownload(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ int limit = getDownloadLimit();
+ if (limit <= 0) {
+ sendErrorDownloadDisabled(resp);
+ return;
+ } else if (limit < numActiveDownloads) {
+ sendErrorTooManyDownloads(resp);
+ return;
+ }
+
+ try {
+ File zip = LookupUtil.getRemoteClientManager().getRemoteClientBinaryFile();
+ if (!zip.exists()) {
+ disableBrowserCache(resp);
+ resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Remote Client binary does not exist: "
+ + zip.getName());
+ return;
+ }
+
+ resp.setContentType("application/octet-stream");
+ resp.setHeader("Content-Disposition", "attachment; filename=" + zip.getName());
+ resp.setContentLength((int) zip.length());
+ resp.setDateHeader("Last-Modified", zip.lastModified());
+
+ FileInputStream zipStream = new FileInputStream(zip);
+ try {
+ StreamUtil.copy(zipStream, resp.getOutputStream(), false);
+ } finally {
+ zipStream.close();
+ }
+ } catch (Throwable t) {
+ log.error("Failed to stream remote client zip.", t);
+ disableBrowserCache(resp);
+ resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to stream remote client zip");
+ }
+
+ return;
+ }
+
+ private void getVersion(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ try {
+ File versionFile = LookupUtil.getRemoteClientManager().getRemoteClientVersionFile();
+ resp.setContentType("text/plain");
+ resp.setDateHeader("Last-Modified", versionFile.lastModified());
+
+ FileInputStream stream = new FileInputStream(versionFile);
+ byte[] versionData = StreamUtil.slurp(stream);
+ resp.getOutputStream().write(versionData);
+ } catch (Throwable t) {
+ log.error("Failed to stream version info.", t);
+ disableBrowserCache(resp);
+ resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to stream version info");
+ }
+
+ return;
+ }
+
+ private int getDownloadLimit() {
+ String limitStr = System.getProperty(SYSPROP_CLIENT_DOWNLOADS_LIMIT);
+ int limit;
+ try {
+ limit = Integer.parseInt(limitStr);
+ } catch (Exception e) {
+ limit = DEFAULT_CLIENT_DOWNLOADS_LIMIT;
+ log.warn("Remote Client downloads limit system property [" + SYSPROP_CLIENT_DOWNLOADS_LIMIT
+ + "] is either not set or invalid [" + limitStr + "] - limit will be [" + limit + "].");
+ }
+
+ return limit;
+ }
+
+ private void disableBrowserCache(HttpServletResponse resp) {
+ resp.setHeader("Cache-Control", "no-cache, no-store");
+ resp.setHeader("Expires", "-1");
+ resp.setHeader("Pragma", "no-cache");
+ }
+
+ private void sendErrorServerNotAcceptingRequests(HttpServletResponse resp) throws IOException {
+ disableBrowserCache(resp);
+ resp.sendError(ERROR_CODE_CLIENT_UPDATE_DISABLED, "Server Is Down For Maintenance");
+ }
+
+ private void sendErrorDownloadDisabled(HttpServletResponse resp) throws IOException {
+ disableBrowserCache(resp);
+ resp.sendError(ERROR_CODE_CLIENT_UPDATE_DISABLED, "Client Download Has Been Disabled");
+ }
+
+ private void sendErrorTooManyDownloads(HttpServletResponse resp) throws IOException {
+ disableBrowserCache(resp);
+ resp.setHeader("Retry-After", "30");
+ resp.sendError(ERROR_CODE_TOO_MANY_DOWNLOADS, "Maximum limit exceeded - download client later");
+ }
+
+ private boolean isServerAcceptingRequests() {
+ try {
+ OperationMode mode = LookupUtil.getServerManager().getServer().getOperationMode();
+ return mode == OperationMode.NORMAL;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+}
diff --git a/modules/enterprise/gui/remote-client-war/src/main/webapp/index.html b/modules/enterprise/gui/remote-client-war/src/main/webapp/index.html
new file mode 100644
index 0000000..5d7a115
--- /dev/null
+++ b/modules/enterprise/gui/remote-client-war/src/main/webapp/index.html
@@ -0,0 +1,5 @@
+<html>
+ <head>
+ <meta http-equiv="Refresh" content="0; URL=version">
+ </head>
+</html>
diff --git a/modules/enterprise/server/ear/pom.xml b/modules/enterprise/server/ear/pom.xml
index a2e91a3..f312015 100644
--- a/modules/enterprise/server/ear/pom.xml
+++ b/modules/enterprise/server/ear/pom.xml
@@ -48,6 +48,28 @@
<dependency>
<groupId>${project.groupId}</groupId>
+ <artifactId>rhq-remote-client-war</artifactId>
+ <version>${project.version}</version>
+ <type>war</type>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>rhq-downloads-war</artifactId>
+ <version>${project.version}</version>
+ <type>war</type>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>rhq-agentupdate-war</artifactId>
+ <version>${project.version}</version>
+ <type>war</type>
+ </dependency>
+
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
<artifactId>rhq-coregui</artifactId>
<version>${project.version}</version>
<type>war</type>
@@ -263,6 +285,27 @@
<contextRoot>/portal</contextRoot>
</webModule>
+ <webModule>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>rhq-remote-client-war</artifactId>
+ <bundleFileName>rhq-client.war</bundleFileName>
+ <contextRoot>/client</contextRoot>
+ </webModule>
+
+ <webModule>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>rhq-downloads-war</artifactId>
+ <bundleFileName>rhq-downloads.war</bundleFileName>
+ <contextRoot>/downloads</contextRoot>
+ </webModule>
+
+ <webModule>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>rhq-agentupdate-war</artifactId>
+ <bundleFileName>rhq-agentupdate.war</bundleFileName>
+ <contextRoot>/agentupdate</contextRoot>
+ </webModule>
+
<!-- used to expose content through http -->
<webModule>
<groupId>${project.groupId}</groupId>
10 years, 2 months
[rhq] modules/common
by snegrea
modules/common/cassandra-installer/src/main/java/org/rhq/storage/installer/StorageInstaller.java | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
New commits:
commit e0e11c053a3b4c0cfc2625a7fa9ae19b1caaa5fd
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Mon Sep 30 16:37:57 2013 -0500
[BZ 1010265] Add a little more verbiage around unknown host exception; the goal is to point the user towards documentation and dns settings.
diff --git a/modules/common/cassandra-installer/src/main/java/org/rhq/storage/installer/StorageInstaller.java b/modules/common/cassandra-installer/src/main/java/org/rhq/storage/installer/StorageInstaller.java
index 58c04ac..30a51a4 100644
--- a/modules/common/cassandra-installer/src/main/java/org/rhq/storage/installer/StorageInstaller.java
+++ b/modules/common/cassandra-installer/src/main/java/org/rhq/storage/installer/StorageInstaller.java
@@ -34,6 +34,7 @@ import java.net.BindException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
+import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -941,7 +942,12 @@ public class StorageInstaller {
CommandLine cmdLine = parser.parse(installer.getOptions(), args);
int status = installer.run(cmdLine);
System.exit(status);
- } catch (ParseException e) {
+ } catch (UnknownHostException unknownHostException) {
+ installer.log
+ .error("Failed to resolve requested binding address. Please check the installation instructions and host DNS settings. "
+ + unknownHostException.getMessage());
+ throw unknownHostException;
+ } catch (ParseException parseException) {
installer.printUsage();
System.exit(STATUS_SHOW_USAGE);
}
10 years, 2 months
[rhq] Branch 'hotfix/jon3.1.2' - modules/enterprise
by Larry O'Leary
modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ResourceTypeFingerprint.java | 51 +++++++++-
1 file changed, 46 insertions(+), 5 deletions(-)
New commits:
commit fa7a68d6e3d216c70592b476105b5f0ae090afd0
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jun 8 12:51:28 2012 +0200
[BZ 829944] - make the resource type fingerprint robust against ordering
of different kinds of definitions in the resource type.
(cherry picked from commit a48f5cda6610222c37b42fb80d29fa589a864ab5)
(cherry picked from commit 1d6c859d2b8aeffec2e2a35ab29ed578f5e671cb)
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ResourceTypeFingerprint.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ResourceTypeFingerprint.java
index 14ccabf..eaaba89 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ResourceTypeFingerprint.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ResourceTypeFingerprint.java
@@ -19,7 +19,11 @@
package org.rhq.bindings.util;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
import java.util.Map;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
@@ -43,6 +47,36 @@ public class ResourceTypeFingerprint {
private String digest;
+ private static final Comparator<MeasurementDefinition> MEASUREMENT_DEFINITION_COMPARATOR = new Comparator<MeasurementDefinition>() {
+ @Override
+ public int compare(MeasurementDefinition o1, MeasurementDefinition o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ };
+
+ private static final Comparator<OperationDefinition> OPERATION_DEFINITION_COMPARATOR = new Comparator<OperationDefinition>() {
+ @Override
+ public int compare(OperationDefinition o1, OperationDefinition o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ };
+
+ private static final Comparator<PackageType> PACKAGE_TYPE_COMPARATOR = new Comparator<PackageType>() {
+ @Override
+ public int compare(PackageType o1, PackageType o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ };
+
+ private static final Comparator<PropertyDefinition> PROPERTY_DEFINITION_COMPARATOR = new Comparator<PropertyDefinition>() {
+
+ @Override
+ public int compare(PropertyDefinition o1, PropertyDefinition o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+
+ };
+
public ResourceTypeFingerprint(ResourceType rt, Collection<MeasurementDefinition> measurements,
Collection<OperationDefinition> operations, Collection<PackageType> packageTypes,
ConfigurationDefinition pluginConfigurationDefinition, ConfigurationDefinition resourceConfigurationDefinition) {
@@ -101,7 +135,9 @@ public class ResourceTypeFingerprint {
if (defs == null) {
bld.append("null");
} else {
- for (MeasurementDefinition d : defs) {
+ List<MeasurementDefinition> adefs = new ArrayList<MeasurementDefinition>(defs);
+ Collections.sort(adefs, MEASUREMENT_DEFINITION_COMPARATOR);
+ for (MeasurementDefinition d : adefs) {
addRepresentation(d, bld);
}
}
@@ -111,7 +147,9 @@ public class ResourceTypeFingerprint {
if (defs == null) {
bld.append("null");
} else {
- for (OperationDefinition d : defs) {
+ List<OperationDefinition> odefs = new ArrayList<OperationDefinition>(defs);
+ Collections.sort(odefs, OPERATION_DEFINITION_COMPARATOR);
+ for (OperationDefinition d : odefs) {
addRepresentation(d, bld);
}
}
@@ -121,7 +159,9 @@ public class ResourceTypeFingerprint {
if (defs == null) {
bld.append("null");
} else {
- for (PackageType d : defs) {
+ List<PackageType> pdefs = new ArrayList<PackageType>(defs);
+ Collections.sort(pdefs, PACKAGE_TYPE_COMPARATOR);
+ for (PackageType d : pdefs) {
addRepresentation(d, bld);
}
}
@@ -150,8 +190,9 @@ public class ResourceTypeFingerprint {
}
private static void addRepresentation(Map<String, PropertyDefinition> defs, StringBuilder bld) {
- for (Map.Entry<String, PropertyDefinition> entry : defs.entrySet()) {
- PropertyDefinition def = entry.getValue();
+ List<PropertyDefinition> pdefs = new ArrayList<PropertyDefinition>(defs.values());
+ Collections.sort(pdefs, PROPERTY_DEFINITION_COMPARATOR);
+ for (PropertyDefinition def : pdefs) {
addRepresentation(def, bld);
}
}
10 years, 2 months
[rhq] Branch 'release/jon3.1.x' - modules/enterprise
by Larry O'Leary
modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ResourceTypeFingerprint.java | 51 +++++++++-
1 file changed, 46 insertions(+), 5 deletions(-)
New commits:
commit 1d6c859d2b8aeffec2e2a35ab29ed578f5e671cb
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Jun 8 12:51:28 2012 +0200
[BZ 829944] - make the resource type fingerprint robust against ordering
of different kinds of definitions in the resource type.
(cherry picked from commit a48f5cda6610222c37b42fb80d29fa589a864ab5)
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ResourceTypeFingerprint.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ResourceTypeFingerprint.java
index 14ccabf..eaaba89 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ResourceTypeFingerprint.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/util/ResourceTypeFingerprint.java
@@ -19,7 +19,11 @@
package org.rhq.bindings.util;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
import java.util.Map;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
@@ -43,6 +47,36 @@ public class ResourceTypeFingerprint {
private String digest;
+ private static final Comparator<MeasurementDefinition> MEASUREMENT_DEFINITION_COMPARATOR = new Comparator<MeasurementDefinition>() {
+ @Override
+ public int compare(MeasurementDefinition o1, MeasurementDefinition o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ };
+
+ private static final Comparator<OperationDefinition> OPERATION_DEFINITION_COMPARATOR = new Comparator<OperationDefinition>() {
+ @Override
+ public int compare(OperationDefinition o1, OperationDefinition o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ };
+
+ private static final Comparator<PackageType> PACKAGE_TYPE_COMPARATOR = new Comparator<PackageType>() {
+ @Override
+ public int compare(PackageType o1, PackageType o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ };
+
+ private static final Comparator<PropertyDefinition> PROPERTY_DEFINITION_COMPARATOR = new Comparator<PropertyDefinition>() {
+
+ @Override
+ public int compare(PropertyDefinition o1, PropertyDefinition o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+
+ };
+
public ResourceTypeFingerprint(ResourceType rt, Collection<MeasurementDefinition> measurements,
Collection<OperationDefinition> operations, Collection<PackageType> packageTypes,
ConfigurationDefinition pluginConfigurationDefinition, ConfigurationDefinition resourceConfigurationDefinition) {
@@ -101,7 +135,9 @@ public class ResourceTypeFingerprint {
if (defs == null) {
bld.append("null");
} else {
- for (MeasurementDefinition d : defs) {
+ List<MeasurementDefinition> adefs = new ArrayList<MeasurementDefinition>(defs);
+ Collections.sort(adefs, MEASUREMENT_DEFINITION_COMPARATOR);
+ for (MeasurementDefinition d : adefs) {
addRepresentation(d, bld);
}
}
@@ -111,7 +147,9 @@ public class ResourceTypeFingerprint {
if (defs == null) {
bld.append("null");
} else {
- for (OperationDefinition d : defs) {
+ List<OperationDefinition> odefs = new ArrayList<OperationDefinition>(defs);
+ Collections.sort(odefs, OPERATION_DEFINITION_COMPARATOR);
+ for (OperationDefinition d : odefs) {
addRepresentation(d, bld);
}
}
@@ -121,7 +159,9 @@ public class ResourceTypeFingerprint {
if (defs == null) {
bld.append("null");
} else {
- for (PackageType d : defs) {
+ List<PackageType> pdefs = new ArrayList<PackageType>(defs);
+ Collections.sort(pdefs, PACKAGE_TYPE_COMPARATOR);
+ for (PackageType d : pdefs) {
addRepresentation(d, bld);
}
}
@@ -150,8 +190,9 @@ public class ResourceTypeFingerprint {
}
private static void addRepresentation(Map<String, PropertyDefinition> defs, StringBuilder bld) {
- for (Map.Entry<String, PropertyDefinition> entry : defs.entrySet()) {
- PropertyDefinition def = entry.getValue();
+ List<PropertyDefinition> pdefs = new ArrayList<PropertyDefinition>(defs.values());
+ Collections.sort(pdefs, PROPERTY_DEFINITION_COMPARATOR);
+ for (PropertyDefinition def : pdefs) {
addRepresentation(def, bld);
}
}
10 years, 2 months
[rhq] 5 commits - modules/enterprise modules/helpers
by John Sanda
modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/DateTimeService.java | 12
modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java | 44 +-
modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/DateTimeServiceTest.java | 12
modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsServerTest.java | 1
modules/helpers/metrics-simulator/pom.xml | 16
modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementAggregator.java | 45 +-
modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementCollector.java | 121 +-----
modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Metrics.java | 30 +
modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Schedule.java | 119 ------
modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Simulator.java | 191 ++--------
modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/SimulatorDateTimeService.java | 27 +
modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/StatsCollector.java | 94 ----
modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/ClusterConfig.java | 94 ----
modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/ScheduleGroup.java | 60 ---
modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java | 63 +--
modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java | 190 +--------
modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/stats/Aggregate.java | 69 ---
modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/stats/Stats.java | 103 -----
modules/helpers/metrics-simulator/src/main/resources/conf/log4j.properties | 2
19 files changed, 284 insertions(+), 1009 deletions(-)
New commits:
commit 45836de0bdb7f19c9b2797848ff1dcab785188de
Author: John Sanda <jsanda(a)redhat.com>
Date: Mon Sep 30 14:42:00 2013 -0400
remove extraneous logging and making reporting interval configurable
diff --git a/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java b/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java
index f77d805..886155f 100644
--- a/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java
+++ b/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java
@@ -345,7 +345,6 @@ public class MetricsServer {
long timeSlice = dateTimeService.getTimeSlice(new DateTime(rawData.getTimestamp()),
configuration.getRawTimeSliceDuration()).getMillis();
- log.debug("Updating metrics_index with time " + new DateTime(timeSlice));
StorageResultSetFuture resultSetFuture = dao.updateMetricsIndex(MetricsTable.ONE_HOUR, rawData.getScheduleId(),
timeSlice);
Futures.addCallback(resultSetFuture, new FutureCallback<ResultSet>() {
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Simulator.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Simulator.java
index 2d2564e..1ec9399 100644
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Simulator.java
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Simulator.java
@@ -88,7 +88,7 @@ public class Simulator implements ShutdownManager {
MeasurementAggregator measurementAggregator = new MeasurementAggregator(metricsServer, this, metrics,
aggregationQueue);
- ConsoleReporter consoleReporter = createConsoleReporter(metrics);
+ ConsoleReporter consoleReporter = createConsoleReporter(metrics, plan.getMetricsReportInterval());
for (int i = 0; i < plan.getNumMeasurementCollectors(); ++i) {
collectors.scheduleAtFixedRate(new MeasurementCollector(plan.getBatchSize(),
@@ -107,14 +107,14 @@ public class Simulator implements ShutdownManager {
shutdown(0);
}
- private ConsoleReporter createConsoleReporter(Metrics metrics) {
+ private ConsoleReporter createConsoleReporter(Metrics metrics, int reportInterval) {
try {
File basedir = new File(System.getProperty("rhq.metrics.simulator.basedir"));
File logDir = new File(basedir, "log");
ConsoleReporter consoleReporter = ConsoleReporter.forRegistry(metrics.registry)
.convertRatesTo(TimeUnit.SECONDS).convertDurationsTo(TimeUnit.MILLISECONDS)
.outputTo(new PrintStream(new FileOutputStream(new File(logDir, "metrics.txt")))).build();
- consoleReporter.start(1, TimeUnit.MINUTES);
+ consoleReporter.start(reportInterval, TimeUnit.SECONDS);
return consoleReporter;
} catch (FileNotFoundException e) {
throw new RuntimeException("Failed to create console reporter", e);
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java
index 1508edf..630c0ca 100644
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java
@@ -32,8 +32,6 @@ import org.rhq.server.metrics.MetricsConfiguration;
*/
public class SimulationPlan {
- private int threadPoolSize;
-
private long collectionInterval;
private long aggregationInterval;
@@ -50,6 +48,8 @@ public class SimulationPlan {
private int batchSize;
+ private int metricsReportInterval;
+
public long getCollectionInterval() {
return collectionInterval;
}
@@ -113,4 +113,12 @@ public class SimulationPlan {
public void setBatchSize(int batchSize) {
this.batchSize = batchSize;
}
+
+ public int getMetricsReportInterval() {
+ return metricsReportInterval;
+ }
+
+ public void setMetricsReportInterval(int metricsReportInterval) {
+ this.metricsReportInterval = metricsReportInterval;
+ }
}
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java
index cb690e5..1674766 100644
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java
@@ -51,6 +51,7 @@ public class SimulationPlanner {
simulation.setNumMeasurementCollectors(getInt(root.get("numMeasurementCollectors"), 5));
simulation.setSimulationTime(getInt(root.get("simulationTime"), 10));
simulation.setBatchSize(getInt(root.get("batchSize"), 5000));
+ simulation.setMetricsReportInterval(getInt(root.get("metricsReportInterval"), 180));
String[] nodes;
if (root.get("nodes") == null || root.get("nodes").size() == 0) {
commit f050eadea380b5f5a26e51f658e6d8f293efba81
Author: John Sanda <jsanda(a)redhat.com>
Date: Mon Sep 30 13:53:14 2013 -0400
remove obsolete config setting and add nowInMills() method
The nowInMills method avoids the overhead of creating a new DateTime object
which could non-trivial since it is called continuously in MeasurementCollector.
diff --git a/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/DateTimeService.java b/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/DateTimeService.java
index 9920ad6..92499fe 100644
--- a/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/DateTimeService.java
+++ b/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/DateTimeService.java
@@ -50,7 +50,11 @@ public class DateTimeService {
}
public DateTime now() {
- return DateTime.now();
+ return new DateTime(nowInMillis());
+ }
+
+ public long nowInMillis() {
+ return System.currentTimeMillis();
}
public DateTime getTimeSlice(long timestamp, Minutes interval) {
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementCollector.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementCollector.java
index 22bf81d..eeb508e 100644
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementCollector.java
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementCollector.java
@@ -66,7 +66,7 @@ public class MeasurementCollector implements Runnable {
private Set<MeasurementDataNumeric> generateData() {
Set<MeasurementDataNumeric> data = new HashSet<MeasurementDataNumeric>(batchSize);
- long timestamp = dateTimeService.now().getMillis();
+ long timestamp = dateTimeService.nowInMillis();
ThreadLocalRandom random = ThreadLocalRandom.current();
for (int i = 0; i < batchSize; ++i) {
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java
index 70c326a..1508edf 100644
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java
@@ -50,14 +50,6 @@ public class SimulationPlan {
private int batchSize;
- public int getThreadPoolSize() {
- return threadPoolSize;
- }
-
- public void setThreadPoolSize(int threadPoolSize) {
- this.threadPoolSize = threadPoolSize;
- }
-
public long getCollectionInterval() {
return collectionInterval;
}
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java
index dc9142c..cb690e5 100644
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java
@@ -50,7 +50,6 @@ public class SimulationPlanner {
simulation.setAggregationInterval(getLong(root.get("aggregationInterval"), 150000L)); // 2.5 minutes
simulation.setNumMeasurementCollectors(getInt(root.get("numMeasurementCollectors"), 5));
simulation.setSimulationTime(getInt(root.get("simulationTime"), 10));
- simulation.setThreadPoolSize(getInt(root.get("threadPoolSize"), simulation.getNumMeasurementCollectors() + 2));
simulation.setBatchSize(getInt(root.get("batchSize"), 5000));
String[] nodes;
commit 97e6cc2ce4d452f64a2a7f46f08b16edcec4ce61
Author: John Sanda <jsanda(a)redhat.com>
Date: Mon Sep 30 13:11:54 2013 -0400
fixing bugs and adding support for compressed time slices
The simulator now uses hard-coded TTLs and time slices. The duration of the
time slice for each table is as follows,
raw data --> 2.5 minutes
1 hr data --> 15 minutes
6 hr data --> 1 hour
Aggregation runs every 2.5 minutes. The execution time for aggregation can and
will exceed 2.5 minutes. I do not want the aggregator thread to block and wind
up kicking aggregation with the wrong start times. It now submits a task for
each aggregation so that the aggregator thread itself does not get delayed.
diff --git a/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/DateTimeService.java b/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/DateTimeService.java
index 01b6f71..9920ad6 100644
--- a/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/DateTimeService.java
+++ b/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/DateTimeService.java
@@ -25,8 +25,6 @@
package org.rhq.server.metrics;
-import static org.joda.time.DateTime.now;
-
import org.joda.time.Chronology;
import org.joda.time.DateTime;
import org.joda.time.DateTimeComparator;
@@ -45,12 +43,16 @@ public class DateTimeService {
private DateTimeComparator dateTimeComparator = DateTimeComparator.getInstance();
- private MetricsConfiguration configuration;
+ protected MetricsConfiguration configuration;
public void setConfiguration(MetricsConfiguration configuration) {
this.configuration = configuration;
}
+ public DateTime now() {
+ return DateTime.now();
+ }
+
public DateTime getTimeSlice(long timestamp, Minutes interval) {
return getTimeSlice(new DateTime(timestamp), interval);
}
diff --git a/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java b/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java
index f21f5c1..f77d805 100644
--- a/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java
+++ b/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java
@@ -98,7 +98,7 @@ public class MetricsServer {
* purged.
*/
private void determineMostRecentRawDataSinceLastShutdown() {
- DateTime previousHour = currentInterval().minus(configuration.getRawTimeSliceDuration());
+ DateTime previousHour = currentHour().minus(configuration.getRawTimeSliceDuration());
DateTime oldestRawTime = previousHour.minus(configuration.getRawRetention());
ResultSet resultSet = dao.setFindTimeSliceForIndex(MetricsTable.ONE_HOUR, previousHour.getMillis());
@@ -126,17 +126,12 @@ public class MetricsServer {
}
}
- protected DateTime currentInterval() {
- return dateTimeService.getTimeSlice(DateTime.now(), configuration.getRawTimeSliceDuration());
- }
-
protected DateTime currentHour() {
- DateTime dt = new DateTime(System.currentTimeMillis());
- return dateTimeService.getTimeSlice(dt, Duration.standardHours(1));
+ return dateTimeService.getTimeSlice(dateTimeService.now(), configuration.getRawTimeSliceDuration());
}
protected DateTime roundDownToHour(long timestamp) {
- return dateTimeService.getTimeSlice(new DateTime(timestamp), Duration.standardHours(1));
+ return dateTimeService.getTimeSlice(new DateTime(timestamp), configuration.getRawTimeSliceDuration());
}
public void shutdown() {
@@ -313,7 +308,7 @@ public class MetricsServer {
log.debug("Inserting " + dataSet.size() + " raw metrics");
}
- final long startTime = System.currentTimeMillis();
+ final long startTime = dateTimeService.now().getMillis();
final AtomicInteger remainingInserts = new AtomicInteger(dataSet.size());
for (final MeasurementDataNumeric data : dataSet) {
@@ -350,6 +345,7 @@ public class MetricsServer {
long timeSlice = dateTimeService.getTimeSlice(new DateTime(rawData.getTimestamp()),
configuration.getRawTimeSliceDuration()).getMillis();
+ log.debug("Updating metrics_index with time " + new DateTime(timeSlice));
StorageResultSetFuture resultSetFuture = dao.updateMetricsIndex(MetricsTable.ONE_HOUR, rawData.getScheduleId(),
timeSlice);
Futures.addCallback(resultSetFuture, new FutureCallback<ResultSet>() {
@@ -385,7 +381,7 @@ public class MetricsServer {
* for subsequently computing baselines.
*/
public Iterable<AggregateNumericMetric> calculateAggregates() {
- DateTime theHour = currentInterval();
+ DateTime theHour = currentHour();
if (pastAggregationMissed) {
calculateAggregates(roundDownToHour(mostRecentRawDataPriorToStartup).plusHours(1).getMillis());
@@ -401,7 +397,9 @@ public class MetricsServer {
DateTime currentHour = dateTimeService.getTimeSlice(dt, configuration.getRawTimeSliceDuration());
DateTime lastHour = currentHour.minus(configuration.getRawTimeSliceDuration());
- long hourTimeSlice = lastHour.getMillis();
+ if (log.isDebugEnabled()) {
+ log.debug("Starting aggregation for time slice " + lastHour);
+ }
long sixHourTimeSlice = dateTimeService.getTimeSlice(lastHour,
configuration.getOneHourTimeSliceDuration()).getMillis();
@@ -424,10 +422,10 @@ public class MetricsServer {
Iterable<AggregateNumericMetric> newOneHourAggregates = null;
- List<AggregateNumericMetric> updatedSchedules = aggregateRawData(hourTimeSlice);
+ List<AggregateNumericMetric> updatedSchedules = aggregateRawData(lastHour);
newOneHourAggregates = updatedSchedules;
if (!updatedSchedules.isEmpty()) {
- dao.deleteMetricsIndexEntries(MetricsTable.ONE_HOUR, hourTimeSlice);
+ dao.deleteMetricsIndexEntries(MetricsTable.ONE_HOUR, lastHour.getMillis());
updateMetricsIndex(MetricsTable.SIX_HOUR, updatedSchedules, configuration.getOneHourTimeSliceDuration());
}
@@ -457,16 +455,20 @@ public class MetricsServer {
dao.updateMetricsIndex(bucket, updates);
}
- private List<AggregateNumericMetric> aggregateRawData(long theHour) {
+ private List<AggregateNumericMetric> aggregateRawData(DateTime theHour) {
long start = System.currentTimeMillis();
try {
- Iterable<MetricsIndexEntry> indexEntries = dao.findMetricsIndexEntries(MetricsTable.ONE_HOUR, theHour);
+ if (log.isDebugEnabled()) {
+ log.debug("Preparing to aggregate raw data. Time slice start time is [" + theHour +
+ "] and the end time is [" + theHour.plus(configuration.getRawTimeSliceDuration()) + "]");
+ }
+ Iterable<MetricsIndexEntry> indexEntries = dao.findMetricsIndexEntries(MetricsTable.ONE_HOUR,
+ theHour.getMillis());
List<AggregateNumericMetric> oneHourMetrics = new ArrayList<AggregateNumericMetric>();
for (MetricsIndexEntry indexEntry : indexEntries) {
DateTime startTime = indexEntry.getTime();
DateTime endTime = startTime.plus(configuration.getRawTimeSliceDuration());
-
Iterable<RawNumericMetric> rawMetrics = dao.findRawMetrics(indexEntry.getScheduleId(),
startTime.getMillis(), endTime.getMillis());
AggregateNumericMetric aggregatedRaw = calculateAggregatedRaw(rawMetrics, startTime.getMillis());
@@ -518,16 +520,14 @@ public class MetricsServer {
private List<AggregateNumericMetric> calculateAggregates(MetricsTable fromTable,
MetricsTable toTable, long timeSlice, Duration nextDuration) {
- if (log.isDebugEnabled()) {
- log.debug("Preparing to compute aggregates for data in " + fromTable + " table");
- }
long start = System.currentTimeMillis();
try {
DateTime startTime = new DateTime(timeSlice);
DateTime endTime = startTime.plus(nextDuration);
- DateTime currentHour = currentInterval();
+ DateTime currentHour = currentHour();
if (log.isDebugEnabled()) {
+ log.debug("Preparing to compute aggregates for data in " + fromTable + " table");
log.debug("Time slice start time is [" + startTime + "] and the end time is [" + endTime + "].");
}
diff --git a/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsServerTest.java b/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsServerTest.java
index a670fcf..95ada4c 100644
--- a/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsServerTest.java
+++ b/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsServerTest.java
@@ -102,10 +102,6 @@ public class MetricsServerTest extends CassandraIntegrationTest {
return currentHour;
}
- @Override
- protected DateTime currentInterval() {
- return currentHour;
- }
}
@BeforeMethod
diff --git a/modules/helpers/metrics-simulator/pom.xml b/modules/helpers/metrics-simulator/pom.xml
index 7f9f6ae..885e86e 100644
--- a/modules/helpers/metrics-simulator/pom.xml
+++ b/modules/helpers/metrics-simulator/pom.xml
@@ -58,12 +58,6 @@
</dependency>
<dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-math3</artifactId>
- <version>3.1.1</version>
- </dependency>
-
- <dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commons-logging.version}</version>
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementAggregator.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementAggregator.java
index ef223cb..03d4afe 100644
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementAggregator.java
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementAggregator.java
@@ -25,6 +25,8 @@
package org.rhq.metrics.simulator;
+import java.util.concurrent.ExecutorService;
+
import com.codahale.metrics.Timer;
import org.apache.commons.logging.Log;
@@ -43,24 +45,34 @@ public class MeasurementAggregator implements Runnable {
private Metrics metrics;
+ private ExecutorService aggregationQueue;
+
private ShutdownManager shutdownManager;
- public MeasurementAggregator(MetricsServer metricsServer, ShutdownManager shutdownManager, Metrics metrics) {
+ public MeasurementAggregator(MetricsServer metricsServer, ShutdownManager shutdownManager, Metrics metrics,
+ ExecutorService aggregationQueue) {
this.metricsServer = metricsServer;
this.shutdownManager = shutdownManager;
this.metrics = metrics;
+ this.aggregationQueue = aggregationQueue;
}
public void run() {
- Timer.Context context = metrics.totalAggregationTime.time();
- try {
- metricsServer.calculateAggregates();
- } catch (Exception e) {
- log.error("An error occurred while trying to perform aggregation", e);
- log.error("Requesting simulation shutdown...");
- shutdownManager.shutdown(1);
- } finally {
- context.stop();
- }
+ aggregationQueue.submit(new Runnable() {
+ @Override
+ public void run() {
+ Timer.Context context = metrics.totalAggregationTime.time();
+ try {
+ log.debug("Starting metrics aggregation");
+ metricsServer.calculateAggregates();
+ } catch (Exception e) {
+ log.error("An error occurred while trying to perform aggregation", e);
+ log.error("Requesting simulation shutdown...");
+ shutdownManager.shutdown(1);
+ } finally {
+ context.stop();
+ }
+ }
+ });
}
}
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementCollector.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementCollector.java
index 45fe409..22bf81d 100644
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementCollector.java
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementCollector.java
@@ -53,16 +53,20 @@ public class MeasurementCollector implements Runnable {
private Metrics metrics;
- public MeasurementCollector(int batchSize, int startingScheduleId, Metrics metrics, MetricsServer metricsServer) {
+ private SimulatorDateTimeService dateTimeService;
+
+ public MeasurementCollector(int batchSize, int startingScheduleId, Metrics metrics, MetricsServer metricsServer,
+ SimulatorDateTimeService dateTimeService) {
this.batchSize = batchSize;
this.startingScheduleId = startingScheduleId;
this.metrics = metrics;
this.metricsServer = metricsServer;
+ this.dateTimeService = dateTimeService;
}
private Set<MeasurementDataNumeric> generateData() {
Set<MeasurementDataNumeric> data = new HashSet<MeasurementDataNumeric>(batchSize);
- long timestamp = System.currentTimeMillis();
+ long timestamp = dateTimeService.now().getMillis();
ThreadLocalRandom random = ThreadLocalRandom.current();
for (int i = 0; i < batchSize; ++i) {
@@ -93,17 +97,4 @@ public class MeasurementCollector implements Runnable {
});
}
- private static class NoOpCallback implements RawDataInsertedCallback {
- @Override
- public void onFinish() {
- }
-
- @Override
- public void onSuccess(MeasurementDataNumeric measurementDataNumeric) {
- }
-
- @Override
- public void onFailure(Throwable throwable) {
- }
- }
}
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Simulator.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Simulator.java
index be45017..2d2564e 100644
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Simulator.java
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Simulator.java
@@ -23,6 +23,7 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
+import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@@ -40,7 +41,6 @@ import org.joda.time.Minutes;
import org.rhq.cassandra.schema.SchemaManager;
import org.rhq.cassandra.util.ClusterBuilder;
import org.rhq.metrics.simulator.plan.SimulationPlan;
-import org.rhq.server.metrics.DateTimeService;
import org.rhq.server.metrics.MetricsDAO;
import org.rhq.server.metrics.MetricsServer;
import org.rhq.server.metrics.StorageSession;
@@ -55,13 +55,17 @@ public class Simulator implements ShutdownManager {
private boolean shutdown = false;
public void run(SimulationPlan plan) {
- final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(plan.getThreadPoolSize(),
- new SimulatorThreadFactory());
+ final ScheduledExecutorService aggregators = Executors.newScheduledThreadPool(1, new SimulatorThreadFactory());
+ final ScheduledExecutorService collectors = Executors.newScheduledThreadPool(
+ plan.getNumMeasurementCollectors(), new SimulatorThreadFactory());
+ final ExecutorService aggregationQueue = Executors.newSingleThreadExecutor(new SimulatorThreadFactory());
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
- shutdown(executorService);
+ shutdown(collectors, "collectors", 5);
+ shutdown(aggregators, "aggregators", 1);
+ shutdown(aggregationQueue, "aggregationQueue", Integer.MAX_VALUE);
}
});
@@ -75,27 +79,25 @@ public class Simulator implements ShutdownManager {
metricsServer.setDAO(metricsDAO);
metricsServer.setConfiguration(plan.getMetricsServerConfiguration());
- DateTimeService dateTimeService = new DateTimeService();
+ SimulatorDateTimeService dateTimeService = new SimulatorDateTimeService();
dateTimeService.setConfiguration(plan.getMetricsServerConfiguration());
metricsServer.setDateTimeService(dateTimeService);
Metrics metrics = new Metrics();
- MeasurementAggregator measurementAggregator = new MeasurementAggregator(metricsServer, this, metrics);
+ MeasurementAggregator measurementAggregator = new MeasurementAggregator(metricsServer, this, metrics,
+ aggregationQueue);
ConsoleReporter consoleReporter = createConsoleReporter(metrics);
- int batchSize = 3;
for (int i = 0; i < plan.getNumMeasurementCollectors(); ++i) {
- MeasurementCollector measurementCollector = new MeasurementCollector(batchSize, batchSize * i, metrics,
- metricsServer);
- executorService.scheduleAtFixedRate(measurementCollector, 0, plan.getCollectionInterval(),
+ collectors.scheduleAtFixedRate(new MeasurementCollector(plan.getBatchSize(),
+ plan.getBatchSize() * i, metrics, metricsServer, dateTimeService), 0, plan.getCollectionInterval(),
TimeUnit.MILLISECONDS);
}
- executorService.scheduleAtFixedRate(measurementAggregator, 0, plan.getAggregationInterval(),
+ aggregators.scheduleAtFixedRate(measurementAggregator, 0, plan.getAggregationInterval(),
TimeUnit.MILLISECONDS);
-
try {
Thread.sleep(Minutes.minutes(plan.getSimulationTime()).toStandardDuration().getMillis());
} catch (InterruptedException e) {
@@ -130,18 +132,18 @@ public class Simulator implements ShutdownManager {
System.exit(status);
}
- private void shutdown(ScheduledExecutorService executorService) {
- log.info("Shutting down executor service");
- executorService.shutdown();
+ private void shutdown(ExecutorService service, String serviceName, int wait) {
+ log.info("Shutting down " + serviceName);
+ service.shutdown();
try {
- executorService.awaitTermination(5, TimeUnit.SECONDS);
+ service.awaitTermination(wait, TimeUnit.SECONDS);
} catch (InterruptedException e) {
}
- if (!executorService.isTerminated()) {
- log.info("Forcing executor service shutdown.");
- executorService.shutdownNow();
+ if (!service.isTerminated()) {
+ log.info("Forcing " + serviceName + " shutdown.");
+ service.shutdownNow();
}
- log.info("Shut down complete");
+ log.info(serviceName + " shut down complete");
}
private void createSchema(String[] nodes, int cqlPort) {
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/SimulatorDateTimeService.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/SimulatorDateTimeService.java
new file mode 100644
index 0000000..c62340b
--- /dev/null
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/SimulatorDateTimeService.java
@@ -0,0 +1,27 @@
+package org.rhq.metrics.simulator;
+
+import org.joda.time.DateTime;
+import org.joda.time.Duration;
+
+import org.rhq.server.metrics.DateTimeService;
+
+/**
+ * @author John Sanda
+ */
+public class SimulatorDateTimeService extends DateTimeService {
+
+ @Override
+ public DateTime getTimeSlice(DateTime dt, Duration duration) {
+ if (duration.equals(configuration.getRawTimeSliceDuration())) {
+ int seconds = ((dt.getMinuteOfHour() * 60) + dt.getSecondOfMinute()) / 150;
+ return dt.hourOfDay().roundFloorCopy().plusSeconds(seconds * 150);
+ } else if (duration.equals(configuration.getOneHourTimeSliceDuration())) {
+ int minutes = dt.minuteOfHour().get() / 15;
+ return dt.hourOfDay().roundFloorCopy().plusMinutes(minutes * 15);
+ } else if (duration.equals(configuration.getSixHourTimeSliceDuration())) {
+ return dt.hourOfDay().roundFloorCopy();
+ } else {
+ throw new IllegalArgumentException("The duration [" + duration + "] is not supported");
+ }
+ }
+}
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/ClusterConfig.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/ClusterConfig.java
deleted file mode 100644
index af3ffeb..0000000
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/ClusterConfig.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- *
- * * RHQ Management Platform
- * * Copyright (C) 2005-2012 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.metrics.simulator.plan;
-
-import java.io.File;
-
-/**
- * @author John Sanda
- */
-public class ClusterConfig {
-
- private boolean embedded = true;
-
- private String clusterDir = new File(System.getProperty("rhq.metrics.simulator.basedir")).getAbsolutePath();
-
- private int numNodes = 2;
-
- private String heapSize = "256M";
-
- private String heapNewSize = "64M";
-
- private String stackSize;
-
- public boolean isEmbedded() {
- return embedded;
- }
-
- public void setEmbedded(boolean embedded) {
- this.embedded = embedded;
- }
-
- public String getClusterDir() {
- return clusterDir;
- }
-
- public void setClusterDir(String clusterDir) {
- this.clusterDir = clusterDir;
- }
-
- public int getNumNodes() {
- return numNodes;
- }
-
- public void setNumNodes(int numNodes) {
- this.numNodes = numNodes;
- }
-
- public String getHeapSize() {
- return heapSize;
- }
-
- public void setHeapSize(String heapSize) {
- this.heapSize = heapSize;
- }
-
- public String getHeapNewSize() {
- return heapNewSize;
- }
-
- public void setHeapNewSize(String heapNewSize) {
- this.heapNewSize = heapNewSize;
- }
-
- public String getStackSize() {
- return stackSize;
- }
-
- public void setStackSize(String stackSize) {
- this.stackSize = stackSize;
- }
-}
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java
index a1079db..70c326a 100644
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java
@@ -48,6 +48,8 @@ public class SimulationPlan {
private int cqlPort;
+ private int batchSize;
+
public int getThreadPoolSize() {
return threadPoolSize;
}
@@ -111,4 +113,12 @@ public class SimulationPlan {
public void setCqlPort(int cqlPort) {
this.cqlPort = cqlPort;
}
+
+ public int getBatchSize() {
+ return batchSize;
+ }
+
+ public void setBatchSize(int batchSize) {
+ this.batchSize = batchSize;
+ }
}
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java
index 06aaaa1..dc9142c 100644
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java
@@ -31,14 +31,10 @@ import java.net.InetAddress;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-import org.joda.time.Days;
-import org.joda.time.Duration;
-import org.joda.time.Hours;
import org.joda.time.Minutes;
import org.joda.time.Seconds;
import org.rhq.server.metrics.MetricsConfiguration;
-import org.rhq.server.metrics.domain.MetricsTable;
/**
* @author John Sanda
@@ -50,11 +46,12 @@ public class SimulationPlanner {
JsonNode root = mapper.readTree(jsonFile);
SimulationPlan simulation = new SimulationPlan();
- simulation.setCollectionInterval(getLong(root.get("collectionInterval"), 1000L));
- simulation.setAggregationInterval(getLong(root.get("aggregationInterval"), 60000L));
+ simulation.setCollectionInterval(getLong(root.get("collectionInterval"), 1250L));
+ simulation.setAggregationInterval(getLong(root.get("aggregationInterval"), 150000L)); // 2.5 minutes
simulation.setNumMeasurementCollectors(getInt(root.get("numMeasurementCollectors"), 5));
simulation.setSimulationTime(getInt(root.get("simulationTime"), 10));
simulation.setThreadPoolSize(getInt(root.get("threadPoolSize"), simulation.getNumMeasurementCollectors() + 2));
+ simulation.setBatchSize(getInt(root.get("batchSize"), 5000));
String[] nodes;
if (root.get("nodes") == null || root.get("nodes").size() == 0) {
@@ -78,26 +75,18 @@ public class SimulationPlanner {
private MetricsConfiguration createDefaultMetricsConfiguration() {
- // 500 ms --> 30 sec
- // 1 sec --> 1 minute
- // 60 sec / 1 minute --> 1 hr
- // 1440 sec / 24 minutes --> 1 day
- // 168 minutes --> 1 week
- // 744 minutes / 12.4 hr --> 31 days / 1 month
- // 8928 minutes / 148.8 hr --> 1 yr
-
MetricsConfiguration configuration = new MetricsConfiguration();
configuration.setRawTTL(Minutes.minutes(168).toStandardSeconds().getSeconds());
configuration.setRawRetention(Minutes.minutes(168).toStandardDuration());
- configuration.setRawTimeSliceDuration(Minutes.ONE.toStandardDuration());
+ configuration.setRawTimeSliceDuration(Seconds.seconds(150).toStandardDuration());
configuration.setOneHourTTL(Minutes.minutes(336).toStandardSeconds().getSeconds());
configuration.setOneHourRetention(Minutes.minutes(336));
- configuration.setOneHourTimeSliceDuration(Minutes.minutes(6).toStandardDuration());
+ configuration.setOneHourTimeSliceDuration(Minutes.minutes(15).toStandardDuration());
configuration.setSixHourTTL(Minutes.minutes(744).toStandardSeconds().getSeconds());
configuration.setSixHourRetention(Minutes.minutes(744).toStandardSeconds());
- configuration.setSixHourTimeSliceDuration(Minutes.minutes(24).toStandardDuration());
+ configuration.setSixHourTimeSliceDuration(Minutes.minutes(60).toStandardDuration());
configuration.setTwentyFourHourTTL(Minutes.minutes(8928).toStandardSeconds().getSeconds());
configuration.setTwentyFourHourRetention(Minutes.minutes(8928).toStandardSeconds());
@@ -105,72 +94,6 @@ public class SimulationPlanner {
return configuration;
}
- private MetricsTable getTable(String name) {
- if (name.equals(MetricsTable.RAW.getTableName())) {
- return MetricsTable.RAW;
- } else if (name.equals(MetricsTable.ONE_HOUR.getTableName())) {
- return MetricsTable.ONE_HOUR;
- } else if (name.equals(MetricsTable.SIX_HOUR.getTableName())) {
- return MetricsTable.SIX_HOUR;
- } else if (name.equals(MetricsTable.TWENTY_FOUR_HOUR.getTableName())) {
- return MetricsTable.TWENTY_FOUR_HOUR;
- } else {
- throw new IllegalArgumentException(name + " is not a valid metrics table name");
- }
- }
-
- private void setTTLAndRetention(MetricsTable table, int ttl, MetricsConfiguration configuration) {
- switch (table) {
- case RAW:
- configuration.setRawTTL(ttl);
- configuration.setRawRetention(Seconds.seconds(ttl).toStandardDuration());
- break;
- case ONE_HOUR:
- configuration.setOneHourTTL(ttl);
- configuration.setOneHourRetention(Seconds.seconds(ttl));
- break;
- case SIX_HOUR:
- configuration.setSixHourTTL(ttl);
- configuration.setSixHourRetention(Seconds.seconds(ttl));
- break;
- default:
- configuration.setTwentyFourHourTTL(ttl);
- configuration.setTwentyFourHourRetention(Seconds.seconds(ttl));
- break;
- }
- }
-
- private Duration getDuration(String units, int value) {
- if (units.equals("seconds")) {
- return Seconds.seconds(value).toStandardDuration();
- } else if (units.equals("minutes")) {
- return Minutes.minutes(value).toStandardDuration();
- } else if (units.equals("hours")) {
- return Hours.hours(value).toStandardDuration();
-
- } else if (units.equals("days")) {
- return Days.days(value).toStandardDuration();
- } else {
- throw new IllegalArgumentException(units + " is not a valid value for the units property.");
- }
- }
-
- private void setTimeSliceDuration(MetricsTable table, Duration duration, MetricsConfiguration configuration) {
- switch (table) {
- case RAW:
- configuration.setRawTimeSliceDuration(duration);
- break;
- case ONE_HOUR:
- configuration.setOneHourTimeSliceDuration(duration);
- break;
- case SIX_HOUR:
- configuration.setSixHourTimeSliceDuration(duration);
- break;
- default:
- // do nothing
- }
- }
-
private long getLong(JsonNode node, long defaultValue) {
if (node == null) {
return defaultValue;
commit cc2c6dbc98c8ae5e34fe11f577d0dfbac35a49a0
Author: John Sanda <jsanda(a)redhat.com>
Date: Fri Sep 27 10:41:55 2013 -0400
allow for configurable time slices
diff --git a/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java b/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java
index 83f7653..f21f5c1 100644
--- a/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java
+++ b/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java
@@ -27,6 +27,7 @@ package org.rhq.server.metrics;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -97,13 +98,13 @@ public class MetricsServer {
* purged.
*/
private void determineMostRecentRawDataSinceLastShutdown() {
- DateTime previousHour = currentHour().minusHours(1);
+ DateTime previousHour = currentInterval().minus(configuration.getRawTimeSliceDuration());
DateTime oldestRawTime = previousHour.minus(configuration.getRawRetention());
ResultSet resultSet = dao.setFindTimeSliceForIndex(MetricsTable.ONE_HOUR, previousHour.getMillis());
Row row = resultSet.one();
while (row == null && previousHour.compareTo(oldestRawTime) > 0) {
- previousHour = previousHour.minusHours(1);
+ previousHour = previousHour.minus(configuration.getRawTimeSliceDuration());
resultSet = dao.setFindTimeSliceForIndex(MetricsTable.ONE_HOUR, previousHour.getMillis());
row = resultSet.one();
}
@@ -125,6 +126,10 @@ public class MetricsServer {
}
}
+ protected DateTime currentInterval() {
+ return dateTimeService.getTimeSlice(DateTime.now(), configuration.getRawTimeSliceDuration());
+ }
+
protected DateTime currentHour() {
DateTime dt = new DateTime(System.currentTimeMillis());
return dateTimeService.getTimeSlice(dt, Duration.standardHours(1));
@@ -380,7 +385,7 @@ public class MetricsServer {
* for subsequently computing baselines.
*/
public Iterable<AggregateNumericMetric> calculateAggregates() {
- DateTime theHour = currentHour();
+ DateTime theHour = currentInterval();
if (pastAggregationMissed) {
calculateAggregates(roundDownToHour(mostRecentRawDataPriorToStartup).plusHours(1).getMillis());
@@ -394,12 +399,15 @@ public class MetricsServer {
private Iterable<AggregateNumericMetric> calculateAggregates(long startTime) {
DateTime dt = new DateTime(startTime);
DateTime currentHour = dateTimeService.getTimeSlice(dt, configuration.getRawTimeSliceDuration());
- DateTime lastHour = currentHour.minusHours(1);
+ DateTime lastHour = currentHour.minus(configuration.getRawTimeSliceDuration());
long hourTimeSlice = lastHour.getMillis();
long sixHourTimeSlice = dateTimeService.getTimeSlice(lastHour,
configuration.getOneHourTimeSliceDuration()).getMillis();
+ if (log.isDebugEnabled()) {
+ log.debug("six hour time slice = " + new Date(sixHourTimeSlice));
+ }
long twentyFourHourTimeSlice = dateTimeService.getTimeSlice(lastHour,
configuration.getSixHourTimeSliceDuration()).getMillis();
@@ -457,7 +465,7 @@ public class MetricsServer {
for (MetricsIndexEntry indexEntry : indexEntries) {
DateTime startTime = indexEntry.getTime();
- DateTime endTime = startTime.plusMinutes(60);
+ DateTime endTime = startTime.plus(configuration.getRawTimeSliceDuration());
Iterable<RawNumericMetric> rawMetrics = dao.findRawMetrics(indexEntry.getScheduleId(),
startTime.getMillis(), endTime.getMillis());
@@ -517,7 +525,7 @@ public class MetricsServer {
try {
DateTime startTime = new DateTime(timeSlice);
DateTime endTime = startTime.plus(nextDuration);
- DateTime currentHour = currentHour();
+ DateTime currentHour = currentInterval();
if (log.isDebugEnabled()) {
log.debug("Time slice start time is [" + startTime + "] and the end time is [" + endTime + "].");
@@ -554,6 +562,9 @@ public class MetricsServer {
AggregateNumericMetric aggregatedMetric = calculateAggregate(metrics, startTime.getMillis());
aggregatedMetric.setScheduleId(indexEntry.getScheduleId());
toMetrics.add(aggregatedMetric);
+ if (toTable == MetricsTable.TWENTY_FOUR_HOUR) {
+ log.debug("Calculated 24 hour metric = " + aggregatedMetric);
+ }
}
switch (toTable) {
diff --git a/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/DateTimeServiceTest.java b/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/DateTimeServiceTest.java
index 2e3d899..01b3a76 100644
--- a/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/DateTimeServiceTest.java
+++ b/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/DateTimeServiceTest.java
@@ -96,6 +96,18 @@ public class DateTimeServiceTest {
}
@Test
+ public void getMinuteTimeSliceForSixHourData() {
+ configuration = new MetricsConfiguration();
+ configuration.setSixHourTimeSliceDuration(Minutes.minutes(24).toStandardDuration());
+
+ DateTime currentHour = dateTimeService.hour0().plusHours(9).plusMinutes(12).plusSeconds(47);
+ DateTime timeSlice = dateTimeService.getTimeSlice(currentHour, configuration.getSixHourTimeSliceDuration());
+ DateTime expected = dateTimeService.hour0().plusHours(9);
+
+ assertEquals(timeSlice, expected, "The hour time slice for six hour data is wrong");
+ }
+
+ @Test
public void timestampBefore7DaysShouldBeInRawDataRange() {
assertTrue(dateTimeService.isInRawDataRange(now().minusHours(1)), "1 hour ago should be in raw data range.");
assertTrue(dateTimeService.isInRawDataRange(now().minusDays(1)), "1 day ago should be in raw data range.");
diff --git a/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsServerTest.java b/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsServerTest.java
index 2c140f6..a670fcf 100644
--- a/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsServerTest.java
+++ b/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsServerTest.java
@@ -101,6 +101,11 @@ public class MetricsServerTest extends CassandraIntegrationTest {
}
return currentHour;
}
+
+ @Override
+ protected DateTime currentInterval() {
+ return currentHour;
+ }
}
@BeforeMethod
commit 3a28eb4c10139416a6ea65597b9d006ec881b313
Author: John Sanda <jsanda(a)redhat.com>
Date: Fri Sep 27 10:29:21 2013 -0400
numerous changes in metrics-simulator to simplify things
Metrics are now captured using the Metrics Core library which renders both
Stats.java and StatsCollector.java obsolete.
MetricsCollector has been simplified substantially. It is now seeded with a
starting schedule id and a batch size and generates batch size inserts each
time it runs.
A good bit of the simulator configuration that is specified in the json file
has been removed as well in an effort to make sure things are correct. As of
now intervals and time slices are fixed.
* raw data --> 1 minute
* 1 hour data --> 6 minutes
* 6 hour data --> 1 hour
This means that a day's worth of data is generated in one hour. Minor changes
have been made in MetricsServer to allow for configurable time slices.
diff --git a/modules/helpers/metrics-simulator/pom.xml b/modules/helpers/metrics-simulator/pom.xml
index 3281f90..7f9f6ae 100644
--- a/modules/helpers/metrics-simulator/pom.xml
+++ b/modules/helpers/metrics-simulator/pom.xml
@@ -10,6 +10,10 @@
<artifactId>rhq-metrics-simulator</artifactId>
<name>RHQ Metrics Simulator</name>
+ <properties>
+ <animal.sniffer.skip>true</animal.sniffer.skip>
+ </properties>
+
<dependencies>
<dependency>
<groupId>org.rhq</groupId>
@@ -76,6 +80,12 @@
<artifactId>commons-cli</artifactId>
<version>1.2</version>
</dependency>
+
+ <dependency>
+ <groupId>com.codahale.metrics</groupId>
+ <artifactId>metrics-core</artifactId>
+ <version>3.0.1</version>
+ </dependency>
</dependencies>
<build>
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementAggregator.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementAggregator.java
index 31bca0b..ef223cb 100644
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementAggregator.java
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementAggregator.java
@@ -25,6 +25,8 @@
package org.rhq.metrics.simulator;
+import com.codahale.metrics.Timer;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -39,20 +41,18 @@ public class MeasurementAggregator implements Runnable {
private MetricsServer metricsServer;
+ private Metrics metrics;
+
private ShutdownManager shutdownManager;
- public void setMetricsServer(MetricsServer metricsServer) {
+ public MeasurementAggregator(MetricsServer metricsServer, ShutdownManager shutdownManager, Metrics metrics) {
this.metricsServer = metricsServer;
- }
-
- public void setShutdownManager(ShutdownManager shutdownManager) {
this.shutdownManager = shutdownManager;
+ this.metrics = metrics;
}
- @Override
public void run() {
- log.info("Starting metrics aggregation...");
- long startTime = System.currentTimeMillis();
+ Timer.Context context = metrics.totalAggregationTime.time();
try {
metricsServer.calculateAggregates();
} catch (Exception e) {
@@ -60,8 +60,7 @@ public class MeasurementAggregator implements Runnable {
log.error("Requesting simulation shutdown...");
shutdownManager.shutdown(1);
} finally {
- long endTime = System.currentTimeMillis();
- log.info("Finished metrics aggregation in " + (endTime - startTime) + " ms");
+ context.stop();
}
}
}
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementCollector.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementCollector.java
index b0a67c8..45fe409 100644
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementCollector.java
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/MeasurementCollector.java
@@ -26,15 +26,15 @@
package org.rhq.metrics.simulator;
import java.util.HashSet;
-import java.util.PriorityQueue;
import java.util.Set;
-import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.ThreadLocalRandom;
+
+import com.codahale.metrics.Timer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.measurement.MeasurementDataNumeric;
-import org.rhq.metrics.simulator.stats.Stats;
import org.rhq.server.metrics.MetricsServer;
import org.rhq.server.metrics.RawDataInsertedCallback;
@@ -45,98 +45,52 @@ public class MeasurementCollector implements Runnable {
private final Log log = LogFactory.getLog(MeasurementCollector.class);
- private PriorityQueue<Schedule> queue;
-
private MetricsServer metricsServer;
- private ReentrantLock queueLock;
-
- private Stats stats;
+ private int batchSize;
- private ShutdownManager shutdownManager;
+ private int startingScheduleId;
- private int batchSize = 500;
-
- private NoOpCallback rawInsertsCallback = new NoOpCallback();
-
- public void setQueue(PriorityQueue<Schedule> queue) {
- this.queue = queue;
- }
+ private Metrics metrics;
- public void setMetricsServer(MetricsServer metricsServer) {
+ public MeasurementCollector(int batchSize, int startingScheduleId, Metrics metrics, MetricsServer metricsServer) {
+ this.batchSize = batchSize;
+ this.startingScheduleId = startingScheduleId;
+ this.metrics = metrics;
this.metricsServer = metricsServer;
}
- public void setQueueLock(ReentrantLock queueLock) {
- this.queueLock = queueLock;
- }
+ private Set<MeasurementDataNumeric> generateData() {
+ Set<MeasurementDataNumeric> data = new HashSet<MeasurementDataNumeric>(batchSize);
+ long timestamp = System.currentTimeMillis();
+ ThreadLocalRandom random = ThreadLocalRandom.current();
- public void setStats(Stats stats) {
- this.stats = stats;
- }
+ for (int i = 0; i < batchSize; ++i) {
+ data.add(new MeasurementDataNumeric(timestamp, startingScheduleId + i, random.nextDouble()));
+ }
- public void setShutdownManager(ShutdownManager shutdownManager) {
- this.shutdownManager = shutdownManager;
+ return data;
}
@Override
public void run() {
- long startTime = System.currentTimeMillis();
- int metricsCollected = 0;
- // TODO parameterize threshold
- try {
- log.info("Starting metrics collections...");
- Set<Schedule> schedules = new HashSet<Schedule>();
- try {
- queueLock.lock();
- Schedule first = queue.peek();
- if (first != null && first.getNextCollection() <= System.currentTimeMillis()) {
- Schedule next = first;
- while (next != null && next.getNextCollection() == first.getNextCollection() &&
- schedules.size() < batchSize) {
- schedules.add(queue.poll());
- next = queue.peek();
- }
- }
- } finally {
- queueLock.unlock();
+ final Timer.Context context = metrics.batchInsertTime.time();
+ metricsServer.addNumericData(generateData(), new RawDataInsertedCallback() {
+ @Override
+ public void onFinish() {
+ context.stop();
}
- if (schedules.isEmpty()) {
- log.debug("No schedules are ready for collections.");
- return;
+ @Override
+ public void onSuccess(MeasurementDataNumeric result) {
+ metrics.rawInserts.mark();
}
- log.debug("There are " + schedules.size() + " schedules ready for collection.");
- Set<MeasurementDataNumeric> data = new HashSet<MeasurementDataNumeric>(schedules.size());
- for (Schedule schedule : schedules) {
- data.add(new MeasurementDataNumeric(schedule.getNextCollection(), schedule.getId(),
- schedule.getNextValue()));
- schedule.updateCollection();
+ @Override
+ public void onFailure(Throwable t) {
+ log.warn("Failed to insert raw data", t);
}
- metricsCollected = data.size();
- try {
- metricsServer.addNumericData(data, rawInsertsCallback);
- } catch (Exception e) {
- log.error("An error occurred while trying to store raw metrics", e);
- log.error("Requesting simulation shutdown...");
- shutdownManager.shutdown(1);
- }
- stats.addRawInserts(metricsCollected);
- try {
- queueLock.lock();
- for (Schedule schedule : schedules) {
- queue.offer(schedule);
- }
- } finally {
- queueLock.unlock();
- }
- } finally {
- long endTime = System.currentTimeMillis();
- long totalTime = endTime - startTime;
- stats.addRawInsertTime(totalTime);
- log.info("Finished collecting and storing " + metricsCollected + " raw metric in " +totalTime + " ms.");
- }
+ });
}
private static class NoOpCallback implements RawDataInsertedCallback {
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Metrics.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Metrics.java
new file mode 100644
index 0000000..f7ea87a
--- /dev/null
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Metrics.java
@@ -0,0 +1,30 @@
+package org.rhq.metrics.simulator;
+
+import static com.codahale.metrics.MetricRegistry.name;
+
+import com.codahale.metrics.Meter;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Timer;
+
+/**
+ * @author John Sanda
+ */
+public class Metrics {
+
+ public final MetricRegistry registry;
+
+ public final Meter rawInserts;
+
+ public final Timer batchInsertTime;
+
+ public final Timer totalAggregationTime;
+
+ public Metrics() {
+ registry = new MetricRegistry();
+
+ rawInserts = registry.meter(name(MeasurementCollector.class, "rawInserts"));
+ batchInsertTime = registry.timer(name(MeasurementCollector.class, "batchInsertTime"));
+ totalAggregationTime = registry.timer(name(MeasurementAggregator.class, "totalAggregationTime"));
+ }
+
+}
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Schedule.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Schedule.java
deleted file mode 100644
index 0bcb4b8..0000000
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Schedule.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *
- * * RHQ Management Platform
- * * Copyright (C) 2005-2012 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.metrics.simulator;
-
-/**
- * @author John Sanda
- */
-public class Schedule implements Comparable<Schedule> {
-
- private int id;
-
- private long lastCollection;
-
- private long nextCollection;
-
- private long interval;
-
- public Schedule(int id) {
- this.id = id;
- }
-
- public int getId() {
- return id;
- }
-
- public long getLastCollection() {
- return lastCollection;
- }
-
- public void setLastCollection(long lastCollection) {
- this.lastCollection = lastCollection;
- }
-
- public long getNextCollection() {
- return nextCollection;
- }
-
- public void setNextCollection(long nextCollection) {
- this.nextCollection = nextCollection;
- }
-
- public void updateCollection() {
- nextCollection += interval;
- }
-
- public long getInterval() {
- return interval;
- }
-
- public void setInterval(long interval) {
- this.interval = interval;
- }
-
- public double getNextValue() {
- return 1.23;
- }
-
- @Override
- public int compareTo(Schedule that) {
- if (this.nextCollection < that.nextCollection) {
- return -1;
- }
-
- if (this.nextCollection > that.nextCollection) {
- return 1;
- }
-
- return 0;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- Schedule schedule = (Schedule) o;
-
- if (id != schedule.id) return false;
- if (interval != schedule.interval) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = id;
- result = 31 * result + (int) (interval ^ (interval >>> 32));
- return result;
- }
-
- @Override
- public String toString() {
- return "Schedule[id= " + id + ", lastCollection= " + lastCollection + ", nextCollection= " + nextCollection +
- ", interval= " + interval + "]";
- }
-}
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Simulator.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Simulator.java
index 59bafcf..be45017 100644
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Simulator.java
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/Simulator.java
@@ -20,18 +20,16 @@
package org.rhq.metrics.simulator;
import java.io.File;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.PriorityQueue;
-import java.util.Set;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.ReentrantLock;
+import com.codahale.metrics.ConsoleReporter;
import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.Host;
-import com.datastax.driver.core.ProtocolOptions;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.exceptions.NoHostAvailableException;
@@ -39,16 +37,9 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.Minutes;
-import org.rhq.cassandra.CassandraClusterManager;
-import org.rhq.cassandra.ClusterInitService;
-import org.rhq.cassandra.DeploymentOptions;
-import org.rhq.cassandra.DeploymentOptionsFactory;
import org.rhq.cassandra.schema.SchemaManager;
import org.rhq.cassandra.util.ClusterBuilder;
-import org.rhq.metrics.simulator.plan.ClusterConfig;
-import org.rhq.metrics.simulator.plan.ScheduleGroup;
import org.rhq.metrics.simulator.plan.SimulationPlan;
-import org.rhq.metrics.simulator.stats.Stats;
import org.rhq.server.metrics.DateTimeService;
import org.rhq.server.metrics.MetricsDAO;
import org.rhq.server.metrics.MetricsServer;
@@ -63,8 +54,6 @@ public class Simulator implements ShutdownManager {
private boolean shutdown = false;
- private CassandraClusterManager ccm;
-
public void run(SimulationPlan plan) {
final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(plan.getThreadPoolSize(),
new SimulatorThreadFactory());
@@ -76,18 +65,9 @@ public class Simulator implements ShutdownManager {
}
});
- initCluster(plan);
- createSchema();
-
- Session session = createSession();
-// if (plan.getClientCompression() == null) {
-// session = createSession();
-// } else {
-// ProtocolOptions.Compression compression = Enum.valueOf(ProtocolOptions.Compression.class,
-// plan.getClientCompression().toUpperCase());
-// session = createSession(compression);
-// }
+ createSchema(plan.getNodes(), plan.getCqlPort());
+ Session session = createSession(plan.getNodes(), plan.getCqlPort());
StorageSession storageSession = new StorageSession(session);
MetricsDAO metricsDAO = new MetricsDAO(storageSession, plan.getMetricsServerConfiguration());
@@ -99,29 +79,16 @@ public class Simulator implements ShutdownManager {
dateTimeService.setConfiguration(plan.getMetricsServerConfiguration());
metricsServer.setDateTimeService(dateTimeService);
- Set<Schedule> schedules = initSchedules(plan.getScheduleSets().get(0));
- PriorityQueue<Schedule> queue = new PriorityQueue<Schedule>(schedules);
- ReentrantLock queueLock = new ReentrantLock();
-
- MeasurementAggregator measurementAggregator = new MeasurementAggregator();
- measurementAggregator.setMetricsServer(metricsServer);
- measurementAggregator.setShutdownManager(this);
+ Metrics metrics = new Metrics();
- Stats stats = new Stats();
- StatsCollector statsCollector = new StatsCollector(stats);
-
- log.info("Starting executor service");
- executorService.scheduleAtFixedRate(statsCollector, 0, 1, TimeUnit.MINUTES);
+ MeasurementAggregator measurementAggregator = new MeasurementAggregator(metricsServer, this, metrics);
+ ConsoleReporter consoleReporter = createConsoleReporter(metrics);
+ int batchSize = 3;
for (int i = 0; i < plan.getNumMeasurementCollectors(); ++i) {
- MeasurementCollector measurementCollector = new MeasurementCollector();
- measurementCollector.setMetricsServer(metricsServer);
- measurementCollector.setQueue(queue);
- measurementCollector.setQueueLock(queueLock);
- measurementCollector.setStats(stats);
- measurementCollector.setShutdownManager(this);
-
+ MeasurementCollector measurementCollector = new MeasurementCollector(batchSize, batchSize * i, metrics,
+ metricsServer);
executorService.scheduleAtFixedRate(measurementCollector, 0, plan.getCollectionInterval(),
TimeUnit.MILLISECONDS);
}
@@ -133,16 +100,31 @@ public class Simulator implements ShutdownManager {
Thread.sleep(Minutes.minutes(plan.getSimulationTime()).toStandardDuration().getMillis());
} catch (InterruptedException e) {
}
- statsCollector.reportSummaryStats();
log.info("Simulation has completed. Initiating shutdown...");
+ consoleReporter.stop();
shutdown(0);
}
+ private ConsoleReporter createConsoleReporter(Metrics metrics) {
+ try {
+ File basedir = new File(System.getProperty("rhq.metrics.simulator.basedir"));
+ File logDir = new File(basedir, "log");
+ ConsoleReporter consoleReporter = ConsoleReporter.forRegistry(metrics.registry)
+ .convertRatesTo(TimeUnit.SECONDS).convertDurationsTo(TimeUnit.MILLISECONDS)
+ .outputTo(new PrintStream(new FileOutputStream(new File(logDir, "metrics.txt")))).build();
+ consoleReporter.start(1, TimeUnit.MINUTES);
+ return consoleReporter;
+ } catch (FileNotFoundException e) {
+ throw new RuntimeException("Failed to create console reporter", e);
+ }
+ }
+
@Override
public synchronized void shutdown(int status) {
if (shutdown) {
return;
}
+
shutdown = true;
log.info("Preparing to shutdown simulator...");
System.exit(status);
@@ -159,65 +141,23 @@ public class Simulator implements ShutdownManager {
log.info("Forcing executor service shutdown.");
executorService.shutdownNow();
}
- shutdownCluster();
log.info("Shut down complete");
}
- private void initCluster(SimulationPlan plan) {
- try {
- deployCluster(plan.getClusterConfig());
- waitForClusterToInitialize();
- } catch (Exception e) {
- throw new RuntimeException("Failed to start simulator. Cluster initialization failed.", e);
- }
- }
-
- private void deployCluster(ClusterConfig clusterConfig) throws IOException {
- File clusterDir = new File(clusterConfig.getClusterDir(), "cassandra");
- log.info("Deploying cluster to " + clusterDir);
- clusterDir.mkdirs();
-
- DeploymentOptionsFactory factory = new DeploymentOptionsFactory();
- DeploymentOptions deploymentOptions = factory.newDeploymentOptions();
- deploymentOptions.setClusterDir(clusterDir.getAbsolutePath());
- deploymentOptions.setNumNodes(clusterConfig.getNumNodes());
- deploymentOptions.setHeapSize(clusterConfig.getHeapSize());
- deploymentOptions.setHeapNewSize(clusterConfig.getHeapNewSize());
- if (clusterConfig.getStackSize() != null) {
- deploymentOptions.setStackSize(clusterConfig.getStackSize());
- }
- deploymentOptions.setLoggingLevel("INFO");
- deploymentOptions.load();
-
- ccm = new CassandraClusterManager(deploymentOptions);
- ccm.createCluster();
- ccm.startCluster(false);
- }
-
- private void shutdownCluster() {
- log.info("Shutting down cluster");
- ccm.shutdownCluster();
- }
-
- private void waitForClusterToInitialize() {
- log.info("Waiting for cluster to initialize");
- ClusterInitService clusterInitService = new ClusterInitService();
- clusterInitService.waitForClusterToStart(ccm.getNodes(), ccm.getJmxPorts(), ccm.getNodes().length, 2000, 20, 10);
- }
-
- private void createSchema() {
+ private void createSchema(String[] nodes, int cqlPort) {
try {
log.info("Creating schema");
- SchemaManager schemaManager = new SchemaManager("rhqadmin", "1eeb2f255e832171df8592078de921bc", ccm.getNodes(), ccm.getCqlPort());
+ SchemaManager schemaManager = new SchemaManager("rhqadmin", "1eeb2f255e832171df8592078de921bc",
+ new String[] {"127.0.0.1"}, 9142);
schemaManager.install();
} catch (Exception e) {
throw new RuntimeException("Failed to start simulator. An error occurred during schema creation.", e);
}
}
- private Session createSession() throws NoHostAvailableException {
+ private Session createSession(String[] nodes, int cqlPort) throws NoHostAvailableException {
try {
- Cluster cluster = new ClusterBuilder().addContactPoints(ccm.getNodes()).withPort(ccm.getCqlPort())
+ Cluster cluster = new ClusterBuilder().addContactPoints(nodes).withPort(cqlPort)
.withCredentials("rhqadmin", "rhqadmin")
.build();
@@ -231,25 +171,6 @@ public class Simulator implements ShutdownManager {
}
}
- private Session createSession(ProtocolOptions.Compression compression)
- throws NoHostAvailableException {
- try {
- log.debug("Creating session using " + compression.name() + " compression");
-
- Cluster cluster = new ClusterBuilder().addContactPoints(ccm.getNodes()).withPort(ccm.getCqlPort())
- .withCredentials("cassandra", "cassandra")
- .withCompression(compression)
- .build();
-
- log.debug("Created cluster object with " + cluster.getConfiguration().getProtocolOptions().getCompression()
- + " compression.");
-
- return initSession(cluster);
- } catch (Exception e) {
- throw new RuntimeException("Failed to start simulator. Unable to create " + Session.class, e);
- }
- }
-
@SuppressWarnings("deprecation")
private Session initSession(Cluster cluster) {
NodeFailureListener listener = new NodeFailureListener();
@@ -260,18 +181,6 @@ public class Simulator implements ShutdownManager {
return cluster.connect("rhq");
}
- private Set<Schedule> initSchedules(ScheduleGroup scheduleSet) {
- long nextCollection = System.currentTimeMillis();
- Set<Schedule> schedules = new HashSet<Schedule>();
- for (int i = 0; i < scheduleSet.getCount(); ++i) {
- Schedule schedule = new Schedule(i);
- schedule.setInterval(scheduleSet.getInterval());
- schedule.setNextCollection(nextCollection);
- schedules.add(schedule);
- }
- return schedules;
- }
-
private static class NodeFailureListener implements Host.StateListener {
private Log log = LogFactory.getLog(NodeFailureListener.class);
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/StatsCollector.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/StatsCollector.java
deleted file mode 100644
index b59ca9c..0000000
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/StatsCollector.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- *
- * * RHQ Management Platform
- * * Copyright (C) 2005-2012 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.metrics.simulator;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.joda.time.Duration;
-
-import org.rhq.metrics.simulator.stats.Stats;
-
-/**
- * @author John Sanda
- */
-public class StatsCollector implements Runnable {
-
- private final Log log = LogFactory.getLog(StatsCollector.class);
-
- private Stats stats;
-
- private long previousRawInsertTotal;
-
- private long lastRunTimestamp;
-
- private SimpleDateFormat dateFormat;
-
- public StatsCollector(Stats stats) {
- this.stats = stats;
- dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
- }
-
- @Override
- public void run() {
- long now = System.currentTimeMillis();
- long totalRawInserts = stats.getTotalRawInserts();
-
- // inserts will be null on the first run
- if (lastRunTimestamp == 0) {
- lastRunTimestamp = now;
- previousRawInsertTotal = totalRawInserts;
- return;
- }
-
- long lastRawInsertsCount = totalRawInserts - previousRawInsertTotal;
- Duration duration = new Duration(lastRunTimestamp, now);
- stats.addRawInsertsPerMinute(lastRawInsertsCount);
-
- StringBuilder data = new StringBuilder("Statistics Report\n")
- .append("------------------------------------------------------------------------------------\n")
- .append("Sampling period start time: " + dateFormat.format(new Date(lastRunTimestamp))).append("\n")
- .append("Sampling period length: " + duration.toStandardSeconds().getSeconds()).append(" seconds\n")
- .append("Total raw metrics inserted: ").append(totalRawInserts).append("\n")
- .append("Raw inserts this sampling period: ").append(lastRawInsertsCount).append("\n")
- .append(stats.getRawInsertsPerMinute()).append("\n")
- .append(stats.getRawInsertTimes()).append("\n")
- .append("------------------------------------------------------------------------------------");
-
- log.info(data);
-
- lastRunTimestamp = now;
- previousRawInsertTotal = totalRawInserts;
- }
-
- public void reportSummaryStats() {
- log.info("Reporting statistics for entire simulation run.");
- log.info(stats.getRawInsertsPerMinute());
- }
-
-}
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/ScheduleGroup.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/ScheduleGroup.java
deleted file mode 100644
index 4dbcf29..0000000
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/ScheduleGroup.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *
- * * RHQ Management Platform
- * * Copyright (C) 2005-2012 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.metrics.simulator.plan;
-
-/**
- * @author John Sanda
- */
-public class ScheduleGroup {
-
- private int count;
-
- private long interval;
-
- public ScheduleGroup() {
- }
-
- public ScheduleGroup(int count, long interval) {
- this.count = count;
- this.interval = interval;
- }
-
- public int getCount() {
- return count;
- }
-
- public void setCount(int count) {
- this.count = count;
- }
-
- public long getInterval() {
- return interval;
- }
-
- public void setInterval(long interval) {
- this.interval = interval;
- }
-}
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java
index d2c62c0..a1079db 100644
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlan.java
@@ -25,9 +25,6 @@
package org.rhq.metrics.simulator.plan;
-import java.util.ArrayList;
-import java.util.List;
-
import org.rhq.server.metrics.MetricsConfiguration;
/**
@@ -35,8 +32,6 @@ import org.rhq.server.metrics.MetricsConfiguration;
*/
public class SimulationPlan {
- private List<ScheduleGroup> scheduleSets = new ArrayList<ScheduleGroup>();
-
private int threadPoolSize;
private long collectionInterval;
@@ -49,21 +44,9 @@ public class SimulationPlan {
private int simulationTime;
- private ClusterConfig clusterConfig;
-
- private String clientCompression = null;
-
- public List<ScheduleGroup> getScheduleSets() {
- return scheduleSets;
- }
-
- public void addScheduleSet(ScheduleGroup scheduleSet) {
- scheduleSets.add(scheduleSet);
- }
+ private String[] nodes;
- public void setScheduleSets(List<ScheduleGroup> scheduleSets) {
- this.scheduleSets = scheduleSets;
- }
+ private int cqlPort;
public int getThreadPoolSize() {
return threadPoolSize;
@@ -113,19 +96,19 @@ public class SimulationPlan {
this.simulationTime = simulationTime;
}
- public ClusterConfig getClusterConfig() {
- return clusterConfig;
+ public String[] getNodes() {
+ return nodes;
}
- public void setClusterConfig(ClusterConfig clusterConfig) {
- this.clusterConfig = clusterConfig;
+ public void setNodes(String[] nodes) {
+ this.nodes = nodes;
}
- public String getClientCompression() {
- return clientCompression;
+ public int getCqlPort() {
+ return cqlPort;
}
- public void setClientCompression(String clientCompression) {
- this.clientCompression = clientCompression;
+ public void setCqlPort(int cqlPort) {
+ this.cqlPort = cqlPort;
}
}
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java
index f0e41ed..06aaaa1 100644
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java
+++ b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/plan/SimulationPlanner.java
@@ -26,6 +26,7 @@
package org.rhq.metrics.simulator.plan;
import java.io.File;
+import java.net.InetAddress;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -49,117 +50,57 @@ public class SimulationPlanner {
JsonNode root = mapper.readTree(jsonFile);
SimulationPlan simulation = new SimulationPlan();
- simulation.setCollectionInterval(getLong(root.get("collectionInterval"), 500L));
- simulation.setAggregationInterval(getLong(root.get("aggregationInterval"), 1000L));
- simulation.setThreadPoolSize(getInt(root.get("threadPoolSize"), 7));
+ simulation.setCollectionInterval(getLong(root.get("collectionInterval"), 1000L));
+ simulation.setAggregationInterval(getLong(root.get("aggregationInterval"), 60000L));
simulation.setNumMeasurementCollectors(getInt(root.get("numMeasurementCollectors"), 5));
simulation.setSimulationTime(getInt(root.get("simulationTime"), 10));
+ simulation.setThreadPoolSize(getInt(root.get("threadPoolSize"), simulation.getNumMeasurementCollectors() + 2));
- JsonNode clientCompressionNode = root.get("clientCompression");
- if (clientCompressionNode != null) {
- simulation.setClientCompression(clientCompressionNode.asText());
- }
-
- JsonNode schedules = root.get("schedules");
- if (schedules == null) {
- simulation.addScheduleSet(new ScheduleGroup(2500, 500L));
+ String[] nodes;
+ if (root.get("nodes") == null || root.get("nodes").size() == 0) {
+ nodes = new String[] {InetAddress.getLocalHost().getHostAddress()};
} else {
- if (schedules.isArray()) {
- for (JsonNode node : schedules) {
- simulation.addScheduleSet(new ScheduleGroup(getInt(node.get("count"), 2500),
- getLong(node.get("interval"), 500L)));
- }
- } else {
- simulation.addScheduleSet(new ScheduleGroup(getInt(schedules.get("count"), 2500),
- getLong(schedules.get("interval"), 500L)));
+ nodes = new String[root.get("nodes").size()];
+ int i = 0;
+ for (JsonNode node : root.get("nodes")) {
+ nodes[i++] = node.asText();
}
}
+ simulation.setNodes(nodes);
+
+ simulation.setCqlPort(getInt(root.get("cqlPort"), 9142));
MetricsConfiguration serverConfiguration = createDefaultMetricsConfiguration();
simulation.setMetricsServerConfiguration(serverConfiguration);
- JsonNode ttlNodes = root.get("ttl");
- if (ttlNodes != null) {
- for (JsonNode node : ttlNodes) {
- String tableName = node.get("table").asText();
- if (!tableName.isEmpty()) {
- MetricsTable table = getTable(tableName);
- JsonNode ttlNode = node.get("value");
- if (ttlNode != null) {
- setTTLAndRetention(table, ttlNode.asInt(), serverConfiguration);
- }
- }
- }
- }
-
- JsonNode timeSliceNode = root.get("timeSliceDuration");
- if (timeSliceNode != null) {
- String units = timeSliceNode.get("units").asText();
- if (units.isEmpty()) {
- units = "minutes";
- }
- for (JsonNode node : timeSliceNode.get("values")) {
- JsonNode valueNode = node.get("value");
- JsonNode tableNode = node.get("table");
- if (!(tableNode == null || valueNode == null)) {
- Duration duration = getDuration(units, valueNode.asInt());
- MetricsTable table = getTable(tableNode.asText());
- setTimeSliceDuration(table, duration, serverConfiguration);
- }
- }
- }
-
- ClusterConfig clusterConfig = new ClusterConfig();
- JsonNode clusterConfigNode = root.get("cluster");
- if (clusterConfigNode != null) {
- JsonNode embeddedNode = clusterConfigNode.get("embedded");
- if (embeddedNode != null) {
- clusterConfig.setEmbedded(embeddedNode.asBoolean(true));
- }
-
- JsonNode clusterDirNode = clusterConfigNode.get("clusterDir");
- if (clusterDirNode != null) {
- clusterConfig.setClusterDir(clusterDirNode.asText());
- }
-
- JsonNode heapSizeNode = clusterConfigNode.get("heapSize");
- if (heapSizeNode != null) {
- clusterConfig.setHeapSize(heapSizeNode.asText());
- }
-
- JsonNode heapNewSizeNode = clusterConfigNode.get("heapNewSize");
- if (heapNewSizeNode != null) {
- clusterConfig.setHeapNewSize(heapNewSizeNode.asText());
- }
-
- JsonNode stackSizeNode = clusterConfigNode.get("stackSize");
- if (stackSizeNode != null) {
- clusterConfig.setStackSize(stackSizeNode.asText());
- }
-
- clusterConfig.setNumNodes(getInt(clusterConfigNode.get("numNodes"), 2));
- }
- simulation.setClusterConfig(clusterConfig);
-
return simulation;
}
private MetricsConfiguration createDefaultMetricsConfiguration() {
+
+ // 500 ms --> 30 sec
+ // 1 sec --> 1 minute
+ // 60 sec / 1 minute --> 1 hr
+ // 1440 sec / 24 minutes --> 1 day
+ // 168 minutes --> 1 week
+ // 744 minutes / 12.4 hr --> 31 days / 1 month
+ // 8928 minutes / 148.8 hr --> 1 yr
+
MetricsConfiguration configuration = new MetricsConfiguration();
- configuration.setRawTTL(180);
- configuration.setRawRetention(Seconds.seconds(180).toStandardDuration());
+ configuration.setRawTTL(Minutes.minutes(168).toStandardSeconds().getSeconds());
+ configuration.setRawRetention(Minutes.minutes(168).toStandardDuration());
configuration.setRawTimeSliceDuration(Minutes.ONE.toStandardDuration());
- configuration.setOneHourTTL(360);
- configuration.setOneHourRetention(Seconds.seconds(360));
+ configuration.setOneHourTTL(Minutes.minutes(336).toStandardSeconds().getSeconds());
+ configuration.setOneHourRetention(Minutes.minutes(336));
configuration.setOneHourTimeSliceDuration(Minutes.minutes(6).toStandardDuration());
- configuration.setSixHourTTL(540);
- configuration.setSixHourRetention(Seconds.seconds(540));
+ configuration.setSixHourTTL(Minutes.minutes(744).toStandardSeconds().getSeconds());
+ configuration.setSixHourRetention(Minutes.minutes(744).toStandardSeconds());
configuration.setSixHourTimeSliceDuration(Minutes.minutes(24).toStandardDuration());
- configuration.setTwentyFourHourTTL(720);
- configuration.setTwentyFourHourRetention(Seconds.seconds(720));
+ configuration.setTwentyFourHourTTL(Minutes.minutes(8928).toStandardSeconds().getSeconds());
+ configuration.setTwentyFourHourRetention(Minutes.minutes(8928).toStandardSeconds());
return configuration;
}
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/stats/Aggregate.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/stats/Aggregate.java
deleted file mode 100644
index 61a6b51..0000000
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/stats/Aggregate.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *
- * * RHQ Management Platform
- * * Copyright (C) 2005-2012 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.metrics.simulator.stats;
-
-/**
- * @author John Sanda
- */
-public class Aggregate {
-
- private String name;
- private double max;
- private double min;
- private double mean;
- private double standardDeviation;
-
-
- public Aggregate(String name, double max, double min, double mean, double standardDeviation) {
- this.name = name;
- this.max = max;
- this.min = min;
- this.mean = mean;
- this.standardDeviation = standardDeviation;
- }
-
- public double getMax() {
- return max;
- }
-
- public double getMin() {
- return min;
- }
-
- public double getMean() {
- return mean;
- }
-
- public double getStandardDeviation() {
- return standardDeviation;
- }
-
- @Override
- public String toString() {
- return name + ": {min: " + getMin() + ", mean: " + getMean() + ", max: " + getMax() + ", standardDeviation: " +
- getStandardDeviation() + "}";
- }
-}
diff --git a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/stats/Stats.java b/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/stats/Stats.java
deleted file mode 100644
index 604f1ba..0000000
--- a/modules/helpers/metrics-simulator/src/main/java/org/rhq/metrics/simulator/stats/Stats.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- *
- * * RHQ Management Platform
- * * Copyright (C) 2005-2012 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.metrics.simulator.stats;
-
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
-
-/**
- * @author John Sanda
- */
-public class Stats {
-
- /**
- * The total number of raw inserts
- */
- private AtomicLong totalRawInserts = new AtomicLong(0);
-
- private AtomicInteger rawInsertsThisMinute = new AtomicInteger(0);
-
- private DescriptiveStatistics rawInsertsPerMinute = new DescriptiveStatistics(200);
-
- private DescriptiveStatistics rawInsertTimesPerMinute = new DescriptiveStatistics(200);
-
- private ReentrantLock insertTimesLock = new ReentrantLock();
-
- public void addRawInserts(int count) {
- totalRawInserts.addAndGet(count);
- rawInsertsThisMinute.addAndGet(count);
- }
-
- public long getTotalRawInserts() {
- return totalRawInserts.get();
- }
-
- /**
- * Called by measurement collectors to report insertion times. This method uses an
- * internal lock to allow for concurrent access.
- *
- * @param time The time to insert a set of raw metrics
- */
- public void addRawInsertTime(long time) {
- try {
- insertTimesLock.lock();
- rawInsertTimesPerMinute.addValue(time);
- } finally {
- insertTimesLock.unlock();
- }
- }
-
- public Aggregate getRawInsertTimes() {
- try {
- insertTimesLock.lock();
- return new Aggregate("raw insertion times (milliseconds)", rawInsertTimesPerMinute.getMax(),
- rawInsertTimesPerMinute.getMin(), rawInsertTimesPerMinute.getMean(),
- rawInsertTimesPerMinute.getStandardDeviation());
- } finally {
- insertTimesLock.unlock();
- }
- }
-
- /**
- * Called by {@link org.rhq.metrics.simulator.StatsCollector} to report the number of raw inserts for a given
- * minute. Since there is only a single {@link org.rhq.metrics.simulator.StatsCollector} this method does not
- * support concurrent access.
- *
- * @param value The number of raw metrics inserted in a given minute.
- */
- public void addRawInsertsPerMinute(long value) {
- rawInsertsPerMinute.addValue(value);
- }
-
- public Aggregate getRawInsertsPerMinute() {
- return new Aggregate("Raw inserts per minute", rawInsertsPerMinute.getMax(), rawInsertsPerMinute.getMin(),
- rawInsertsPerMinute.getMean(), rawInsertsPerMinute.getStandardDeviation());
- }
-
-}
diff --git a/modules/helpers/metrics-simulator/src/main/resources/conf/log4j.properties b/modules/helpers/metrics-simulator/src/main/resources/conf/log4j.properties
index ee270e8..58fa73c 100644
--- a/modules/helpers/metrics-simulator/src/main/resources/conf/log4j.properties
+++ b/modules/helpers/metrics-simulator/src/main/resources/conf/log4j.properties
@@ -35,5 +35,5 @@ log4j.appender.FILE.Append=false
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
-log4j.appender.CONSOLE.layout.ConversionPattern=%5p %d{HH:mm:ss,SSS} %m%n
+log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-5p [%t] (%c{5}) - %m%n
log4j.logger.org.rhq=DEBUG
\ No newline at end of file
10 years, 2 months
[rhq] Changes to 'jsanda/metrics-perf'
by John Sanda
New branch 'jsanda/metrics-perf' available with the following commits:
commit aab88075b12acdcbe738932fe70fcc16f2bbb34b
Author: John Sanda <jsanda(a)redhat.com>
Date: Mon Sep 30 13:53:14 2013 -0400
remove obsolete config setting and add nowInMills() method
The nowInMills method avoids the overhead of creating a new DateTime object
which could non-trivial since it is called continuously in MeasurementCollector.
commit ed6d7de1cc90522f0f53d8d420019391d72faae3
Author: John Sanda <jsanda(a)redhat.com>
Date: Mon Sep 30 13:11:54 2013 -0400
fixing bugs and adding support for compressed time slices
The simulator now uses hard-coded TTLs and time slices. The duration of the
time slice for each table is as follows,
raw data --> 2.5 minutes
1 hr data --> 15 minutes
6 hr data --> 1 hour
Aggregation runs every 2.5 minutes. The execution time for aggregation can and
will exceed 2.5 minutes. I do not want the aggregator thread to block and wind
up kicking aggregation with the wrong start times. It now submits a task for
each aggregation so that the aggregator thread itself does not get delayed.
commit 4ba727016bdc7727badd79e174937775d74f42cd
Author: John Sanda <jsanda(a)redhat.com>
Date: Fri Sep 27 10:41:55 2013 -0400
allow for configurable time slices
commit aef8b23966c1c2d81ff08bb0d02b899eae5a526d
Author: John Sanda <jsanda(a)redhat.com>
Date: Fri Sep 27 10:29:21 2013 -0400
numerous changes in metrics-simulator to simplify things
Metrics are now captured using the Metrics Core library which renders both
Stats.java and StatsCollector.java obsolete.
MetricsCollector has been simplified substantially. It is now seeded with a
starting schedule id and a batch size and generates batch size inserts each
time it runs.
A good bit of the simulator configuration that is specified in the json file
has been removed as well in an effort to make sure things are correct. As of
now intervals and time slices are fixed.
* raw data --> 1 minute
* 1 hour data --> 6 minutes
* 6 hour data --> 1 hour
This means that a day's worth of data is generated in one hour. Minor changes
have been made in MetricsServer to allow for configurable time slices.
10 years, 2 months
[rhq] Branch 'hotfix/jon3.1.2' - 2 commits - modules/enterprise
by Larry O'Leary
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java | 8 ++++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/discovery/ResourceAutodiscoveryView.java | 1 +
2 files changed, 9 insertions(+)
New commits:
commit 8b25170f5f32a55a10235daeb68ddd7fdfa16733
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Sep 24 16:44:28 2012 +0200
[BZ 859982] - Resetting the custom blur event handling before and after a popup dialog is shown in the configuration editor.
This prevents unhandled errors when for example entering an entry into the
list of maps multiple times.
(cherry picked from commit d41955c0175c795668d8e51ea7b742453a30b5ee)
(cherry picked from commit 4080f94678c99b4d467693e2b9d4fd4f9fae5b34)
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
index ebf3507..935545a 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
@@ -1703,6 +1703,10 @@ public class ConfigurationEditor extends LocatableVLayout {
summaryTable.redraw();
}
+ //reset the custom blur event handling - we're destroying the new form here
+ blurUnsetItem = null;
+ blurValueItem = null;
+
layout.destroy();
popup.destroy();
}
@@ -1731,6 +1735,10 @@ public class ConfigurationEditor extends LocatableVLayout {
buttonBar.addMember(cancelButton);
}
+ //reset the custom blur event handling - we're creating a new form here
+ blurUnsetItem = null;
+ blurValueItem = null;
+
layout.addMember(buttonBar);
popup.addItem(layout);
popup.show();
commit 3f8ed4139e413a499abe5894dbf17c415de7891a
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Fri Sep 20 13:21:02 2013 -0500
[BZ 889602] Force a vertical recalculation after a redraw when loading new data. There is a problem with IE support in the current GWT version and forcing the toolstrip to get moved 1px higher is the only workaround.
This bug has been resolved in new versions of GWT so no changes are required in coregui for branches that use a newer version.
(cherry picked from commit 070a7971506df4febf733ce67aa040ca875e3819)
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/discovery/ResourceAutodiscoveryView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/discovery/ResourceAutodiscoveryView.java
index 0e473a7..c900174 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/discovery/ResourceAutodiscoveryView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/discovery/ResourceAutodiscoveryView.java
@@ -259,6 +259,7 @@ public class ResourceAutodiscoveryView extends LocatableVLayout implements Refre
// to cause it to redraw, but it is obviously not reasonable to expect that. So we must
// explicitly call redraw() here.
treeGrid.redraw();
+ treeGrid.resizeBy(0, -1);
}
}
});
10 years, 2 months
[rhq] Branch 'nightly/rhq.jon' - pom.xml
by lkrejci
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit e24b2f229e1e5a9d579cff42f2c43419f214dc29
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Sep 23 21:00:44 2013 +0200
Bumping Clirr maven plugin version to remove the need for our patched version.
diff --git a/pom.xml b/pom.xml
index c305a40..1411a96 100644
--- a/pom.xml
+++ b/pom.xml
@@ -261,7 +261,7 @@
<animal.sniffer.java.signature.artifactId>java16</animal.sniffer.java.signature.artifactId>
<animal.sniffer.java.signature.version>1.0</animal.sniffer.java.signature.version>
<!-- API checks -->
- <clirr.version>2.5</clirr.version>
+ <clirr.version>2.6</clirr.version>
<!-- a default value for the child modules indicating that the module is not
part of our public API and is therefore not API-checked. -->
<rhq.internal>true</rhq.internal>
10 years, 2 months
[rhq] modules/enterprise
by Jiri Kremser
modules/enterprise/server/jar/intentional-api-changes-since-4.9.0.xml | 8 ++++++++
1 file changed, 8 insertions(+)
New commits:
commit 56c6467abcfe9af7e61568209a55267a48a4a5be
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Mon Sep 30 17:19:40 2013 +0200
api checks: adding the change as a intentional change not to break JON compatibility.
diff --git a/modules/enterprise/server/jar/intentional-api-changes-since-4.9.0.xml b/modules/enterprise/server/jar/intentional-api-changes-since-4.9.0.xml
index 488adc3..6ab00ba 100644
--- a/modules/enterprise/server/jar/intentional-api-changes-since-4.9.0.xml
+++ b/modules/enterprise/server/jar/intentional-api-changes-since-4.9.0.xml
@@ -56,4 +56,12 @@
<justification>Adding a method to a remote API interface is safe. This is method is added in order to deprecate the getAggregate. For more details see the previous intentional change.</justification>
</difference>
+ <difference>
+ <className>org/rhq/enterprise/server/operation/OperationManagerRemote</className>
+ <differenceType>7006</differenceType> <!-- method return type changed -->
+ <method>org.rhq.core.domain.util.PageList findOperationDefinitionsByCriteria(org.rhq.core.domain.auth.Subject, org.rhq.core.domain.criteria.OperationDefinitionCriteria)</method>
+ <to>java.util.List</to>
+ <justification> While this is technically a welcome change (because impl of that method returned the PageList anyway), it breaks the strongly typed clients, because the methods are linked by their full signature and hence a library compiled against JON312GA version of that remote will fail to find the method with the new signature and will fail with NoSuchMethodError at runtime.</justification>
+ </difference>
+
</differences>
10 years, 2 months
[rhq] Branch 'nightly/rhq.jon' - 12 commits - modules/core modules/enterprise modules/plugins
by lkrejci
modules/core/domain/src/main/java/org/rhq/core/domain/alert/composite/AlertConditionAvailabilityCategoryComposite.java | 11
modules/core/domain/src/main/java/org/rhq/core/domain/cloud/Server.java | 9
modules/core/domain/src/main/java/org/rhq/core/domain/common/ServerDetails.java | 15
modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ConfigurationUtility.java | 8
modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ObfuscatedPropertySimple.java | 13
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/MeasurementScheduleCriteria.java | 30 +
modules/enterprise/binding/intentional-api-changes-since-4.9.0.xml | 53 ++
modules/enterprise/binding/src/main/java/org/rhq/bindings/client/AbstractRhqFacade.java | 200 +++++++++
modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqFacade.java | 217 ++++++++++
modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqManagers.java | 139 ++++++
modules/enterprise/binding/src/test/java/org/rhq/bindings/FakeRhqFacade.java | 3
modules/enterprise/binding/src/test/java/org/rhq/bindings/client/AbstractRhqFacadeProxyTest.java | 2
modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/clientapi/RemoteClient.java | 5
modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClient.java | 3
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBeanTest.java | 2
modules/enterprise/server/jar/intentional-api-changes-since-4.9.0.xml | 15
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java | 12
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementAggregate.java | 83 +++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java | 2
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementChartsManagerBean.java | 2
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBean.java | 34 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerRemote.java | 21
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/operation/OperationManagerRemote.java | 9
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java | 6
modules/plugins/database/src/main/java/org/rhq/plugins/database/DatabaseQueryUtility.java | 16
25 files changed, 885 insertions(+), 25 deletions(-)
New commits:
commit a4d9ab43dd4b2e4129a7d118c53cbebd75aaad00
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Sep 27 17:43:01 2013 +0200
[BZ 873866] - Minimizing API changes between JON 3.1.2.GA and JON 3.2.0.GA.
[BZ 873866] - Minimizing API changes between JON 3.1.2.GA and JON 3.2.0.GA.
Commit 0ba8c5f (among other things) removed several public constants in
MeasurementScheduleCriteria because they were improperly named and didn't
do what they seemed to.
Users might be using those constants even if they don't do what they're
supposed to. The constants have therefore been re-introduced with a
deprecation notice.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/MeasurementScheduleCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/MeasurementScheduleCriteria.java
index 33d2623..1980d01 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/MeasurementScheduleCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/MeasurementScheduleCriteria.java
@@ -42,10 +42,37 @@ public class MeasurementScheduleCriteria extends Criteria {
private static final long serialVersionUID = 3L;
// sort fields from the MeasurementSchedule's MeasurementDefinition
+
+ /**
+ * Note that sorting by definition id alone might not produce repeatable results. This depends on the filters
+ * and other sort field applied.
+ */
+ public static final String SORT_FIELD_DEFINITION_ID = "definitionId";
public static final String SORT_FIELD_NAME = "name";
public static final String SORT_FIELD_DISPLAY_NAME = "displayName";
public static final String SORT_FIELD_DATA_TYPE = "dataType";
+ /**
+ * @deprecated Sorting by this field has never been supported. This constant has been introduced in error and will
+ * be removed in the next major release.
+ */
+ @Deprecated
+ public static final String SORT_FIELD_ENABLED = "enabled";
+
+ /**
+ * @deprecated Sorting by this field has never been supported. This constant has been introduced in error and will
+ * be removed in the next major release.
+ */
+ @Deprecated
+ public static final String SORT_FIELD_INTERVAL = "interval";
+
+ /**
+ * @deprecated Sorting by this field has never been supported. This constant has been introduced in error and will
+ * be removed in the next major release.
+ */
+ @Deprecated
+ public static final String SORT_FIELD_DESCRIPTION = "description";
+
// filter fields
public static final String FILTER_FIELD_DEFINITION_IDS = "definitionIds";
public static final String FILTER_FIELD_RESOURCE_ID = "resourceId";
@@ -93,6 +120,7 @@ public class MeasurementScheduleCriteria extends Criteria {
+ " WHERE parent.id = ? )");
filterOverrides.put(FILTER_FIELD_RESOURCE_TYPE_ID, "resource.type.id = ?");
+ sortOverrides.put(SORT_FIELD_DEFINITION_ID, "definition.id");
sortOverrides.put(SORT_FIELD_NAME, "definition.name");
sortOverrides.put(SORT_FIELD_DISPLAY_NAME, "definition.displayName");
sortOverrides.put(SORT_FIELD_DATA_TYPE, "definition.dataType");
@@ -167,4 +195,4 @@ public class MeasurementScheduleCriteria extends Criteria {
this.sortDataType = sortDataType;
}
-}
\ No newline at end of file
+}
commit 4e94002f7af0c4a9bd2accf35362924b8bb0a7dc
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Sep 27 16:20:45 2013 +0200
[BZ 873866] - Minimizing API changes between JON 3.1.2.GA and JON 3.2.0.GA.
Commit 26959a31d8c37bcb86dc6a845b5707a277bff3cb made the constructor of
the DatabaseQueryUtility private, which it should be, and removed an
unused class.
While the chances of anyone either instantiating the utility class or using
the absolutely useless DatabaseQueryUtility.StatementParameter are very
slim, we need to keep API back-compat.
The public constructor and the class have been reintroduced with
a deprecation notice.
diff --git a/modules/plugins/database/src/main/java/org/rhq/plugins/database/DatabaseQueryUtility.java b/modules/plugins/database/src/main/java/org/rhq/plugins/database/DatabaseQueryUtility.java
index 95e981d..d6d83f2 100644
--- a/modules/plugins/database/src/main/java/org/rhq/plugins/database/DatabaseQueryUtility.java
+++ b/modules/plugins/database/src/main/java/org/rhq/plugins/database/DatabaseQueryUtility.java
@@ -44,7 +44,11 @@ public class DatabaseQueryUtility {
private static final Log LOG = LogFactory.getLog(DatabaseQueryUtility.class);
- private DatabaseQueryUtility() {}
+ /**
+ * @deprecated instantiating a static utility class doesn't make sense. Don't do it.
+ */
+ @Deprecated
+ public DatabaseQueryUtility() {}
/**
* Executes a database update.
@@ -274,4 +278,14 @@ public class DatabaseQueryUtility {
}
}
}
+
+ /**
+ * @deprecated This class is not used for anything in the codebase of the database plugin. If you are using it
+ * in some way or another, move it to your own code, because this class will be removed in future.
+ */
+ @Deprecated
+ public static class StatementParameter {
+ private String name;
+ private String value;
+ }
}
commit bc2a200a61a5a1d06ab3b8e11b7052187e7dd729
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Sep 27 15:06:43 2013 +0200
[BZ 873866] - Minimizing API changes between JON 3.1.2.GA and JON 3.2.0.GA.
The fix for bug 840512 changed the way we handle the value of an obfuscated
property, which rendered the obfuscate() method unused. It has been removed
which unfortunately is an API breaking change due to its protected
visibility.
While the chances of anyone using that method are miniscule we cannot break
the API. The method was re-introduced but made a NOOP so that it doesn't
break the obfuscation. The deprecation notice on the method suggests to
stop using it.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ObfuscatedPropertySimple.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ObfuscatedPropertySimple.java
index bb00ef5..ac0598f 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ObfuscatedPropertySimple.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ObfuscatedPropertySimple.java
@@ -216,7 +216,18 @@ public class ObfuscatedPropertySimple extends PropertySimple {
throw new IllegalArgumentException("Failed to obfuscate property value: [" + value + "]", e);
}
}
-
+
+ /**
+ * @deprecated do not use this method. It has been superseded by the {@link #deobfuscate(String)} and
+ * {@link #obfuscate(String)} pair. The way the obfuscated value is handled has changed and is fully contained
+ * within this class. You should not worry about it, nor have a need to call any of the obfuscate() methods.
+ * This method is currently no-op and will be removed in future.
+ */
+ @Deprecated
+ protected void obfuscate() {
+
+ }
+
/**
* Overriden to not leak the unobfuscated value in the toString() method, output of which
* might end up in logs, etc.
commit b40b9e3c72ec1b8d92973d9766a214ee2f47ab86
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Sep 27 15:02:58 2013 +0200
[BZ 873866] - Minimizing API changes between JON 3.1.2.GA and JON 3.2.0.GA.
The fix for bug 1000006 declared the constructor of
o.r.c.d.configuration.ConfigurationUtility private. It previously had the
default pulic constructor and hence this was a API breaking change.
While the utility class should have had the private constructor in first
place, we cannot break the API, so the public constructor has been
re-introduced with a deprecation notice.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ConfigurationUtility.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ConfigurationUtility.java
index f4d575a..fa49454 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ConfigurationUtility.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ConfigurationUtility.java
@@ -36,8 +36,12 @@ import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
*/
public class ConfigurationUtility {
- private ConfigurationUtility() {
- // Utility class
+ /**
+ * @deprecated do not create instances of this class. It is meant as a static utility class.
+ */
+ @Deprecated
+ public ConfigurationUtility() {
+
}
/**
commit 44e69df8c0b60ce961b78ec0f590a77997750379
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Sep 27 14:46:57 2013 +0200
[BZ 873866] - Minimizing API changes between JON 3.1.2.GA and JON 3.2.0.GA.
Commit 85f75e0 removed 2 enum fields from the server details, because they
are no longer used due to our move from DB to Cassandra for metric storage.
Nevertheless the clients might be using those fields to get back that
information. To retain the backwards compatibility, we need to keep those
enum fields, making the server details work without recompilation.
The server details will no longer contain any information for the for those
fields. The fact that some information might be missing is part of the
contract of the ServerDetails class though, so the users should be able to
handle that situation.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/common/ServerDetails.java b/modules/core/domain/src/main/java/org/rhq/core/domain/common/ServerDetails.java
index 5cfcc96..b9637bf 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/common/ServerDetails.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/common/ServerDetails.java
@@ -47,6 +47,21 @@ public class ServerDetails implements Serializable {
SERVER_LOCAL_TIME, //
SERVER_INSTALL_DIR, // where RHQ is installed, the top directory where everything else is
SERVER_HOME_DIR, // where the RHQ server's JBossAS deployment is; this is under the install dir
+
+ /**
+ * @deprecated this is no longer used or exposed by the server. The measurements are not stored in the database
+ * anymore.
+ */
+ @Deprecated
+ CURRENT_MEASUREMENT_TABLE, //
+
+ /**
+ * @deprecated this is no longer used or exposed by the server. The measurements are not stored in the database
+ * anymore.
+ */
+ @Deprecated
+ NEXT_MEASUREMENT_TABLE_ROTATION, //
+
SERVER_IDENTITY;
};
commit 1793cd14fa63144e1860a4fe6aa61456f02e71d6
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Sep 27 14:40:42 2013 +0200
[BZ 873866] - Minimizing API changes between JON 3.1.2.GA and JON 3.2.0.GA.
Commit a4b78eb6e1adeffaa519115a9ef07b3f00025168 fixed the handling of the
server status, but changed the signature of
o.r.c.d.cloud.Server#clearStatus() method in an incompatible way. Adding
the old method back with a deprecation notice.
The chances of anyone using this method are miniscule but we need to retain
back-compat.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/Server.java b/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/Server.java
index 671db6b..6e04ab6 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/Server.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/Server.java
@@ -306,6 +306,15 @@ public class Server implements Serializable {
}
/**
+ * @deprecated do not use this method as it may corrupt the tracking of the server status. Use the new
+ * {@link #clearStatus(org.rhq.core.domain.cloud.Server.Status)} instead.
+ */
+ @Deprecated
+ public void clearStatus() {
+ this.status = 0;
+ }
+
+ /**
* If some subsystem makes a change to some data that this server cares about (as summarized
* by the various {@link Status} elements), then that change should be added via this method.
* Periodically, a background job will come along, check the status, and possibly perform
commit dc13106517ba845e8fd8f41bca8617eaa8526314
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Sep 27 14:37:22 2013 +0200
[BZ 873866] - Minimizing API changes between JON 3.1.2.GA and JON 3.2.0.GA.
Bug 888927 changed the signature of the
AlertConditionAvailabilityCategoryComposite class to add a missing
parameter.
While the chances of anyone using this method miniscule, we need to retain
the back-compat. Therefore I added the wrong constructor back with
a deprecation notice.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/composite/AlertConditionAvailabilityCategoryComposite.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/composite/AlertConditionAvailabilityCategoryComposite.java
index 870dbd2..cd1a948 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/composite/AlertConditionAvailabilityCategoryComposite.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/composite/AlertConditionAvailabilityCategoryComposite.java
@@ -49,6 +49,17 @@ public class AlertConditionAvailabilityCategoryComposite extends AbstractAlertCo
this.availabilityType = (null != availabilityType) ? availabilityType : AvailabilityType.UNKNOWN;
}
+ /**
+ * @deprecated This constructor will NOT produce a valid instance of this class, because it cannot specify
+ * the required alert definition id. Use {@link #AlertConditionAvailabilityCategoryComposite(
+ * org.rhq.core.domain.alert.AlertCondition, Integer, Integer, org.rhq.core.domain.measurement.AvailabilityType)}
+ * instead.
+ */
+ @Deprecated
+ public AlertConditionAvailabilityCategoryComposite(AlertCondition condition, Integer resourceId, AvailabilityType availabilityType) {
+ this(condition, null, resourceId, availabilityType);
+ }
+
public Integer getAlertDefinitionId() {
return alertDefinitionId;
}
commit 580ce223e27f2293a8234a31e352fea5c87362a3
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Sep 23 15:37:06 2013 +0200
Adding intentional api changes for the new methods ported over from RHQ 4.4.0.
diff --git a/modules/enterprise/binding/intentional-api-changes-since-4.9.0.xml b/modules/enterprise/binding/intentional-api-changes-since-4.9.0.xml
new file mode 100644
index 0000000..e9a97bc
--- /dev/null
+++ b/modules/enterprise/binding/intentional-api-changes-since-4.9.0.xml
@@ -0,0 +1,53 @@
+<?xml version="1.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 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.,
+ ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ -->
+
+<differences>
+
+ <difference>
+ <className>org/rhq/bindings/client/RhqFacade</className>
+ <differenceType>7012</differenceType> <!-- method added to an interface -->
+ <method>*ManagerRemote get*Manager()</method>
+ <justification>
+ Adding back methods removed in RHQ 4.5.0 to regain compatibility with RHQ 4.4.0 interface.
+ This is safe, because this interface is not to be implemented by 3rd parties.
+ </justification>
+ </difference>
+
+ <difference>
+ <className>org/rhq/bindings/client/RhqFacade</className>
+ <differenceType>7012</differenceType> <!-- method added to an interface -->
+ <method>org.rhq.enterprise.server.discovery.DiscoveryBossRemote getDiscoveryBoss()</method>
+ <justification>
+ Adding back methods removed in RHQ 4.5.0 to regain compatibility with RHQ 4.4.0 interface.
+ This is safe, because this interface is not to be implemented by 3rd parties.
+ </justification>
+ </difference>
+
+ <difference>
+ <className>org/rhq/bindings/client/RhqFacade</className>
+ <differenceType>7012</differenceType> <!-- method added to an interface -->
+ <method>java.util.Map getManagers()</method>
+ <justification>
+ Adding back methods removed in RHQ 4.5.0 to regain compatibility with RHQ 4.4.0 interface.
+ This is safe, because this interface is not to be implemented by 3rd parties.
+ </justification>
+ </difference>
+</differences>
+
commit a20757315620c1ae01a32e4ad47cc6303ed4ec77
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Sep 20 21:09:02 2013 +0200
(Almost) regain back-compat with RHQ 4.4.0 in script bindings.
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/AbstractRhqFacade.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/AbstractRhqFacade.java
new file mode 100644
index 0000000..8ee82e2
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/AbstractRhqFacade.java
@@ -0,0 +1,200 @@
+package org.rhq.bindings.client;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.rhq.enterprise.server.alert.AlertDefinitionManagerRemote;
+import org.rhq.enterprise.server.alert.AlertManagerRemote;
+import org.rhq.enterprise.server.auth.SubjectManagerRemote;
+import org.rhq.enterprise.server.authz.RoleManagerRemote;
+import org.rhq.enterprise.server.bundle.BundleManagerRemote;
+import org.rhq.enterprise.server.configuration.ConfigurationManagerRemote;
+import org.rhq.enterprise.server.content.ContentManagerRemote;
+import org.rhq.enterprise.server.content.RepoManagerRemote;
+import org.rhq.enterprise.server.discovery.DiscoveryBossRemote;
+import org.rhq.enterprise.server.drift.DriftManagerRemote;
+import org.rhq.enterprise.server.event.EventManagerRemote;
+import org.rhq.enterprise.server.install.remote.RemoteInstallManagerRemote;
+import org.rhq.enterprise.server.measurement.AvailabilityManagerRemote;
+import org.rhq.enterprise.server.measurement.CallTimeDataManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementBaselineManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementDataManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementDefinitionManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerRemote;
+import org.rhq.enterprise.server.operation.OperationManagerRemote;
+import org.rhq.enterprise.server.report.DataAccessManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceFactoryManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceTypeManagerRemote;
+import org.rhq.enterprise.server.resource.group.ResourceGroupManagerRemote;
+import org.rhq.enterprise.server.search.SavedSearchManagerRemote;
+import org.rhq.enterprise.server.support.SupportManagerRemote;
+import org.rhq.enterprise.server.sync.SynchronizationManagerRemote;
+import org.rhq.enterprise.server.system.SystemManagerRemote;
+import org.rhq.enterprise.server.tagging.TagManagerRemote;
+
+/**
+ * This is a support base class for the implementations of the RhqFacade interface that
+ * implements the deprecated methods by the means of the new version of the {@link RhqFacade} methods.
+ *
+ * @author Lukas Krejci
+ * @since 4.10
+ */
+public abstract class AbstractRhqFacade implements RhqFacade {
+
+ @Override
+ public AlertDefinitionManagerRemote getAlertDefinitionManager() {
+ return getProxy(AlertDefinitionManagerRemote.class);
+ }
+
+ @Override
+ public AlertManagerRemote getAlertManager() {
+ return getProxy(AlertManagerRemote.class);
+ }
+
+ @Override
+ public AvailabilityManagerRemote getAvailabilityManager() {
+ return getProxy(AvailabilityManagerRemote.class);
+ }
+
+ @Override
+ public BundleManagerRemote getBundleManager() {
+ return getProxy(BundleManagerRemote.class);
+ }
+
+ @Override
+ public CallTimeDataManagerRemote getCallTimeDataManager() {
+ return getProxy(CallTimeDataManagerRemote.class);
+ }
+
+ @Override
+ public ConfigurationManagerRemote getConfigurationManager() {
+ return getProxy(ConfigurationManagerRemote.class);
+ }
+
+ @Override
+ public ContentManagerRemote getContentManager() {
+ return getProxy(ContentManagerRemote.class);
+ }
+
+ @Override
+ public DataAccessManagerRemote getDataAccessManager() {
+ return getProxy(DataAccessManagerRemote.class);
+ }
+
+ @Override
+ public DiscoveryBossRemote getDiscoveryBoss() {
+ return getProxy(DiscoveryBossRemote.class);
+ }
+
+ @Override
+ public DriftManagerRemote getDriftManager() {
+ return getProxy(DriftManagerRemote.class);
+ }
+
+ @Override
+ public EventManagerRemote getEventManager() {
+ return getProxy(EventManagerRemote.class);
+ }
+
+ @Override
+ public Map<RhqManagers, Object> getManagers() {
+ HashMap<RhqManagers, Object> ret = new HashMap<RhqManagers, Object>();
+
+ for(RhqManagers m : RhqManagers.values()) {
+ ret.put(m, getProxy(m.remote()));
+ }
+
+ return ret;
+ }
+
+ @Override
+ public MeasurementBaselineManagerRemote getMeasurementBaselineManager() {
+ return getProxy(MeasurementBaselineManagerRemote.class);
+ }
+
+ @Override
+ public MeasurementDataManagerRemote getMeasurementDataManager() {
+ return getProxy(MeasurementDataManagerRemote.class);
+ }
+
+ @Override
+ public MeasurementDefinitionManagerRemote getMeasurementDefinitionManager() {
+ return getProxy(MeasurementDefinitionManagerRemote.class);
+ }
+
+ @Override
+ public MeasurementScheduleManagerRemote getMeasurementScheduleManager() {
+ return getProxy(MeasurementScheduleManagerRemote.class);
+ }
+
+ @Override
+ public OperationManagerRemote getOperationManager() {
+ return getProxy(OperationManagerRemote.class);
+ }
+
+ @Override
+ public RemoteInstallManagerRemote getRemoteInstallManager() {
+ return getProxy(RemoteInstallManagerRemote.class);
+ }
+
+ @Override
+ public RepoManagerRemote getRepoManager() {
+ return getProxy(RepoManagerRemote.class);
+ }
+
+ @Override
+ public ResourceFactoryManagerRemote getResourceFactoryManager() {
+ return getProxy(ResourceFactoryManagerRemote.class);
+ }
+
+ @Override
+ public ResourceGroupManagerRemote getResourceGroupManager() {
+ return getProxy(ResourceGroupManagerRemote.class);
+ }
+
+ @Override
+ public ResourceManagerRemote getResourceManager() {
+ return getProxy(ResourceManagerRemote.class);
+ }
+
+ @Override
+ public ResourceTypeManagerRemote getResourceTypeManager() {
+ return getProxy(ResourceTypeManagerRemote.class);
+ }
+
+ @Override
+ public RoleManagerRemote getRoleManager() {
+ return getProxy(RoleManagerRemote.class);
+ }
+
+ @Override
+ public SavedSearchManagerRemote getSavedSearchManager() {
+ return getProxy(SavedSearchManagerRemote.class);
+ }
+
+ @Override
+ public SubjectManagerRemote getSubjectManager() {
+ return getProxy(SubjectManagerRemote.class);
+ }
+
+ @Override
+ public SupportManagerRemote getSupportManager() {
+ return getProxy(SupportManagerRemote.class);
+ }
+
+ @Override
+ public SynchronizationManagerRemote getSynchronizationManager() {
+ return getProxy(SynchronizationManagerRemote.class);
+ }
+
+ @Override
+ public SystemManagerRemote getSystemManager() {
+ return getProxy(SystemManagerRemote.class);
+ }
+
+ @Override
+ public TagManagerRemote getTagManager() {
+ return getProxy(TagManagerRemote.class);
+ }
+}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqFacade.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqFacade.java
index 2f80f0c..e6ec7a9 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqFacade.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqFacade.java
@@ -22,6 +22,35 @@ package org.rhq.bindings.client;
import java.util.Map;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.enterprise.server.alert.AlertDefinitionManagerRemote;
+import org.rhq.enterprise.server.alert.AlertManagerRemote;
+import org.rhq.enterprise.server.auth.SubjectManagerRemote;
+import org.rhq.enterprise.server.authz.RoleManagerRemote;
+import org.rhq.enterprise.server.bundle.BundleManagerRemote;
+import org.rhq.enterprise.server.configuration.ConfigurationManagerRemote;
+import org.rhq.enterprise.server.content.ContentManagerRemote;
+import org.rhq.enterprise.server.content.RepoManagerRemote;
+import org.rhq.enterprise.server.discovery.DiscoveryBossRemote;
+import org.rhq.enterprise.server.drift.DriftManagerRemote;
+import org.rhq.enterprise.server.event.EventManagerRemote;
+import org.rhq.enterprise.server.install.remote.RemoteInstallManagerRemote;
+import org.rhq.enterprise.server.measurement.AvailabilityManagerRemote;
+import org.rhq.enterprise.server.measurement.CallTimeDataManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementBaselineManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementDataManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementDefinitionManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerRemote;
+import org.rhq.enterprise.server.operation.OperationManagerRemote;
+import org.rhq.enterprise.server.report.DataAccessManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceFactoryManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceTypeManagerRemote;
+import org.rhq.enterprise.server.resource.group.ResourceGroupManagerRemote;
+import org.rhq.enterprise.server.search.SavedSearchManagerRemote;
+import org.rhq.enterprise.server.support.SupportManagerRemote;
+import org.rhq.enterprise.server.sync.SynchronizationManagerRemote;
+import org.rhq.enterprise.server.system.SystemManagerRemote;
+import org.rhq.enterprise.server.tagging.TagManagerRemote;
/**
* This is an interface through which the script can communicate with RHQ server.
@@ -59,4 +88,192 @@ public interface RhqFacade {
* @return the proxy of the remote API interface backed by this facade
*/
<T> T getProxy(Class<T> remoteApiIface);
+
+ ///////////////////// deprecated methods added to re-introduce compatibility with RHQ 4.4.0
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ AlertDefinitionManagerRemote getAlertDefinitionManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ AlertManagerRemote getAlertManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ AvailabilityManagerRemote getAvailabilityManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ BundleManagerRemote getBundleManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ CallTimeDataManagerRemote getCallTimeDataManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ ConfigurationManagerRemote getConfigurationManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ ContentManagerRemote getContentManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ DataAccessManagerRemote getDataAccessManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ DiscoveryBossRemote getDiscoveryBoss();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ DriftManagerRemote getDriftManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ EventManagerRemote getEventManager();
+
+ /**
+ * Kept for backwards compatibility but otherwise unused.
+ * In RHQ prior to 4.5.0, the values in the map, i.e. the manager objects themselves both implemented the various
+ * {@code *Remote} interfaces and contained methods with the modified signatures with the {@link Subject} parameter
+ * removed.
+ * <p />
+ * Since RHQ 4.5.0 the returned objects no longer contain the modified method. If you want to obtain objects with
+ * such methods (intended for use in scripted environments), use {@link #getScriptingAPI()} method instead.
+ */
+ @Deprecated
+ Map<RhqManagers, Object> getManagers();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ MeasurementBaselineManagerRemote getMeasurementBaselineManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ MeasurementDataManagerRemote getMeasurementDataManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ MeasurementDefinitionManagerRemote getMeasurementDefinitionManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ MeasurementScheduleManagerRemote getMeasurementScheduleManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ OperationManagerRemote getOperationManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ RemoteInstallManagerRemote getRemoteInstallManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ RepoManagerRemote getRepoManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ ResourceFactoryManagerRemote getResourceFactoryManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ ResourceGroupManagerRemote getResourceGroupManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ ResourceManagerRemote getResourceManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ ResourceTypeManagerRemote getResourceTypeManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ RoleManagerRemote getRoleManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ SavedSearchManagerRemote getSavedSearchManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ SubjectManagerRemote getSubjectManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ SupportManagerRemote getSupportManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ SynchronizationManagerRemote getSynchronizationManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ SystemManagerRemote getSystemManager();
+
+ /**
+ * deprecated use {@code RhqFacade.getProxy(RhqManager.XXX.remote())} instead
+ */
+ @Deprecated
+ TagManagerRemote getTagManager();
}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqManagers.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqManagers.java
new file mode 100644
index 0000000..77612d1
--- /dev/null
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/RhqManagers.java
@@ -0,0 +1,139 @@
+package org.rhq.bindings.client;
+
+import org.rhq.enterprise.server.alert.AlertDefinitionManagerRemote;
+import org.rhq.enterprise.server.alert.AlertManagerRemote;
+import org.rhq.enterprise.server.auth.SubjectManagerRemote;
+import org.rhq.enterprise.server.authz.RoleManagerRemote;
+import org.rhq.enterprise.server.bundle.BundleManagerRemote;
+import org.rhq.enterprise.server.cloud.StorageNodeManagerRemote;
+import org.rhq.enterprise.server.configuration.ConfigurationManagerRemote;
+import org.rhq.enterprise.server.content.ContentManagerRemote;
+import org.rhq.enterprise.server.content.RepoManagerRemote;
+import org.rhq.enterprise.server.discovery.DiscoveryBossRemote;
+import org.rhq.enterprise.server.drift.DriftManagerRemote;
+import org.rhq.enterprise.server.drift.DriftTemplateManagerRemote;
+import org.rhq.enterprise.server.event.EventManagerRemote;
+import org.rhq.enterprise.server.install.remote.RemoteInstallManagerRemote;
+import org.rhq.enterprise.server.measurement.AvailabilityManagerRemote;
+import org.rhq.enterprise.server.measurement.CallTimeDataManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementBaselineManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementDataManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementDefinitionManagerRemote;
+import org.rhq.enterprise.server.measurement.MeasurementScheduleManagerRemote;
+import org.rhq.enterprise.server.operation.OperationManagerRemote;
+import org.rhq.enterprise.server.report.DataAccessManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceFactoryManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceManagerRemote;
+import org.rhq.enterprise.server.resource.ResourceTypeManagerRemote;
+import org.rhq.enterprise.server.resource.group.ResourceGroupManagerRemote;
+import org.rhq.enterprise.server.resource.group.definition.GroupDefinitionManagerRemote;
+import org.rhq.enterprise.server.search.SavedSearchManagerRemote;
+import org.rhq.enterprise.server.support.SupportManagerRemote;
+import org.rhq.enterprise.server.sync.SynchronizationManagerRemote;
+import org.rhq.enterprise.server.system.SystemManagerRemote;
+import org.rhq.enterprise.server.tagging.TagManagerRemote;
+
+/**
+ * @author Lukas Krejci
+ *
+ * @deprecated since 4.10 do not use this. Use {@link RhqManager} instead.
+ */
+@Deprecated
+public enum RhqManagers {
+ AlertManager(AlertManagerRemote.class, "${AlertManager}"), //
+ AlertDefinitionManager(AlertDefinitionManagerRemote.class, "${AlertDefinitionManager}"), //
+ AvailabilityManager(AvailabilityManagerRemote.class, "${AvailabilityManager}"), //
+ BundleManager(BundleManagerRemote.class, "${BundleManager}"), //
+ CallTimeDataManager(CallTimeDataManagerRemote.class, "${CallTimeDataManager}"), //
+ RepoManager(RepoManagerRemote.class, "${RepoManager}"), //
+ ConfigurationManager(ConfigurationManagerRemote.class, "${ConfigurationManager}"), //
+ ContentManager(ContentManagerRemote.class, "${ContentManager}"), //
+ DataAccessManager(DataAccessManagerRemote.class, "${DataAccessManager}"), //
+ DriftManager(DriftManagerRemote.class, "${DriftManager}"), //
+ DriftTemplateManager(DriftTemplateManagerRemote.class, "${DriftTemplateManager}"), //
+ DiscoveryBoss(DiscoveryBossRemote.class, "${DiscoveryBoss}"), //
+ EventManager(EventManagerRemote.class, "${EventManager}"), //
+ GroupDefinitionManager(GroupDefinitionManagerRemote.class, "${GroupDefinitionManager}"), //
+ MeasurementBaselineManager(MeasurementBaselineManagerRemote.class, "${MeasurementBaselineManager}"), //
+ MeasurementDataManager(MeasurementDataManagerRemote.class, "${MeasurementDataManager}"), //
+ MeasurementDefinitionManager(MeasurementDefinitionManagerRemote.class, "${MeasurementDefinitionManager}"), //
+ MeasurementScheduleManager(MeasurementScheduleManagerRemote.class, "${MeasurementScheduleManager}"), //
+ OperationManager(OperationManagerRemote.class, "${OperationManager}"), //
+ ResourceManager(ResourceManagerRemote.class, "${ResourceManager}"), //
+ ResourceFactoryManager(ResourceFactoryManagerRemote.class, "${ResourceFactoryManager}"), //
+ ResourceGroupManager(ResourceGroupManagerRemote.class, "${ResourceGroupManager}"), //
+ ResourceTypeManager(ResourceTypeManagerRemote.class, "${ResourceTypeManager}"), //
+ RoleManager(RoleManagerRemote.class, "${RoleManager}"), //
+ SavedSearchManager(SavedSearchManagerRemote.class, "${SavedSearchManager}"), //
+ StorageNodeManager(StorageNodeManagerRemote.class, "${StorageNodeManager}"), //
+ SubjectManager(SubjectManagerRemote.class, "${SubjectManager}"), //
+ SupportManager(SupportManagerRemote.class, "${SupportManager}"), //
+ SystemManager(SystemManagerRemote.class, "${SystemManager}"), //
+ RemoteInstallManager(RemoteInstallManagerRemote.class, "${RemoteInstallManager}"), //
+ TagManager(TagManagerRemote.class, "${TagManager}"), //
+ SynchronizationManager(SynchronizationManagerRemote.class, "${SynchronizationManager}");
+
+ private Class<?> remote;
+ private String localInterfaceClassName;
+ private String beanName;
+ private boolean enabled;
+
+
+ private RhqManagers(Class<?> remote, String enable) {
+ this.remote = remote;
+ this.beanName = this.name() + "Bean";
+ localInterfaceClassName = getLocalInterfaceClassName(remote);
+
+ //defaults and evaluates to TRUE unless the string contains "false". Done to defend against
+ //possible errors in string replacement during rhq build.
+ this.enabled = true;
+ if ((enable != null) && (enable.trim().length() > 0)) {
+ this.enabled = (enable.trim().equalsIgnoreCase("false")) ? Boolean.FALSE : Boolean.TRUE;
+ }
+ }
+
+ public static RhqManagers forInterface(Class<?> iface) {
+ for (RhqManagers m : values()) {
+ if (m.remote().equals(iface)) {
+ return m;
+ }
+ }
+
+ return null;
+ }
+
+ public Class<?> remote() {
+ return this.remote;
+ }
+
+ /**
+ * @deprecated since 4.6.0, use the {@link #remote()} method instead
+ * @return the class name of the remote interface
+ */
+ @Deprecated
+ public String remoteName() {
+ return this.remote.getName();
+ }
+
+ public String localInterfaceClassName() {
+ return localInterfaceClassName;
+ }
+
+ public String beanName() {
+ return this.beanName;
+ }
+
+ public boolean enabled() {
+ return this.enabled;
+ }
+
+ private static String getLocalInterfaceClassName(Class<?> remoteIface) {
+ String ifaceName = remoteIface.getName();
+ if (!ifaceName.endsWith("Remote")) {
+ throw new AssertionError("Inconsistent SLSB naming in RHQ! Remote interface '" + remoteIface.getName()
+ + "' does not follow the established naming convention. This is a bug, please report it.");
+ }
+
+ return (ifaceName.substring(0, ifaceName.lastIndexOf("Remote")) + "Local");
+ }
+}
diff --git a/modules/enterprise/binding/src/test/java/org/rhq/bindings/FakeRhqFacade.java b/modules/enterprise/binding/src/test/java/org/rhq/bindings/FakeRhqFacade.java
index 39cb145..c420c1b 100644
--- a/modules/enterprise/binding/src/test/java/org/rhq/bindings/FakeRhqFacade.java
+++ b/modules/enterprise/binding/src/test/java/org/rhq/bindings/FakeRhqFacade.java
@@ -22,11 +22,12 @@ package org.rhq.bindings;
import java.util.Collections;
import java.util.Map;
+import org.rhq.bindings.client.AbstractRhqFacade;
import org.rhq.bindings.client.RhqFacade;
import org.rhq.bindings.client.RhqManager;
import org.rhq.core.domain.auth.Subject;
-public class FakeRhqFacade implements RhqFacade {
+public class FakeRhqFacade extends AbstractRhqFacade {
public Subject getSubject() {
return null;
diff --git a/modules/enterprise/binding/src/test/java/org/rhq/bindings/client/AbstractRhqFacadeProxyTest.java b/modules/enterprise/binding/src/test/java/org/rhq/bindings/client/AbstractRhqFacadeProxyTest.java
index d1042df..65f6178 100644
--- a/modules/enterprise/binding/src/test/java/org/rhq/bindings/client/AbstractRhqFacadeProxyTest.java
+++ b/modules/enterprise/binding/src/test/java/org/rhq/bindings/client/AbstractRhqFacadeProxyTest.java
@@ -44,7 +44,7 @@ public class AbstractRhqFacadeProxyTest {
void method();
}
- public static class TestFacade implements RhqFacade {
+ public static class TestFacade extends AbstractRhqFacade {
private Subject subject;
diff --git a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/clientapi/RemoteClient.java b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/clientapi/RemoteClient.java
index 95c00ae..b0f25b7 100644
--- a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/clientapi/RemoteClient.java
+++ b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/clientapi/RemoteClient.java
@@ -35,6 +35,7 @@ import org.jboss.remoting.invocation.NameBasedInvocation;
import org.jboss.remoting.security.SSLSocketBuilder;
import org.jboss.remoting.transport.http.ssl.HTTPSClientInvoker;
+import org.rhq.bindings.client.AbstractRhqFacade;
import org.rhq.bindings.client.RhqFacade;
import org.rhq.bindings.client.RhqManager;
import org.rhq.bindings.util.InterfaceSimplifier;
@@ -52,7 +53,7 @@ import org.rhq.enterprise.server.system.SystemManagerRemote;
* @author Jay Shaughnessy
* @author John Mazzitelli
*/
-public class RemoteClient implements RhqFacade {
+public class RemoteClient extends AbstractRhqFacade {
private static final Log LOG = LogFactory.getLog(RemoteClient.class);
@@ -512,4 +513,4 @@ public class RemoteClient implements RhqFacade {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClient.java b/modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClient.java
index df0eab4..51b3b2e 100644
--- a/modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClient.java
+++ b/modules/enterprise/server/client-api/src/main/java/org/rhq/enterprise/client/LocalClient.java
@@ -28,6 +28,7 @@ import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.bindings.client.AbstractRhqFacade;
import org.rhq.bindings.client.RhqFacade;
import org.rhq.bindings.client.RhqManager;
import org.rhq.bindings.util.InterfaceSimplifier;
@@ -39,7 +40,7 @@ import org.rhq.enterprise.server.util.LookupUtil;
*
* @author Lukas Krejci
*/
-public class LocalClient implements RhqFacade {
+public class LocalClient extends AbstractRhqFacade {
private static final Log LOG = LogFactory.getLog(LocalClient.class);
commit a917e38cf672fe9b09d886582b065889a1f49c85
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Mon Sep 30 16:55:49 2013 +0200
api checks: reverting a change that broke JON 3.2 backward compatibility
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/operation/OperationManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/operation/OperationManagerRemote.java
index 3c6e81d..c10bc88 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/operation/OperationManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/operation/OperationManagerRemote.java
@@ -267,7 +267,14 @@ public interface OperationManagerRemote {
List<GroupOperationSchedule> findScheduledGroupOperations(Subject subject, int groupId) throws Exception;
- PageList<OperationDefinition> findOperationDefinitionsByCriteria(Subject subject, OperationDefinitionCriteria criteria);
+ /**
+ * TODO: major release: this should return PageList as all our criteria finder do
+ *
+ * @param subject The logged in user's subject.
+ * @param criteria The criteria object for the finding.
+ * @return instance of PageList<OperationDefinition> (can be safely casted)
+ */
+ List<OperationDefinition> findOperationDefinitionsByCriteria(Subject subject, OperationDefinitionCriteria criteria);
PageList<ResourceOperationHistory> findResourceOperationHistoriesByCriteria(Subject subject,
ResourceOperationHistoryCriteria criteria);
commit 95cf3e68da8ace2ed91654536649d9a1f967d7ee
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Thu Sep 26 22:36:43 2013 +0200
api checks: Adding back the org.rhq.enterprise.server.measurement.MeasurementAggregate see the commit c2a609f48 for more details.
diff --git a/modules/enterprise/server/jar/intentional-api-changes-since-4.9.0.xml b/modules/enterprise/server/jar/intentional-api-changes-since-4.9.0.xml
index 40508c6..488adc3 100644
--- a/modules/enterprise/server/jar/intentional-api-changes-since-4.9.0.xml
+++ b/modules/enterprise/server/jar/intentional-api-changes-since-4.9.0.xml
@@ -41,4 +41,19 @@
<justification>Adding a method to a remote API interface is safe. This is newly implemented functionality.</justification>
</difference>
+ <difference>
+ <className>org/rhq/enterprise/server/measurement/MeasurementDataManagerRemote</className>
+ <differenceType>7006</differenceType> <!-- method return type changed -->
+ <method>org.rhq.core.domain.measurement.MeasurementAggregate getAggregate(org.rhq.core.domain.auth.Subject, int, long, long)</method>
+ <to>org.rhq.enterprise.server.measurement.MeasurementAggregate</to>
+ <justification>In RHQ 4.8 the MeasurementAggregate class was moved from server jar module to core domain module. This change is not backward compatible with Java clients using the remote EJB API. The breaking change was introduced by commit 2f6e74080e2299 the backward compatible change was introduced by c2a609f48d5f36.</justification>
+ </difference>
+
+ <difference>
+ <className>org/rhq/enterprise/server/measurement/MeasurementDataManagerRemote</className>
+ <differenceType>7012</differenceType> <!-- method added to an interface -->
+ <method>org.rhq.core.domain.measurement.MeasurementAggregate getMeasurementAggregate(org.rhq.core.domain.auth.Subject, int, long, long)</method>
+ <justification>Adding a method to a remote API interface is safe. This is method is added in order to deprecate the getAggregate. For more details see the previous intentional change.</justification>
+ </difference>
+
</differences>
commit 4843149492e349f558bb6dd3f5a2f2b244fe8942
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Thu Sep 26 22:32:46 2013 +0200
Adding back the org.rhq.enterprise.server.measurement.MeasurementAggregate because of the JON 3.2 backward compatibility breakage (for EJB remote clients). This contains also adding a new method, deprecating the old method and the added class so that it can be removed in the next major release.
diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBeanTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBeanTest.java
index dbd03ae..e07fb65 100644
--- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBeanTest.java
+++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBeanTest.java
@@ -258,7 +258,7 @@ public class MeasurementDataManagerBeanTest extends AbstractEJB3Test {
dataManager.mergeMeasurementReport(report);
waitForRawInserts();
- MeasurementAggregate actual = dataManager.getAggregate(getOverlord(), dynamicSchedule.getId(),
+ MeasurementAggregate actual = dataManager.getMeasurementAggregate(getOverlord(), dynamicSchedule.getId(),
beginTime.getMillis(), endTime.getMillis());
MeasurementAggregate expected = new MeasurementAggregate(1.1, divide((1.1 + 2.2 + 3.3 + 4.4 + 5.5 + 6.6), 6),
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
index 97dd33f..70a0e60 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
@@ -347,7 +347,7 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
// find the aggregates and enrich the result instance
if (!scheduleIdsMap.isEmpty()) {
if ((scheduleId = scheduleIdsMap.get(METRIC_TOKENS)) != null) {
- MeasurementAggregate tokensAggregate = measurementManager.getAggregate(subject, scheduleId, beginTime,
+ MeasurementAggregate tokensAggregate = measurementManager.getMeasurementAggregate(subject, scheduleId, beginTime,
endTime);
result.setTokens(tokensAggregate);
}
@@ -369,7 +369,7 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
result.setTotalDiskUsedPercentage(totalDiskUsedPercentageAggregateWithUnits);
}
if ((scheduleId = scheduleIdsMap.get(METRIC_FREE_DISK_TO_DATA_RATIO)) != null) {
- MeasurementAggregate freeDiskToDataRatioAggregate = measurementManager.getAggregate(subject,
+ MeasurementAggregate freeDiskToDataRatioAggregate = measurementManager.getMeasurementAggregate(subject,
scheduleId, beginTime, endTime);
result.setFreeDiskToDataSizeRatio(freeDiskToDataRatioAggregate);
}
@@ -383,17 +383,17 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
}
if ((scheduleId = scheduleIdsMap.get(METRIC_KEY_CACHE_SIZE)) != null) {
updateAggregateTotal(totalDiskUsedAggregate,
- measurementManager.getAggregate(subject, scheduleId, beginTime, endTime));
+ measurementManager.getMeasurementAggregate(subject, scheduleId, beginTime, endTime));
}
if ((scheduleId = scheduleIdsMap.get(METRIC_ROW_CACHE_SIZE)) != null) {
updateAggregateTotal(totalDiskUsedAggregate,
- measurementManager.getAggregate(subject, scheduleId, beginTime, endTime));
+ measurementManager.getMeasurementAggregate(subject, scheduleId, beginTime, endTime));
}
if ((scheduleId = scheduleIdsMap.get(METRIC_TOTAL_COMMIT_LOG_SIZE)) != null) {
updateAggregateTotal(totalDiskUsedAggregate,
- measurementManager.getAggregate(subject, scheduleId, beginTime, endTime));
+ measurementManager.getMeasurementAggregate(subject, scheduleId, beginTime, endTime));
}
if (totalDiskUsedAggregate.getMax() > 0) {
StorageNodeLoadComposite.MeasurementAggregateWithUnits totalDiskUsedAggregateWithUnits = new StorageNodeLoadComposite.MeasurementAggregateWithUnits(
@@ -539,7 +539,7 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
private StorageNodeLoadComposite.MeasurementAggregateWithUnits getMeasurementAggregateWithUnits(Subject subject,
int schedId, MeasurementUnits units, long beginTime, long endTime) {
- MeasurementAggregate measurementAggregate = measurementManager.getAggregate(subject, schedId, beginTime,
+ MeasurementAggregate measurementAggregate = measurementManager.getMeasurementAggregate(subject, schedId, beginTime,
endTime);
StorageNodeLoadComposite.MeasurementAggregateWithUnits measurementAggregateWithUnits = new StorageNodeLoadComposite.MeasurementAggregateWithUnits(
measurementAggregate, units);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementAggregate.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementAggregate.java
new file mode 100644
index 0000000..7acc5f6
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementAggregate.java
@@ -0,0 +1,83 @@
+/*
+ * 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.enterprise.server.measurement;;
+
+import java.io.Serializable;
+
+/**
+ * Simple Java Bean to hold aggregate values
+ *
+ * @author <a href="mailto:heiko.rupp@redhat.com">Heiko W. Rupp</a>
+ * @deprecated As of release RHQ 4.8, replaced by {@link org.rhq.core.domain.measurement.MeasurementAggregate}. Use this class from core domain instead.
+ */
+public class MeasurementAggregate implements Serializable {
+
+ static final long serialVersionUID = 5673395371271765240L;
+
+ Double min;
+ Double avg;
+ Double max;
+
+ public MeasurementAggregate() {
+ }
+
+ public MeasurementAggregate(Double min, Double avg, Double max) {
+ this.min = (min != null) ? min : Double.NaN;
+ this.avg = (avg != null) ? avg : Double.NaN;
+ this.max = (max != null) ? max : Double.NaN;
+ }
+
+ public Double getMin() {
+ return min;
+ }
+
+ public void setMin(Double min) {
+ this.min = min;
+ }
+
+ public Double getAvg() {
+ return avg;
+ }
+
+ public void setAvg(Double avg) {
+ this.avg = avg;
+ }
+
+ public Double getMax() {
+ return max;
+ }
+
+ public void setMax(Double max) {
+ this.max = max;
+ }
+
+ @Override
+ public String toString() {
+ return "Min: " + min + ", Max: " + max + ", Avg: " + avg;
+ }
+
+ /**
+ * Return true if the aggregate has "no real data" I.e. when all values are Not A Number.
+ *
+ * @return
+ */
+ public boolean isEmpty() {
+ return min.isNaN() && avg.isNaN() && max.isNaN();
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
index 3504cdc..1470337 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
@@ -480,7 +480,7 @@ public class MeasurementBaselineManagerBean implements MeasurementBaselineManage
throw new BaselineCreationException("Baseline calculation is only valid for a dynamic measurement");
}
- MeasurementAggregate agg = dataManager.getAggregate(subjectManager.getOverlord(), schedule.getId(), startDate,
+ MeasurementAggregate agg = dataManager.getMeasurementAggregate(subjectManager.getOverlord(), schedule.getId(), startDate,
endDate);
// attach the entity, so we can find the baseline
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementChartsManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementChartsManagerBean.java
index c481c6e..618bcc7 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementChartsManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementChartsManagerBean.java
@@ -373,7 +373,7 @@ public class MeasurementChartsManagerBean implements MeasurementChartsManagerLoc
summary.setCollectionType(collectionType);
if (!narrowed) {
- MeasurementAggregate compositeHighLow = dataManager.getAggregate(subject, schedule.getId(), begin, end);
+ MeasurementAggregate compositeHighLow = dataManager.getMeasurementAggregate(subject, schedule.getId(), begin, end);
if (compositeHighLow.isEmpty()) {
summary.setValuesPresent(false);
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBean.java
index 19c5ecf..ee679f1 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerBean.java
@@ -605,9 +605,41 @@ public class MeasurementDataManagerBean implements MeasurementDataManagerLocal,
log.debug(callingMethod + ": " + stats.toString());
}
+ @Deprecated
@Override
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
- public MeasurementAggregate getAggregate(Subject subject, int scheduleId, long startTime, long endTime) {
+ public org.rhq.enterprise.server.measurement.MeasurementAggregate getAggregate(Subject subject, int scheduleId, long startTime, long endTime) {
+ MeasurementScheduleCriteria criteria = new MeasurementScheduleCriteria();
+ criteria.addFilterId(scheduleId);
+ criteria.fetchResource(true);
+
+ PageList<MeasurementSchedule> schedules = measurementScheduleManager.findSchedulesByCriteria(
+ subjectManager.getOverlord(), criteria);
+ if (schedules.isEmpty()) {
+ throw new MeasurementException("Could not fine MeasurementSchedule with the id[" + scheduleId + "]");
+ }
+ MeasurementSchedule schedule = schedules.get(0);
+
+ if (authorizationManager.canViewResource(subject, schedule.getResource().getId()) == false) {
+ throw new PermissionException("User[" + subject.getName()
+ + "] does not have permission to view schedule[id=" + scheduleId + "]");
+ }
+
+ if (schedule.getDefinition().getDataType() != DataType.MEASUREMENT) {
+ throw new IllegalArgumentException(schedule + " is not about numerical values. Can't compute aggregates");
+ }
+
+ if (startTime > endTime) {
+ throw new IllegalArgumentException("Start date " + startTime + " is not before " + endTime);
+ }
+
+ MetricsServer metricsServer = storageClientManager.getMetricsServer();
+ AggregateNumericMetric summary = metricsServer.getSummaryAggregate(scheduleId, startTime, endTime);
+
+ return new org.rhq.enterprise.server.measurement.MeasurementAggregate(summary.getMin(), summary.getAvg(), summary.getMax());
+ }
+
+ public MeasurementAggregate getMeasurementAggregate(Subject subject, int scheduleId, long startTime, long endTime) {
MeasurementScheduleCriteria criteria = new MeasurementScheduleCriteria();
criteria.addFilterId(scheduleId);
criteria.fetchResource(true);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerRemote.java
index 116c82a..1a049c3 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementDataManagerRemote.java
@@ -51,8 +51,27 @@ public interface MeasurementDataManagerRemote {
*
* @throws FetchException if the schedule does not reference numerical data or if the user is not allowed to view
* the {@link Resource} corresponding to this scheduleId
+ * @deprecated class {@link org.rhq.enterprise.server.measurement.MeasurementAggregate} has been deprecated
+ * since RHQ 4.8, therefore this method was deprecated as well and
+ * replaced by {@link #getMeasurementAggregate(org.rhq.core.domain.auth.Subject,int,long,long)}
*/
- MeasurementAggregate getAggregate(Subject subject, int scheduleId, long startTime, long endTime);
+ org.rhq.enterprise.server.measurement.MeasurementAggregate getAggregate(Subject subject, int scheduleId, long startTime, long endTime);
+
+ /**
+ * Get the aggregate values of the numerical values for a given schedule. This can only provide aggregates for data
+ * in the "live" table
+ *
+ * @param subject the user requesting the aggregate
+ * @param scheduleId the id of the {@link MeasurementSchedule} for which this aggregate is being requested
+ * @param start the start time
+ * @param end the end time
+ *
+ * @return MeasurementAggregate bean with the data
+ *
+ * @throws FetchException if the schedule does not reference numerical data or if the user is not allowed to view
+ * the {@link Resource} corresponding to this scheduleId
+ */
+ MeasurementAggregate getMeasurementAggregate(Subject subject, int scheduleId, long startTime, long endTime);
/**
* Return all known trait data for the passed schedule, defined by resourceId and definitionId
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java
index d5ca8dc..fb927ec 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/rest/MetricHandlerBean.java
@@ -162,7 +162,7 @@ public class MetricHandlerBean extends AbstractRestBean {
MeasurementSchedule schedule = obtainSchedule(scheduleId, false, DataType.MEASUREMENT);
- MeasurementAggregate aggr = dataManager.getAggregate(caller, scheduleId, startTime, endTime);
+ MeasurementAggregate aggr = dataManager.getMeasurementAggregate(caller, scheduleId, startTime, endTime);
MetricAggregate res = new MetricAggregate(scheduleId, aggr.getMin(),aggr.getAvg(),aggr.getMax());
int definitionId = schedule.getDefinition().getId();
@@ -387,7 +387,7 @@ public class MetricHandlerBean extends AbstractRestBean {
List<List<MeasurementDataNumericHighLowComposite>> listList =
dataManager.findDataForContext(caller, EntityContext.forResource(sched.getResource().getId()),definitionId,startTime,endTime,dataPoints);
if (!listList.isEmpty()) {
- MeasurementAggregate measurementAggregate = dataManager.getAggregate(caller,scheduleId,startTime,endTime);
+ MeasurementAggregate measurementAggregate = dataManager.getMeasurementAggregate(caller,scheduleId,startTime,endTime);
List<MeasurementDataNumericHighLowComposite> list = listList.get(0);
MetricAggregate res = new MetricAggregate(scheduleId,measurementAggregate.getMin(),measurementAggregate.getAvg(),measurementAggregate.getMax());
boolean isHtml = mediaType.equals(MediaType.TEXT_HTML_TYPE);
@@ -552,7 +552,7 @@ public class MetricHandlerBean extends AbstractRestBean {
List<MetricAggregate> ret = new ArrayList<MetricAggregate>(schedules.size());
for (MeasurementSchedule schedule: schedules) {
- MeasurementAggregate aggr = dataManager.getAggregate(caller,schedule.getId(),startTime,endTime);
+ MeasurementAggregate aggr = dataManager.getMeasurementAggregate(caller,schedule.getId(),startTime,endTime);
MetricAggregate res = new MetricAggregate(schedule.getId(), aggr.getMin(),aggr.getAvg(),aggr.getMax());
if (includeDataPoints) {
10 years, 2 months