[rhq] modules/core
by Joseph Marques
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
New commits:
commit 303467aeda8d90b48cb68581d53211c774a82fd5
Author: Joseph Marques <joseph(a)redhat.com>
Date: Wed Apr 28 10:06:54 2010 -0400
BA-586918 - fix for ClassCastException when using AlertDefinitionCriteria when filtering by either alertTemplateParentId or alertTemplateResourceTypeId
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java
index c3992cb..e553ca8 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertDefinitionCriteria.java
@@ -29,8 +29,8 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
-import org.rhq.core.domain.alert.AlertPriority;
import org.rhq.core.domain.alert.AlertDefinition;
+import org.rhq.core.domain.alert.AlertPriority;
import org.rhq.core.domain.util.PageOrdering;
/**
@@ -46,8 +46,8 @@ public class AlertDefinitionCriteria extends Criteria {
private String filterName;
private String filterDescription;
private AlertPriority filterPriority;
- private String filterAlertTemplateParentId; // requires overrides
- private String filterAlertTemplateResourceTypeId; // requires overrides
+ private Integer filterAlertTemplateParentId; // requires overrides
+ private Integer filterAlertTemplateResourceTypeId; // requires overrides
private String filterAlertTemplateResourceTypeName; // requires overrides
private List<Integer> filterResourceIds; // requires overrides
private Boolean filterEnabled;
@@ -90,11 +90,11 @@ public class AlertDefinitionCriteria extends Criteria {
this.filterPriority = filterPriority;
}
- public void addFilterAlertTemplateParentId(String filterAlertTemplateParentId) {
+ public void addFilterAlertTemplateParentId(Integer filterAlertTemplateParentId) {
this.filterAlertTemplateParentId = filterAlertTemplateParentId;
}
- public void addFilterAlertTemplateResourceTypeId(String filterAlertTemplateResourceTypeId) {
+ public void addFilterAlertTemplateResourceTypeId(Integer filterAlertTemplateResourceTypeId) {
this.filterAlertTemplateResourceTypeId = filterAlertTemplateResourceTypeId;
}
14 years
[rhq] modules/enterprise
by Joseph Marques
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
New commits:
commit 1851fe41127d4fb136b88184189efc37439f8677
Author: Joseph Marques <joseph(a)redhat.com>
Date: Wed Apr 28 03:12:49 2010 -0400
BZ-586676: fix for alert>history sub-tab as a result of changes to dbsetup
* alert entity no longer refers to the subject entity via foreign key relationship, update Facelet accordingly
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml
index b708ab7..0d0a46d 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml
@@ -174,16 +174,16 @@
<f:facet name="header">
<h:outputText styleClass="headerText" value="Ack by" />
</f:facet>
- <h:outputText value="#{item.alert.ackBy.name}" title="#{item.alert.ackBy.firstName} #{item.alert.ackBy.lastName}"/>
+ <h:outputText value="#{item.alert.acknowledgingSubject}" />
</rich:column>
<rich:column>
<f:facet name="header">
- <onc:sortableColumnHeader sort="a.ackTime">
+ <onc:sortableColumnHeader sort="a.acknowledgeTime">
<h:outputText styleClass="headerText" value="Ack date" />
</onc:sortableColumnHeader>
</f:facet>
- <h:outputText value="#{item.alert.ackTime}">
+ <h:outputText value="#{item.alert.acknowledgeTime}">
<f:converter converterId="RelativeDurationConverter" />
</h:outputText>
</rich:column>
14 years
[rhq] modules/enterprise
by Joseph Marques
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/WebUserPreferences.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 605b051d37b98be46f183e3d2bce214d256507f5
Author: Joseph Marques <joseph(a)redhat.com>
Date: Wed Apr 28 01:29:18 2010 -0400
move logging message to DEBUG level
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/WebUserPreferences.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/WebUserPreferences.java
index c0abd7e..e2414a7 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/WebUserPreferences.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/WebUserPreferences.java
@@ -777,7 +777,7 @@ public class WebUserPreferences extends SubjectPreferencesBase {
pageControlProperties.add(field.getOrdering().toString());
pageControlProperties.add(field.getField());
}
- System.out.println("setPageControl(" + view + ", " + pageControl + ")");
+ log.debug("setPageControl(" + view + ", " + pageControl + ")");
setPreference(view.toString(), pageControlProperties);
}
14 years
[rhq] Branch 'gwt' - modules/enterprise
by mazz
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/UberBundleFileUploadServlet.java | 77 +++++++++
modules/enterprise/gui/coregui/src/main/webapp/WEB-INF/web.xml | 8
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java | 5
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java | 31 ++-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/UberBundleFileInfo.java | 84 ++++++++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginFacet.java | 23 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginManager.java | 18 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java | 5
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginService.java | 5
modules/enterprise/server/plugins/ant-bundle/src/main/java/org/rhq/enterprise/server/plugins/ant/AntBundleServerPluginComponent.java | 6
modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java | 7
11 files changed, 260 insertions(+), 9 deletions(-)
New commits:
commit 12e0c3daee48cffa56263c4e0999a6f26a8dc0af
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Apr 27 23:35:28 2010 -0400
stub out some server side bundle API that allows a user to provide a "uber bundle file" and have it be processed such that from it we can create a bundle, bundle version and associated bundle files
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/UberBundleFileUploadServlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/UberBundleFileUploadServlet.java
new file mode 100644
index 0000000..9033dc8
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/UberBundleFileUploadServlet.java
@@ -0,0 +1,77 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 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.coregui.server.gwt;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.enterprise.server.bundle.BundleManagerLocal;
+import org.rhq.enterprise.server.util.LookupUtil;
+
+/**
+ * Accepts a "uber bundle file" - which is simply a zip file that contains within it
+ * a bundle recipe and additional bundle files.
+ *
+ * @author John Mazzitelli
+ */
+public class UberBundleFileUploadServlet extends FileUploadServlet {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void processUploadedFiles(Subject subject, Map<String, File> files, Map<String, String> formFields,
+ HttpServletRequest request, HttpServletResponse response) throws IOException {
+
+ String successMsg;
+
+ try {
+ // note that this assumes 1 and only 1 file is uploaded
+ File file = files.values().iterator().next();
+
+ BundleManagerLocal bundleManager = LookupUtil.getBundleManager();
+ BundleVersion bundleVersion = bundleManager.createBundleVersionViaUberBundleFileURL(subject, file.toURI()
+ .toURL());
+ successMsg = "success [" + bundleVersion.getId() + "]";
+ } catch (Exception e) {
+ writeExceptionResponse(response, "Failed to upload uber bundle file", e); // clients will look for this string!
+ return;
+ }
+
+ PrintWriter writer = response.getWriter();
+ writer.println("<html>");
+ writer.println(successMsg);
+ writer.println("</html>");
+ writer.flush();
+ return;
+ }
+
+ private String getFormField(Map<String, String> formFields, String key, String defaultValue) {
+ String value = formFields.get(key);
+ if (value == null) {
+ value = defaultValue;
+ }
+ return value;
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/WEB-INF/web.xml b/modules/enterprise/gui/coregui/src/main/webapp/WEB-INF/web.xml
index 8dc1bcd..4b75b04 100644
--- a/modules/enterprise/gui/coregui/src/main/webapp/WEB-INF/web.xml
+++ b/modules/enterprise/gui/coregui/src/main/webapp/WEB-INF/web.xml
@@ -59,6 +59,10 @@
<servlet-name>org.rhq.enterprise.gui.coregui.CoreGUI BundleFileUploadServlet</servlet-name>
<servlet-class>org.rhq.enterprise.gui.coregui.server.gwt.BundleFileUploadServlet</servlet-class>
</servlet>
+ <servlet>
+ <servlet-name>org.rhq.enterprise.gui.coregui.CoreGUI UberBundleFileUploadServlet</servlet-name>
+ <servlet-class>org.rhq.enterprise.gui.coregui.server.gwt.UberBundleFileUploadServlet</servlet-class>
+ </servlet>
<servlet>
<servlet-name>org.rhq.enterprise.gui.coregui.CoreGUI ResourceBossGWTService</servlet-name>
@@ -117,6 +121,10 @@
<servlet-name>org.rhq.enterprise.gui.coregui.CoreGUI BundleFileUploadServlet</servlet-name>
<url-pattern>/org.rhq.enterprise.gui.coregui.CoreGUI/BundleFileUploadServlet</url-pattern>
</servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>org.rhq.enterprise.gui.coregui.CoreGUI UberBundleFileUploadServlet</servlet-name>
+ <url-pattern>/org.rhq.enterprise.gui.coregui.CoreGUI/UberBundleFileUploadServlet</url-pattern>
+ </servlet-mapping>
<servlet-mapping>
<servlet-name>org.rhq.enterprise.gui.coregui.CoreGUI ResourceBossGWTService</servlet-name>
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
index ca3e76b..22b5e89 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
@@ -314,6 +314,11 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
return bundleVersion;
}
+ public BundleVersion createBundleVersionViaUberBundleFileURL(Subject subject, URL uberBundleFile) throws Exception {
+ // TODO: bundle implement me
+ return null;
+ }
+
@SuppressWarnings("unchecked")
private String getVersion(String version, Bundle bundle) {
if (null != version && version.trim().length() > 0) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java
index ca22f58..524af5e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java
@@ -63,7 +63,7 @@ public interface BundleManagerRemote {
* Adds a BundleFile to the BundleVersion and implicitly creates the backing PackageVersion. If the PackageVersion
* already exists use {@link addBundleFile(Subject, int, String, int, boolean)}
*
- * @param subject must be InventoryManager
+ * @param subject user that must have proper permissions
* @param bundleVersionId id of the BundleVersion incorporating this BundleFile
* @param name name of the BundleFile (and the resulting Package)
* @param version version of the backing package
@@ -119,7 +119,7 @@ public interface BundleManagerRemote {
@WebParam(name = "packageVersionId") int packageVersionId) throws Exception;
/**
- * @param subject must be InventoryManager
+ * @param subject user that must have proper permissions
* @param name not null or empty
* @param description optional long description of the bundle
* @param bundleTypeId valid bundleType
@@ -132,7 +132,7 @@ public interface BundleManagerRemote {
@WebParam(name = "bundleTypeId") int bundleTypeId) throws Exception;
/**
- * @param subject must be InventoryManager
+ * @param subject user that must have proper permissions
* @param BundleVersionId the BundleVersion being deployed by this deployment
* @param name a name for this deployment. not null or empty
* @param description an optional longer description describing this deployment
@@ -151,7 +151,7 @@ public interface BundleManagerRemote {
@WebParam(name = "configuration") Configuration configuration) throws Exception;
/**
- * @param subject must be InventoryManager
+ * @param subject user that must have proper permissions
* @param bundleId the bundle for which this will be the next version
* @param name not null or empty
* @param description optional long description of the bundle version
@@ -167,11 +167,24 @@ public interface BundleManagerRemote {
@WebParam(name = "recipe") String recipe) throws Exception;
/**
+ * Creates a bundle version based on a "uber bundle" zip file. The "uber bundle" zip file should contain
+ * the recipe for a supported bundle type, along with 0, 1 or more bundle files that will be associated
+ * with the bundle version.
+ *
+ * @param subject
+ * @param uberBundleZipFile a zip file containing a bundle recipe and bundle files
+ * @return the persisted BundleVersion (id is assigned)
+ */
+ BundleVersion createBundleVersionViaUberBundleFileURL( //
+ @WebParam(name = "subject") Subject subject, //
+ @WebParam(name = "url") URL uberBundleZipFile) throws Exception;
+
+ /**
* Convienence method that combines {@link #createBundle(Subject, String, int)} and {@link #createBundleVersion(Subject, int, String, String, String)}.
* This will first check to see if a bundle with the given type/name exists - if it doesn't, it will be created. If it does, it will be reused.
* This will then create the bundle version that will be associated with the bundle that was created or found.
*
- * @param subject must be InventoryManager
+ * @param subject user that must have proper permissions
* @param bundleName name of the bundle to use (if not found, it will be created)
* @param bundleDescription optional long description of the bundle
* @param bundleTypeId the bundle type for the new bundle (if it is created) for which this will be the first version
@@ -259,7 +272,7 @@ public interface BundleManagerRemote {
* Determine the files required for a BundleVersion and return all of the filenames or optionally, just those
* that lack BundleFiles for the BundleVersion. The recipe may be parsed as part of this call.
*
- * @param subject must be InventoryManager
+ * @param subject user that must have proper permissions
* @param bundleVersionId the BundleVersion being queried
* @param withoutBundleFileOnly if true omit any filenames that already have a corresponding BundleFile for
* the BundleVersion.
@@ -276,7 +289,7 @@ public interface BundleManagerRemote {
* all of the filenames, with the values of the map being true if they already exist or false if they lack BundleFile representation
* in the BundleVersion.
*
- * @param subject must be InventoryManager
+ * @param subject user that must have proper permissions
* @param bundleVersionId the BundleVersion being queried
* @return map keyed on filenames whose value indicates if a bundle file exists for the file or not
* @throws Exception
@@ -294,7 +307,7 @@ public interface BundleManagerRemote {
*
* TODO: Add the scheduling capability, currently it's Immediate.
*
- * @param subject must be InventoryManager
+ * @param subject user that must have proper permissions
* @param bundleDeploymentId the BundleDeployment being used to guide the deployments
* @param resourceId the target resource (must exist), typically platforms, for the deployments
* @return the {@link BundleResourceDeployment} created to track the deployment.
@@ -314,7 +327,7 @@ public interface BundleManagerRemote {
*
* TODO: Add the scheduling capability, currently it's Immediate.
*
- * @param subject must be InventoryManager
+ * @param subject user that must have proper permissions
* @param bundleDeploymentId the BundleDeployment being used to guide the deployments
* @param resourceGroupId the target resourceGroup (must exist), typically platforms, for the deployments
* @return the BundleGroupDeployment created to track the deployments.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/UberBundleFileInfo.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/UberBundleFileInfo.java
new file mode 100644
index 0000000..66881a9
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/UberBundleFileInfo.java
@@ -0,0 +1,84 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2009 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.bundle;
+
+import java.io.File;
+import java.util.Map;
+
+import org.rhq.core.domain.bundle.BundleVersion;
+
+/**
+ * Information found when a uber bundle file was cracked open and inspected.
+ *
+ * @author John Mazzitelli
+ */
+public class UberBundleFileInfo {
+ private final BundleVersion bundleVersion;
+ private final RecipeParseResults recipeParseResults;
+ private final Map<String, File> bundleFiles;
+
+ public UberBundleFileInfo(BundleVersion bundleVersion, RecipeParseResults recipeParseResults,
+ Map<String, File> bundleFiles) {
+
+ this.bundleVersion = bundleVersion;
+ this.recipeParseResults = recipeParseResults;
+ this.bundleFiles = bundleFiles;
+ }
+
+ /**
+ * The metadata about the bundle version represented by the uber bundle file.
+ * The uber bundle file must have metadata encoded in it that provides details
+ * such as the name of the bundle, the version of the bundle, etc. Usually this
+ * information is found within the recipe itself but that is not a requirement - the
+ * uber bundle file merely has to have the information somewhere that the bundle type
+ * server side plugin can find.
+ *
+ * @return the bundle version information
+ */
+ public BundleVersion getBundleVersion() {
+ return bundleVersion;
+ }
+
+ /**
+ * The information gleened from the recipe that was found in the uber bundle file.
+ *
+ * @return the recipe information
+ */
+ public RecipeParseResults getRecipeParseResults() {
+ return recipeParseResults;
+ }
+
+ /**
+ * If the uber bundle file contained within it one or more bundle files that need
+ * to be associated with the bundle version, this map will contain those files.
+ * The key to the map is the name of the bundle file as referenced to it via
+ * the recipe (i.e. the keys will be filenames that are mentioned in the
+ * {@link #getRecipeParseResults() parse results}). The values are files referencing
+ * the bundle files' content - it is the job of the server side plugin to extract
+ * the bundle files from the uber bundle file and store them on the local file
+ * system.
+ *
+ * @return names and file locations of all bundle files found in the uber bundle file
+ */
+ public Map<String, File> getBundleFiles() {
+ return bundleFiles;
+ }
+
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginFacet.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginFacet.java
index a2d6b96..f798945 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginFacet.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginFacet.java
@@ -19,7 +19,10 @@
package org.rhq.enterprise.server.plugin.pc.bundle;
+import java.io.File;
+
import org.rhq.enterprise.server.bundle.RecipeParseResults;
+import org.rhq.enterprise.server.bundle.UberBundleFileInfo;
/**
* All bundle server plugins must implement this facet.
@@ -27,5 +30,25 @@ import org.rhq.enterprise.server.bundle.RecipeParseResults;
* @author John Mazzitelli
*/
public interface BundleServerPluginFacet {
+ /**
+ * The server side plugin is being given a recipe which must be parsed. The results
+ * of the parse are to be returned.
+ *
+ * @param recipe the content of the recipe to be parsed
+ * @return the information gleened from the recipe after being parsed
+ * @throws Exception if the recipe could not be successfully parsed
+ */
RecipeParseResults parseRecipe(String recipe) throws Exception;
+
+ /**
+ * The server side plugin is being given an uber bundle file that must be procssed.
+ * The results of the processing are to be returned.
+ *
+ * An uber bundle file is a zip file that contains a recipe and 0, 1 or more bundle files.
+ *
+ * @param uberBundleFile
+ * @return the information gleened by cracking open the uber bundle file and examining its contents
+ * @throws Exception if the uber bundle file could not be processed successfully
+ */
+ UberBundleFileInfo processUberBundleFile(File uberBundleFile) throws Exception;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginManager.java
index 7387f3a..1358348 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginManager.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginManager.java
@@ -18,7 +18,10 @@
*/
package org.rhq.enterprise.server.plugin.pc.bundle;
+import java.io.File;
+
import org.rhq.enterprise.server.bundle.RecipeParseResults;
+import org.rhq.enterprise.server.bundle.UberBundleFileInfo;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment;
import org.rhq.enterprise.server.plugin.pc.ServerPluginManager;
@@ -116,4 +119,19 @@ public class BundleServerPluginManager extends ServerPluginManager {
Thread.currentThread().setContextClassLoader(originalContextClassLoader);
}
}
+
+ /**
+ * Given an uber bundle file, this will find the appropriate server side plugin that can process it
+ * and will ask that plugin to crack open the uber bundle file and return information about it.
+ *
+ * An uber bundle file is a zip file that contains a recipe and 0, 1 or more bundle files.
+ *
+ * @param uberBundleFile
+ * @return the information gleened by cracking open the uber bundle file and examining its contents
+ * @throws Exception if the uber bundle file could not be processed successfully
+ */
+ public UberBundleFileInfo processUberBundleFile(File uberBundleFile) throws Exception {
+ // TODO: bundle implement me
+ return null;
+ }
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
index f2df079..69cadad 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
@@ -353,6 +353,11 @@ public class WebservicesManagerBean implements WebservicesRemote {
return bundleManager.createBundleVersion(subject, bundleId, name, description, version, recipe);
}
+ public BundleVersion createBundleVersionViaUberBundleFileURL(Subject subject, URL uberBundleZipFile)
+ throws Exception {
+ return bundleManager.createBundleVersionViaUberBundleFileURL(subject, uberBundleZipFile);
+ }
+
public BundleVersion createBundleAndBundleVersion(Subject subject, String bundleName, String bundleDescription,
int bundleTypeId, String bundleVersionName, String bundleVersionDescription, String version, String recipe)
throws Exception {
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginService.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginService.java
index 5217e0f..196a7f1 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginService.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginService.java
@@ -216,5 +216,10 @@ public class TestBundleServerPluginService extends ServerPluginService implement
return new RecipeParseResults(metadata, configDef, bundleFileNames);
}
+
+ public UberBundleFileInfo processUberBundleFile(File uberBundleFile) throws Exception {
+ // TODO: bundle implement me
+ throw new UnsupportedOperationException("this mock object cannot do this");
+ }
}
}
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/ant-bundle/src/main/java/org/rhq/enterprise/server/plugins/ant/AntBundleServerPluginComponent.java b/modules/enterprise/server/plugins/ant-bundle/src/main/java/org/rhq/enterprise/server/plugins/ant/AntBundleServerPluginComponent.java
index 6309b55..28b8137 100644
--- a/modules/enterprise/server/plugins/ant-bundle/src/main/java/org/rhq/enterprise/server/plugins/ant/AntBundleServerPluginComponent.java
+++ b/modules/enterprise/server/plugins/ant-bundle/src/main/java/org/rhq/enterprise/server/plugins/ant/AntBundleServerPluginComponent.java
@@ -33,6 +33,7 @@ import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.util.stream.StreamUtil;
import org.rhq.core.util.updater.DeploymentProperties;
import org.rhq.enterprise.server.bundle.RecipeParseResults;
+import org.rhq.enterprise.server.bundle.UberBundleFileInfo;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
import org.rhq.enterprise.server.plugin.pc.ServerPluginContext;
import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginFacet;
@@ -114,6 +115,11 @@ public class AntBundleServerPluginComponent implements ServerPluginComponent, Bu
return results;
}
+ public UberBundleFileInfo processUberBundleFile(File uberBundleFile) throws Exception {
+ // TODO: bundle implement me
+ return null;
+ }
+
@Override
public String toString() {
if (this.context == null) {
diff --git a/modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java b/modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java
index 33ae3f5..4d36238 100644
--- a/modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java
+++ b/modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java
@@ -19,6 +19,7 @@
package org.rhq.enterprise.server.plugins.filetemplate;
+import java.io.File;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -35,6 +36,7 @@ import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
import org.rhq.core.domain.configuration.definition.PropertySimpleType;
import org.rhq.core.util.updater.DeploymentProperties;
import org.rhq.enterprise.server.bundle.RecipeParseResults;
+import org.rhq.enterprise.server.bundle.UberBundleFileInfo;
import org.rhq.enterprise.server.plugin.pc.ControlFacet;
import org.rhq.enterprise.server.plugin.pc.ControlResults;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
@@ -100,6 +102,11 @@ public class BundleServerPluginComponent implements ServerPluginComponent, Bundl
}
+ public UberBundleFileInfo processUberBundleFile(File uberBundleFile) throws Exception {
+ // TODO: bundle implement me
+ return null;
+ }
+
public ControlResults invoke(String name, Configuration parameters) {
ControlResults controlResults = new ControlResults();
if (name.equals("testControl")) {
14 years
[rhq] modules/enterprise
by Simeon Pinder
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/AddLdapGroupsAction.java | 8
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/AddLdapGroupsFormPrepareAction.java | 36
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/RemoveLdapGroupsAction.java | 6
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/ViewAction.java | 13
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/user/RegisterAction.java | 44 -
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/RoleManagerBean.java | 103 --
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/RoleManagerLocal.java | 11
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/jaas/LdapLoginModule.java | 10
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/LdapGroupManager.java | 304 -------
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/LdapGroupManagerBean.java | 426 ++++++++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/LdapGroupManagerLocal.java | 53 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/LookupUtil.java | 6
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/authz/test/RoleManagerBeanTest.java | 5
13 files changed, 581 insertions(+), 444 deletions(-)
New commits:
commit 20fe0ece0175e24f2a8905c3a666011802decea5
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Tue Apr 27 18:44:32 2010 -0400
BZ 584355: i)refactored ldap auth classes to be more consitently defined.ii)modified exception handling.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/AddLdapGroupsAction.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/AddLdapGroupsAction.java
index fe91d46..036f8c1 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/AddLdapGroupsAction.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/AddLdapGroupsAction.java
@@ -35,13 +35,16 @@ import org.rhq.enterprise.gui.legacy.action.BaseAction;
import org.rhq.enterprise.gui.legacy.action.BaseValidatorForm;
import org.rhq.enterprise.gui.legacy.util.RequestUtils;
import org.rhq.enterprise.gui.legacy.util.SessionUtils;
-import org.rhq.enterprise.server.authz.RoleManagerLocal;
+import org.rhq.enterprise.server.resource.group.LdapGroupManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
/**
* An Action that adds resource groups for a role.
*/
public class AddLdapGroupsAction extends BaseAction {
+
+ LdapGroupManagerLocal ldapManager = LookupUtil.getLdapGroupManager();
+
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {
Log log = LogFactory.getLog(AddLdapGroupsAction.class.getName());
@@ -75,8 +78,7 @@ public class AddLdapGroupsAction extends BaseAction {
log.debug("adding group [" + id + "] for role [" + roleId + "]");
}
- RoleManagerLocal roleManager = LookupUtil.getRoleManager();
- roleManager.addLdapGroupsToRole(RequestUtils.getSubject(request), roleId, pendingGroupIds);
+ ldapManager.addLdapGroupsToRole(RequestUtils.getSubject(request), roleId, pendingGroupIds);
log.debug("removing pending group list");
SessionUtils.removeList(session, Constants.PENDING_RESGRPS_SES_ATTR);
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/AddLdapGroupsFormPrepareAction.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/AddLdapGroupsFormPrepareAction.java
index 39fe62e..6cbbfce 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/AddLdapGroupsFormPrepareAction.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/AddLdapGroupsFormPrepareAction.java
@@ -28,6 +28,7 @@ import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;
+import javax.ejb.EJBException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -55,7 +56,7 @@ import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.authz.RoleManagerLocal;
import org.rhq.enterprise.server.exception.LdapCommunicationException;
import org.rhq.enterprise.server.exception.LdapFilterException;
-import org.rhq.enterprise.server.resource.group.LdapGroupManager;
+import org.rhq.enterprise.server.resource.group.LdapGroupManagerLocal;
import org.rhq.enterprise.server.system.SystemManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -65,6 +66,9 @@ import org.rhq.enterprise.server.util.LookupUtil;
public class AddLdapGroupsFormPrepareAction extends TilesAction {
final String LDAP_GROUP_CACHE = "ldapGroupCache";
+ RoleManagerLocal roleManager = LookupUtil.getRoleManager();
+ LdapGroupManagerLocal ldapManager = LookupUtil.getLdapGroupManager();
+
public ActionForward execute(ComponentContext context, ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception {
Log log = LogFactory.getLog(AddLdapGroupsFormPrepareAction.class.getName());
@@ -111,16 +115,16 @@ public class AddLdapGroupsFormPrepareAction extends TilesAction {
try { //defend against ldap communication runtime difficulties.
if (cachedAvailableLdapGroups == null) {
- allGroups = LdapGroupManager.getInstance().findAvailableGroups();
+ // allGroups = LdapGroupManagerBean.getInstance().findAvailableGroups();
+ allGroups = ldapManager.findAvailableGroups();
} else {//reuse cached.
allGroups = cachedAvailableLdapGroups;
}
//store unmodified list in session.
cachedAvailableLdapGroups = allGroups;
- RoleManagerLocal roleManager = LookupUtil.getRoleManager();
//retrieve currently assigned groups
- assignedList = roleManager.findLdapGroupsByRole(role.getId(), PageControl.getUnlimitedInstance());
+ assignedList = ldapManager.findLdapGroupsByRole(role.getId(), PageControl.getUnlimitedInstance());
//trim already defined from all groups returned.
allGroups = filterExisting(assignedList, allGroups);
@@ -217,6 +221,30 @@ public class AddLdapGroupsFormPrepareAction extends TilesAction {
availableGroups.setTotalSize(groupLookup.size());
availableGroups.setPageControl(pca);
+ } catch (EJBException ejx) {
+ //this is the exception type thrown now that we use SLSB.Local methods
+ // mine out other exceptions
+ Exception cause = ejx.getCausedByException();
+ if (cause == null) {
+ ActionMessages actionMessages = new ActionMessages();
+ actionMessages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("errors.cam.general"));
+ saveErrors(request, actionMessages);
+ } else {
+ if (cause instanceof LdapFilterException) {
+ ActionMessages actionMessages = new ActionMessages();
+ actionMessages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
+ "admin.role.LdapGroupFilterMessage"));
+ saveErrors(request, actionMessages);
+ } else if (cause instanceof LdapCommunicationException) {
+ ActionMessages actionMessages = new ActionMessages();
+ SystemManagerLocal manager = LookupUtil.getSystemManager();
+ Properties options = manager.getSystemConfiguration();
+ String providerUrl = options.getProperty(RHQConstants.LDAPUrl, "(unavailable)");
+ actionMessages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
+ "admin.role.LdapCommunicationMessage", providerUrl));
+ saveErrors(request, actionMessages);
+ }
+ }
} catch (LdapFilterException lce) {
ActionMessages actionMessages = new ActionMessages();
actionMessages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("admin.role.LdapGroupFilterMessage"));
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/RemoveLdapGroupsAction.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/RemoveLdapGroupsAction.java
index fb359c6..48ab1c5 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/RemoveLdapGroupsAction.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/RemoveLdapGroupsAction.java
@@ -31,12 +31,16 @@ import org.rhq.core.util.collection.ArrayUtils;
import org.rhq.enterprise.gui.legacy.Constants;
import org.rhq.enterprise.gui.legacy.action.BaseAction;
import org.rhq.enterprise.gui.legacy.util.RequestUtils;
+import org.rhq.enterprise.server.resource.group.LdapGroupManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
/**
* An Action that retrieves data to facilitate display of the form for removing groups to a role.
*/
public class RemoveLdapGroupsAction extends BaseAction {
+
+ LdapGroupManagerLocal ldapManager = LookupUtil.getLdapGroupManager();
+
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {
Log log = LogFactory.getLog(RemoveLdapGroupsAction.class.getName());
@@ -46,7 +50,7 @@ public class RemoveLdapGroupsAction extends BaseAction {
int[] groupIds = ArrayUtils.unwrapArray(rmForm.getLdapGroups());
log.debug("removing groups " + groupIds + "] for role [" + roleId + "]");
- LookupUtil.getRoleManager().removeLdapGroupsFromRole(RequestUtils.getSubject(request), roleId, groupIds);
+ ldapManager.removeLdapGroupsFromRole(RequestUtils.getSubject(request), roleId, groupIds);
RequestUtils.setConfirmation(request, "admin.role.confirm.RemoveLdapGroups");
return returnSuccess(request, mapping, Constants.ROLE_PARAM, roleId);
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/ViewAction.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/ViewAction.java
index 3414dab..b2e884e 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/ViewAction.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/role/ViewAction.java
@@ -45,6 +45,7 @@ import org.rhq.enterprise.gui.legacy.action.WorkflowPrepareAction;
import org.rhq.enterprise.gui.legacy.util.RequestUtils;
import org.rhq.enterprise.gui.util.WebUtility;
import org.rhq.enterprise.server.authz.RoleManagerLocal;
+import org.rhq.enterprise.server.resource.group.LdapGroupManagerLocal;
import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -52,6 +53,11 @@ import org.rhq.enterprise.server.util.LookupUtil;
* An Action that retrieves a specific role. This is executed when you view a specific role.
*/
public class ViewAction extends WorkflowPrepareAction {
+
+ LdapGroupManagerLocal ldapManager = LookupUtil.getLdapGroupManager();
+ RoleManagerLocal roleManager = LookupUtil.getRoleManager();
+ ResourceGroupManagerLocal groupManager = LookupUtil.getResourceGroupManager();
+
/**
*/
public ActionForward workflow(ComponentContext context, ActionMapping mapping, ActionForm form,
@@ -75,8 +81,8 @@ public class ViewAction extends WorkflowPrepareAction {
log.trace("group page control: " + pcg);
log.trace("ldap group page control: " + pcldap);
- RoleManagerLocal roleManager = LookupUtil.getRoleManager();
- ResourceGroupManagerLocal groupManager = LookupUtil.getResourceGroupManager();
+ // RoleManagerLocal roleManager = LookupUtil.getRoleManager();
+ // ResourceGroupManagerLocal groupManager = LookupUtil.getResourceGroupManager();
// get all the role permissions
Set<Permission> permissions = roleManager.getPermissions(roleId);
@@ -91,6 +97,7 @@ public class ViewAction extends WorkflowPrepareAction {
// get the subjects attached to the role
log.trace("getting users for role [" + roleId + "]");
+ // PageList<Subject> users = roleManager.findSubjectsByRole(roleId, pcu);
PageList<Subject> users = roleManager.findSubjectsByRole(roleId, pcu);
request.setAttribute(Constants.ROLE_USERS_ATTR, users);
@@ -104,7 +111,7 @@ public class ViewAction extends WorkflowPrepareAction {
request.setAttribute(Constants.NUM_RESGRPS_ATTR, new Integer(groups.getTotalSize()));
}
- PageList<LdapGroup> ldapGroups = roleManager.findLdapGroupsByRole(roleId, pcldap);
+ PageList<LdapGroup> ldapGroups = ldapManager.findLdapGroupsByRole(roleId, pcldap);
request.setAttribute(Constants.ROLE_LDAPGRPS_ATTR, ldapGroups);
if (ldapGroups == null) {
request.setAttribute(Constants.NUM_LDAPGRPS_ATTR, new Integer(0));
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/user/RegisterAction.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/user/RegisterAction.java
index 9d4ec7a..91980ad 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/user/RegisterAction.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/admin/user/RegisterAction.java
@@ -23,6 +23,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Properties;
+import javax.ejb.EJBException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@@ -44,10 +45,9 @@ import org.rhq.enterprise.gui.legacy.util.RequestUtils;
import org.rhq.enterprise.gui.legacy.util.SessionUtils;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
-import org.rhq.enterprise.server.authz.RoleManagerLocal;
import org.rhq.enterprise.server.exception.LdapCommunicationException;
import org.rhq.enterprise.server.exception.LdapFilterException;
-import org.rhq.enterprise.server.resource.group.LdapGroupManager;
+import org.rhq.enterprise.server.resource.group.LdapGroupManagerLocal;
import org.rhq.enterprise.server.system.SystemManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -55,6 +55,11 @@ import org.rhq.enterprise.server.util.LookupUtil;
* Registers a user. Triggered when authenticated via LDAP.
*/
public class RegisterAction extends BaseAction {
+
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+ SystemManagerLocal systemManager = LookupUtil.getSystemManager();
+ LdapGroupManagerLocal ldapManager = LookupUtil.getLdapGroupManager();
+
/**
* Create the user with the attributes specified in the given <code>NewForm</code> and save it into the session
* attribute <code>Constants.USER_ATTR</code>.
@@ -96,7 +101,6 @@ public class RegisterAction extends BaseAction {
String password = (String) session.getAttribute(Constants.PASSWORD_SES_ATTR);
session.removeAttribute(Constants.PASSWORD_SES_ATTR);
- SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
Subject superuser = subjectManager.getOverlord();
// create the subject, but don't add a principal since LDAP will handle authentication
@@ -118,8 +122,7 @@ public class RegisterAction extends BaseAction {
parms.put(Constants.USER_PARAM, newSubject.getId());
//BZ-580127: only do group authz check if one or both of group filter fields is set
- SystemManagerLocal manager = LookupUtil.getSystemManager();
- Properties options = manager.getSystemConfiguration();
+ Properties options = systemManager.getSystemConfiguration();
String groupFilter = (String) options.getProperty(RHQConstants.LDAPGroupFilter, "");
String groupMember = (String) options.getProperty(RHQConstants.LDAPGroupMember, "");
if ((groupFilter.trim().length() > 0) || (groupMember.trim().length() > 0)) {
@@ -127,11 +130,32 @@ public class RegisterAction extends BaseAction {
String provider = LookupUtil.getSystemManager().getSystemConfiguration().getProperty(
RHQConstants.JAASProvider);
if (RHQConstants.LDAPJAASProvider.equals(provider)) {
- List<String> groupNames = new ArrayList(LdapGroupManager.getInstance().findAvailableGroupsFor(
- newSubject.getName()));
- RoleManagerLocal roleManager = LookupUtil.getRoleManager();
- roleManager.assignRolesToLdapSubject(newSubject.getId(), groupNames);
-
+ List<String> groupNames = new ArrayList(ldapManager.findAvailableGroupsFor(newSubject.getName()));
+ ldapManager.assignRolesToLdapSubject(newSubject.getId(), groupNames);
+ }
+ } catch (EJBException ejx) {
+ //this is the exception type thrown now that we use SLSB.Local methods
+ // mine out other exceptions
+ Exception cause = ejx.getCausedByException();
+ if (cause == null) {
+ ActionMessages actionMessages = new ActionMessages();
+ actionMessages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("errors.cam.general"));
+ saveErrors(request, actionMessages);
+ } else {
+ if (cause instanceof LdapFilterException) {
+ ActionMessages actionMessages = new ActionMessages();
+ actionMessages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
+ "admin.role.LdapGroupFilterMessage"));
+ saveErrors(request, actionMessages);
+ } else if (cause instanceof LdapCommunicationException) {
+ ActionMessages actionMessages = new ActionMessages();
+ SystemManagerLocal manager = LookupUtil.getSystemManager();
+ options = manager.getSystemConfiguration();
+ String providerUrl = options.getProperty(RHQConstants.LDAPUrl, "(unavailable)");
+ actionMessages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
+ "admin.role.LdapCommunicationMessage", providerUrl));
+ saveErrors(request, actionMessages);
+ }
}
} catch (LdapFilterException lce) {
ActionMessages actionMessages = new ActionMessages();
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/RoleManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/RoleManagerBean.java
index 8e4d96e..00d4c31 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/RoleManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/RoleManagerBean.java
@@ -20,9 +20,7 @@ package org.rhq.enterprise.server.authz;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashSet;
-import java.util.LinkedList;
import java.util.List;
import java.util.Set;
@@ -40,7 +38,6 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.authz.Role;
import org.rhq.core.domain.criteria.RoleCriteria;
-import org.rhq.core.domain.resource.group.LdapGroup;
import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
@@ -91,29 +88,6 @@ public class RoleManagerBean implements RoleManagerLocal, RoleManagerRemote {
return roles;
}
- @Override
- public PageList<LdapGroup> findLdapGroupsByRole(int roleId, PageControl pageControl) {
- Role role = entityManager.find(Role.class, roleId);
- if (role == null) {
- throw new IllegalArgumentException("Could not find role[" + roleId + "] to lookup ldap Groups on");
- }
- return new PageList<LdapGroup>(role.getLdapGroups(), role.getLdapGroups().size(), pageControl);
- }
-
- public PageList<LdapGroup> findLdapGroups(PageControl pc) {
-
- pc.initDefaultOrderingField("g.name");
-
- String queryName = LdapGroup.QUERY_FIND_ALL;
- Query queryCount = PersistenceUtility.createCountQuery(entityManager, queryName);
- Query query = PersistenceUtility.createQueryWithOrderBy(entityManager, queryName, pc);
-
- long count = (Long) queryCount.getSingleResult();
- // List<Role> roles = query.getResultList();
- List<LdapGroup> groups = query.getResultList();
- return new PageList<LdapGroup>(groups, (int) count, pc);
- }
-
/**
* @see org.rhq.enterprise.server.authz.RoleManagerLocal#findRoles(PageControl)
*/
@@ -466,83 +440,6 @@ public class RoleManagerBean implements RoleManagerLocal, RoleManagerRemote {
}
}
- /**
- * @see org.rhq.enterprise.server.authz.RoleManagerLocal#addResourceGroupsToRole(Subject, int, int[])
- */
- @RequiredPermission(Permission.MANAGE_SECURITY)
- public void addLdapGroupsToRole(Subject subject, int roleId, List<String> groupIds) {
- if ((groupIds != null) && (groupIds.size() > 0)) {
- Role role = entityManager.find(Role.class, roleId);
- if (role == null) {
- throw new IllegalArgumentException("Could not find role[" + roleId + "] to add resourceGroups to");
- }
- role.getLdapGroups().size(); // load them in
-
- for (String groupId : groupIds) {
- LdapGroup group = new LdapGroup();
- group.setName(groupId);
- if (role == null) {
- throw new IllegalArgumentException("Tried to add ldapGroup[" + groupId + "] to role[" + roleId
- + "], but resourceGroup was not found");
- }
- role.addLdapGroup(group);
- }
- }
- }
-
- /**
- * @see org.rhq.enterprise.server.authz.RoleManagerLocal#removeLdapGroupsFromRole(Subject, int, int[])
- */
-
- @RequiredPermission(Permission.MANAGE_SECURITY)
- public void removeLdapGroupsFromRole(Subject subject, int roleId, int[] groupIds) {
- if ((groupIds != null) && (groupIds.length > 0)) {
- Role role = entityManager.find(Role.class, roleId);
- if (role == null) {
- throw new IllegalArgumentException("Could not find role[" + roleId + "] to remove resourceGroups from");
- }
- role.getLdapGroups().size(); // load them in
-
- for (Integer groupId : groupIds) {
- LdapGroup doomedGroup = entityManager.find(LdapGroup.class, groupId);
- if (doomedGroup == null) {
- throw new IllegalArgumentException("Tried to remove doomedGroup[" + groupId + "] from role["
- + roleId + "], but subject was not found");
- }
- role.removeLdapGroup(doomedGroup);
- }
-
- Query purgeQuery = entityManager.createNamedQuery(LdapGroup.DELETE_BY_ID);
-
- List<Integer> ids = new LinkedList<Integer>();
- for (int i : groupIds) {
- ids.add(i);
- }
- purgeQuery.setParameter("ids", ids);
- purgeQuery.executeUpdate();
- }
- }
-
- private List<Role> findRolesByLdapGroupNames(List<String> ldapGroupNames) {
- if (ldapGroupNames.isEmpty()) {
- return Collections.EMPTY_LIST;
- }
- Query query = entityManager.createNamedQuery(LdapGroup.FIND_BY_ROLES_GROUP_NAMES);
- query.setParameter("names", ldapGroupNames);
- return (List<Role>) query.getResultList();
- }
-
- public void assignRolesToLdapSubject(int subjectId, List<String> ldapGroupNames) {
- Subject sub = entityManager.find(Subject.class, subjectId);
- List<Role> roles = findRolesByLdapGroupNames(ldapGroupNames);
- sub.getRoles().clear();
- sub.getLdapRoles().clear();
- for (Role role : roles) {
- sub.addRole(role);
- sub.addLdapRole(role);
- }
- }
-
private void processDependentPermissions(Role role) {
/*
* if you can control user/roles, then you can give yourself permissions, too; so we might as well
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/RoleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/RoleManagerLocal.java
index b89020f..58f962a 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/RoleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/RoleManagerLocal.java
@@ -18,7 +18,6 @@
*/
package org.rhq.enterprise.server.authz;
-import java.util.List;
import java.util.Set;
import javax.ejb.Local;
@@ -27,7 +26,6 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.authz.Role;
import org.rhq.core.domain.criteria.RoleCriteria;
-import org.rhq.core.domain.resource.group.LdapGroup;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
@@ -161,8 +159,6 @@ public interface RoleManagerLocal {
Role getRole(Subject subject, int roleId);
- PageList<LdapGroup> findLdapGroupsByRole(int roleId, PageControl pageControl);
-
PageList<Role> findSubjectAssignedRoles(Subject subject, int subjectId, PageControl pc);
//This is a proxy of getAvailableRolesForSubject but without pendingRoleIds as required by remote spec
@@ -202,8 +198,6 @@ public interface RoleManagerLocal {
void addRolesToResourceGroup(Subject subject, int groupId, int[] roleIds);
- void addLdapGroupsToRole(Subject subject, int roleId, List<String> groupIds);
-
/**
* Removes the given resource groups from the given role.
*
@@ -215,11 +209,6 @@ public interface RoleManagerLocal {
void removeRolesFromResourceGroup(Subject subject, int groupId, int[] roleIds);
- void removeLdapGroupsFromRole(Subject subject, int roleId, int[] groupIds);
-
PageList<Role> findRolesByCriteria(Subject subject, RoleCriteria criteria);
- void assignRolesToLdapSubject(int subjectId, List<String> ldapGroupNames);
-
- PageList<LdapGroup> findLdapGroups(PageControl pc);
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/jaas/LdapLoginModule.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/jaas/LdapLoginModule.java
index d6fcaa7..d6e6ae8 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/jaas/LdapLoginModule.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/core/jaas/LdapLoginModule.java
@@ -45,7 +45,7 @@ import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.authz.RoleManagerLocal;
-import org.rhq.enterprise.server.resource.group.LdapGroupManager;
+import org.rhq.enterprise.server.resource.group.LdapGroupManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
import org.rhq.enterprise.server.util.security.UntrustedSSLSocketFactory;
@@ -94,6 +94,8 @@ import org.rhq.enterprise.server.util.security.UntrustedSSLSocketFactory;
public class LdapLoginModule extends UsernamePasswordLoginModule {
private Log log = LogFactory.getLog(LdapLoginModule.class);
+ LdapGroupManagerLocal ldapManager = LookupUtil.getLdapGroupManager();
+
// The delimimiter to use when specifiying multiple BaseDN's.
private static final String BASEDN_DELIMITER = ";";
@@ -218,11 +220,11 @@ public class LdapLoginModule extends UsernamePasswordLoginModule {
//BUT still must always return true as authz is handled by RHQ if roles/groups correct
//retrieve all ldap groups that this user is authorized for based on ldap group filter and group member settings
- Set<String> authorizedLdapGroups = LdapGroupManager.getInstance().findAvailableGroupsFor(userName);
+ Set<String> authorizedLdapGroups = ldapManager.findAvailableGroupsFor(userName);
RoleManagerLocal roleManager = LookupUtil.getRoleManager();
//find all currently mapped ldap groups
- PageList<LdapGroup> allCurrentLdapGroupsRegistered = roleManager.findLdapGroups(PageControl
+ PageList<LdapGroup> allCurrentLdapGroupsRegistered = ldapManager.findLdapGroups(PageControl
.getUnlimitedInstance());
//find all roles for currently mapped ldap groups.
@@ -239,7 +241,7 @@ public class LdapLoginModule extends UsernamePasswordLoginModule {
//else add this subject back to all AuthoriziedLdapGroups
//lookup all roles that map to the authorizedLdapGroup names
List authorizedList = new ArrayList(authorizedLdapGroups);
- roleManager.assignRolesToLdapSubject(ldapSubject.getId(), authorizedList);
+ ldapManager.assignRolesToLdapSubject(ldapSubject.getId(), authorizedList);
}
return true;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/LdapGroupManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/LdapGroupManager.java
deleted file mode 100644
index e372777..0000000
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/LdapGroupManager.java
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2009 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.resource.group;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import javax.naming.Context;
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.directory.Attribute;
-import javax.naming.directory.InvalidSearchFilterException;
-import javax.naming.directory.SearchControls;
-import javax.naming.directory.SearchResult;
-import javax.naming.ldap.InitialLdapContext;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.rhq.enterprise.server.RHQConstants;
-import org.rhq.enterprise.server.exception.LdapCommunicationException;
-import org.rhq.enterprise.server.exception.LdapFilterException;
-import org.rhq.enterprise.server.system.SystemManagerLocal;
-import org.rhq.enterprise.server.util.LookupUtil;
-import org.rhq.enterprise.server.util.security.UntrustedSSLSocketFactory;
-
-/**
- * @author paji
- */
-public class LdapGroupManager {
- private static final LdapGroupManager INSTANCE = new LdapGroupManager();
- private static final String BASEDN_DELIMITER = ";";
- private Log log = LogFactory.getLog(LdapGroupManager.class);
-
- private LdapGroupManager() {
- }
-
- public static LdapGroupManager getInstance() {
- return INSTANCE;
- }
-
- public Set<Map<String, String>> findAvailableGroups() {
- SystemManagerLocal manager = LookupUtil.getSystemManager();
-
- Properties options = manager.getSystemConfiguration();
- String groupFilter = (String) options.get(RHQConstants.LDAPGroupFilter);
- String filter = String.format("(%s)", groupFilter);
-
- return buildGroup(options, filter);
- }
-
- public Set<String> findAvailableGroupsFor(String userName) {
- SystemManagerLocal manager = LookupUtil.getSystemManager();
- Properties options = manager.getSystemConfiguration();
- String groupFilter = (String) options.getProperty(RHQConstants.LDAPGroupFilter, "");
- String groupMember = (String) options.getProperty(RHQConstants.LDAPGroupMember, "");
- String userDN = getUserDN(options, userName);
- //TODO: spinder 4/21/10 put in error/debug logging messages for badly formatted filter combinations
- String filter = "";
- //form assumes examples where groupFilter is like 'objecclass=groupOfNames' and groupMember is 'member'
- // to produce ldaf filter like (&(objecclass=groupOfNames)(member=cn=Administrator,ou=People,dc=test,dc=com))
- filter = String.format("(&(%s)(%s=%s))", groupFilter, groupMember, userDN);
-
- Set<Map<String, String>> matched = buildGroup(options, filter);
-
- Set<String> ldapSet = new HashSet<String>();
- for (Map<String, String> match : matched) {
- ldapSet.add(match.get("id"));
- }
- return ldapSet;
- }
-
- private String getUserDN(Properties options, String userName) {
- // Load our LDAP specific properties
- Properties env = getProperties(options);
-
- // Load the BaseDN
- // Load the BaseDN
- String baseDN = (String) options.get(RHQConstants.LDAPBaseDN);
-
- // Load the LoginProperty
- String loginProperty = (String) options.get(RHQConstants.LDAPLoginProperty);
- if (loginProperty == null) {
- // Use the default
- loginProperty = "cn";
- }
- // Load any information we may need to bind
- String bindDN = (String) options.get(RHQConstants.LDAPBindDN);
- String bindPW = (String) options.get(RHQConstants.LDAPBindPW);
-
- // Load any search filter
- String searchFilter = (String) options.get(RHQConstants.LDAPFilter);
- if (bindDN != null) {
- env.setProperty(Context.SECURITY_PRINCIPAL, bindDN);
- env.setProperty(Context.SECURITY_CREDENTIALS, bindPW);
- env.setProperty(Context.SECURITY_AUTHENTICATION, "simple");
- }
-
- try {
- InitialLdapContext ctx = new InitialLdapContext(env, null);
- SearchControls searchControls = getSearchControls();
-
- // Add the search filter if specified. This only allows for a single search filter.. i.e. foo=bar.
- String filter;
- if ((searchFilter != null) && (searchFilter.length() != 0)) {
- filter = "(&(" + loginProperty + "=" + userName + ")" + "(" + searchFilter + "))";
- } else {
- filter = "(" + loginProperty + "=" + userName + ")";
- }
-
- log.debug("Using LDAP filter=" + filter);
-
- // Loop through each configured base DN. It may be useful
- // in the future to allow for a filter to be configured for
- // each BaseDN, but for now the filter will apply to all.
- String[] baseDNs = baseDN.split(BASEDN_DELIMITER);
- for (int x = 0; x < baseDNs.length; x++) {
- NamingEnumeration answer = ctx.search(baseDNs[x], filter, searchControls);
- if (!answer.hasMoreElements()) { //BZ:582471- ldap api bug change
- log.debug("User " + userName + " not found for BaseDN " + baseDNs[x]);
- // Nothing found for this DN, move to the next one if we have one.
- continue;
- }
-
- // We use the first match
- SearchResult si = (SearchResult) answer.next();
-
- // Construct the UserDN
- String userDN = si.getName() + "," + baseDNs[x];
- return userDN;
- }
-
- // If we try all the BaseDN's and have not found a match, return false
- return "";
- } catch (NamingException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * @throws NamingException
- * @see org.jboss.security.auth.spi.UsernamePasswordLoginModule#validatePassword(java.lang.String,java.lang.String)
- */
- protected Set<Map<String, String>> buildGroup(Properties options, String filter) {
- Set<Map<String, String>> ret = new HashSet<Map<String, String>>();
- // Load our LDAP specific properties
- Properties env = getProperties(options);
-
- // Load the BaseDN
- String baseDN = (String) options.get(RHQConstants.LDAPBaseDN);
-
- // Load the LoginProperty
- String loginProperty = (String) options.get(RHQConstants.LDAPLoginProperty);
- if (loginProperty == null) {
- // Use the default
- loginProperty = "cn";
- }
- // Load any information we may need to bind
- String bindDN = (String) options.get(RHQConstants.LDAPBindDN);
- String bindPW = (String) options.get(RHQConstants.LDAPBindPW);
- if (bindDN != null) {
- env.setProperty(Context.SECURITY_PRINCIPAL, bindDN);
- env.setProperty(Context.SECURITY_CREDENTIALS, bindPW);
- env.setProperty(Context.SECURITY_AUTHENTICATION, "simple");
- }
- try {
- InitialLdapContext ctx = new InitialLdapContext(env, null);
- SearchControls searchControls = getSearchControls();
- /*String filter = "(&(objectclass=groupOfUniqueNames)(uniqueMember=uid=" + userName
- + ",ou=People, dc=rhndev, dc=redhat, dc=com))";*/
-
- // Loop through each configured base DN. It may be useful
- // in the future to allow for a filter to be configured for
- // each BaseDN, but for now the filter will apply to all.
- String[] baseDNs = baseDN.split(BASEDN_DELIMITER);
-
- for (int x = 0; x < baseDNs.length; x++) {
- NamingEnumeration answer = ctx.search(baseDNs[x], filter, searchControls);
- boolean ldapApiEnumerationBugEncountered = false;
- while ((!ldapApiEnumerationBugEncountered) && answer.hasMoreElements()) {//BZ:582471- ldap api bug change
- // We use the first match
- SearchResult si = null;
- try {
- si = (SearchResult) answer.next();
- } catch (NullPointerException npe) {
- ldapApiEnumerationBugEncountered = true;
- break;
- }
- Map<String, String> entry = new HashMap<String, String>();
- String name = (String) si.getAttributes().get("cn").get();
- name = name.trim();
- Attribute desc = si.getAttributes().get("description");
- String description = desc != null ? (String) desc.get() : "";
- description = description.trim();
- entry.put("id", name);
- entry.put("name", name);
- entry.put("description", description);
- ret.add(entry);
- }
- }
- } catch (NamingException e) {
- if (e instanceof InvalidSearchFilterException) {
- InvalidSearchFilterException fException = (InvalidSearchFilterException) e;
- String message = "The ldap group filter defined is invalid ";
- log.error(message, fException);
- throw new LdapFilterException(message + " " + fException.getMessage());
- }
- //TODO: check for ldap connection/unavailable/etc. exceptions.
- else {
- log.error("LDAP communication error: " + e.getMessage(), e);
- throw new LdapCommunicationException(e);
- }
- }
-
- return ret;
- }
-
- /**
- * Load a default set of properties to use when connecting to the LDAP server. If basic authentication is needed,
- * the caller must set Context.SECURITY_PRINCIPAL, Context.SECURITY_CREDENTIALS and Context.SECURITY_AUTHENTICATION
- * appropriately.
- *
- * @return properties that are to be used when connecting to LDAP server
- */
- private Properties getProperties(Properties options) {
- Properties env = new Properties(options);
- // Set our default factory name if one is not given
- String factoryName = env.getProperty(RHQConstants.LDAPFactory);
- env.setProperty(Context.INITIAL_CONTEXT_FACTORY, factoryName);
-
- // Setup SSL if requested
- String protocol = env.getProperty(RHQConstants.LDAPProtocol);
- if ((protocol != null) && protocol.equals("ssl")) {
- String ldapSocketFactory = env.getProperty("java.naming.ldap.factory.socket");
- if (ldapSocketFactory == null) {
- env.put("java.naming.ldap.factory.socket", UntrustedSSLSocketFactory.class.getName());
- }
- env.put(Context.SECURITY_PROTOCOL, "ssl");
- }
-
- // Set the LDAP url
- String providerUrl = env.getProperty(RHQConstants.LDAPUrl);
- if (providerUrl == null) {
- providerUrl = "ldap://localhost:" + (((protocol != null) && protocol.equals("ssl")) ? "636" : "389");
- }
-
- env.setProperty(Context.PROVIDER_URL, providerUrl);
-
- // Follow referrals automatically
- env.setProperty(Context.REFERRAL, "ignore"); //BZ:582471- active directory query change
-
- return env;
- }
-
- /**
- * A simple method to construct a SearchControls object for use when doing LDAP searches. All of the defaults are
- * used, with the exception of the scope, which is set to SUBTREE rather than the default of ONE_LEVEL
- *
- * @return controls what is searched in LDAP
- */
- private SearchControls getSearchControls() {
- // Set the scope to subtree, default is one-level
- int scope = SearchControls.SUBTREE_SCOPE;
-
- // No limit on the time waiting for a response
- int timeLimit = 0;
-
- // No limit on the number of entries returned
- long countLimit = 0;
-
- // Attributes to return.
- String[] returnedAttributes = null;
-
- // Don't return the object
- boolean returnObject = false;
-
- // No dereferencing during the search
- boolean deference = false;
-
- SearchControls constraints = new SearchControls(scope, countLimit, timeLimit, returnedAttributes, returnObject,
- deference);
- return constraints;
- }
-}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/LdapGroupManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/LdapGroupManagerBean.java
new file mode 100644
index 0000000..63e36db
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/LdapGroupManagerBean.java
@@ -0,0 +1,426 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2009 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.resource.group;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.ejb.EJB;
+import javax.ejb.Stateless;
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.InvalidSearchFilterException;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.InitialLdapContext;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.authz.Permission;
+import org.rhq.core.domain.authz.Role;
+import org.rhq.core.domain.resource.group.LdapGroup;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.core.server.PersistenceUtility;
+import org.rhq.enterprise.server.RHQConstants;
+import org.rhq.enterprise.server.auth.SubjectManagerLocal;
+import org.rhq.enterprise.server.authz.RequiredPermission;
+import org.rhq.enterprise.server.exception.LdapCommunicationException;
+import org.rhq.enterprise.server.exception.LdapFilterException;
+import org.rhq.enterprise.server.system.SystemManagerLocal;
+import org.rhq.enterprise.server.util.security.UntrustedSSLSocketFactory;
+
+/**
+ * This bean provides functionality to manipulate the ldap auth/authz funcitonality.
+ * That is, adding/modifying/deleting ldap group/users and their
+ * associated subjects and permissions are performed by this manager.
+ * @author paji
+ * @author Simeon Pinder
+ */
+@Stateless
+public class LdapGroupManagerBean implements LdapGroupManagerLocal {
+
+ // private static final LdapGroupManagerBean INSTANCE = new LdapGroupManagerBean();
+ private Log log = LogFactory.getLog(LdapGroupManagerBean.class);
+
+ private static final String BASEDN_DELIMITER = ";";
+
+ @PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
+ private EntityManager entityManager;
+
+ @EJB
+ private SubjectManagerLocal subjectManager;
+
+ @EJB
+ private SystemManagerLocal systemManager;
+
+ public Set<Map<String, String>> findAvailableGroups() {
+ Properties options = systemManager.getSystemConfiguration();
+ String groupFilter = (String) options.get(RHQConstants.LDAPGroupFilter);
+ String filter = String.format("(%s)", groupFilter);
+
+ return buildGroup(options, filter);
+ }
+
+ public Set<String> findAvailableGroupsFor(String userName) {
+ Properties options = systemManager.getSystemConfiguration();
+ String groupFilter = (String) options.getProperty(RHQConstants.LDAPGroupFilter, "");
+ String groupMember = (String) options.getProperty(RHQConstants.LDAPGroupMember, "");
+ String userDN = getUserDN(options, userName);
+ //TODO: spinder 4/21/10 put in error/debug logging messages for badly formatted filter combinations
+ String filter = "";
+ //form assumes examples where groupFilter is like 'objecclass=groupOfNames' and groupMember is 'member'
+ // to produce ldaf filter like (&(objecclass=groupOfNames)(member=cn=Administrator,ou=People,dc=test,dc=com))
+ filter = String.format("(&(%s)(%s=%s))", groupFilter, groupMember, userDN);
+
+ Set<Map<String, String>> matched = buildGroup(options, filter);
+
+ Set<String> ldapSet = new HashSet<String>();
+ for (Map<String, String> match : matched) {
+ ldapSet.add(match.get("id"));
+ }
+ return ldapSet;
+ }
+
+ /**
+ * @see org.rhq.enterprise.server.authz.RoleManagerLocal#addResourceGroupsToRole(Subject, int, int[])
+ */
+ @RequiredPermission(Permission.MANAGE_SECURITY)
+ public void addLdapGroupsToRole(Subject subject, int roleId, List<String> groupIds) {
+ if ((groupIds != null) && (groupIds.size() > 0)) {
+ Role role = entityManager.find(Role.class, roleId);
+ if (role == null) {
+ throw new IllegalArgumentException("Could not find role[" + roleId + "] to add resourceGroups to");
+ }
+ role.getLdapGroups().size(); // load them in
+
+ for (String groupId : groupIds) {
+ LdapGroup group = new LdapGroup();
+ group.setName(groupId);
+ if (role == null) {
+ throw new IllegalArgumentException("Tried to add ldapGroup[" + groupId + "] to role[" + roleId
+ + "], but resourceGroup was not found");
+ }
+ role.addLdapGroup(group);
+ }
+ }
+ }
+
+ /**
+ * @see org.rhq.enterprise.server.authz.RoleManagerLocal#removeLdapGroupsFromRole(Subject, int, int[])
+ */
+
+ @RequiredPermission(Permission.MANAGE_SECURITY)
+ public void removeLdapGroupsFromRole(Subject subject, int roleId, int[] groupIds) {
+ if ((groupIds != null) && (groupIds.length > 0)) {
+ Role role = entityManager.find(Role.class, roleId);
+ if (role == null) {
+ throw new IllegalArgumentException("Could not find role[" + roleId + "] to remove resourceGroups from");
+ }
+ role.getLdapGroups().size(); // load them in
+
+ for (Integer groupId : groupIds) {
+ LdapGroup doomedGroup = entityManager.find(LdapGroup.class, groupId);
+ if (doomedGroup == null) {
+ throw new IllegalArgumentException("Tried to remove doomedGroup[" + groupId + "] from role["
+ + roleId + "], but subject was not found");
+ }
+ role.removeLdapGroup(doomedGroup);
+ }
+
+ Query purgeQuery = entityManager.createNamedQuery(LdapGroup.DELETE_BY_ID);
+
+ List<Integer> ids = new LinkedList<Integer>();
+ for (int i : groupIds) {
+ ids.add(i);
+ }
+ purgeQuery.setParameter("ids", ids);
+ purgeQuery.executeUpdate();
+ }
+ }
+
+ private List<Role> findRolesByLdapGroupNames(List<String> ldapGroupNames) {
+ if (ldapGroupNames.isEmpty()) {
+ return Collections.EMPTY_LIST;
+ }
+ Query query = entityManager.createNamedQuery(LdapGroup.FIND_BY_ROLES_GROUP_NAMES);
+ query.setParameter("names", ldapGroupNames);
+ return (List<Role>) query.getResultList();
+ }
+
+ public void assignRolesToLdapSubject(int subjectId, List<String> ldapGroupNames) {
+ Subject sub = entityManager.find(Subject.class, subjectId);
+ List<Role> roles = findRolesByLdapGroupNames(ldapGroupNames);
+ sub.getRoles().clear();
+ sub.getLdapRoles().clear();
+ for (Role role : roles) {
+ sub.addRole(role);
+ sub.addLdapRole(role);
+ }
+ }
+
+ @Override
+ public PageList<LdapGroup> findLdapGroupsByRole(int roleId, PageControl pageControl) {
+ Role role = entityManager.find(Role.class, roleId);
+ if (role == null) {
+ throw new IllegalArgumentException("Could not find role[" + roleId + "] to lookup ldap Groups on");
+ }
+ return new PageList<LdapGroup>(role.getLdapGroups(), role.getLdapGroups().size(), pageControl);
+ }
+
+ public PageList<LdapGroup> findLdapGroups(PageControl pc) {
+
+ pc.initDefaultOrderingField("g.name");
+
+ String queryName = LdapGroup.QUERY_FIND_ALL;
+ Query queryCount = PersistenceUtility.createCountQuery(entityManager, queryName);
+ Query query = PersistenceUtility.createQueryWithOrderBy(entityManager, queryName, pc);
+
+ long count = (Long) queryCount.getSingleResult();
+ // List<Role> roles = query.getResultList();
+ List<LdapGroup> groups = query.getResultList();
+ return new PageList<LdapGroup>(groups, (int) count, pc);
+ }
+
+ private String getUserDN(Properties options, String userName) {
+ // Load our LDAP specific properties
+ Properties env = getProperties(options);
+
+ // Load the BaseDN
+ // Load the BaseDN
+ String baseDN = (String) options.get(RHQConstants.LDAPBaseDN);
+
+ // Load the LoginProperty
+ String loginProperty = (String) options.get(RHQConstants.LDAPLoginProperty);
+ if (loginProperty == null) {
+ // Use the default
+ loginProperty = "cn";
+ }
+ // Load any information we may need to bind
+ String bindDN = (String) options.get(RHQConstants.LDAPBindDN);
+ String bindPW = (String) options.get(RHQConstants.LDAPBindPW);
+
+ // Load any search filter
+ String searchFilter = (String) options.get(RHQConstants.LDAPFilter);
+ if (bindDN != null) {
+ env.setProperty(Context.SECURITY_PRINCIPAL, bindDN);
+ env.setProperty(Context.SECURITY_CREDENTIALS, bindPW);
+ env.setProperty(Context.SECURITY_AUTHENTICATION, "simple");
+ }
+
+ try {
+ InitialLdapContext ctx = new InitialLdapContext(env, null);
+ SearchControls searchControls = getSearchControls();
+
+ // Add the search filter if specified. This only allows for a single search filter.. i.e. foo=bar.
+ String filter;
+ if ((searchFilter != null) && (searchFilter.length() != 0)) {
+ filter = "(&(" + loginProperty + "=" + userName + ")" + "(" + searchFilter + "))";
+ } else {
+ filter = "(" + loginProperty + "=" + userName + ")";
+ }
+
+ log.debug("Using LDAP filter=" + filter);
+
+ // Loop through each configured base DN. It may be useful
+ // in the future to allow for a filter to be configured for
+ // each BaseDN, but for now the filter will apply to all.
+ String[] baseDNs = baseDN.split(BASEDN_DELIMITER);
+ for (int x = 0; x < baseDNs.length; x++) {
+ NamingEnumeration answer = ctx.search(baseDNs[x], filter, searchControls);
+ if (!answer.hasMoreElements()) { //BZ:582471- ldap api bug change
+ log.debug("User " + userName + " not found for BaseDN " + baseDNs[x]);
+ // Nothing found for this DN, move to the next one if we have one.
+ continue;
+ }
+
+ // We use the first match
+ SearchResult si = (SearchResult) answer.next();
+
+ // Construct the UserDN
+ String userDN = si.getName() + "," + baseDNs[x];
+ return userDN;
+ }
+
+ // If we try all the BaseDN's and have not found a match, return false
+ return "";
+ } catch (NamingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * @throws NamingException
+ * @see org.jboss.security.auth.spi.UsernamePasswordLoginModule#validatePassword(java.lang.String,java.lang.String)
+ */
+ protected Set<Map<String, String>> buildGroup(Properties options, String filter) {
+ Set<Map<String, String>> ret = new HashSet<Map<String, String>>();
+ // Load our LDAP specific properties
+ Properties env = getProperties(options);
+
+ // Load the BaseDN
+ String baseDN = (String) options.get(RHQConstants.LDAPBaseDN);
+
+ // Load the LoginProperty
+ String loginProperty = (String) options.get(RHQConstants.LDAPLoginProperty);
+ if (loginProperty == null) {
+ // Use the default
+ loginProperty = "cn";
+ }
+ // Load any information we may need to bind
+ String bindDN = (String) options.get(RHQConstants.LDAPBindDN);
+ String bindPW = (String) options.get(RHQConstants.LDAPBindPW);
+ if (bindDN != null) {
+ env.setProperty(Context.SECURITY_PRINCIPAL, bindDN);
+ env.setProperty(Context.SECURITY_CREDENTIALS, bindPW);
+ env.setProperty(Context.SECURITY_AUTHENTICATION, "simple");
+ }
+ try {
+ InitialLdapContext ctx = new InitialLdapContext(env, null);
+ SearchControls searchControls = getSearchControls();
+ /*String filter = "(&(objectclass=groupOfUniqueNames)(uniqueMember=uid=" + userName
+ + ",ou=People, dc=rhndev, dc=redhat, dc=com))";*/
+
+ // Loop through each configured base DN. It may be useful
+ // in the future to allow for a filter to be configured for
+ // each BaseDN, but for now the filter will apply to all.
+ String[] baseDNs = baseDN.split(BASEDN_DELIMITER);
+
+ for (int x = 0; x < baseDNs.length; x++) {
+ NamingEnumeration answer = ctx.search(baseDNs[x], filter, searchControls);
+ boolean ldapApiEnumerationBugEncountered = false;
+ while ((!ldapApiEnumerationBugEncountered) && answer.hasMoreElements()) {//BZ:582471- ldap api bug change
+ // We use the first match
+ SearchResult si = null;
+ try {
+ si = (SearchResult) answer.next();
+ } catch (NullPointerException npe) {
+ ldapApiEnumerationBugEncountered = true;
+ break;
+ }
+ Map<String, String> entry = new HashMap<String, String>();
+ String name = (String) si.getAttributes().get("cn").get();
+ name = name.trim();
+ Attribute desc = si.getAttributes().get("description");
+ String description = desc != null ? (String) desc.get() : "";
+ description = description.trim();
+ entry.put("id", name);
+ entry.put("name", name);
+ entry.put("description", description);
+ ret.add(entry);
+ }
+ }
+ } catch (NamingException e) {
+ if (e instanceof InvalidSearchFilterException) {
+ InvalidSearchFilterException fException = (InvalidSearchFilterException) e;
+ String message = "The ldap group filter defined is invalid ";
+ log.error(message, fException);
+ throw new LdapFilterException(message + " " + fException.getMessage());
+ }
+ //TODO: check for ldap connection/unavailable/etc. exceptions.
+ else {
+ log.error("LDAP communication error: " + e.getMessage(), e);
+ throw new LdapCommunicationException(e);
+ }
+ }
+
+ return ret;
+ }
+
+ /**
+ * Load a default set of properties to use when connecting to the LDAP server. If basic authentication is needed,
+ * the caller must set Context.SECURITY_PRINCIPAL, Context.SECURITY_CREDENTIALS and Context.SECURITY_AUTHENTICATION
+ * appropriately.
+ *
+ * @return properties that are to be used when connecting to LDAP server
+ */
+ private Properties getProperties(Properties options) {
+ Properties env = new Properties(options);
+ // Set our default factory name if one is not given
+ String factoryName = env.getProperty(RHQConstants.LDAPFactory);
+ env.setProperty(Context.INITIAL_CONTEXT_FACTORY, factoryName);
+
+ // Setup SSL if requested
+ String protocol = env.getProperty(RHQConstants.LDAPProtocol);
+ if ((protocol != null) && protocol.equals("ssl")) {
+ String ldapSocketFactory = env.getProperty("java.naming.ldap.factory.socket");
+ if (ldapSocketFactory == null) {
+ env.put("java.naming.ldap.factory.socket", UntrustedSSLSocketFactory.class.getName());
+ }
+ env.put(Context.SECURITY_PROTOCOL, "ssl");
+ }
+
+ // Set the LDAP url
+ String providerUrl = env.getProperty(RHQConstants.LDAPUrl);
+ if (providerUrl == null) {
+ providerUrl = "ldap://localhost:" + (((protocol != null) && protocol.equals("ssl")) ? "636" : "389");
+ }
+
+ env.setProperty(Context.PROVIDER_URL, providerUrl);
+
+ // Follow referrals automatically
+ env.setProperty(Context.REFERRAL, "ignore"); //BZ:582471- active directory query change
+
+ return env;
+ }
+
+ /**
+ * A simple method to construct a SearchControls object for use when doing LDAP searches. All of the defaults are
+ * used, with the exception of the scope, which is set to SUBTREE rather than the default of ONE_LEVEL
+ *
+ * @return controls what is searched in LDAP
+ */
+ private SearchControls getSearchControls() {
+ // Set the scope to subtree, default is one-level
+ int scope = SearchControls.SUBTREE_SCOPE;
+
+ // No limit on the time waiting for a response
+ int timeLimit = 0;
+
+ // No limit on the number of entries returned
+ long countLimit = 0;
+
+ // Attributes to return.
+ String[] returnedAttributes = null;
+
+ // Don't return the object
+ boolean returnObject = false;
+
+ // No dereferencing during the search
+ boolean deference = false;
+
+ SearchControls constraints = new SearchControls(scope, countLimit, timeLimit, returnedAttributes, returnObject,
+ deference);
+ return constraints;
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/LdapGroupManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/LdapGroupManagerLocal.java
new file mode 100644
index 0000000..6709b32
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/LdapGroupManagerLocal.java
@@ -0,0 +1,53 @@
+/*
+ * 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.resource.group;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ejb.Local;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.resource.group.LdapGroup;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
+
+/**
+ * A manager that provides methods for creating, updating, deleting, and querying {@link LdapGroup}s.
+ *
+ * @author Simeon Pinder
+ */
+@Local
+public interface LdapGroupManagerLocal {
+
+ PageList<LdapGroup> findLdapGroupsByRole(int roleId, PageControl pageControl);
+
+ PageList<LdapGroup> findLdapGroups(PageControl pc);
+
+ void addLdapGroupsToRole(Subject subject, int roleId, List<String> groupIds);
+
+ void removeLdapGroupsFromRole(Subject subject, int roleId, int[] groupIds);
+
+ void assignRolesToLdapSubject(int subjectId, List<String> ldapGroupNames);
+
+ Set<Map<String, String>> findAvailableGroups();
+
+ Set<String> findAvailableGroupsFor(String userName);
+}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/LookupUtil.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/LookupUtil.java
index c21526a..e5171e9 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/LookupUtil.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/LookupUtil.java
@@ -155,6 +155,8 @@ import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeManagerRemote;
import org.rhq.enterprise.server.resource.cluster.ClusterManagerBean;
import org.rhq.enterprise.server.resource.cluster.ClusterManagerLocal;
+import org.rhq.enterprise.server.resource.group.LdapGroupManagerBean;
+import org.rhq.enterprise.server.resource.group.LdapGroupManagerLocal;
import org.rhq.enterprise.server.resource.group.ResourceGroupManagerBean;
import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal;
import org.rhq.enterprise.server.resource.group.definition.GroupDefinitionExpressionBuilderManagerBean;
@@ -655,4 +657,8 @@ public final class LookupUtil {
return lookupLocal(DataAccessManagerBean.class);
}
+ public static LdapGroupManagerLocal getLdapGroupManager() {
+ return lookupLocal(LdapGroupManagerBean.class);
+ }
+
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/authz/test/RoleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/authz/test/RoleManagerBeanTest.java
index 2315ee8..c0ae4d9 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/authz/test/RoleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/authz/test/RoleManagerBeanTest.java
@@ -33,6 +33,7 @@ import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
import org.rhq.enterprise.server.authz.RoleManagerLocal;
+import org.rhq.enterprise.server.resource.group.LdapGroupManagerLocal;
import org.rhq.enterprise.server.test.AbstractEJB3Test;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -43,6 +44,7 @@ import org.rhq.enterprise.server.util.LookupUtil;
public class RoleManagerBeanTest extends AbstractEJB3Test {
private SubjectManagerLocal subjectManager;
private RoleManagerLocal roleManager;
+ private LdapGroupManagerLocal ldapManager;
/**
* Prepares things for the entire test class.
@@ -51,6 +53,7 @@ public class RoleManagerBeanTest extends AbstractEJB3Test {
public void beforeClass() {
roleManager = LookupUtil.getRoleManager();
subjectManager = LookupUtil.getSubjectManager();
+ ldapManager = LookupUtil.getLdapGroupManager();
}
/**
@@ -263,7 +266,7 @@ public class RoleManagerBeanTest extends AbstractEJB3Test {
LdapGroup group = new LdapGroup();
group.setName("Foo");
role.addLdapGroup(group);
- assert roleManager.findLdapGroupsByRole(role.getId(), PageControl.getUnlimitedInstance()).size() == 1 : "Ldap Group Foo Should be assigned";
+ assert ldapManager.findLdapGroupsByRole(role.getId(), PageControl.getUnlimitedInstance()).size() == 1 : "Ldap Group Foo Should be assigned";
} finally {
getTransactionManager().rollback();
}
14 years
[rhq] Branch 'gwt' - modules/common modules/plugins
by ips
modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/BundleAntProject.java | 6 +++++
modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/task/DeployTask.java | 11 +++++----
modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/AntBundlePluginComponent.java | 12 +++++++---
modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/DeploymentAuditorBuildListener.java | 11 +++++----
4 files changed, 28 insertions(+), 12 deletions(-)
New commits:
commit e865a40a1ea53b11fdf3b9f0485a1fc55e80ff67
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Tue Apr 27 18:06:18 2010 -0400
diffs are now logged to the Ant project log as well as sent back to the Server to be stored in the deployment history
diff --git a/modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/BundleAntProject.java b/modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/BundleAntProject.java
index 1936997..8849ded 100644
--- a/modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/BundleAntProject.java
+++ b/modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/BundleAntProject.java
@@ -30,6 +30,7 @@ import org.apache.tools.ant.Project;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.util.updater.DeployDifferences;
/**
* This is the Ant project object that is used when processing bundle Ant scripts
@@ -53,6 +54,7 @@ public class BundleAntProject extends Project {
private File deployDir;
private final Set<String> bundleFileNames = new HashSet<String>();
private int deploymentId;
+ private DeployDifferences deployDiffs = new DeployDifferences();
public Set<String> getBundleFileNames() {
return bundleFileNames;
@@ -111,4 +113,8 @@ public class BundleAntProject extends Project {
public void setDeploymentId(int deploymentId) {
this.deploymentId = deploymentId;
}
+
+ public DeployDifferences getDeployDifferences() {
+ return deployDiffs;
+ }
}
diff --git a/modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/task/DeployTask.java b/modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/task/DeployTask.java
index 53df7c9..d9f4118 100644
--- a/modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/task/DeployTask.java
+++ b/modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/task/DeployTask.java
@@ -27,6 +27,7 @@ import java.util.regex.Pattern;
import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
import org.rhq.bundle.ant.type.ArchiveType;
import org.rhq.bundle.ant.type.FileSet;
import org.rhq.bundle.ant.type.FileType;
@@ -69,20 +70,22 @@ public class DeployTask extends AbstractBundleTask {
throw new BuildException("You must specify at least one file to deploy via nested rhq:file and/or rhq:archive elements.");
}
if (!this.files.isEmpty()) {
- log("Deploying files " + this.files + "...");
+ log("Deploying files " + this.files + "...", Project.MSG_VERBOSE);
}
if (!this.archives.isEmpty()) {
- log("Deploying archives " + this.archives + "...");
+ log("Deploying archives " + this.archives + "...", Project.MSG_VERBOSE);
}
Deployer deployer = new Deployer(deploymentProps, this.archives, this.files, deployDir, this.replacePattern,
templateEngine, this.ignorePattern);
try {
- DeployDifferences diff = null;
- deployer.deploy(diff);
+ DeployDifferences diffs = getProject().getDeployDifferences();
+ deployer.deploy(diffs);
+ getProject().log("Results:\n" + diffs + "\n");
} catch (Exception e) {
throw new BuildException("Failed to deploy bundle '" + getProject().getBundleName() + "' version "
+ getProject().getBundleVersion() + ": " + e, e);
}
+
return;
}
diff --git a/modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/AntBundlePluginComponent.java b/modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/AntBundlePluginComponent.java
index f78a5f3..1309f79 100644
--- a/modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/AntBundlePluginComponent.java
+++ b/modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/AntBundlePluginComponent.java
@@ -33,9 +33,7 @@ import org.rhq.bundle.ant.AntLauncher;
import org.rhq.bundle.ant.BundleAntProject;
import org.rhq.bundle.ant.DeployPropertyNames;
import org.rhq.bundle.ant.LoggerAntBuildListener;
-import org.rhq.core.domain.bundle.BundleDeployment;
-import org.rhq.core.domain.bundle.BundleResourceDeployment;
-import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.bundle.*;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertySimple;
@@ -43,10 +41,12 @@ import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.pluginapi.bundle.BundleDeployRequest;
import org.rhq.core.pluginapi.bundle.BundleDeployResult;
import org.rhq.core.pluginapi.bundle.BundleFacet;
+import org.rhq.core.pluginapi.bundle.BundleManagerProvider;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.system.SystemInfoFactory;
import org.rhq.core.util.stream.StreamUtil;
+import org.rhq.core.util.updater.DeployDifferences;
/**
* @author John Mazzitelli
@@ -113,6 +113,12 @@ public class AntBundlePluginComponent implements ResourceComponent, BundleFacet
AntLauncher antLauncher = new AntLauncher();
BundleAntProject project = antLauncher.executeBundleDeployFile(recipeFile, null, antProps,
buildListeners);
+
+ // Send the diffs to the Server so it can store them as an entry in the deployment history.
+ BundleManagerProvider bundleManagerProvider = request.getBundleManagerProvider();
+ DeployDifferences diffs = project.getDeployDifferences();
+ bundleManagerProvider.auditDeployment(resourceDeployment, BundleDeploymentAction.DEPLOYMENT_STEP,
+ BundleDeploymentStatus.SUCCESS, diffs.toString());
} catch (Throwable t) {
if (log.isDebugEnabled()) {
try {
diff --git a/modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/DeploymentAuditorBuildListener.java b/modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/DeploymentAuditorBuildListener.java
index eacc8eb..86bde70 100644
--- a/modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/DeploymentAuditorBuildListener.java
+++ b/modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/DeploymentAuditorBuildListener.java
@@ -31,6 +31,9 @@ import org.rhq.core.domain.bundle.BundleResourceDeployment;
import org.rhq.core.pluginapi.bundle.BundleManagerProvider;
/**
+ * Ant build listener that sends targetFinished and taskFinished events to the Server to be stored as entries in the
+ * deployment history.
+ *
* @author Ian Springer
*/
public class DeploymentAuditorBuildListener implements BuildListener {
@@ -67,7 +70,7 @@ public class DeploymentAuditorBuildListener implements BuildListener {
auditEvent(event);
}
- public void messageLogged(BuildEvent event) {
+ public void messageLogged(BuildEvent event) {
return;
}
@@ -84,6 +87,7 @@ public class DeploymentAuditorBuildListener implements BuildListener {
return;
}
+ @SuppressWarnings({"ThrowableResultOfMethodCallIgnored"})
private static String createMessage(BuildEvent event) {
StringBuilder msg = new StringBuilder();
if (event.getTarget() != null) {
@@ -98,11 +102,8 @@ public class DeploymentAuditorBuildListener implements BuildListener {
msg.append(event.getMessage());
}
- //noinspection ThrowableResultOfMethodCallIgnored
if (event.getException() != null) {
- msg.append("\n");
- //noinspection ThrowableResultOfMethodCallIgnored
- msg.append(StringUtils.getStackTrace(event.getException()));
+ msg.append("\n").append(StringUtils.getStackTrace(event.getException()));
}
return msg.toString();
}
14 years
[rhq] Branch 'gwt' - modules/common modules/core modules/enterprise modules/plugins
by ips
modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/AntLauncher.java | 41 +--
modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/LoggerAntBuildListener.java | 16 -
modules/common/ant-bundle/src/test/java/org/rhq/bundle/ant/AntLauncherTest.java | 41 ++-
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleManagerProvider.java | 20 +
modules/core/plugin-container/src/main/java/org/rhq/core/pc/bundle/BundleManager.java | 1
modules/enterprise/server/plugins/ant-bundle/src/main/java/org/rhq/enterprise/server/plugins/ant/AntBundleServerPluginComponent.java | 3
modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/AntBundlePluginComponent.java | 107 +++++----
modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/DeploymentAuditorBuildListener.java | 109 ++++++++++
modules/plugins/ant-bundle/src/test/java/org/rhq/plugins/ant/AntBundlePluginComponentTest.java | 26 +-
9 files changed, 259 insertions(+), 105 deletions(-)
New commits:
commit 2b9a540779aacae53ddd7af642b13f460c59f5f0
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Tue Apr 27 17:40:26 2010 -0400
Ant bundle agent-plugin now reports target-finished and task-finished Ant events back to Server so they can be saved to the deployment history
diff --git a/modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/AntLauncher.java b/modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/AntLauncher.java
index cc9525c..b29e5e9 100644
--- a/modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/AntLauncher.java
+++ b/modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/AntLauncher.java
@@ -55,17 +55,19 @@ public class AntLauncher {
private final Log log = LogFactory.getLog(AntLauncher.class);
/**
- * Launches Ant and parses the given build file and optionally executes it.
+ * Executes the specified bundle deploy Ant build file (i.e. rhq-deploy.xml).
+ *
+ * @param buildFile the path to the build file (i.e. rhq-deploy.xml)
+ * @param targetName the target to run, <code>null</code> will run the default target
+ * @param buildProperties the properties to pass into Ant
+ * @param buildListeners a list of build listeners (provide callback methods for targetExecuted, taskExecuted, etc.)
*
- * @param buildFile the path to the build file (i.e. rhq-deploy.xml)
- * @param targetName the target to run, <code>null</code> will run the default target
- * @param properties set of properties to set for the Ant task to access
- * @param logFile where Ant messages will be logged
- * @param logStdOut if <code>true</code>, log messages will be sent to stdout as well as the log file
* @return the bundle Ant project containing information about the specified build file
+ *
+ * @throws InvalidBuildFileException if the build file is invalid
*/
- public BundleAntProject executeBundleDeployFile(File buildFile, String targetName, Properties properties,
- File logFile, boolean logStdOut)
+ public BundleAntProject executeBundleDeployFile(File buildFile, String targetName, Properties buildProperties,
+ List<BuildListener> buildListeners)
throws InvalidBuildFileException {
parseBundleDeployFile(buildFile);
@@ -75,12 +77,9 @@ public class AntLauncher {
project.init();
project.setBaseDir(buildFile.getParentFile());
- PrintWriter logFileOutput = null;
try {
- logFileOutput = new PrintWriter(new FileOutputStream(logFile, true));
-
- if (properties != null) {
- for (Map.Entry<Object, Object> property : properties.entrySet()) {
+ if (buildProperties != null) {
+ for (Map.Entry<Object, Object> property : buildProperties.entrySet()) {
// On the assumption that these properties will be slurped in via Properties.load we
// need to escape backslashes to have them treated as literals
project.setUserProperty(property.getKey().toString(), property.getValue().toString().replace("\\",
@@ -93,12 +92,10 @@ public class AntLauncher {
MagicNames.ANT_FILE_TYPE_FILE);
ProjectHelper.configureProject(project, buildFile);
- // notice we are adding the listener after we set the properties - we do not want the
- // the properties echoed out in the log (in case they contain sensitive passwords)
- project.addBuildListener(new LoggerAntBuildListener(targetName, logFileOutput, Project.MSG_DEBUG));
- if (logStdOut) {
- PrintWriter stdout = new PrintWriter(System.out);
- project.addBuildListener(new LoggerAntBuildListener(targetName, stdout, Project.MSG_INFO));
+ if (buildListeners != null) {
+ for (BuildListener buildListener : buildListeners) {
+ project.addBuildListener(buildListener);
+ }
}
// Add tasks defs for the Ant tasks that we bundle, so user won't have to explicitly declare them in their
@@ -114,11 +111,7 @@ public class AntLauncher {
return project;
} catch (Exception e) {
- throw new RuntimeException("Cannot run Ant on build file [" + buildFile + "]. Cause: " + e, e);
- } finally {
- if (logFileOutput != null) {
- logFileOutput.close();
- }
+ throw new RuntimeException("Failed to execute bundle deploy file [" + buildFile.getAbsolutePath() + "]. Cause: " + e, e);
}
}
diff --git a/modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/LoggerAntBuildListener.java b/modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/LoggerAntBuildListener.java
index 6df3294..bcdf37d 100644
--- a/modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/LoggerAntBuildListener.java
+++ b/modules/common/ant-bundle/src/main/java/org/rhq/bundle/ant/LoggerAntBuildListener.java
@@ -27,7 +27,7 @@ import org.apache.tools.ant.Target;
import org.apache.tools.ant.Task;
/**
- * Listens for Ant build events and logs them to a log stream.
+ * Listens for Ant build events and logs them to a print writer.
*
* @author John Mazzitelli
*/
@@ -36,15 +36,15 @@ public class LoggerAntBuildListener implements BuildListener {
private final PrintWriter output;
private final int priorityThreshold;
- public LoggerAntBuildListener(String target, PrintWriter logFile, int priorityThreshold) {
+ public LoggerAntBuildListener(String target, PrintWriter printWriter, int priorityThreshold) {
this.mainTarget = (target != null) ? target : "(default)";
- this.output = logFile;
+ this.output = printWriter;
this.priorityThreshold = priorityThreshold;
// start with the date this was started
this.output.println("======================================");
this.output.println("Ant target [" + this.mainTarget + "]");
- this.output.println(new Date().toString());
+ this.output.println(new Date());
this.output.println("======================================");
}
@@ -57,7 +57,9 @@ public class LoggerAntBuildListener implements BuildListener {
}
public void messageLogged(BuildEvent event) {
- logEvent(event, null);
+ if (event.getPriority() <= this.priorityThreshold) {
+ logEvent(event, null);
+ }
}
public void targetFinished(BuildEvent event) {
@@ -77,10 +79,6 @@ public class LoggerAntBuildListener implements BuildListener {
}
private void logEvent(BuildEvent event, String additionalMessage) {
- if (event.getPriority() > this.priorityThreshold) {
- return;
- }
-
String message = event.getMessage();
Throwable exception = event.getException();
Target target = event.getTarget();
diff --git a/modules/common/ant-bundle/src/test/java/org/rhq/bundle/ant/AntLauncherTest.java b/modules/common/ant-bundle/src/test/java/org/rhq/bundle/ant/AntLauncherTest.java
index 2c98845..7235815 100644
--- a/modules/common/ant-bundle/src/test/java/org/rhq/bundle/ant/AntLauncherTest.java
+++ b/modules/common/ant-bundle/src/test/java/org/rhq/bundle/ant/AntLauncherTest.java
@@ -25,9 +25,13 @@ package org.rhq.bundle.ant;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Properties;
-import org.testng.annotations.BeforeMethod;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.DefaultLogger;
+import org.apache.tools.ant.Project;
import org.testng.annotations.Test;
import org.rhq.core.domain.configuration.Configuration;
@@ -36,23 +40,14 @@ import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
import org.rhq.core.domain.configuration.definition.PropertySimpleType;
import org.rhq.core.util.file.FileUtil;
+/**
+ * @author John Mazzitelli
+ * @author Ian Springer
+ */
@Test
public class AntLauncherTest {
private static final File DEPLOY_DIR = new File("target/test-ant-bundle").getAbsoluteFile();
- private File logFile;
-
- @BeforeMethod
- public void beforeMethod() {
- logFile = new File("target/test-ant-log.txt");
- if (logFile.exists()) {
- if (!logFile.delete()) {
- System.out.println("Failed to delete log file [" + this.logFile + "] prior to executing test method.");
- }
- }
- return;
- }
-
public void testParse() throws Exception {
AntLauncher ant = new AntLauncher();
@@ -75,8 +70,10 @@ public class AntLauncherTest {
AntLauncher ant = new AntLauncher();
Properties inputProps = createInputProperties("/test-bundle-v1-input.properties");
+ List<BuildListener> buildListeners = createBuildListeners();
+
BundleAntProject project = ant.executeBundleDeployFile(getBuildXml("test-bundle-v1.xml"), "deploy", inputProps,
- this.logFile, true);
+ buildListeners);
/*Map<String, String> bundleFiles = project.getBundleFiles();
assert bundleFiles != null;
assert bundleFiles.size() == 2 : bundleFiles;
@@ -94,14 +91,26 @@ public class AntLauncherTest {
assert "10000".equals(config.getSimpleValue("listener.port", null)) : config.getProperties();
}
+ private List<BuildListener> createBuildListeners() {
+ List<BuildListener> buildListeners = new ArrayList<BuildListener>();
+ DefaultLogger logger = new DefaultLogger();
+ logger.setMessageOutputLevel(Project.MSG_DEBUG);
+ logger.setOutputPrintStream(System.out);
+ logger.setErrorPrintStream(System.err);
+ buildListeners.add(logger);
+ return buildListeners;
+ }
+
@Test(dependsOnMethods = "testInstall")
public void testUpgrade() throws Exception {
// We want to test an upgrade, so do *not* wipe out the deploy dir.
AntLauncher ant = new AntLauncher();
Properties inputProps = createInputProperties("/test-bundle-v2-input.properties");
+ List<BuildListener> buildListeners = createBuildListeners();
+
BundleAntProject project = ant.executeBundleDeployFile(getBuildXml("test-bundle-v2.xml"), "deploy", inputProps,
- this.logFile, true);
+ buildListeners);
/*Map<String, String> bundleFiles = project.getBundleFiles();
assert bundleFiles != null;
assert bundleFiles.size() == 2 : bundleFiles;
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleManagerProvider.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleManagerProvider.java
index 00ba3d6..7c816c9 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleManagerProvider.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleManagerProvider.java
@@ -16,7 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
package org.rhq.core.pluginapi.bundle;
import java.io.OutputStream;
@@ -37,9 +36,12 @@ public interface BundleManagerProvider {
/**
* Bundle plugins call back into this manager to add progressive auditing of a deployment.
*
- * @param bundleVersion
- * @return the bundle files that are associated with the given bundle
- * @throws Exception
+ * @param deployment
+ * @param action
+ * @param status
+ * @param message
+ *
+ * @throws Exception on failure
*/
void auditDeployment(BundleResourceDeployment deployment, BundleDeploymentAction action,
BundleDeploymentStatus status, String message) throws Exception;
@@ -47,9 +49,11 @@ public interface BundleManagerProvider {
/**
* Bundle plugins call back into this manager to obtain the bundle files that belong to a given bundle version.
*
- * @param bundleVersion
+ * @param bundleVersion a bundle version
+ *
* @return the bundle files that are associated with the given bundle
- * @throws Exception
+ *
+ * @throws Exception on failure
*/
List<PackageVersion> getAllBundleVersionPackageVersions(BundleVersion bundleVersion) throws Exception;
@@ -58,8 +62,10 @@ public interface BundleManagerProvider {
*
* @param packageVersion the package whose bits are to be downloaded
* @param outputStream where the package bits will get written to
+ *
* @return the size of the package version content that was downloaded and output
- * @throws Exception
+ *
+ * @throws Exception on failure
*/
long getFileContent(PackageVersion packageVersion, OutputStream outputStream) throws Exception;
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/bundle/BundleManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/bundle/BundleManager.java
index 0b633d7..2f49887 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/bundle/BundleManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/bundle/BundleManager.java
@@ -170,6 +170,7 @@ public class BundleManager extends AgentService implements BundleAgentService, B
}
BundleResourceDeploymentHistory history = new BundleResourceDeploymentHistory("Bundle Plugin", action, status,
message);
+ log.debug("Reporting deployment step [" + history + "] to Server...");
getBundleServerService().addDeploymentHistory(bundleResourceeployment.getId(), history);
}
diff --git a/modules/enterprise/server/plugins/ant-bundle/src/main/java/org/rhq/enterprise/server/plugins/ant/AntBundleServerPluginComponent.java b/modules/enterprise/server/plugins/ant-bundle/src/main/java/org/rhq/enterprise/server/plugins/ant/AntBundleServerPluginComponent.java
index 9301abd..6309b55 100644
--- a/modules/enterprise/server/plugins/ant-bundle/src/main/java/org/rhq/enterprise/server/plugins/ant/AntBundleServerPluginComponent.java
+++ b/modules/enterprise/server/plugins/ant-bundle/src/main/java/org/rhq/enterprise/server/plugins/ant/AntBundleServerPluginComponent.java
@@ -38,7 +38,7 @@ import org.rhq.enterprise.server.plugin.pc.ServerPluginContext;
import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginFacet;
/**
- * A bundle server-side plugin component that the server uses to process ant-based bundles.
+ * A bundle server-side plugin component that the server uses to process Ant-based bundles.
*
* @author John Mazzitelli
*/
@@ -52,6 +52,7 @@ public class AntBundleServerPluginComponent implements ServerPluginComponent, Bu
public void initialize(ServerPluginContext context) throws Exception {
this.context = context;
this.tmpDirectory = new File(this.context.getTemporaryDirectory(), "ant-bundle-server-plugin");
+ //noinspection ResultOfMethodCallIgnored
this.tmpDirectory.mkdirs();
if (!this.tmpDirectory.exists() || !this.tmpDirectory.isDirectory()) {
throw new Exception("Failed to create tmp dir [" + this.tmpDirectory + "] - cannot process Ant bundles");
diff --git a/modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/AntBundlePluginComponent.java b/modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/AntBundlePluginComponent.java
index 6f9d206..f78a5f3 100644
--- a/modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/AntBundlePluginComponent.java
+++ b/modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/AntBundlePluginComponent.java
@@ -18,19 +18,21 @@
*/
package org.rhq.plugins.ant;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.Project;
import org.rhq.bundle.ant.AntLauncher;
import org.rhq.bundle.ant.BundleAntProject;
import org.rhq.bundle.ant.DeployPropertyNames;
+import org.rhq.bundle.ant.LoggerAntBuildListener;
import org.rhq.core.domain.bundle.BundleDeployment;
import org.rhq.core.domain.bundle.BundleResourceDeployment;
import org.rhq.core.domain.bundle.BundleVersion;
@@ -86,52 +88,31 @@ public class AntBundlePluginComponent implements ResourceComponent, BundleFacet
String recipe = bundleVersion.getRecipe();
File recipeFile = File.createTempFile("ant-bundle-recipe", ".xml", request.getBundleFilesLocation());
File logFile = File.createTempFile("ant-bundle-recipe", ".log", this.tmpDirectory);
+ PrintWriter logFileOutput = null;
try {
- // store the recipe in the tmp recipe file
+ // Open the log file for writing.
+ logFileOutput = new PrintWriter(new FileOutputStream(logFile, true));
+
+ // Store the recipe in the tmp recipe file.
ByteArrayInputStream in = new ByteArrayInputStream(recipe.getBytes());
FileOutputStream out = new FileOutputStream(recipeFile);
StreamUtil.copy(in, out);
- // get the bundle's configuration values and the global system facts and
- // add them as Ant properties so the ant script can get their values
- Properties antProps = new Properties();
-
- String installDir = bundleDeployment.getInstallDir();
- if (installDir == null) {
- throw new IllegalStateException("Bundle deployment does not specify install dir: "
- + bundleDeployment);
- }
- antProps.setProperty(DeployPropertyNames.DEPLOY_DIR, installDir);
-
- int deploymentId = bundleDeployment.getId();
- antProps.setProperty(DeployPropertyNames.DEPLOY_ID, Integer.toString(deploymentId));
-
- Map<String, String> sysFacts = SystemInfoFactory.fetchTemplateEngine().getTokens();
- for (Map.Entry<String, String> fact : sysFacts.entrySet()) {
- antProps.setProperty(fact.getKey(), fact.getValue());
- }
+ // Get the bundle's configuration values and the global system facts and
+ // add them as Ant properties so the ant script can get their values.
+ Properties antProps = createAntProperties(bundleDeployment);
- Configuration config = bundleDeployment.getConfiguration();
- if (config != null) {
- Map<String, Property> allProperties = config.getAllProperties();
- for (Map.Entry<String, Property> entry : allProperties.entrySet()) {
- String name = entry.getKey();
- Property prop = entry.getValue();
- String value;
- if (prop instanceof PropertySimple) {
- value = ((PropertySimple) prop).getStringValue();
- } else {
- // for now, just skip all property lists and maps, just assume we are getting simples
- continue;
- }
- antProps.setProperty(name, value);
- }
- }
+ List<BuildListener> buildListeners = new ArrayList();
+ LoggerAntBuildListener logger = new LoggerAntBuildListener(null, logFileOutput, Project.MSG_DEBUG);
+ buildListeners.add(logger);
+ DeploymentAuditorBuildListener auditor = new DeploymentAuditorBuildListener(
+ request.getBundleManagerProvider(), resourceDeployment);
+ buildListeners.add(auditor);
- // parse & execute the Ant script
+ // Parse & execute the Ant script.
AntLauncher antLauncher = new AntLauncher();
- BundleAntProject project = antLauncher.executeBundleDeployFile(recipeFile, null, antProps, logFile,
- true);
+ BundleAntProject project = antLauncher.executeBundleDeployFile(recipeFile, null, antProps,
+ buildListeners);
} catch (Throwable t) {
if (log.isDebugEnabled()) {
try {
@@ -139,8 +120,11 @@ public class AntBundlePluginComponent implements ResourceComponent, BundleFacet
} catch (Exception e) {
}
}
- throw new Exception("Failed to parse the bundle Ant script", t);
+ throw new Exception("Failed to execute the bundle Ant script", t);
} finally {
+ if (logFileOutput != null) {
+ logFileOutput.close();
+ }
recipeFile.delete();
logFile.delete();
}
@@ -151,4 +135,41 @@ public class AntBundlePluginComponent implements ResourceComponent, BundleFacet
}
return result;
}
+
+ private Properties createAntProperties(BundleDeployment bundleDeployment) {
+ Properties antProps = new Properties();
+
+ String installDir = bundleDeployment.getInstallDir();
+ if (installDir == null) {
+ throw new IllegalStateException("Bundle deployment does not specify install dir: "
+ + bundleDeployment);
+ }
+ antProps.setProperty(DeployPropertyNames.DEPLOY_DIR, installDir);
+
+ int deploymentId = bundleDeployment.getId();
+ antProps.setProperty(DeployPropertyNames.DEPLOY_ID, Integer.toString(deploymentId));
+
+ Map<String, String> sysFacts = SystemInfoFactory.fetchTemplateEngine().getTokens();
+ for (Map.Entry<String, String> fact : sysFacts.entrySet()) {
+ antProps.setProperty(fact.getKey(), fact.getValue());
+ }
+
+ Configuration config = bundleDeployment.getConfiguration();
+ if (config != null) {
+ Map<String, Property> allProperties = config.getAllProperties();
+ for (Map.Entry<String, Property> entry : allProperties.entrySet()) {
+ String name = entry.getKey();
+ Property prop = entry.getValue();
+ String value;
+ if (prop instanceof PropertySimple) {
+ value = ((PropertySimple) prop).getStringValue();
+ } else {
+ // for now, just skip all property lists and maps, just assume we are getting simples
+ continue;
+ }
+ antProps.setProperty(name, value);
+ }
+ }
+ return antProps;
+ }
}
diff --git a/modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/DeploymentAuditorBuildListener.java b/modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/DeploymentAuditorBuildListener.java
new file mode 100644
index 0000000..eacc8eb
--- /dev/null
+++ b/modules/plugins/ant-bundle/src/main/java/org/rhq/plugins/ant/DeploymentAuditorBuildListener.java
@@ -0,0 +1,109 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2010 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.plugins.ant;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.util.StringUtils;
+import org.rhq.core.domain.bundle.BundleDeploymentAction;
+import org.rhq.core.domain.bundle.BundleDeploymentStatus;
+import org.rhq.core.domain.bundle.BundleResourceDeployment;
+import org.rhq.core.pluginapi.bundle.BundleManagerProvider;
+
+/**
+ * @author Ian Springer
+ */
+public class DeploymentAuditorBuildListener implements BuildListener {
+ private BundleManagerProvider bundleManagerProvider;
+ private BundleResourceDeployment bundleResourceDeployment;
+
+ public DeploymentAuditorBuildListener(BundleManagerProvider bundleManagerProvider,
+ BundleResourceDeployment bundleResourceDeployment) {
+ this.bundleManagerProvider = bundleManagerProvider;
+ this.bundleResourceDeployment = bundleResourceDeployment;
+ }
+
+ public void buildStarted(BuildEvent event) {
+ return;
+ }
+
+ public void buildFinished(BuildEvent event) {
+ return;
+ }
+
+ public void targetStarted(BuildEvent event) {
+ return;
+ }
+
+ public void targetFinished(BuildEvent event) {
+ auditEvent(event);
+ }
+
+ public void taskStarted(BuildEvent event) {
+ return;
+ }
+
+ public void taskFinished(BuildEvent event) {
+ auditEvent(event);
+ }
+
+ public void messageLogged(BuildEvent event) {
+ return;
+ }
+
+ private void auditEvent(BuildEvent event) {
+ BundleDeploymentStatus status = (event.getException() == null) ? BundleDeploymentStatus.SUCCESS :
+ BundleDeploymentStatus.FAILURE;
+ String message = createMessage(event);
+ try {
+ this.bundleManagerProvider.auditDeployment(this.bundleResourceDeployment,
+ BundleDeploymentAction.DEPLOYMENT_STEP, status, message);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return;
+ }
+
+ private static String createMessage(BuildEvent event) {
+ StringBuilder msg = new StringBuilder();
+ if (event.getTarget() != null) {
+ msg.append("[").append(event.getTarget().getName()).append("] ");
+ }
+
+ if (event.getTask() != null) {
+ msg.append("<").append(event.getTask().getTaskName()).append("> ");
+ }
+
+ if (event.getMessage() != null) {
+ msg.append(event.getMessage());
+ }
+
+ //noinspection ThrowableResultOfMethodCallIgnored
+ if (event.getException() != null) {
+ msg.append("\n");
+ //noinspection ThrowableResultOfMethodCallIgnored
+ msg.append(StringUtils.getStackTrace(event.getException()));
+ }
+ return msg.toString();
+ }
+}
diff --git a/modules/plugins/ant-bundle/src/test/java/org/rhq/plugins/ant/AntBundlePluginComponentTest.java b/modules/plugins/ant-bundle/src/test/java/org/rhq/plugins/ant/AntBundlePluginComponentTest.java
index d7ec711..32b5f3e 100644
--- a/modules/plugins/ant-bundle/src/test/java/org/rhq/plugins/ant/AntBundlePluginComponentTest.java
+++ b/modules/plugins/ant-bundle/src/test/java/org/rhq/plugins/ant/AntBundlePluginComponentTest.java
@@ -25,18 +25,18 @@ package org.rhq.plugins.ant;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import org.rhq.core.domain.bundle.*;
+import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.pluginapi.bundle.BundleManagerProvider;
import org.rhq.core.util.file.FileUtil;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
-import org.rhq.core.domain.bundle.Bundle;
-import org.rhq.core.domain.bundle.BundleDeployment;
-import org.rhq.core.domain.bundle.BundleResourceDeployment;
-import org.rhq.core.domain.bundle.BundleType;
-import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.content.PackageType;
@@ -143,6 +143,7 @@ public class AntBundlePluginComponentTest {
BundleDeployRequest request = new BundleDeployRequest();
request.setBundleFilesLocation(tmpDir);
request.setResourceDeployment(new BundleResourceDeployment(deployment, null));
+ request.setBundleManagerProvider(new MockBundleManagerProvider());
BundleDeployResult results = plugin.deployBundle(request);
@@ -160,4 +161,19 @@ public class AntBundlePluginComponentTest {
byte[] contents = StreamUtil.slurp(stream);
return new String(contents);
}
+
+ private class MockBundleManagerProvider implements BundleManagerProvider {
+ public void auditDeployment(BundleResourceDeployment deployment, BundleDeploymentAction action,
+ BundleDeploymentStatus status, String message) throws Exception {
+ System.out.println("Auditing deployment step [" + message + "]...");
+ }
+
+ public List<PackageVersion> getAllBundleVersionPackageVersions(BundleVersion bundleVersion) throws Exception {
+ return null;
+ }
+
+ public long getFileContent(PackageVersion packageVersion, OutputStream outputStream) throws Exception {
+ return 0;
+ }
+ }
}
14 years
[rhq] modules/core
by Joseph Marques
modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml | 1 -
1 file changed, 1 deletion(-)
New commits:
commit 03be63bc157f46c0c6192e25063da5fcf6b76e73
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Apr 27 16:35:00 2010 -0400
oops, referring to a table that no longer exists
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml b/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml
index 145b8e2..1837d73 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml
@@ -124,7 +124,6 @@
<column name="ID" default="sequence-only" initial="10001"
primarykey="true" required="true" type="INTEGER"/>
<column name="ALERT_DEFINITION_ID" required="false" type="INTEGER" references="RHQ_ALERT_DEFINITION(ID)"/>
- <column name="TEMPLATE_ID" required="false" type="INTEGER" references="RHQ_ALERT_NOTIF_TEMPL(ID)"/>
<column name="SENDER_CONFIG_ID" required="false" type="INTEGER" references="RHQ_CONFIG(ID)"/>
<column name="SENDER_NAME" required="true" size="100" type="VARCHAR2" />
</table>
14 years
[rhq] 3 commits - modules/enterprise
by Joseph Marques
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/common/paging/PagedListDataModel.java | 4 -
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/WebUserPreferences.java | 10 +++-
modules/enterprise/gui/portal-war/src/main/webapp/rhq/inventory/browseGroups.xhtml | 8 +--
modules/enterprise/gui/portal-war/src/main/webapp/rhq/inventory/browseResources.xhtml | 12 ++---
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java | 24 +++++++---
5 files changed, 38 insertions(+), 20 deletions(-)
New commits:
commit e2e2e300fa0fe5441b962cd7c109e13a2c2f8eb9
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Apr 27 16:25:52 2010 -0400
improve debug logging for pagination/sorting issues, so that root cause can more readily be determined in the future
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/WebUserPreferences.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/WebUserPreferences.java
index a939ab4..c0abd7e 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/WebUserPreferences.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/WebUserPreferences.java
@@ -693,16 +693,21 @@ public class WebUserPreferences extends SubjectPreferencesBase {
}
public PageControl getPageControl(PageControlView view) {
- return getPageControl(view, 15);
+ PageControl results = getPageControl(view, 15);
+ log.debug("getPageControl(" + view + ") " + results);
+ return results;
}
public PageControl getPageControl(PageControlView view, int defaultPageSize) {
if (view == PageControlView.NONE) {
+ log.debug("getPageControl(" + view + ") -> PageControl.getUnlimitedInstance()");
return PageControl.getUnlimitedInstance();
}
List<String> pageControlProperties = getPreferenceAsList(view.toString());
+ log.debug("getPageControl(" + view + ") -> pageControlProperties: " + pageControlProperties);
if (pageControlProperties.size() == 0) {
+ log.debug("getPageControl(" + view + ") -> getDefaultPageControl for empty properties");
PageControl defaultControl = getDefaultPageControl(view, defaultPageSize);
return defaultControl;
} else {
@@ -722,6 +727,7 @@ public class WebUserPreferences extends SubjectPreferencesBase {
i += 2;
}
+ log.debug("getPageControl(" + view + ") -> " + pageControl);
if (view.isUnlimited() && pageSize != PageControl.SIZE_UNLIMITED) {
// make sure pageSize for an unlimited view is actually unlimited
@@ -739,6 +745,7 @@ public class WebUserPreferences extends SubjectPreferencesBase {
* persist and load just fine because the logic in this method and its counterpart
* setPageControl are kept in sync
*/
+ log.debug("getPageControl(" + view + ") -> getDefaultPageControl for exception: " + t.getMessage());
pageControl = getDefaultPageControl(view, defaultPageSize);
}
return pageControl;
@@ -770,6 +777,7 @@ public class WebUserPreferences extends SubjectPreferencesBase {
pageControlProperties.add(field.getOrdering().toString());
pageControlProperties.add(field.getField());
}
+ System.out.println("setPageControl(" + view + ", " + pageControl + ")");
setPreference(view.toString(), pageControlProperties);
}
commit 85f04f40d6ca346279b916804e3c23a486ba98a8
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Apr 27 16:25:19 2010 -0400
do now swallow the error message when their appears to be an error handling PageControl data
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/common/paging/PagedListDataModel.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/common/paging/PagedListDataModel.java
index adbc7cf..ca3f353 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/common/paging/PagedListDataModel.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/common/paging/PagedListDataModel.java
@@ -340,9 +340,7 @@ public abstract class PagedListDataModel<T> extends DataModel {
* ordering (though the underlying SLSB may add a default ordering downstream).
*/
resetToDefaults(pc);
- if (log.isTraceEnabled()) {
- log.trace(pageControlView + ": Received error[" + t.getMessage() + "], resetting to " + pc);
- }
+ log.error(pageControlView + ": Received error[" + t.getMessage() + "], resetting to " + pc);
tryQueryAgain = true;
}
commit d568a683944cbb81c717589f7c8c1a341a0ae433
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Apr 27 16:24:38 2010 -0400
BZ-584149 fix for broken sorting on the inventory browser (resources and groups)
* CriteriaQueryGenerator now automatically prepends the alias to the ordering fields when building the query
* needed to remove explicit alias identifier from the sortableColumnHeader definitions
* also, updated CriteriaQueryGenerator to support sorting by column ordinals (required by group browser's availability columns)
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/inventory/browseGroups.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/inventory/browseGroups.xhtml
index 65be544..70d9821 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/inventory/browseGroups.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/inventory/browseGroups.xhtml
@@ -144,7 +144,7 @@
<rich:column>
<f:facet name="header">
- <onc:sortableColumnHeader sort="rg.name">
+ <onc:sortableColumnHeader sort="name">
<h:outputText styleClass="headerText" value="Name" />
</onc:sortableColumnHeader>
</f:facet>
@@ -157,7 +157,7 @@
<rich:column>
<f:facet name="header">
- <onc:sortableColumnHeader sort="rg.resourceType.name">
+ <onc:sortableColumnHeader sort="resourceType.name">
<h:outputText styleClass="headerText" value="Group Type" />
</onc:sortableColumnHeader>
</f:facet>
@@ -167,7 +167,7 @@
<rich:column>
<f:facet name="header">
- <onc:sortableColumnHeader sort="rg.resourceType.plugin">
+ <onc:sortableColumnHeader sort="resourceType.plugin">
<h:outputText styleClass="headerText" value="Plugin" />
</onc:sortableColumnHeader>
</f:facet>
@@ -177,7 +177,7 @@
<rich:column>
<f:facet name="header">
- <onc:sortableColumnHeader sort="rg.description">
+ <onc:sortableColumnHeader sort="description">
<h:outputText styleClass="headerText" value="Description" />
</onc:sortableColumnHeader>
</f:facet>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/inventory/browseResources.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/inventory/browseResources.xhtml
index 90d45c0..3a4c7ea 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/inventory/browseResources.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/inventory/browseResources.xhtml
@@ -157,7 +157,7 @@
<rich:column>
<f:facet name="header">
- <onc:sortableColumnHeader sort="r.name">
+ <onc:sortableColumnHeader sort="name">
<h:outputText styleClass="headerText" value="Name" />
</onc:sortableColumnHeader>
</f:facet>
@@ -178,7 +178,7 @@
<rich:column>
<f:facet name="header">
- <onc:sortableColumnHeader sort="r.resourceType.category">
+ <onc:sortableColumnHeader sort="resourceType.category">
<h:outputText styleClass="headerText" value="Category" />
</onc:sortableColumnHeader>
</f:facet>
@@ -188,7 +188,7 @@
<rich:column>
<f:facet name="header">
- <onc:sortableColumnHeader sort="r.resourceType.name">
+ <onc:sortableColumnHeader sort="resourceType.name">
<h:outputText styleClass="headerText" value="Type" />
</onc:sortableColumnHeader>
</f:facet>
@@ -198,7 +198,7 @@
<rich:column>
<f:facet name="header">
- <onc:sortableColumnHeader sort="r.resourceType.plugin">
+ <onc:sortableColumnHeader sort="resourceType.plugin">
<h:outputText styleClass="headerText" value="Plugin" />
</onc:sortableColumnHeader>
</f:facet>
@@ -208,7 +208,7 @@
<rich:column>
<f:facet name="header">
- <onc:sortableColumnHeader sort="r.description">
+ <onc:sortableColumnHeader sort="description">
<h:outputText styleClass="headerText" value="Description" />
</onc:sortableColumnHeader>
</f:facet>
@@ -218,7 +218,7 @@
<rich:column>
<f:facet name="header">
- <onc:sortableColumnHeader sort="r.currentAvailability.availabilityType">
+ <onc:sortableColumnHeader sort="currentAvailability.availabilityType">
<h:outputText styleClass="headerText" value="Availability" />
</onc:sortableColumnHeader>
</f:facet>
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
index ff71760..2272f12 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
@@ -302,15 +302,15 @@ public final class CriteriaQueryGenerator {
String fieldName = orderingField.getField();
String override = criteria.getJPQLSortOverride(fieldName);
- if (override == null) {
- override = alias + "." + fieldName;
- } else {
- override = alias + "." + override;
- }
+ String suffix = (override == null) ? fieldName : override;
+
+ // if the suffix is numerical, do not prefix the alias
+ // this allows us to sort by column ordinal, which is required for availability on the group browser
+ String sortFragment = (isNumber(suffix)) ? suffix : (alias + "." + suffix);
PageOrdering ordering = orderingField.getOrdering();
- results.append(override).append(' ').append(ordering);
+ results.append(sortFragment).append(' ').append(ordering);
}
}
results.append(NL);
@@ -319,6 +319,18 @@ public final class CriteriaQueryGenerator {
return results.toString();
}
+ private boolean isNumber(String input) {
+ if (input == null) {
+ return false;
+ }
+ for (char next : input.toCharArray()) {
+ if (Character.isDigit(next) == false) {
+ return false;
+ }
+ }
+ return true;
+ }
+
public List<String> getFetchFields(Criteria criteria) {
List<String> results = new ArrayList<String>();
for (Field fetchField : getFields(criteria, Criteria.Type.FETCH)) {
14 years